164 lines
4.7 KiB
C#
164 lines
4.7 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// 토글 버튼 그룹 컴포넌트.
|
|
/// Unity ToggleButtonGroup을 래핑하여 커스텀 스타일을 적용합니다.
|
|
/// </summary>
|
|
/// <example>
|
|
/// <para><b>C# 코드에서 사용:</b></para>
|
|
/// <code>
|
|
/// // 토글 버튼 그룹 생성
|
|
/// var group = new UTKToggleButtonGroup();
|
|
/// group.Add(new Button { text = "왼쪽" });
|
|
/// group.Add(new Button { text = "가운데" });
|
|
/// group.Add(new Button { text = "오른쪽" });
|
|
///
|
|
/// // 단일 선택 모드
|
|
/// group.allowEmptySelection = false;
|
|
///
|
|
/// // 다중 선택 모드
|
|
/// group.isMultipleSelection = true;
|
|
///
|
|
/// // 선택 변경 이벤트
|
|
/// group.OnSelectionChanged += (indices) => {
|
|
/// Debug.Log($"선택됨: {string.Join(", ", indices)}");
|
|
/// };
|
|
/// </code>
|
|
/// <para><b>UXML에서 사용:</b></para>
|
|
/// <code>
|
|
/// <ui:UXML xmlns:utk="UVC.UIToolkit">
|
|
/// <utk:UTKToggleButtonGroup allow-empty-selection="false">
|
|
/// <ui:Button text="왼쪽" />
|
|
/// <ui:Button text="가운데" />
|
|
/// <ui:Button text="오른쪽" />
|
|
/// </utk:UTKToggleButtonGroup>
|
|
/// </ui:UXML>
|
|
/// </code>
|
|
/// </example>
|
|
[UxmlElement]
|
|
public partial class UTKToggleButtonGroup : ToggleButtonGroup, IDisposable
|
|
{
|
|
#region Constants
|
|
private const string USS_PATH = "UIToolkit/Button/UTKToggleButtonGroup";
|
|
#endregion
|
|
|
|
#region Fields
|
|
private bool _disposed;
|
|
private bool _isEnabled = true;
|
|
#endregion
|
|
|
|
#region Events
|
|
/// <summary>선택 변경 이벤트</summary>
|
|
public event Action<IEnumerable<int>>? OnSelectionChanged;
|
|
#endregion
|
|
|
|
#region Properties
|
|
/// <summary>활성화 상태</summary>
|
|
[UxmlAttribute]
|
|
public bool IsEnabled
|
|
{
|
|
get => _isEnabled;
|
|
set
|
|
{
|
|
_isEnabled = value;
|
|
SetEnabled(value);
|
|
EnableInClassList("utk-toggle-group--disabled", !value);
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Constructor
|
|
public UTKToggleButtonGroup() : 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-toggle-group");
|
|
}
|
|
|
|
private void SetupEvents()
|
|
{
|
|
this.RegisterValueChangedCallback(OnValueChanged);
|
|
}
|
|
|
|
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 OnValueChanged(ChangeEvent<ToggleButtonGroupState> evt)
|
|
{
|
|
var state = evt.newValue;
|
|
var buffer = new int[state.length];
|
|
var activeOptions = state.GetActiveOptions(buffer);
|
|
var result = new List<int>();
|
|
foreach (var idx in activeOptions)
|
|
{
|
|
result.Add(idx);
|
|
}
|
|
OnSelectionChanged?.Invoke(result);
|
|
}
|
|
#endregion
|
|
|
|
#region Methods
|
|
/// <summary>
|
|
/// 토글 버튼 추가
|
|
/// </summary>
|
|
public void AddButton(string text, string? icon = null)
|
|
{
|
|
var button = new Button { text = text };
|
|
button.AddToClassList("utk-toggle-group__button");
|
|
if (!string.IsNullOrEmpty(icon))
|
|
{
|
|
var iconLabel = new Label(icon);
|
|
iconLabel.AddToClassList("utk-toggle-group__icon");
|
|
button.Insert(0, iconLabel);
|
|
}
|
|
Add(button);
|
|
}
|
|
#endregion
|
|
|
|
#region IDisposable
|
|
public void Dispose()
|
|
{
|
|
if (_disposed) return;
|
|
_disposed = true;
|
|
|
|
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
|
|
OnSelectionChanged = null;
|
|
}
|
|
#endregion
|
|
}
|
|
}
|