157 lines
5.6 KiB
C#
157 lines
5.6 KiB
C#
using System.Collections.Generic;
|
|
using TMPro;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using UVC.Extention;
|
|
using UVC.UI.Tooltip;
|
|
|
|
namespace UVC.UI.Window.PropertyWindow.UI
|
|
{
|
|
/// <summary>
|
|
/// RadioGroupProperty를 위한 UI를 제어하는 스크립트입니다.
|
|
/// 동적으로 생성된 Toggle들을 사용하여 항목을 선택합니다.
|
|
/// </summary>
|
|
[RequireComponent(typeof(LayoutElement))]
|
|
public class RadioGroupPropertyUI : MonoBehaviour, IPropertyUI
|
|
{
|
|
[Header("UI Components")]
|
|
[SerializeField]
|
|
private TextMeshProUGUI _nameLabel; // 속성 이름을 표시할 Text
|
|
|
|
[SerializeField]
|
|
private TextMeshProUGUI _descriptionLabel;
|
|
|
|
[SerializeField]
|
|
private RectTransform _toggleContainer; // Toggle들이 생성될 부모 컨테이너
|
|
|
|
[SerializeField]
|
|
private GameObject _togglePrefab; // 개별 라디오 버튼(Toggle) 프리팹
|
|
|
|
private RadioGroupProperty _propertyItem;
|
|
private PropertyWindow _controller;
|
|
private ToggleGroup _toggleGroup;
|
|
private readonly List<Toggle> _toggles = new List<Toggle>();
|
|
|
|
/// <summary>
|
|
/// PropertyView에 의해 호출되어 UI를 초기화하고 데이터를 설정합니다.
|
|
/// </summary>
|
|
public void Setup(IPropertyItem item, PropertyWindow controller)
|
|
{
|
|
if (!(item is RadioGroupProperty radioItem))
|
|
{
|
|
Debug.LogError($"RadioGroupPropertyUI에 잘못된 타입의 PropertyItem이 전달되었습니다. {item.GetType()}");
|
|
return;
|
|
}
|
|
if (_togglePrefab == null)
|
|
{
|
|
Debug.LogError("RadioGroupPropertyUI에 Toggle 프리팹이 연결되지 않았습니다.");
|
|
return;
|
|
}
|
|
|
|
_propertyItem = radioItem;
|
|
_controller = controller;
|
|
|
|
// --- 데이터 바인딩 ---
|
|
_nameLabel.text = _propertyItem.Name;
|
|
|
|
// 툴팁 설정 (TooltipHandler 컴포넌트가 있다면 연동)
|
|
TooltipHandler tooltipHandler = _nameLabel.GetComponent<TooltipHandler>();
|
|
if (tooltipHandler != null && !_propertyItem.Tooltip.IsNullOrEmpty())
|
|
{
|
|
tooltipHandler.Tooltip = _propertyItem.Tooltip;
|
|
}
|
|
|
|
if (_propertyItem.Description.IsNullOrEmpty())
|
|
{
|
|
_descriptionLabel.gameObject.SetActive(false);
|
|
}
|
|
else
|
|
{
|
|
_descriptionLabel.gameObject.SetActive(true);
|
|
_descriptionLabel.text = _propertyItem.Description;
|
|
}
|
|
|
|
// 기존 토글 정리
|
|
foreach (Transform child in _toggleContainer)
|
|
{
|
|
Destroy(child.gameObject);
|
|
}
|
|
_toggles.Clear();
|
|
|
|
// ToggleGroup 컴포넌트 가져오기 (없으면 추가)
|
|
_toggleGroup = _toggleContainer.GetComponent<ToggleGroup>();
|
|
if (_toggleGroup == null)
|
|
{
|
|
_toggleGroup = _toggleContainer.gameObject.AddComponent<ToggleGroup>();
|
|
}
|
|
_toggleGroup.allowSwitchOff = false; // 항상 하나는 선택되도록 설정
|
|
|
|
// ItemsSource를 기반으로 토글 동적 생성
|
|
for (int i = 0; i < _propertyItem.ItemsSource.Count; i++)
|
|
{
|
|
string optionValue = _propertyItem.ItemsSource[i];
|
|
GameObject toggleInstance = Instantiate(_togglePrefab, _toggleContainer);
|
|
toggleInstance.name = $"RadioToggle_{optionValue}";
|
|
|
|
Toggle toggle = toggleInstance.GetComponent<Toggle>();
|
|
TextMeshProUGUI label = toggleInstance.GetComponentInChildren<TextMeshProUGUI>();
|
|
|
|
if (toggle != null)
|
|
{
|
|
_toggles.Add(toggle);
|
|
toggle.group = _toggleGroup;
|
|
toggle.interactable = !_propertyItem.IsReadOnly;
|
|
|
|
// 현재 값과 일치하는 토글을 활성화
|
|
toggle.isOn = (optionValue == _propertyItem.Value);
|
|
|
|
// 리스너 등록
|
|
toggle.onValueChanged.RemoveAllListeners();
|
|
toggle.onValueChanged.AddListener((isOn) =>
|
|
{
|
|
// 토글이 켜졌을 때만 값 업데이트
|
|
if (isOn)
|
|
{
|
|
OnToggleValueChanged(optionValue);
|
|
}
|
|
});
|
|
}
|
|
|
|
if (label != null)
|
|
{
|
|
label.text = optionValue;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 토글 값이 변경되었을 때 호출됩니다.
|
|
/// </summary>
|
|
/// <param name="selectedValue">선택된 토글에 해당하는 값</param>
|
|
private void OnToggleValueChanged(string selectedValue)
|
|
{
|
|
|
|
if(selectedValue == _propertyItem.Value)
|
|
{
|
|
return; // 값이 변경되지 않았으면 무시
|
|
}
|
|
|
|
// 컨트롤러를 통해 모델의 값을 업데이트합니다.
|
|
_controller.UpdatePropertyValue(_propertyItem.Id, _propertyItem.PropertyType, selectedValue);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 이 UI 오브젝트가 파괴될 때 Unity에 의해 호출됩니다.
|
|
/// </summary>
|
|
private void OnDestroy()
|
|
{
|
|
foreach (var toggle in _toggles)
|
|
{
|
|
if (toggle != null)
|
|
{
|
|
toggle.onValueChanged.RemoveAllListeners();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |