Files
Emberwild/Assets/GAME/Script/Settings/Widgets/SettingDropdownWidget.cs
2026-06-26 16:23:20 +02:00

80 lines
2.3 KiB
C#

using System;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
namespace Ashwild.Settings
{
/// <summary>
/// A reusable dropdown. Pure UI: it knows nothing about which setting it drives. The panel
/// calls <see cref="Init"/> once to register the selection action, supplies the option list via
/// <see cref="SetOptions"/> (resolutions, monitors… are all built by the panel) and selects the
/// current entry through <see cref="SetValue"/>.
/// </summary>
[DisallowMultipleComponent]
public class SettingDropdownWidget : MonoBehaviour
{
#region Serialized Fields
[Header("References")]
[SerializeField] private TMP_Dropdown dropdown;
#endregion
#region State
private Action<int> onChanged;
#endregion
#region Public API
/// <summary>
/// Registers the action to run when the user picks an option. Call once.
/// </summary>
public void Init(Action<int> onChanged)
{
if (dropdown == null)
{
Debug.LogError($"[SettingDropdownWidget] '{name}' has no Dropdown assigned.", this);
return;
}
this.onChanged = onChanged;
dropdown.onValueChanged.RemoveListener(HandleChanged);
dropdown.onValueChanged.AddListener(HandleChanged);
}
/// <summary>
/// Replaces the dropdown's options. Call before <see cref="SetValue"/> on refresh.
/// </summary>
public void SetOptions(IEnumerable<string> options)
{
if (dropdown == null) return;
dropdown.ClearOptions();
dropdown.AddOptions(new List<string>(options));
}
/// <summary>
/// Selects the given index (clamped to the current options) without invoking the action.
/// </summary>
public void SetValue(int index)
{
if (dropdown == null) return;
dropdown.SetValueWithoutNotify(Mathf.Clamp(index, 0, dropdown.options.Count - 1));
dropdown.RefreshShownValue();
}
#endregion
#region Event Handlers
/// <summary>
/// Runs the apply action with the chosen index.
/// </summary>
private void HandleChanged(int index) => onChanged?.Invoke(index);
#endregion
}
}