125 lines
3.0 KiB
C#
125 lines
3.0 KiB
C#
// UXGroup.cs
|
|
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
using System.Collections.Generic;
|
|
using Sirenix.OdinInspector;
|
|
using UnityEngine.EventSystems;
|
|
|
|
[DisallowMultipleComponent]
|
|
public class UXGroup : UIBehaviour
|
|
{
|
|
[SerializeField] private bool m_AllowSwitchOff;
|
|
[ReadOnly] [SerializeField] private List<UXButton> m_Buttons = new List<UXButton>();
|
|
|
|
private UXButton currentUXButton = null;
|
|
|
|
public UnityEvent<UXButton> onSelectedChanged = new UnityEvent<UXButton>();
|
|
|
|
public bool allowSwitchOff
|
|
{
|
|
get => m_AllowSwitchOff;
|
|
set
|
|
{
|
|
m_AllowSwitchOff = value;
|
|
ValidateGroupState();
|
|
}
|
|
}
|
|
|
|
protected override void OnDestroy()
|
|
{
|
|
base.OnDestroy();
|
|
m_Buttons.Clear();
|
|
currentUXButton = null;
|
|
}
|
|
|
|
|
|
protected override void Awake()
|
|
{
|
|
base.Awake();
|
|
ValidateGroupState();
|
|
}
|
|
|
|
public void RegisterButton(UXButton button)
|
|
{
|
|
if (!m_Buttons.Contains(button))
|
|
{
|
|
m_Buttons.Add(button);
|
|
if (button.IsSelected)
|
|
{
|
|
if (currentUXButton != null && currentUXButton != button)
|
|
{
|
|
currentUXButton.IsSelected = false;
|
|
}
|
|
currentUXButton = button;
|
|
}
|
|
ValidateGroupState();
|
|
}
|
|
}
|
|
|
|
public void UnregisterButton(UXButton button)
|
|
{
|
|
if (m_Buttons.Contains(button))
|
|
{
|
|
m_Buttons.Remove(button);
|
|
button.IsSelected = false;
|
|
}
|
|
}
|
|
|
|
internal void NotifyButtonClicked(UXButton clickedButton)
|
|
{
|
|
if (!clickedButton.IsSelected)
|
|
{
|
|
SetSelectedButton(clickedButton);
|
|
}
|
|
else
|
|
{
|
|
if (m_AllowSwitchOff)
|
|
SetSelectedButton(null);
|
|
else if (currentUXButton != clickedButton)
|
|
clickedButton.IsSelected = true;
|
|
}
|
|
}
|
|
|
|
private void SetSelectedButton(UXButton targetButton)
|
|
{
|
|
UXButton previousSelected = currentUXButton;
|
|
currentUXButton = null; // 防止递归
|
|
|
|
foreach (var button in m_Buttons)
|
|
{
|
|
bool shouldSelect = (button == targetButton);
|
|
if (button.IsSelected != shouldSelect)
|
|
{
|
|
button.IsSelected = shouldSelect;
|
|
}
|
|
if (shouldSelect) currentUXButton = button;
|
|
}
|
|
|
|
if (previousSelected != currentUXButton)
|
|
{
|
|
onSelectedChanged.Invoke(currentUXButton);
|
|
}
|
|
}
|
|
|
|
private void ValidateGroupState()
|
|
{
|
|
bool anySelected = m_Buttons.Exists(b => b.IsSelected);
|
|
if (!anySelected && m_Buttons.Count > 0 && !m_AllowSwitchOff)
|
|
{
|
|
SetSelectedButton(m_Buttons[0]);
|
|
}
|
|
}
|
|
|
|
public bool AnyOtherSelected(UXButton exclusion)
|
|
{
|
|
foreach (var button in m_Buttons)
|
|
{
|
|
if (button != exclusion && button.IsSelected)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
}
|