namespace UIWidgets
{
using System;
using UIWidgets.Styles;
using UnityEngine;
using UnityEngine.UI;
///
/// Base class for Pickers.
///
/// Type of value.
/// Type of picker.
public abstract class Picker : MonoBehaviour, ITemplatable, IStylable
where TPicker : Picker
{
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;
}
static Templates templates;
///
/// Picker templates.
///
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1000:DoNotDeclareStaticMembersOnGenericTypes", Justification = "Reviewed")]
public static Templates Templates
{
get
{
if (templates == null)
{
templates = new Templates();
}
return templates;
}
set
{
templates = value;
}
}
[SerializeField]
Button closeButton;
///
/// Close button.
///
public Button CloseButton
{
get
{
return closeButton;
}
set
{
if (isInited && (closeButton != null))
{
closeButton.onClick.RemoveListener(Cancel);
}
closeButton = value;
if (isInited && (closeButton != null))
{
closeButton.onClick.AddListener(Cancel);
}
}
}
///
/// Awake is called when the script instance is being loaded.
///
protected virtual void Awake()
{
if (IsTemplate)
{
gameObject.SetActive(false);
}
}
///
/// Start this instance.
///
protected virtual void Start()
{
Init();
}
bool isInited;
///
/// Init this instance.
///
public virtual void Init()
{
if (isInited)
{
return;
}
if (closeButton != null)
{
closeButton.onClick.AddListener(Cancel);
}
isInited = true;
}
///
/// This function is called when the MonoBehaviour will be destroyed.
///
protected virtual void OnDestroy()
{
if (!IsTemplate)
{
templates = null;
return;
}
// if FindTemplates never called than TemplateName == null
if (TemplateName != null)
{
Templates.Delete(TemplateName);
}
}
///
/// Return picker instance using current instance as template.
///
/// New picker instance.
[Obsolete("Use Clone() instead.")]
public TPicker Template()
{
return Clone();
}
///
/// Return picker instance using current instance as template.
///
/// New picker instance.
public virtual TPicker Clone()
{
var picker = this as TPicker;
if ((TemplateName != null) && Templates.Exists(TemplateName))
{
// do nothing
}
else if (!Templates.Exists(gameObject.name))
{
Templates.Add(gameObject.name, picker);
}
else if (Templates.Get(gameObject.name) != this)
{
Templates.Add(gameObject.name, picker);
}
var id = gameObject.GetInstanceID().ToString();
if (!Templates.Exists(id))
{
Templates.Add(id, picker);
}
else if (Templates.Get(id) != this)
{
Templates.Add(id, picker);
}
return Templates.Instance(id);
}
///
/// The modal key.
///
protected int? ModalKey;
///
/// Callback with selected value.
///
protected Action OnSelect;
///
/// Callback when picker closed without any value selected.
///
protected Action OnCancel;
///
/// Show picker.
///
/// Default value.
/// Callback with selected value.
/// Callback when picker closed without any value selected.
/// Modal sprite.
/// Modal color.
/// Canvas.
public virtual void Show(
TValue defaultValue,
Action onSelect,
Action onCancel = null,
Sprite modalSprite = null,
Color? modalColor = null,
Canvas canvas = null)
{
if (IsTemplate)
{
Debug.LogWarning("Use the template clone, not the template itself: PickerTemplate.Clone().Show(...), not PickerTemplate.Show(...)");
}
OnSelect = onSelect;
OnCancel = onCancel;
var parent = (canvas != null) ? canvas.transform as RectTransform : UtilitiesUI.FindTopmostCanvas(gameObject.transform);
if (parent != null)
{
transform.SetParent(parent, false);
}
if (modalColor == null)
{
modalColor = new Color(0, 0, 0, 0.8f);
}
ModalKey = ModalHelper.Open(this, modalSprite, modalColor, Close, parent);
transform.SetAsLastSibling();
gameObject.SetActive(true);
BeforeOpen(defaultValue);
}
///
/// Close picker with specified value.
///
/// Value.
public virtual void Selected(TValue value)
{
OnSelect(value);
Close();
}
///
/// Close picker without specified value.
///
public virtual void Cancel()
{
if (OnCancel != null)
{
OnCancel();
}
Close();
}
///
/// Prepare picker to open.
///
/// Default value.
public abstract void BeforeOpen(TValue defaultValue);
///
/// Prepare picker to close.
///
public abstract void BeforeClose();
///
/// Close picker.
///
protected virtual void Close()
{
BeforeClose();
if (ModalKey.HasValue)
{
ModalHelper.Close(ModalKey.Value);
}
Return();
}
///
/// Return this instance to cache.
///
protected virtual void Return()
{
Templates.ToCache(this as TPicker);
}
#region IStylable implementation
///
public virtual bool SetStyle(Style style)
{
style.Dialog.Background.ApplyTo(GetComponent());
style.Dialog.Title.ApplyTo(transform.Find("Header/Title"));
style.Dialog.ContentBackground.ApplyTo(transform.Find("Content"));
style.Dialog.Delimiter.ApplyTo(transform.Find("Delimiter/Delimiter"));
if (closeButton != null)
{
style.ButtonClose.ApplyTo(closeButton);
}
else
{
style.ButtonClose.Background.ApplyTo(transform.Find("Header/CloseButton"));
style.ButtonClose.Text.ApplyTo(transform.Find("Header/CloseButton/Text"));
}
return true;
}
///
public virtual bool GetStyle(Style style)
{
style.Dialog.Background.GetFrom(GetComponent());
style.Dialog.Title.GetFrom(transform.Find("Header/Title"));
style.Dialog.ContentBackground.GetFrom(transform.Find("Content"));
style.Dialog.Delimiter.GetFrom(transform.Find("Delimiter/Delimiter"));
if (closeButton != null)
{
style.ButtonClose.GetFrom(closeButton);
}
else
{
style.ButtonClose.Background.GetFrom(transform.Find("Header/CloseButton"));
style.ButtonClose.Text.GetFrom(transform.Find("Header/CloseButton/Text"));
}
return true;
}
#endregion
}
}