using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
namespace DuloGames.UI
{
[ExecuteInEditMode, DisallowMultipleComponent, AddComponentMenu("UI/Switch Select Field", 58)]
public class UISwitchSelect : MonoBehaviour
{
[SerializeField] private Text m_Text;
[SerializeField] private Button m_PrevButton;
[SerializeField] private Button m_NextButton;
// Currently selected item
[HideInInspector][SerializeField] private string m_SelectedItem;
///
/// New line-delimited list of items.
///
[SerializeField] private List m_Options = new List();
///
/// The list of options.
///
public List options
{
get
{
return this.m_Options;
}
}
///
/// Currently selected option.
///
public string value
{
get
{
return this.m_SelectedItem;
}
set
{
m_Text.text = value;
this.SelectOption(value);
}
}
///
/// Gets the index of the selected option.
///
/// The index of the selected option.
public int selectedOptionIndex
{
get
{
return this.GetOptionIndex(this.m_SelectedItem);
}
}
[System.Serializable] public class ChangeEvent : UnityEvent { }
///
/// Event delegates triggered when the selected option changes.
///
public ChangeEvent onChange = new ChangeEvent();
protected void OnEnable()
{
// Hook the buttons click events
if (this.m_PrevButton != null)
this.m_PrevButton.onClick.AddListener(OnPrevButtonClick);
if (this.m_NextButton != null)
this.m_NextButton.onClick.AddListener(OnNextButtonClick);
}
protected void OnDisable()
{
// Unhook the buttons click events
if (this.m_PrevButton != null)
this.m_PrevButton.onClick.RemoveListener(OnPrevButtonClick);
if (this.m_NextButton != null)
this.m_NextButton.onClick.RemoveListener(OnNextButtonClick);
}
protected void OnPrevButtonClick()
{
int prevIndex = this.selectedOptionIndex - 1;
// Check if the option index is valid
if (prevIndex < 0)
prevIndex = this.m_Options.Count - 1;
if (prevIndex >= this.m_Options.Count)
prevIndex = 0;
// Select the new option
this.SelectOptionByIndex(prevIndex);
}
protected void OnNextButtonClick()
{
int nextIndex = this.selectedOptionIndex + 1;
// Check if the option index is valid
if (nextIndex < 0)
nextIndex = this.m_Options.Count - 1;
if (nextIndex >= this.m_Options.Count)
nextIndex = 0;
// Select the new option
this.SelectOptionByIndex(nextIndex);
}
///
/// Gets the index of the given option.
///
/// The option index. (-1 if the option was not found)
/// Option value.
public int GetOptionIndex(string optionValue)
{
// Find the option index in the options list
if (this.m_Options != null && this.m_Options.Count > 0 && !string.IsNullOrEmpty(optionValue))
for (int i = 0; i < this.m_Options.Count; i++)
if (optionValue.Equals(this.m_Options[i], System.StringComparison.OrdinalIgnoreCase))
return i;
// Default
return -1;
}
///
/// Selects the option by index.
///
/// Option index.
public void SelectOptionByIndex(int index)
{
// Check if the option index is valid
if (index < 0 || index >= this.m_Options.Count)
return;
string newOption = this.m_Options[index];
// If the options changes
if (!newOption.Equals(this.m_SelectedItem))
{
// Set as selected
this.m_SelectedItem = newOption;
// Trigger change
this.TriggerChangeEvent();
}
}
///
/// Selects the option by value.
///
/// The option value.
public void SelectOption(string optionValue)
{
if (string.IsNullOrEmpty(optionValue))
return;
// Get the option
int index = this.GetOptionIndex(optionValue);
// Check if the option index is valid
if (index < 0 || index >= this.m_Options.Count)
return;
// Select the option
this.SelectOptionByIndex(index);
}
///
/// Adds an option.
///
/// Option value.
public void AddOption(string optionValue)
{
if (this.m_Options != null)
this.m_Options.Add(optionValue);
}
///
/// Adds an option at given index.
///
/// Option value.
/// Index.
public void AddOptionAtIndex(string optionValue, int index)
{
if (this.m_Options == null)
return;
// Check if the index is outside the list
if (index >= this.m_Options.Count)
{
this.m_Options.Add(optionValue);
}
else
{
this.m_Options.Insert(index, optionValue);
}
}
///
/// Removes the option.
///
/// Option value.
public void RemoveOption(string optionValue)
{
if (this.m_Options == null)
return;
// Remove the option if exists
if (this.m_Options.Contains(optionValue))
{
this.m_Options.Remove(optionValue);
this.ValidateSelectedOption();
}
}
///
/// Removes the option at the given index.
///
/// Index.
public void RemoveOptionAtIndex(int index)
{
if (this.m_Options == null)
return;
// Remove the option if the index is valid
if (index >= 0 && index < this.m_Options.Count)
{
this.m_Options.RemoveAt(index);
this.ValidateSelectedOption();
}
}
///
/// Validates the selected option and makes corrections if it's missing.
///
public void ValidateSelectedOption()
{
if (this.m_Options == null)
return;
// Fix the selected option if it no longer exists
if (!this.m_Options.Contains(this.m_SelectedItem))
{
// Select the first option
this.SelectOptionByIndex(0);
}
}
///
/// Tiggers the change event.
///
protected virtual void TriggerChangeEvent()
{
// Apply the string to the label componenet
if (this.m_Text != null)
this.m_Text.text = this.m_SelectedItem;
// Invoke the on change event
if (onChange != null)
onChange.Invoke(this.selectedOptionIndex, this.m_SelectedItem);
}
}
}