209 lines
5.4 KiB
C#
209 lines
5.4 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// 탭 뷰 컴포넌트.
|
|
/// Unity TabView를 래핑하여 커스텀 스타일을 적용합니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <para><b>C# 코드에서 사용:</b></para>
|
|
/// <code>
|
|
/// // 탭 뷰 생성
|
|
/// var tabView = new UTKTabView();
|
|
///
|
|
/// // 탭 추가
|
|
/// var tab1 = tabView.AddTab("일반", UTKMaterialIcons.Settings);
|
|
/// tab1.Add(new Label("일반 설정 내용"));
|
|
///
|
|
/// var tab2 = tabView.AddTab("고급", UTKMaterialIcons.Build);
|
|
/// tab2.Add(new Label("고급 설정 내용"));
|
|
///
|
|
/// // 탭 변경 이벤트
|
|
/// tabView.OnTabChanged += (index, tab) => Debug.Log($"탭 {index} 선택됨");
|
|
///
|
|
/// // 탭 선택
|
|
/// tabView.SelectedIndex = 0;
|
|
/// </code>
|
|
/// <para><b>UXML에서 사용:</b></para>
|
|
/// <code>
|
|
/// <ui:UXML xmlns:utk="UVC.UIToolkit">
|
|
/// <utk:UTKTabView>
|
|
/// <utk:UTKTab label="일반">
|
|
/// <ui:Label text="일반 탭 내용" />
|
|
/// </utk:UTKTab>
|
|
/// <utk:UTKTab label="고급">
|
|
/// <ui:Label text="고급 탭 내용" />
|
|
/// </utk:UTKTab>
|
|
/// </utk:UTKTabView>
|
|
/// </ui:UXML>
|
|
/// </code>
|
|
/// </example>
|
|
[UxmlElement]
|
|
public partial class UTKTabView : TabView, IDisposable
|
|
{
|
|
#region Constants
|
|
private const string USS_PATH = "UIToolkit/Tab/UTKTabView";
|
|
#endregion
|
|
|
|
#region Fields
|
|
private bool _disposed;
|
|
private readonly List<UTKTab> _utkTabs = new();
|
|
#endregion
|
|
|
|
#region Events
|
|
/// <summary>탭 변경 이벤트</summary>
|
|
public event Action<int, Tab?>? OnTabChanged;
|
|
#endregion
|
|
|
|
#region Properties
|
|
/// <summary>선택된 탭 인덱스</summary>
|
|
public int SelectedIndex
|
|
{
|
|
get => selectedTabIndex;
|
|
set => selectedTabIndex = value;
|
|
}
|
|
|
|
/// <summary>UTK 탭 목록</summary>
|
|
public IReadOnlyList<UTKTab> UTKTabs => _utkTabs;
|
|
#endregion
|
|
|
|
#region Constructor
|
|
public UTKTabView() : base()
|
|
{
|
|
UTKThemeManager.Instance.ApplyThemeToElement(this);
|
|
|
|
var uss = Resources.Load<StyleSheet>(USS_PATH);
|
|
if (uss != null)
|
|
{
|
|
styleSheets.Add(uss);
|
|
}
|
|
|
|
SetupStyles();
|
|
SetupEvents();
|
|
SubscribeToThemeChanges();
|
|
}
|
|
#endregion
|
|
|
|
#region Setup
|
|
private void SetupStyles()
|
|
{
|
|
AddToClassList("utk-tabview");
|
|
}
|
|
|
|
private void SetupEvents()
|
|
{
|
|
this.RegisterCallback<ChangeEvent<int>>(OnTabIndexChanged);
|
|
}
|
|
|
|
private void SubscribeToThemeChanges()
|
|
{
|
|
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
|
|
RegisterCallback<DetachFromPanelEvent>(_ =>
|
|
{
|
|
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
|
|
});
|
|
}
|
|
|
|
private void OnThemeChanged(UTKTheme theme)
|
|
{
|
|
UTKThemeManager.Instance.ApplyThemeToElement(this);
|
|
}
|
|
#endregion
|
|
|
|
#region Event Handlers
|
|
private void OnTabIndexChanged(ChangeEvent<int> evt)
|
|
{
|
|
UpdateTabSelection();
|
|
OnTabChanged?.Invoke(evt.newValue, activeTab);
|
|
}
|
|
|
|
private void UpdateTabSelection()
|
|
{
|
|
for (int i = 0; i < _utkTabs.Count; i++)
|
|
{
|
|
_utkTabs[i].IsSelected = (i == selectedTabIndex);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Methods
|
|
/// <summary>
|
|
/// UTK 탭 추가
|
|
/// </summary>
|
|
public UTKTab AddUTKTab(string text, VisualElement? content = null)
|
|
{
|
|
var tab = new UTKTab(text);
|
|
if (content != null)
|
|
{
|
|
tab.Add(content);
|
|
}
|
|
AddTab(tab);
|
|
return tab;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 탭 추가
|
|
/// </summary>
|
|
public void AddTab(UTKTab tab)
|
|
{
|
|
_utkTabs.Add(tab);
|
|
Add(tab);
|
|
|
|
if (_utkTabs.Count == 1)
|
|
{
|
|
tab.IsSelected = true;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 탭 제거
|
|
/// </summary>
|
|
public void RemoveTab(UTKTab tab)
|
|
{
|
|
int index = _utkTabs.IndexOf(tab);
|
|
if (index < 0) return;
|
|
|
|
_utkTabs.RemoveAt(index);
|
|
tab.RemoveFromHierarchy();
|
|
tab.Dispose();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 탭 제거
|
|
/// </summary>
|
|
public void ClearTabs()
|
|
{
|
|
foreach (var tab in _utkTabs)
|
|
{
|
|
tab.RemoveFromHierarchy();
|
|
tab.Dispose();
|
|
}
|
|
_utkTabs.Clear();
|
|
}
|
|
#endregion
|
|
|
|
#region IDisposable
|
|
public void Dispose()
|
|
{
|
|
if (_disposed) return;
|
|
_disposed = true;
|
|
|
|
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
|
|
|
|
foreach (var tab in _utkTabs)
|
|
{
|
|
tab.Dispose();
|
|
}
|
|
_utkTabs.Clear();
|
|
|
|
OnTabChanged = null;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|