Files
XRLib/Assets/Scripts/UVC/UIToolkit/Tab/UTKTabView.cs

176 lines
4.3 KiB
C#
Raw Normal View History

2026-01-08 20:15:57 +09:00
#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit
{
/// <summary>
/// 탭 뷰 컴포넌트.
/// Unity TabView를 래핑하여 커스텀 스타일을 적용합니다.
/// </summary>
[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
}
}