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));
}
}
}