namespace UIWidgets
{
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;
///
/// Modal helper for UI widgets.
/// modalKey = ModalHelper.Open(this, modalSprite, modalColor);
/// //...
/// ModalHelper.Close(modalKey);
///
[RequireComponent(typeof(RectTransform))]
public class ModalHelper : MonoBehaviour, ITemplatable, IPointerClickHandler
{
static readonly Dictionary Used = new Dictionary();
static Templates Templates = new Templates();
static string key = "ModalTemplate";
#if UNITY_2019_3_OR_NEWER
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void StaticInit()
{
Templates = new Templates();
Used.Clear();
key = "ModalTemplate";
}
#endif
bool isTemplate = true;
///
/// Gets a value indicating whether this instance is template.
///
/// true if this instance is template; otherwise, false.
public bool IsTemplate
{
get
{
return isTemplate;
}
set
{
isTemplate = value;
}
}
///
/// Gets the name of the template.
///
/// The name of the template.
public string TemplateName
{
get;
set;
}
readonly UnityEvent OnClick = new UnityEvent();
///
/// Create modal helper with the specified parent, sprite and color.
///
/// Parent game object.
/// Sprite.
/// Color.
/// onClick callback
/// Parent.
/// Modal helper index
public static int Open(Component parentGameObject, Sprite sprite = null, Color? color = null, UnityAction onClick = null, RectTransform parent = null)
{
// check if in cache
if (!Templates.Exists(key))
{
Templates.FindTemplates();
CreateTemplate();
}
var modal = Templates.Instance(key);
if (parent == null)
{
parent = UtilitiesUI.FindTopmostCanvas(parentGameObject.transform);
}
modal.gameObject.SetActive(true);
var rt = modal.transform as RectTransform;
rt.SetParent(parent, false);
rt.SetAsLastSibling();
rt.localPosition = Vector3.zero;
rt.sizeDelta = new Vector2(0, 0);
rt.anchorMin = new Vector2(0, 0);
rt.anchorMax = new Vector2(1, 1);
rt.anchoredPosition = new Vector2(0, 0);
var img = modal.GetComponent();
if (sprite != null)
{
img.sprite = sprite;
}
if (color != null)
{
img.color = (Color)color;
}
modal.OnClick.RemoveAllListeners();
if (onClick != null)
{
modal.OnClick.AddListener(onClick);
}
Used.Add(modal.GetInstanceID(), modal);
return modal.GetInstanceID();
}
///
/// Creates the template.
///
static void CreateTemplate()
{
var template = new GameObject(key);
var modal = template.AddComponent();
template.AddComponent();
var le = template.AddComponent();
le.ignoreLayout = true;
Templates.Add(key, modal);
template.gameObject.SetActive(false);
}
///
/// Gets the modal instance.
///
/// The instance.
/// Index.
public static GameObject GetInstance(int index)
{
return ((Used != null) && Used.ContainsKey(index))
? Used[index].gameObject
: null;
}
///
/// Set instance as last sibling.
///
/// Instance index.
/// true if instance exists; otherwise false.
public static bool SetAsLastSibling(int? index)
{
if (index.HasValue)
{
return SetAsLastSibling(index.Value);
}
return false;
}
///
/// Set instance as last sibling.
///
/// Instance index.
/// true if instance exists; otherwise false.
public static bool SetAsLastSibling(int index)
{
var instance = GetInstance(index);
if (instance != null)
{
instance.transform.SetAsLastSibling();
return true;
}
return false;
}
///
/// Close modal helper with the specified index.
///
/// Index.
public static void Close(int index)
{
if ((Used != null) && Used.ContainsKey(index))
{
Used[index].OnClick.RemoveAllListeners();
Templates.ToCache(Used[index]);
Used.Remove(index);
}
}
///
/// Remove template.
///
protected virtual void OnDestroy()
{
Templates.Delete(key);
}
///
/// Process the pointer click event.
///
/// Event data.
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button != PointerEventData.InputButton.Left)
{
return;
}
OnClick.Invoke();
}
}
}