182 lines
4.6 KiB
C#
182 lines
4.6 KiB
C#
#nullable enable
|
|
|
|
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// UIToolkit 기반 개별 메뉴 아이템 UI 컴포넌트입니다 (Label 기반).
|
|
/// 메뉴 아이템의 시각적 표현과 클릭 이벤트를 처리합니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <code>
|
|
/// // 메뉴 아이템 생성
|
|
/// var menuItem = new UTKTopMenuItem();
|
|
/// menuItem.SetData(menuItemData);
|
|
///
|
|
/// // 클릭 이벤트 구독
|
|
/// menuItem.OnClicked += (data) => Debug.Log($"Clicked: {data.ItemId}");
|
|
///
|
|
/// // 사용 후 정리
|
|
/// menuItem.Dispose();
|
|
/// </code>
|
|
/// </example>
|
|
[UxmlElement]
|
|
public partial class UTKTopMenuItem : UTKMenuItemBase
|
|
{
|
|
#region Constants
|
|
|
|
private const string UXML_PATH = "UIToolkit/Menu/UTKMenuItem";
|
|
private const string USS_PATH = "UIToolkit/Menu/UTKMenuItemUss";
|
|
|
|
#endregion
|
|
|
|
#region Fields
|
|
|
|
private UTKLabel? _label;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// UTKTopMenuItem의 새 인스턴스를 초기화합니다.
|
|
/// </summary>
|
|
public UTKTopMenuItem() : base()
|
|
{
|
|
_ussPath = USS_PATH;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Setup
|
|
|
|
/// <summary>
|
|
/// UI를 생성합니다.
|
|
/// </summary>
|
|
protected override void CreateUI()
|
|
{
|
|
AddToClassList("utk-menu-item");
|
|
|
|
var asset = Resources.Load<VisualTreeAsset>(UXML_PATH);
|
|
if (asset != null)
|
|
{
|
|
CreateUIFromUxml(asset);
|
|
}
|
|
else
|
|
{
|
|
CreateUIFallback();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// UXML에서 UI를 생성합니다.
|
|
/// </summary>
|
|
/// <param name="asset">UXML 에셋</param>
|
|
private void CreateUIFromUxml(VisualTreeAsset asset)
|
|
{
|
|
var root = asset.Instantiate();
|
|
|
|
// USS를 root에 추가
|
|
var uss = Resources.Load<StyleSheet>(USS_PATH);
|
|
if (uss != null)
|
|
{
|
|
root.styleSheets.Add(uss);
|
|
}
|
|
|
|
// UI 요소 참조 가져오기 (쿼리 캐싱)
|
|
_button = root.Q<Button>("menu-button");
|
|
_label = root.Q<UTKLabel>("label");
|
|
_arrow = root.Q<VisualElement>("arrow");
|
|
|
|
Add(root);
|
|
|
|
// 버튼 클릭 이벤트 등록
|
|
if (_button != null)
|
|
{
|
|
_onClickCallback = OnButtonClicked;
|
|
_button.RegisterCallback(_onClickCallback);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Fallback UI를 생성합니다 (UXML 로드 실패 시).
|
|
/// </summary>
|
|
private void CreateUIFallback()
|
|
{
|
|
_button = new Button();
|
|
_button.name = "menu-button";
|
|
_button.AddToClassList("menu-item");
|
|
|
|
_label = new UTKLabel();
|
|
_label.name = "label";
|
|
_label.AddToClassList("menu-item__label");
|
|
|
|
_arrow = new VisualElement();
|
|
_arrow.name = "arrow";
|
|
_arrow.AddToClassList("menu-item__arrow");
|
|
_arrow.style.display = DisplayStyle.None;
|
|
|
|
_button.Add(_label);
|
|
_button.Add(_arrow);
|
|
Add(_button);
|
|
|
|
_onClickCallback = OnButtonClicked;
|
|
_button.RegisterCallback(_onClickCallback);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Protected Methods
|
|
|
|
/// <summary>
|
|
/// UI를 업데이트합니다.
|
|
/// </summary>
|
|
protected override void UpdateUI()
|
|
{
|
|
if (_label != null && !string.IsNullOrEmpty(DisplayName))
|
|
{
|
|
// 다국어 적용
|
|
if (_locManager != null)
|
|
{
|
|
_label.Text = _locManager.GetString(DisplayName);
|
|
}
|
|
else
|
|
{
|
|
_label.Text = DisplayName;
|
|
}
|
|
}
|
|
|
|
UpdateOpacity();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 활성화 상태에 따라 투명도를 업데이트합니다.
|
|
/// </summary>
|
|
protected override void UpdateOpacity()
|
|
{
|
|
if (_label != null)
|
|
{
|
|
_label.style.opacity = IsEnabled ? 1f : 0.5f;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region IDisposable
|
|
|
|
/// <summary>
|
|
/// 리소스를 정리합니다.
|
|
/// </summary>
|
|
public override void Dispose()
|
|
{
|
|
base.Dispose();
|
|
_label = null;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|