Files
XRLib/Assets/Scripts/UVC/UIToolkit/ToolBar/Data/UTKToolBarExpandableButtonData.cs
2026-02-19 18:40:37 +09:00

145 lines
4.7 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
namespace UVC.UIToolkit
{
/// <summary>
/// 서브 버튼 목록을 가진 확장 가능한 버튼 데이터입니다.
/// 클릭 시 서브 메뉴를 표시하고, 서브 버튼 선택 시 메인 아이콘을 업데이트할 수 있습니다.
/// </summary>
public class UTKToolBarExpandableButtonData : UTKToolBarButtonData
{
#region Fields
private UTKToolBarButtonData? _selectedSubButton;
private string _originalText = "";
#endregion
#region Properties
/// <summary>서브 버튼 목록</summary>
public List<UTKToolBarButtonData> SubButtons { get; private set; } = new();
/// <summary>서브 버튼 선택 시 메인 아이콘 업데이트 여부</summary>
public bool UpdateIconOnSelection { get; set; }
/// <summary>현재 선택된 서브 버튼</summary>
public UTKToolBarButtonData? SelectedSubButton => _selectedSubButton;
/// <summary>원본 텍스트 (서브 버튼 선택 시 변경 전 저장용)</summary>
public string OriginalText => _originalText;
/// <summary>서브 버튼 선택 콜백</summary>
public Action<UTKToolBarButtonData>? OnSubButtonSelected { get; set; }
#endregion
#region Events
/// <summary>서브 버튼 선택 변경 이벤트 (mainText, selectedSubText)</summary>
public event Action<string, string>? OnSubButtonSelectionChanged;
#endregion
#region Constructor
/// <summary>
/// UTKToolBarExpandableButtonData의 새 인스턴스를 초기화합니다.
/// </summary>
/// <param name="itemId">아이템 고유 식별자. null이면 GUID 자동 생성.</param>
public UTKToolBarExpandableButtonData(string? itemId = null) : base(itemId)
{
}
#endregion
#region Methods
/// <summary>
/// 원본 텍스트를 설정합니다. AddExpandableButton에서 호출됩니다.
/// </summary>
/// <param name="text">원본 텍스트</param>
public void SetOriginalText(string text)
{
_originalText = text;
}
/// <summary>
/// 서브 버튼을 선택합니다. UpdateIconOnSelection이 true이면 메인 아이콘도 업데이트합니다.
/// </summary>
/// <param name="selectedSubButton">선택할 서브 버튼</param>
public void SelectSubButton(UTKToolBarButtonData selectedSubButton)
{
if (selectedSubButton == null || !selectedSubButton.IsEnabled) return;
// 동일 버튼 재선택 시 무시
if (_selectedSubButton == selectedSubButton) return;
_selectedSubButton = selectedSubButton;
if (UpdateIconOnSelection)
{
if (Text != selectedSubButton.Text)
{
Text = selectedSubButton.Text;
}
if (IconPath != selectedSubButton.IconPath)
{
IconPath = selectedSubButton.IconPath;
}
}
OnSubButtonSelected?.Invoke(selectedSubButton);
OnSubButtonSelectionChanged?.Invoke(_originalText, selectedSubButton.Text);
}
/// <summary>
/// 클릭 실행. 기본 Command를 실행합니다.
/// 서브 메뉴 표시/숨김은 View에서 처리합니다.
/// </summary>
/// <param name="parameter">ClickCommand에 전달할 파라미터</param>
public override void ExecuteClick(object? parameter = null)
{
if (!IsEnabled) return;
base.ExecuteClick(parameter);
}
/// <summary>
/// 모든 이벤트 핸들러를 해제합니다. 서브 버튼의 핸들러도 정리합니다.
/// </summary>
public override void ClearEventHandlers()
{
base.ClearEventHandlers();
OnSubButtonSelected = null;
OnSubButtonSelectionChanged = null;
foreach (var subButton in SubButtons)
{
subButton.ClearEventHandlers();
}
}
/// <summary>
/// 리소스 정리. 서브 버튼도 재귀적으로 정리합니다.
/// </summary>
/// <param name="disposing">관리 리소스 정리 여부</param>
protected override void Dispose(bool disposing)
{
if (disposing)
{
foreach (var subButton in SubButtons)
{
subButton.Dispose();
}
SubButtons.Clear();
}
base.Dispose(disposing);
}
#endregion
}
}