using System; using System.Collections.Generic; using System.Linq; using MelonLoader; using UnityEngine.UIElements; namespace ADOFAIRenderer.Data { /// /// Binds a UI Toolkit to an enum type. /// Populates choices from enum names and provides typed access to the selected value. /// /// The enum type to bind. public class EnumDropdownBinder where T : struct, Enum { private readonly DropdownField? _dropdown; private readonly List _values; private Action? _onValueChanged; /// /// The currently selected enum value. /// public T Value => _dropdown != null && _dropdown.index >= 0 && _dropdown.index < _values.Count ? _values[_dropdown.index] : default; /// /// Queries a by name from the root VisualElement, /// populates it with enum names, and selects the default value. /// /// The root VisualElement loaded from the UXML bundle. /// The name of the DropdownField in the UXML. /// The initial selected value. Defaults to the first enum member. public EnumDropdownBinder(VisualElement rootVisualElement, string fieldName, T? defaultValue = null) { _values = Enum.GetValues(typeof(T)).Cast().ToList(); _dropdown = rootVisualElement.Q(fieldName); if (_dropdown == null) { Melon.Logger.Error( $"DropdownField '{fieldName}'을(를) 찾을 수 없습니다."); return; } _dropdown.choices = _values.Select(v => v.ToString()).ToList(); // Register the callback BEFORE setting index so the initial selection fires it too _dropdown.RegisterValueChangedCallback(_ => { _onValueChanged?.Invoke(Value); }); var initial = defaultValue ?? _values[0]; _dropdown.index = _values.IndexOf(initial); } /// /// Registers a callback that fires when the selection changes, providing the new enum value. /// public void OnValueChanged(Action callback) { _onValueChanged = callback; // Fire immediately with current value so the caller gets the initial state if (_dropdown != null) { callback(Value); } } } }