#nullable enable using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; using UVC.Locale; using UVC.UIToolkit; namespace UVC.Studio.UIToolkit { /// /// 언어 선택 드롭다운 컴포넌트. /// 내부적으로 을 사용하며, /// 에서 지원 언어 목록을 가져와 표시합니다. /// 선택 시 를 호출하고, /// 외부에서 언어가 변경되면 이벤트를 통해 자동 동기화됩니다. /// /// /// C# 코드에서 사용: /// /// var dropdown = new UTKLanguageDropdownController(); /// container.Add(dropdown); /// /// // 씬 초기화 완료 후 언어 목록 로드 /// dropdown.LoadLanguages(); /// /// UXML에서 사용: /// /// /// /// /// /// [UxmlElement] public partial class UTKLanguageDropdownController : VisualElement, IDisposable { #region Fields private bool _disposed; // 언어 코드 목록 (인덱스 매핑용): ["ko", "en", ...] private List _languageCodes = new(); // 내부 드롭다운 컴포넌트 private readonly UTKButtonDropdown _dropdown; #endregion #region Properties /// 활성화 상태. [UxmlAttribute("is-enabled")] public bool IsEnabled { get => _dropdown.IsEnabled; set => _dropdown.IsEnabled = value; } /// 현재 선택된 언어 코드 (읽기 전용). public string? SelectedLanguageCode { get { int idx = _dropdown.SelectedIndex; return idx >= 0 && idx < _languageCodes.Count ? _languageCodes[idx] : null; } } #endregion #region Constructor public UTKLanguageDropdownController() { _dropdown = new UTKButtonDropdown(); if(_dropdown.TriggerButton != null) { _dropdown.TriggerButton.SetMaterialIcon(UTKMaterialIcons.Language, 18); _dropdown.TriggerButton.Text = "KOR"; } Add(_dropdown); _dropdown.OnSelectionChanged += OnDropdownSelectionChanged; LocalizationManager.Instance.OnReady += LoadLanguages; } #endregion #region Public Methods /// /// 에서 지원 언어 목록을 읽어 드롭다운을 초기화합니다. /// 씬 초기화(Initialized 이벤트) 완료 후 호출해야 합니다. /// private void LoadLanguages() { var displayLanguages = LocalizationManager.Instance.AvailableDisplayLanguages; _languageCodes.Clear(); var displayNames = new List(); foreach (var kv in displayLanguages) { _languageCodes.Add(kv.Key); displayNames.Add(kv.Value); } _dropdown.SetOptions(displayNames); // 현재 언어로 초기 선택 동기화 (이벤트 없이) SyncToCurrentLanguage(); // 외부 언어 변경 감지 LocalizationManager.Instance.OnLanguageChanged -= OnLanguageChanged; LocalizationManager.Instance.OnLanguageChanged += OnLanguageChanged; } #endregion #region Event Handlers private void OnDropdownSelectionChanged(int index, string displayName) { if (index < 0 || index >= _languageCodes.Count) return; LocalizationManager.Instance.SetCurrentLanguage(_languageCodes[index]); } private void OnLanguageChanged(string newLanguageCode) { // 외부에서 언어 변경 시 드롭다운 선택 동기화 SyncToCurrentLanguage(); } #endregion #region Private Methods private void SyncToCurrentLanguage() { string currentCode = LocalizationManager.Instance.CurrentLanguage; int index = _languageCodes.IndexOf(currentCode); if (index >= 0) { // notify: false — SetCurrentLanguage 재호출 방지 _dropdown.SetSelectedIndex(index, notify: false); } } #endregion #region IDisposable /// 이벤트 구독 및 내부 드롭다운을 해제합니다. public void Dispose() { if (_disposed) return; _disposed = true; LocalizationManager.Instance.OnLanguageChanged -= OnLanguageChanged; _dropdown.OnSelectionChanged -= OnDropdownSelectionChanged; _dropdown.Dispose(); } #endregion } }