191 lines
10 KiB
C#
191 lines
10 KiB
C#
using System;
|
|
|
|
namespace UVC.UI.Toolbar.Model
|
|
{
|
|
/// <summary>
|
|
/// 클릭할 때마다 선택(On) 또는 해제(Off) 상태가 전환되는 토글 버튼입니다.
|
|
/// ToolbarButtonBase를 상속받으며, 추가적으로 선택 상태(IsSelected)와
|
|
/// 해제 상태일 때의 아이콘 경로(OffIconSpritePath), 상태 변경 시 호출될 콜백(OnToggle)을 관리합니다.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// View 레이어(예: ToolbarView)에서는 이 모델에 해당하는 UI 요소(예: UnityEngine.UI.Toggle)를 생성하고,
|
|
/// 사용자가 UI 토글을 조작하면 이 모델의 ExecuteClick 메서드를 호출하거나 IsSelected 속성을 직접 변경하여
|
|
/// 모델과 UI의 상태를 동기화합니다. IsSelected 속성이 변경되면 OnStateChanged 및 OnToggleStateChanged 이벤트가 발생하여
|
|
/// View가 아이콘(선택/해제 상태에 따라 IconSpritePath 또는 OffIconSpritePath 사용) 및 기타 시각적 요소를 업데이트합니다.
|
|
/// </remarks>
|
|
/// <example>
|
|
/// <code>
|
|
/// // Toolbar 또는 ToolbarModel 등에서 ToolbarToggleButton 생성 및 사용 예시
|
|
///
|
|
/// // 1. 토글 상태 변경 시 실행될 액션 정의 (OnToggle 콜백용)
|
|
/// Action<bool> handleMuteToggle = (isMuted) =>
|
|
/// {
|
|
/// UnityEngine.Debug.Log(isMuted ? "음소거됨" : "음소거 해제됨");
|
|
/// // 여기에 실제 음소거/해제 로직 구현
|
|
/// };
|
|
///
|
|
/// // 2. 토글 버튼 클릭 시 실행될 커맨드 정의 (선택 사항, 주로 상태 변경 후 추가 작업)
|
|
/// // 이 커맨드는 IsSelected 상태가 변경된 *후에* ExecuteClick 내부에서 호출됩니다.
|
|
/// // 커맨드 파라미터로 현재 IsSelected 상태를 받고 싶다면 ActionCommand<bool> 사용 가능.
|
|
/// ICommand muteCommand = new ActionCommand<bool>((IsSelected) =>
|
|
/// {
|
|
/// UnityEngine.Debug.Log($"음소거 버튼 커맨드 실행됨. 현재 선택 상태: {IsSelected}");
|
|
/// });
|
|
///
|
|
/// // 3. ToolbarToggleButton 인스턴스 생성 및 속성 설정
|
|
/// ToolbarToggleButton muteToggleButton = new ToolbarToggleButton
|
|
/// {
|
|
/// Text = "button_mute", // 버튼 텍스트 (다국어 키)
|
|
/// IconSpritePath = "icons/toolbar/sound_on_icon", // 선택(On) 상태 아이콘
|
|
/// OffIconSpritePath = "icons/toolbar/sound_off_icon", // 해제(Off) 상태 아이콘
|
|
/// Tooltip = "tooltip_mute_button", // 툴팁 (다국어 키)
|
|
/// IsSelected = false, // 초기 상태는 해제(Off)
|
|
/// OnToggle = handleMuteToggle, // 상태 변경 시 콜백 할당
|
|
/// ClickCommand = muteCommand, // 클릭 커맨드 할당
|
|
/// IsEnabled = true // 버튼 활성화 상태
|
|
/// };
|
|
///
|
|
/// // 4. 생성된 버튼 모델을 ToolbarModel에 추가
|
|
/// // toolbarModel.AddItem(muteToggleButton);
|
|
/// // 또는
|
|
/// // toolbarModel.AddToggleButton("button_mute", false, "icons/toolbar/sound_on_icon", "icons/toolbar/sound_off_icon", handleMuteToggle, muteCommand, "tooltip_mute_button");
|
|
///
|
|
/// // 5. 버튼 상태 프로그래밍 방식으로 변경 예시
|
|
/// // muteToggleButton.IsSelected = true; // 버튼을 선택 상태로 변경 (OnToggle 콜백 및 이벤트 발생)
|
|
/// </code>
|
|
/// </example>
|
|
public class ToolbarToggleButton : ToolbarButtonBase
|
|
{
|
|
/// <summary>
|
|
/// 버튼의 선택 상태(IsSelected)가 변경될 때 발생하는 이벤트입니다.
|
|
/// 변경된 IsSelected 값을 파라미터로 전달합니다.
|
|
/// View에서 이 이벤트를 구독하여 UI의 시각적 상태(예: Toggle 컴포넌트의 isOn 상태)를 업데이트할 수 있습니다.
|
|
/// OnStateChanged 이벤트와 별개로, IsSelected 상태 변경에 좀 더 특화된 알림입니다.
|
|
/// </summary>
|
|
public event Action<bool> OnToggleStateChanged; // IsSelected 변경 시 IsSelected 값을 전달하는 이벤트
|
|
|
|
protected string _offIconSpritePath;
|
|
/// <summary>
|
|
/// 버튼이 선택되지 않은(해제된, Off) 상태일 때 표시될 아이콘의 Resources 폴더 내 경로입니다.
|
|
/// 이 값이 변경되면 OnStateChanged 이벤트가 발생하여 View가 아이콘을 업데이트할 수 있습니다.
|
|
/// 선택(On) 상태일 때는 ToolbarButtonBase의 IconSpritePath가 사용됩니다.
|
|
/// </summary>
|
|
public string OffIconSpritePath
|
|
{
|
|
get => _offIconSpritePath;
|
|
set
|
|
{
|
|
if (_offIconSpritePath != value)
|
|
{
|
|
_offIconSpritePath = value;
|
|
NotifyStateChanged();// 아이콘 경로 변경 시 전체 상태 변경으로 간주
|
|
}
|
|
}
|
|
}
|
|
|
|
private bool _isSelected;
|
|
/// <summary>
|
|
/// 버튼의 현재 선택 상태를 나타냅니다. true이면 선택(On)된 상태, false이면 해제(Off)된 상태입니다.
|
|
/// 이 속성 값이 변경되면 OnStateChanged 이벤트와 OnToggleStateChanged 이벤트가 발생하며,
|
|
/// OnToggle 콜백이 호출됩니다.
|
|
/// </summary>
|
|
public bool IsSelected
|
|
{
|
|
get => _isSelected;
|
|
set
|
|
{
|
|
if (_isSelected != value)
|
|
{
|
|
_isSelected = value;
|
|
OnToggle?.Invoke(_isSelected); // OnToggle 콜백 호출
|
|
OnToggleStateChanged?.Invoke(_isSelected); // IsSelected 값과 함께 이벤트 발생
|
|
NotifyStateChanged(); // 일반 상태 변경 이벤트도 발생
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 버튼의 선택 상태(IsSelected)가 변경될 때 호출될 사용자 정의 콜백 액션입니다.
|
|
/// IsSelected 속성의 setter 내부에서 호출됩니다.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// ClickCommand와는 별개로, 순수하게 토글 상태 변경에 대한 응답 로직을 정의할 때 유용합니다.
|
|
/// 예를 들어, UI 상태 변경에 따른 즉각적인 모델 데이터 변경 등에 사용할 수 있습니다.
|
|
/// </remarks>
|
|
public Action<bool> OnToggle { get; set; }
|
|
|
|
/// <summary>
|
|
/// 이벤트 발생 여부를 선택하여 선택 상태를 설정합니다.
|
|
/// UI 업데이트 이벤트(OnToggleStateChanged, OnStateChanged)는 항상 발생하며,
|
|
/// raiseEvent는 OnToggle 콜백 호출 여부만 제어합니다.
|
|
/// </summary>
|
|
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
|
/// <param name="raiseEvent">true이면 OnToggle 콜백을 호출하고, false이면 호출하지 않습니다.</param>
|
|
public void SetSelected(bool isSelected, bool raiseEvent)
|
|
{
|
|
if (_isSelected != isSelected)
|
|
{
|
|
_isSelected = isSelected;
|
|
if (raiseEvent)
|
|
{
|
|
OnToggle?.Invoke(_isSelected);
|
|
}
|
|
OnToggleStateChanged?.Invoke(_isSelected);
|
|
NotifyStateChanged();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 버튼 클릭 로직을 실행합니다.
|
|
/// 토글 버튼의 경우, 클릭 시 IsSelected 상태를 반전시키고,
|
|
/// ClickCommand가 있다면 현재 IsSelected 상태를 파라미터로 전달하여 실행합니다.
|
|
/// </summary>
|
|
/// <param name="parameter">
|
|
/// 이 파라미터는 일반적으로 사용되지 않거나 무시될 수 있습니다.
|
|
/// ClickCommand에는 현재 IsSelected 상태가 전달됩니다.
|
|
/// 만약 외부에서 특정 값을 전달해야 한다면, ClickCommand가 ActionCommand<object> 등으로 정의되어야 합니다.
|
|
/// </param>
|
|
public override void ExecuteClick(object parameter = null)
|
|
{
|
|
if (!IsEnabled) return;
|
|
|
|
if (parameter is bool newSelectedStateFromUI)
|
|
{
|
|
// UI로부터 직접 상태가 전달된 경우 (View의 OnValueChanged 리스너)
|
|
// IsSelected 프로퍼티 setter가 OnToggle 및 NotifyStateChanged를 호출
|
|
IsSelected = newSelectedStateFromUI;
|
|
}
|
|
else
|
|
{
|
|
// 일반적인 ExecuteClick (파라미터 없거나 bool이 아님) - 기존 토글 로직
|
|
IsSelected = !IsSelected;
|
|
}
|
|
|
|
// ClickCommand 실행. IsSelected 상태가 변경된 *후에* 실행됩니다.
|
|
// ClickCommand에 현재 선택 상태(IsSelected)를 파라미터로 전달합니다.
|
|
// 만약 ClickCommand가 파라미터를 받지 않는 ActionCommand라면, 파라미터 없이 실행됩니다.
|
|
// ClickCommand가 ActionCommand<bool>이라면 IsSelected 값이 전달됩니다.
|
|
// ClickCommand가 ActionCommand<object>라면 IsSelected 값이 object로 박싱되어 전달됩니다.
|
|
if (ClickCommand != null)
|
|
{
|
|
// ClickCommand의 구체적인 타입(제네릭 여부 등)에 따라 파라미터 전달 방식이 달라질 수 있습니다.
|
|
// 가장 일반적인 경우는 ClickCommand가 현재 상태를 알 수 있도록 하는 것입니다.
|
|
// ToolbarView에서 연결 시 new ActionCommand<bool>((isSelectedParam) => { /* 로직 */ }) 형태로 커맨드를 생성했다면,
|
|
// isSelectedParam으로 현재 IsSelected 값이 전달됩니다.
|
|
ClickCommand.Execute(IsSelected);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 이 버튼 모델에 연결된 모든 이벤트 핸들러를 정리합니다.
|
|
/// ToolbarButtonBase의 이벤트 외에 ToolbarToggleButton에 특화된 이벤트(OnToggleStateChanged, OnToggle)를 추가로 정리합니다.
|
|
/// </summary>
|
|
public override void ClearEventHandlers()
|
|
{
|
|
base.ClearEventHandlers(); // 부모 클래스의 이벤트 정리 (OnStateChanged)
|
|
OnToggleStateChanged = null;
|
|
OnToggle = null;
|
|
}
|
|
}
|
|
}
|