#nullable enable using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; namespace UVC.UIToolkit { /// /// 드롭다운 메뉴 컴포넌트. /// Unity DropdownField를 래핑하여 커스텀 스타일을 적용합니다. /// /// /// C# 코드에서 사용: /// /// // 기본 드롭다운 /// var dropdown = new UTKDropdown(); /// dropdown.Label = "국가 선택"; /// dropdown.SetChoices(new List { "한국", "미국", "일본" }); /// dropdown.OnSelectionChanged += (index, value) => Debug.Log($"선택: {value}"); /// /// // 기본값 설정 /// dropdown.value = "한국"; /// dropdown.index = 0; /// /// UXML에서 사용: /// /// /// /// /// /// /// /// /// /// /// /// /// [UxmlElement] public partial class UTKDropdown : DropdownField, IDisposable { #region Constants private const string USS_PATH = "UIToolkit/Dropdown/UTKDropdown"; #endregion #region Fields private bool _disposed; private bool _isEnabled = true; #endregion #region Events /// 선택 변경 이벤트 public event Action? OnSelectionChanged; #endregion #region Properties /// 선택된 인덱스 public int SelectedIndex { get => index; set => index = value; } /// 선택된 값 public string? SelectedValue => value; /// 활성화 상태 [UxmlAttribute] public bool IsEnabled { get => _isEnabled; set { _isEnabled = value; SetEnabled(value); EnableInClassList("utk-dropdown--disabled", !value); } } #endregion #region Constructor public UTKDropdown() : base() { UTKThemeManager.Instance.ApplyThemeToElement(this); var uss = Resources.Load(USS_PATH); if (uss != null) { styleSheets.Add(uss); } SetupStyles(); SetupEvents(); SubscribeToThemeChanges(); } public UTKDropdown(string label, List? options = null) : this() { this.label = label; if (options != null) { choices = options; } } #endregion #region Setup private void SetupStyles() { AddToClassList("utk-dropdown"); } private void SetupEvents() { this.RegisterValueChangedCallback(OnDropdownValueChanged); } private void SubscribeToThemeChanges() { UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged; RegisterCallback(_ => { UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged; }); } private void OnThemeChanged(UTKTheme theme) { UTKThemeManager.Instance.ApplyThemeToElement(this); } #endregion #region Event Handlers private void OnDropdownValueChanged(ChangeEvent evt) { OnSelectionChanged?.Invoke(index, evt.newValue); } #endregion #region Methods /// /// 옵션 목록 설정 /// public void SetOptions(List options) { choices = options ?? new List(); } /// /// 옵션 추가 /// public void AddOption(string option) { var list = new List(choices) { option }; choices = list; } /// /// 값으로 선택 /// public void SetSelectedValue(string? selectedValue, bool notify = true) { if (selectedValue == null) { index = -1; return; } var idx = choices.IndexOf(selectedValue); if (idx >= 0) { if (notify) { index = idx; } else { SetValueWithoutNotify(selectedValue); } } } #endregion #region IDisposable public void Dispose() { if (_disposed) return; _disposed = true; UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged; OnSelectionChanged = null; } #endregion } }