Files

225 lines
6.4 KiB
C#

#nullable enable
using System;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
/// <summary>
/// 버튼 속성 View 클래스입니다.
/// UTKButton을 표시하고 클릭 시 Action 이름을 이벤트로 전달합니다.
/// </summary>
[UxmlElement]
public partial class UTKButtonItemView : UTKPropertyItemViewBase, IUTKPropertyItemView<string>
{
#region Fields
private UTKButton? _button;
private IUTKPropertyItem<string>? _boundData;
#endregion
#region Properties
protected override string ViewTypeName => "UTKButtonItemView";
/// <summary>값 변경 이벤트 (IUTKPropertyItemView 인터페이스 구현)</summary>
public event Action<string>? OnValueChanged;
/// <summary>버튼 클릭 이벤트</summary>
public event Action<string>? OnButtonClicked;
/// <summary>액션 이름 (현재 Value)</summary>
public string Value
{
get => _boundData?.Value ?? "";
set
{
if (_boundData != null)
{
_boundData.Value = value;
}
}
}
#endregion
#region Constructor
public UTKButtonItemView() : base()
{
InitializeUI();
}
public UTKButtonItemView(UTKButtonItem data) : this()
{
Bind(data);
}
#endregion
#region Initialization
private void InitializeUI()
{
AddToClassList("utk-property-item-view");
AddToClassList("utk-property-item-view--button");
if (!CreateUIFromUxml())
{
CreateUIFallback();
}
QueryUIElements();
}
private void QueryUIElements()
{
if (_valueContainer == null) return;
_button = this.Q<UTKButton>("button-field");
if (_button == null)
{
_button = new UTKButton { name = "button-field" };
_button.AddToClassList("utk-property-item-view__button");
_valueContainer.Add(_button);
}
// 버튼 클릭 이벤트 등록
_button.OnClicked += OnButtonClickedInternal;
}
#endregion
#region Override Methods
protected override void CreateValueUI(VisualElement container)
{
// Fallback: UXML 로드 실패 시 코드로 생성
_button = new UTKButton { name = "button-field" };
_button.AddToClassList("utk-property-item-view__button");
container.Add(_button);
_button.OnClicked += OnButtonClickedInternal;
}
public override void RefreshUI()
{
// 버튼은 정적이므로 별도 갱신 불필요
}
protected override void OnReadOnlyStateChanged(bool isReadOnly)
{
// 버튼은 ReadOnly 개념이 적용되지 않으므로 IsEnabled로 제어
if (_button != null)
{
_button.IsEnabled = !isReadOnly;
}
}
#endregion
#region Event Handling
private void OnButtonClickedInternal()
{
if (_boundData is UTKButtonItem buttonItem)
{
OnButtonClicked?.Invoke(buttonItem.ActionName);
}
}
#endregion
#region Data Binding
public void Bind(IUTKPropertyItem data)
{
if (data is IUTKPropertyItem<string> stringData)
{
Bind(stringData);
}
else
{
Debug.LogWarning($"[UTKButtonItemView] Cannot bind to non-string data: {data.GetType().Name}");
}
}
public void Bind(IUTKPropertyItem<string> data)
{
Unbind();
_boundData = data;
BindBase(data);
// 라벨 텍스트 설정
if (_labelElement != null)
{
_labelElement.Text = data.DisplayName;
}
// UTKButtonItem 설정 적용
if (data is UTKButtonItem buttonItem && _button != null)
{
_button.Text = buttonItem.Text;
_button.Icon = buttonItem.Icon;
_button.IconSize = buttonItem.IconSize;
_button.Variant = buttonItem.Variant;
_button.Size = buttonItem.Size;
_button.IconOnly = buttonItem.IconOnly;
if (buttonItem.BackgroundColor.HasValue)
{
_button.BackgroundColor = buttonItem.BackgroundColor;
}
if (buttonItem.BorderWidth >= 0)
{
_button.BorderWidth = buttonItem.BorderWidth;
}
_button.IsEnabled = !buttonItem.IsReadOnly;
// 라벨 표시 여부 제어
if (_labelElement != null)
{
if (buttonItem.ShowLabel)
{
_labelElement.style.display = DisplayStyle.Flex;
RemoveFromClassList("utk-property-item-view--button-no-label");
}
else
{
_labelElement.style.display = DisplayStyle.None;
AddToClassList("utk-property-item-view--button-no-label");
}
}
}
IsReadOnly = data.IsReadOnly;
IsVisible = data.IsVisible;
TooltipText = data.Tooltip;
}
public void Unbind()
{
if (_boundData != null)
{
UnbindBase();
_boundData = null;
}
}
#endregion
#region Dispose
protected override void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
if (_button != null)
{
_button.OnClicked -= OnButtonClickedInternal;
_button.Dispose();
}
Unbind();
OnValueChanged = null;
OnButtonClicked = null;
_button = null;
}
base.Dispose(disposing);
}
#endregion
}
}