#nullable enable using System; using System.Collections.Generic; using System.Linq; using UnityEngine.UIElements; namespace UVC.UIToolkit { /// /// 라디오 그룹 속성 아이템 /// UTKRadioButton 그룹으로 단일 선택 /// public class UTKRadioPropertyItem : UTKPropertyItemBase { #region Fields private VisualElement? _radioContainer; private List _radioButtons = new(); private List _choices; #endregion #region Properties public override UTKPropertyType PropertyType => UTKPropertyType.RadioGroup; /// 선택 가능한 항목 목록 public List Choices { get => _choices; set { _choices = value ?? new List(); RebuildRadioButtons(); } } /// 현재 선택된 항목의 텍스트 public string? SelectedText { get { if (Value >= 0 && Value < _choices.Count) { return _choices[Value]; } return null; } } #endregion #region Constructor public UTKRadioPropertyItem(string id, string name, List choices, int selectedIndex = 0) : base(id, name, Math.Max(0, Math.Min(selectedIndex, (choices?.Count ?? 1) - 1))) { _choices = choices ?? new List(); } public UTKRadioPropertyItem(string id, string name, IEnumerable choices, int selectedIndex = 0) : this(id, name, choices?.ToList() ?? new List(), selectedIndex) { } #endregion #region Override Methods public override VisualElement CreateUI() { var container = CreateUIFromUxml("UTKRadioPropertyItem"); if (container == null) { return CreateUIFallback(); } _radioContainer = container.Q("radio-container"); if (_radioContainer != null) { CreateRadioButtons(); } return container; } private VisualElement CreateUIFallback() { var container = CreateContainer(); var label = CreateNameLabel(); container.Add(label); var valueContainer = new VisualElement(); valueContainer.AddToClassList("utk-property-item__value"); _radioContainer = new VisualElement(); _radioContainer.name = "radio-container"; _radioContainer.AddToClassList("utk-property-item__radio-container"); valueContainer.Add(_radioContainer); CreateRadioButtons(); container.Add(valueContainer); return container; } public override void BindUI(VisualElement element) { base.BindUI(element); _radioContainer = element.Q("radio-container"); if (_radioContainer != null) { // 기존 라디오 버튼 찾기 또는 새로 생성 _radioButtons.Clear(); var existingButtons = _radioContainer.Query().ToList(); if (existingButtons.Count == _choices.Count) { // 기존 버튼 재사용 for (int i = 0; i < existingButtons.Count; i++) { var radio = existingButtons[i]; _radioButtons.Add(radio); radio.IsEnabled = !IsReadOnly; int index = i; radio.OnValueChanged += (isChecked) => OnRadioChanged(index, isChecked); } } else { // 새로 생성 CreateRadioButtons(); } UpdateSelection(); } } public override void UnbindUI(VisualElement element) { _radioButtons.Clear(); _radioContainer = null; base.UnbindUI(element); } public override void RefreshUI() { UpdateSelection(); } protected override void UpdateReadOnlyState() { base.UpdateReadOnlyState(); foreach (var radio in _radioButtons) { radio.IsEnabled = !IsReadOnly; } } #endregion #region Public Methods /// 텍스트로 선택 public void SelectByText(string text) { int index = _choices.IndexOf(text); if (index >= 0) { Value = index; } } #endregion #region Private Methods private void CreateRadioButtons() { if (_radioContainer == null) return; _radioContainer.Clear(); _radioButtons.Clear(); for (int i = 0; i < _choices.Count; i++) { var radio = new UTKRadioButton(_choices[i]); radio.name = $"radio-{i}"; radio.AddToClassList("utk-property-item__radio"); int index = i; radio.OnValueChanged += (isChecked) => OnRadioChanged(index, isChecked); _radioButtons.Add(radio); _radioContainer.Add(radio); } UpdateSelection(); } private void RebuildRadioButtons() { if (_radioContainer != null) { CreateRadioButtons(); } } private void UpdateSelection() { for (int i = 0; i < _radioButtons.Count; i++) { _radioButtons[i].SetChecked(i == Value, false); } } private void OnRadioChanged(int index, bool isChecked) { if (isChecked && index != Value) { // 다른 라디오 버튼 해제 for (int i = 0; i < _radioButtons.Count; i++) { if (i != index) { _radioButtons[i].SetChecked(false, false); } } Value = index; } } #endregion } }