BITKit/Src/Unity/Scripts/UX/Library/TabBar.cs

146 lines
3.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace BITKit.UX
{
/// <summary>
/// Tab容器,仅用于快速生成TabBar
/// </summary>
[UnityEngine.Scripting.Preserve]
public class TabBar : VisualElement,INotifyValueChanged<int>
{
public new class UxmlTraits:VisualElement.UxmlTraits
{
private readonly UxmlIntAttributeDescription m_TabBarAttribute = new ()
{
name = "CurrentTab",
defaultValue = -1
};
private readonly UxmlStringAttributeDescription m_TabsAttribute = new ()
{
name = "tabs"
};
private readonly UxmlBoolAttributeDescription m_allowFocus = new ()
{
name = "allowFocus",
defaultValue = true
};
public override void Init(VisualElement ve, IUxmlAttributes bag, CreationContext cc)
{
base.Init(ve, bag, cc);
var tabBar = (TabBar)ve;
tabBar.CurrentTab = m_TabBarAttribute.GetValueFromBag(bag, cc);
tabBar.Tabs = m_TabsAttribute.GetValueFromBag(bag, cc);
tabBar.allowFocus = m_allowFocus.GetValueFromBag(bag, cc);
}
}
public new class UxmlFactory : UxmlFactory<TabBar, UxmlTraits> { }
// These are USS class names for the control overall and the label.
public TabBar()
{
RegisterCallback<AttachToPanelEvent>(UpdateI);
RegisterCallback<DetachFromPanelEvent>(UpdateI);
RegisterCallback<GeometryChangedEvent>(UpdateI);
}
private void UpdateI(object _)
{
CurrentTab = _currentTab;
}
public event Action<int> OnTabChanged;
private Button[] _buttons = Array.Empty<Button>();
private int _currentTab;
public int CurrentTab
{
get=>_currentTab;
set
{
if(_currentTab == value)return;
_currentTab = value;
SetTabs(value);
}
}
private string tabs;
public string Tabs
{
get => tabs;
set
{
tabs = value;
SetTabs(value);
}
}
private bool allowFocus;
public bool AllowFocus
{
get => allowFocus;
set
{
allowFocus = value;
foreach (var x in _buttons)
{
x.focusable = value;
}
}
}
private void SetTabs(string value)
{
var split = value.Split(",");
foreach (var x in _buttons)
{
x.RemoveFromHierarchy();
}
_buttons = new Button[split.Length];
for (var i = 0; i < split.Length; i++)
{
var tabName = split[i];
var index = i;
var button = _buttons[i] = this.Create<Button>();
button.AddToClassList("v"+i);
button.text = tabName;
button.focusable = allowFocus;
button.clicked += () => CurrentTab = index;
}
}
private void SetTabs(int index)
{
SetValueWithoutNotify(index);
OnTabChanged?.Invoke(index);
MarkDirtyRepaint();
}
public void SetValueWithoutNotify(int newValue)
{
switch (newValue)
{
case var _ when newValue < 0 || newValue > _buttons.Length:
return;
}
for (var i = 0; i < _buttons.Length; i++)
{
var button = _buttons[i];
var entry = newValue == i;
button.SetEnabled(!entry);
}
}
int INotifyValueChanged<int>.value
{
get => CurrentTab;
set=>CurrentTab = value;
}
}
}