using System; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; namespace DTT.Utils.Components { /// /// Can be implemented to populate a dropdown ui element with enum values /// and provide callbacks on its changed values. /// /// The type of enum. [RequireComponent(typeof(Dropdown))] public class EnumDropdown : MonoBehaviour where T : Enum { /// /// Called when the dropdown value has changed. /// public event Action ValueChanged; /// /// The dropdown reference. /// protected Dropdown p_dropdown; /// /// The names of the enum values. /// protected readonly string[] p_enumNames; /// /// The default dropdown option data used based on the enum names. /// protected readonly Dropdown.OptionData[] p_defaultOptions; /// /// Whether the dropdown already uses the default options. /// protected bool p_UsesDefaultOptions { get { List options = p_dropdown.options; if (options.Count != p_defaultOptions.Length) return false; for(int i = 0; i < options.Count; i++) if (options[i].text != p_defaultOptions[i].text) return false; return true; } } /// /// Creates the enum dropdown instance initializing the read only fields. /// public EnumDropdown() { p_enumNames = Enum.GetNames(typeof(T)); p_defaultOptions = p_enumNames.Select(enumName => new Dropdown.OptionData(enumName)).ToArray(); } /// /// Populates the dropdown with enum name options. /// private void Awake() { if(p_dropdown == null) p_dropdown = GetComponent(); if(!p_UsesDefaultOptions) ResetOptions(); } /// /// Starts listening for value changes. /// private void OnEnable() => p_dropdown.onValueChanged.AddListener(OnValueChanged); /// /// Stops listening for value changes. /// private void OnDisable() => p_dropdown.onValueChanged.RemoveListener(OnValueChanged); /// /// Sets the current value displayed on the dropdown. /// /// The new value to display in the dropdown. public void SetValue(T newValue) { string newEnumName = newValue.ToString(); int index = Array.IndexOf(p_enumNames, newEnumName); if (index != -1) p_dropdown.value = index; } /// /// Called when the current value on the dropdown has changed to fire the /// ValueChanged event. /// /// The new index of the values stored in the dropdown. private void OnValueChanged(int newValue) { if (newValue >= 0 && newValue <= p_enumNames.Length) { string enumName = p_enumNames[newValue]; T enumValue = (T)Enum.Parse(typeof(T), enumName); ValueChanged?.Invoke(enumValue); } } /// /// Re-initializes the dropdown with default values. /// private void Reset() { p_dropdown = GetComponent(); if(!p_UsesDefaultOptions) ResetOptions(); p_dropdown.SetValueWithoutNotify(0); } /// /// Re-initializes the dropdown options with default values. /// private void ResetOptions() { p_dropdown.ClearOptions(); p_dropdown.AddOptions(new List(p_defaultOptions)); } } }