Files
XRLib/Assets/Scripts/UVC/UIToolkit/Property/Items/UTKRadioPropertyItem.cs
2026-02-02 19:33:27 +09:00

232 lines
6.5 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
/// <summary>
/// 라디오 그룹 속성 아이템
/// UTKRadioButton 그룹으로 단일 선택
/// </summary>
public class UTKRadioPropertyItem : UTKPropertyItemBase<int>
{
#region Fields
private VisualElement? _radioContainer;
private List<UTKRadioButton> _radioButtons = new();
private List<string> _choices;
#endregion
#region Properties
public override UTKPropertyType PropertyType => UTKPropertyType.RadioGroup;
/// <summary>선택 가능한 항목 목록</summary>
public List<string> Choices
{
get => _choices;
set
{
_choices = value ?? new List<string>();
RebuildRadioButtons();
}
}
/// <summary>현재 선택된 항목의 텍스트</summary>
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<string> choices, int selectedIndex = 0)
: base(id, name, Math.Max(0, Math.Min(selectedIndex, (choices?.Count ?? 1) - 1)))
{
_choices = choices ?? new List<string>();
}
public UTKRadioPropertyItem(string id, string name, IEnumerable<string> choices, int selectedIndex = 0)
: this(id, name, choices?.ToList() ?? new List<string>(), selectedIndex)
{
}
#endregion
#region Override Methods
public override VisualElement CreateUI()
{
var container = CreateUIFromUxml("UTKRadioPropertyItem");
if (container == null)
{
return CreateUIFallback();
}
_radioContainer = container.Q<VisualElement>("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<VisualElement>("radio-container");
if (_radioContainer != null)
{
// 기존 라디오 버튼 찾기 또는 새로 생성
_radioButtons.Clear();
var existingButtons = _radioContainer.Query<UTKRadioButton>().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
/// <summary>텍스트로 선택</summary>
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
}
}