using System; using System.Collections; using System.Collections.Generic; using EasyLayout; using UnityEngine; using UnityEngine.UI; namespace UIWidgets { public class Notify : MonoBehaviour, ITemplatable { [SerializeField] private Button hideButton; [SerializeField] private Text text; [SerializeField] private float HideDelay = 10f; private bool isTemplate = true; private static Templates templates; public Func ShowAnimation; public Func HideAnimation; private Func oldShowAnimation; private Func oldHideAnimation; private IEnumerator showCorutine; private IEnumerator hideCorutine; public bool SlideUpOnHide = true; public float SequenceDelay; private static NotifySequenceManager notifyManager; private Action OnHideCallback; private static Stack slides = new Stack(); public Button HideButton { get { return hideButton; } set { if (hideButton != null) { hideButton.onClick.RemoveListener(Hide); } hideButton = value; if (hideButton != null) { hideButton.onClick.AddListener(Hide); } } } public Text Text { get { return text; } set { text = value; } } public bool IsTemplate { get { return isTemplate; } set { isTemplate = value; } } public string TemplateName { get; set; } public static Templates Templates { get { if (templates == null) { templates = new Templates(AddCloseCallback); } return templates; } set { templates = value; } } public static NotifySequenceManager NotifyManager { get { if (notifyManager == null) { GameObject gameObject = new GameObject("NotifySequenceManager"); notifyManager = gameObject.AddComponent(); } return notifyManager; } } private void Awake() { if (IsTemplate) { base.gameObject.SetActive(false); } } private static void FindTemplates() { Templates.FindTemplates(); } private void OnDestroy() { HideButton = null; if (!IsTemplate) { templates = null; } else if (TemplateName != null) { DeleteTemplate(TemplateName); } } public static void ClearCache() { Templates.ClearCache(); } public static void ClearCache(string templateName) { Templates.ClearCache(templateName); } public static Notify GetTemplate(string template) { return Templates.Get(template); } public static void DeleteTemplate(string template) { Templates.Delete(template); } public static void AddTemplate(string template, Notify notifyTemplate, bool replace = true) { Templates.Add(template, notifyTemplate, replace); } public static Notify Template(string template) { return Templates.Instance(template); } private static void AddCloseCallback(Notify notify) { if (!(notify.hideButton == null)) { notify.hideButton.onClick.AddListener(notify.Hide); } } public void Show(string message = null, float? customHideDelay = null, Transform container = null, Func showAnimation = null, Func hideAnimation = null, bool? slideUpOnHide = null, NotifySequence sequenceType = NotifySequence.None, float sequenceDelay = 0.3f, bool clearSequence = false) { if (clearSequence) { NotifyManager.Clear(); } SequenceDelay = sequenceDelay; oldShowAnimation = ShowAnimation; oldHideAnimation = HideAnimation; if (message != null && text != null) { text.text = message; } if (container != null) { base.transform.SetParent(container, false); } if (customHideDelay.HasValue) { HideDelay = customHideDelay.Value; } if (slideUpOnHide.HasValue) { SlideUpOnHide = slideUpOnHide.Value; } if (showAnimation != null) { ShowAnimation = showAnimation; } if (hideAnimation != null) { HideAnimation = hideAnimation; } if (sequenceType != NotifySequence.None) { NotifyManager.Add(this, sequenceType); } else { Display(); } } public void Display(Action onHideCallback = null) { base.transform.SetAsLastSibling(); base.gameObject.SetActive(true); OnHideCallback = onHideCallback; if (ShowAnimation != null) { showCorutine = ShowAnimation(this); StartCoroutine(showCorutine); } else { showCorutine = null; } if (HideDelay > 0f) { hideCorutine = HideCorutine(); StartCoroutine(hideCorutine); } else { hideCorutine = null; } } private IEnumerator HideCorutine() { yield return new WaitForSeconds(HideDelay); if (HideAnimation != null) { yield return StartCoroutine(HideAnimation(this)); } Hide(); } public void Hide() { if (SlideUpOnHide) { SlideUp(); } if (OnHideCallback != null) { OnHideCallback(); } Return(); } public void Return() { Templates.ToCache(this); ShowAnimation = oldShowAnimation; HideAnimation = oldHideAnimation; if (text != null) { text.text = Templates.Get(TemplateName).text.text; } } private RectTransform GetSlide() { RectTransform rectTransform; if (slides.Count == 0) { GameObject gameObject = new GameObject("SlideUp"); gameObject.SetActive(false); rectTransform = gameObject.AddComponent(); gameObject.AddComponent(); Image image = gameObject.AddComponent(); image.color = Color.clear; } else { do { rectTransform = ((slides.Count <= 0) ? GetSlide() : slides.Pop()); } while (rectTransform == null); } return rectTransform; } private void SlideUp() { RectTransform slide = GetSlide(); SlideUp component = slide.GetComponent(); RectTransform rectTransform = base.transform as RectTransform; slide.localRotation = rectTransform.localRotation; slide.localPosition = rectTransform.localPosition; slide.localScale = rectTransform.localScale; slide.anchorMin = rectTransform.anchorMin; slide.anchorMax = rectTransform.anchorMax; slide.anchoredPosition = rectTransform.anchoredPosition; slide.anchoredPosition3D = rectTransform.anchoredPosition3D; slide.sizeDelta = rectTransform.sizeDelta; slide.pivot = rectTransform.pivot; slide.transform.SetParent(base.transform.parent, false); slide.transform.SetSiblingIndex(base.transform.GetSiblingIndex()); slide.gameObject.SetActive(true); component.Run(); } public static void FreeSlide(RectTransform slide) { slides.Push(slide); } public static IEnumerator AnimationRotate(Notify notify) { RectTransform rect = notify.transform as RectTransform; Vector3 start_rotarion = rect.rotation.eulerAngles; float time = 0.5f; float end_time = Time.time + time; while (Time.time <= end_time) { float rotation_x = Mathf.Lerp(0f, 90f, 1f - (end_time - Time.time) / time); rect.rotation = Quaternion.Euler(rotation_x, start_rotarion.y, start_rotarion.z); yield return null; } rect.rotation = Quaternion.Euler(start_rotarion); } public static IEnumerator AnimationCollapse(Notify notify) { RectTransform rect = notify.transform as RectTransform; global::EasyLayout.EasyLayout layout = notify.GetComponentInParent(); float max_height = rect.rect.height; float speed = 200f; float time = max_height / speed; float end_time = Time.time + time; while (Time.time <= end_time) { float height = Mathf.Lerp(max_height, 0f, 1f - (end_time - Time.time) / time); rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, height); if (layout != null) { layout.UpdateLayout(); } yield return null; } rect.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, max_height); } } }