165 lines
9.1 KiB
C#
165 lines
9.1 KiB
C#
using System;
|
|
|
|
namespace UVC.UI.Toolbar.Model
|
|
{
|
|
/// <summary>
|
|
/// 라디오 버튼 그룹 내에서 사용되는 버튼입니다. 동일한 GroupName을 가진 라디오 버튼들 중에서
|
|
/// 단 하나만 선택될 수 있도록 동작합니다. ToolbarToggleButton을 상속받습니다.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 각 ToolbarRadioButton은 GroupName을 가지며, 이 GroupName을 기준으로 ToolbarModel에서
|
|
/// ToolbarRadioButtonGroup에 의해 관리됩니다. 사용자가 라디오 버튼을 클릭하면,
|
|
/// 이 버튼은 자신이 속한 RadioGroup에 선택 상태 변경을 요청하고, RadioGroup은
|
|
/// 그룹 내 다른 버튼들의 선택을 해제하고 이 버튼만 선택된 상태로 만듭니다.
|
|
/// IsSelected 상태 변경 시 OnToggle, OnStateChanged, OnToggleStateChanged 이벤트가 발생합니다.
|
|
/// </remarks>
|
|
/// <example>
|
|
/// <code>
|
|
/// // Toolbar 또는 ToolbarModel 등에서 ToolbarRadioButton 생성 및 사용 예시
|
|
///
|
|
/// string cameraViewGroupName = "CameraViewOptions";
|
|
///
|
|
/// // 1. 라디오 버튼1: 탑뷰
|
|
/// ToolbarRadioButton topViewRadio = new ToolbarRadioButton(cameraViewGroupName)
|
|
/// {
|
|
/// Text = "view_top",
|
|
/// IconSpritePath = "icons/toolbar/view_top_on",
|
|
/// OffIconSpritePath = "icons/toolbar/view_top_off",
|
|
/// Tooltip = "tooltip_top_view",
|
|
/// IsSelected = true, // 초기 선택 상태
|
|
/// OnToggle = (IsSelected) =>
|
|
/// {
|
|
/// if (IsSelected) UnityEngine.Debug.Log("탑뷰 선택됨 (OnToggle)");
|
|
/// },
|
|
/// ClickCommand = new ActionCommand(() =>
|
|
/// {
|
|
/// UnityEngine.Debug.Log("탑뷰 커맨드 실행");
|
|
/// // 실제 탑뷰로 변경하는 로직
|
|
/// })
|
|
/// };
|
|
///
|
|
/// // 2. 라디오 버튼2: 프론트뷰
|
|
/// ToolbarRadioButton frontViewRadio = new ToolbarRadioButton(cameraViewGroupName)
|
|
/// {
|
|
/// Text = "view_front",
|
|
/// IconSpritePath = "icons/toolbar/view_front_on",
|
|
/// OffIconSpritePath = "icons/toolbar/view_front_off",
|
|
/// Tooltip = "tooltip_front_view",
|
|
/// IsSelected = false, // 초기 선택 안됨
|
|
/// OnToggle = (IsSelected) =>
|
|
/// {
|
|
/// if (IsSelected) UnityEngine.Debug.Log("프론트뷰 선택됨 (OnToggle)");
|
|
/// },
|
|
/// ClickCommand = new ActionCommand(() =>
|
|
/// {
|
|
/// UnityEngine.Debug.Log("프론트뷰 커맨드 실행");
|
|
/// // 실제 프론트뷰로 변경하는 로직
|
|
/// })
|
|
/// };
|
|
///
|
|
/// // 3. 생성된 라디오 버튼들을 ToolbarModel에 추가
|
|
/// // toolbarModel.AddItem(topViewRadio);
|
|
/// // toolbarModel.AddItem(frontViewRadio);
|
|
/// // 또는 ToolbarModel의 AddRadioButton 헬퍼 메서드 사용
|
|
/// // toolbarModel.AddRadioButton(cameraViewGroupName, "view_top", true, "icons/toolbar/view_top_on", ...);
|
|
/// // toolbarModel.AddRadioButton(cameraViewGroupName, "view_front", false, "icons/toolbar/view_front_on", ...);
|
|
///
|
|
/// // ToolbarModel은 AddItem 시 GroupName을 보고 내부적으로 ToolbarRadioButtonGroup을 생성/관리하며
|
|
/// // 각 라디오 버튼을 해당 그룹에 등록합니다.
|
|
/// </code>
|
|
/// </example>
|
|
public class ToolbarRadioButton : ToolbarToggleButton
|
|
{
|
|
/// <summary>
|
|
/// 이 라디오 버튼이 속한 그룹의 이름입니다.
|
|
/// 동일한 GroupName을 가진 라디오 버튼들은 하나의 그룹으로 묶여 동작합니다.
|
|
/// </summary>
|
|
public string GroupName { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 이 라디오 버튼을 관리하는 ToolbarRadioButtonGroup의 내부 참조입니다.
|
|
/// ToolbarModel에 의해 설정되며, 버튼이 그룹에 등록될 때 할당됩니다.
|
|
/// </summary>
|
|
internal ToolbarRadioButtonGroup RadioGroup { get; set; }
|
|
|
|
/// <summary>
|
|
/// 지정된 그룹 이름을 사용하여 ToolbarRadioButton의 새 인스턴스를 초기화합니다.
|
|
/// </summary>
|
|
/// <param name="groupName">이 라디오 버튼이 속할 그룹의 이름입니다. null이거나 비어있을 수 없습니다.</param>
|
|
/// <exception cref="ArgumentNullException">groupName이 null이거나 빈 문자열일 경우 발생합니다.</exception>
|
|
public ToolbarRadioButton(string groupName)
|
|
{
|
|
if (string.IsNullOrEmpty(groupName))
|
|
{
|
|
throw new ArgumentNullException(nameof(groupName), "라디오 버튼은 반드시 GroupName을 가져야 합니다.");
|
|
}
|
|
GroupName = groupName;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 라디오 버튼 클릭 로직을 실행합니다.
|
|
/// 버튼이 활성화되어 있다면, 자신이 속한 RadioGroup에 자신을 선택하도록 요청합니다.
|
|
/// RadioGroup은 이 요청을 받아 그룹 내 다른 버튼들의 선택을 해제하고 이 버튼만 선택 상태로 만듭니다.
|
|
/// 그 후, 이 버튼의 ClickCommand가 실행됩니다 (선택된 상태에서만).
|
|
/// </summary>
|
|
/// <param name="parameter">
|
|
/// 이 파라미터는 ClickCommand에 전달될 수 있습니다.
|
|
/// ToolbarView에서 UI 이벤트 연결 시, 라디오 버튼의 경우 보통 선택 상태(true)를 전달하거나,
|
|
/// 버튼 모델 자체를 전달하여 Command가 필요한 정보를 추출하도록 할 수 있습니다.
|
|
/// 기본적으로는 현재 IsSelected 상태가 ClickCommand에 전달되도록 고려할 수 있습니다.
|
|
/// </param>
|
|
public override void ExecuteClick(object parameter = null)
|
|
{
|
|
if (!IsEnabled) return;
|
|
|
|
// bool previousSelectionState = IsSelected; // 이전 선택 상태 (필요하다면)
|
|
|
|
if (RadioGroup != null)
|
|
{
|
|
// RadioGroup의 SetSelected 메서드를 호출하여 그룹 내 선택 상태를 관리합니다.
|
|
// SetSelected 내부에서 이 버튼의 IsSelected가 true로 설정되고,
|
|
// 다른 버튼들은 false로 설정됩니다.
|
|
// IsSelected setter는 OnToggle, OnStateChanged, OnToggleStateChanged 이벤트를 발생시킵니다.
|
|
RadioGroup.SetSelected(this);
|
|
}
|
|
else
|
|
{
|
|
// RadioGroup이 할당되지 않은 경우 (예: ToolbarModel에 추가되기 전 또는 독립적으로 사용 시도)
|
|
// 이 경우 일반 토글 버튼처럼 동작하거나, 경고를 로깅할 수 있습니다.
|
|
// 현재 구현은 그룹이 없으면 단독으로 선택되는 것을 방지하거나 특별 처리를 하도록 되어 있습니다.
|
|
UnityEngine.Debug.LogWarning($"ToolbarRadioButton '{Text}' (그룹: {GroupName})에 RadioGroup이 할당되지 않았습니다. 단독으로 상태가 변경될 수 없습니다. ToolbarModel에 먼저 추가되어야 합니다.");
|
|
// 만약 그룹 없이도 토글 가능하게 하려면 아래 주석 해제 및 로직 수정 필요
|
|
// IsSelected = !IsSelected;
|
|
}
|
|
|
|
// ClickCommand 실행:
|
|
// 라디오 버튼의 ClickCommand는 일반적으로 해당 버튼이 "선택되었을 때"의 액션을 정의합니다.
|
|
// RadioGroup.SetSelected에 의해 IsSelected 상태가 true로 변경된 후에 실행되어야 합니다.
|
|
if (IsSelected && ClickCommand != null)
|
|
{
|
|
// 파라미터 처리: parameter가 null이 아니면 그것을 우선 사용하고,
|
|
// 아니면 현재 IsSelected 상태(true) 또는 버튼 자체(this)를 전달할 수 있습니다.
|
|
// ToolbarView의 SetupButtonVisualsAndInteractions에서 radioModel.ExecuteClick(true)로 호출하는 경우,
|
|
// parameter는 true가 됩니다.
|
|
object commandParameterToUse = parameter ?? this; // 예: 명시적 파라미터가 없으면 버튼 인스턴스 전달
|
|
|
|
ClickCommand.Execute(commandParameterToUse);
|
|
}
|
|
// 만약 선택 해제 시(다른 라디오 버튼이 선택되어 이 버튼이 해제될 때)에도 Command를 실행해야 한다면,
|
|
// 위 if(IsSelected) 조건을 제거하거나, 별도의 Command(예: DeselectCommand)를 고려해야 합니다.
|
|
// 하지만 일반적인 라디오 버튼의 사용 패턴은 선택 시의 액션에 중점을 둡니다.
|
|
}
|
|
|
|
/// <summary>
|
|
/// 이 버튼 모델에 연결된 모든 이벤트 핸들러를 정리합니다.
|
|
/// ToolbarRadioButton은 ToolbarToggleButton에서 상속받은 이벤트 외에 추가적인 이벤트가 없으므로,
|
|
/// 부모 클래스의 ClearEventHandlers를 호출합니다.
|
|
/// </summary>
|
|
public override void ClearEventHandlers()
|
|
{
|
|
base.ClearEventHandlers(); // 부모 클래스(ToolbarToggleButton)의 이벤트 정리
|
|
// ToolbarRadioButton에 특화된 이벤트가 있다면 여기서 정리합니다.
|
|
}
|
|
}
|
|
}
|