탐색기, 라이브러리, 화면 객체 배치
This commit is contained in:
@@ -58,6 +58,12 @@ namespace UVC.UI.Toolbar.Model
|
||||
/// </remarks>
|
||||
public event Action OnStateChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 버튼이 클릭되었을 때 발생하는 이벤트입니다.
|
||||
/// ExecuteClick 메서드가 호출될 때 발생합니다.
|
||||
/// </summary>
|
||||
public event Action OnClicked;
|
||||
|
||||
protected string _text;
|
||||
/// <summary>
|
||||
/// 버튼에 표시될 텍스트 또는 텍스트의 다국어 키입니다.
|
||||
@@ -191,10 +197,10 @@ namespace UVC.UI.Toolbar.Model
|
||||
/// <param name="parameter">ClickCommand에 전달할 선택적 파라미터입니다.</param>
|
||||
public virtual void ExecuteClick(object parameter = null)
|
||||
{
|
||||
if (IsEnabled && ClickCommand != null)
|
||||
{
|
||||
ClickCommand.Execute(parameter); // 커맨드에 파라미터 전달
|
||||
}
|
||||
if (!IsEnabled) return;
|
||||
|
||||
ClickCommand?.Execute(parameter); // 커맨드에 파라미터 전달
|
||||
OnClicked?.Invoke(); // 클릭 이벤트 발생
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -225,6 +231,7 @@ namespace UVC.UI.Toolbar.Model
|
||||
public virtual void ClearEventHandlers()
|
||||
{
|
||||
OnStateChanged = null;
|
||||
OnClicked = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,6 +71,42 @@ namespace UVC.UI.Toolbar.Model
|
||||
/// </remarks>
|
||||
public Action<ToolbarButtonBase> OnSubButtonSelected { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 하위 버튼 선택 변경 시 발생하는 이벤트입니다.
|
||||
/// 확장 버튼의 텍스트와 선택된 하위 버튼의 텍스트가 파라미터로 전달됩니다.
|
||||
/// Toolbar/Toolbox에서 OnAction 이벤트를 발생시키기 위해 구독합니다.
|
||||
/// </summary>
|
||||
public event Action<string, string> OnSubButtonSelectionChanged;
|
||||
|
||||
/// <summary>
|
||||
/// 현재 선택된 하위 버튼을 저장합니다.
|
||||
/// 동일한 버튼이 다시 선택될 때 이벤트 중복 발생을 방지합니다.
|
||||
/// </summary>
|
||||
private ToolbarButtonBase _selectedSubButton;
|
||||
|
||||
/// <summary>
|
||||
/// 현재 선택된 하위 버튼을 가져옵니다.
|
||||
/// </summary>
|
||||
public ToolbarButtonBase SelectedSubButton => _selectedSubButton;
|
||||
|
||||
/// <summary>
|
||||
/// AddExpandableButton에서 설정한 원본 텍스트를 저장합니다.
|
||||
/// OnSubButtonSelectionChanged 이벤트 발생 시 이 값이 Text로 전달됩니다.
|
||||
/// </summary>
|
||||
private string _originalText;
|
||||
|
||||
/// <summary>
|
||||
/// AddExpandableButton에서 설정한 원본 텍스트를 가져옵니다.
|
||||
/// </summary>
|
||||
public string OriginalText => _originalText;
|
||||
|
||||
/// <summary>
|
||||
/// 서브 버튼 선택 시 주 버튼의 아이콘을 선택된 서브 버튼의 아이콘으로 변경할지 여부입니다.
|
||||
/// true이면 아이콘이 변경되고, false이면 원래 아이콘을 유지합니다.
|
||||
/// 기본값은 true입니다.
|
||||
/// </summary>
|
||||
public bool UpdateIconOnSelection { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// ToolbarExpandableButton의 새 인스턴스를 초기화합니다.
|
||||
/// SubButtons 리스트를 빈 리스트로 생성합니다.
|
||||
@@ -80,6 +116,15 @@ namespace UVC.UI.Toolbar.Model
|
||||
SubButtons = new List<ToolbarButtonBase>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 원본 텍스트를 설정합니다. AddExpandableButton에서 호출됩니다.
|
||||
/// </summary>
|
||||
/// <param name="text">원본 텍스트</param>
|
||||
public void SetOriginalText(string text)
|
||||
{
|
||||
_originalText = text;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 주 확장 버튼이 클릭되었을 때의 로직을 실행합니다.
|
||||
/// 기본적으로 부모 클래스(ToolbarButtonBase)의 ExecuteClick을 호출하여
|
||||
@@ -118,23 +163,40 @@ namespace UVC.UI.Toolbar.Model
|
||||
{
|
||||
if (selectedSubButton != null && selectedSubButton.IsEnabled)
|
||||
{
|
||||
// 주 버튼의 텍스트를 선택된 하위 버튼의 텍스트로 변경
|
||||
// Text 속성의 setter는 내부적으로 OnStateChanged를 호출하여 View 업데이트를 트리거합니다.
|
||||
if (this.Text != selectedSubButton.Text)
|
||||
// 동일한 버튼이 다시 선택된 경우 이벤트를 발생시키지 않음
|
||||
if (_selectedSubButton == selectedSubButton)
|
||||
{
|
||||
this.Text = selectedSubButton.Text;
|
||||
return;
|
||||
}
|
||||
|
||||
// 주 버튼의 아이콘 경로를 선택된 하위 버튼의 아이콘 경로로 변경
|
||||
// IconSpritePath 속성의 setter는 내부적으로 OnStateChanged를 호출합니다.
|
||||
if (this.IconSpritePath != selectedSubButton.IconSpritePath)
|
||||
// 현재 선택된 하위 버튼 업데이트
|
||||
_selectedSubButton = selectedSubButton;
|
||||
|
||||
// UpdateIconOnSelection이 true일 때만 주 버튼의 텍스트와 아이콘을 변경
|
||||
if (UpdateIconOnSelection)
|
||||
{
|
||||
this.IconSpritePath = selectedSubButton.IconSpritePath;
|
||||
// 주 버튼의 텍스트를 선택된 하위 버튼의 텍스트로 변경
|
||||
// Text 속성의 setter는 내부적으로 OnStateChanged를 호출하여 View 업데이트를 트리거합니다.
|
||||
if (Text != selectedSubButton.Text)
|
||||
{
|
||||
Text = selectedSubButton.Text;
|
||||
}
|
||||
|
||||
// 주 버튼의 아이콘 경로를 선택된 하위 버튼의 아이콘 경로로 변경
|
||||
// IconSpritePath 속성의 setter는 내부적으로 OnStateChanged를 호출합니다.
|
||||
if (IconSpritePath != selectedSubButton.IconSpritePath)
|
||||
{
|
||||
IconSpritePath = selectedSubButton.IconSpritePath;
|
||||
}
|
||||
}
|
||||
|
||||
// 하위 버튼 선택 콜백 호출
|
||||
OnSubButtonSelected?.Invoke(selectedSubButton);
|
||||
|
||||
// 하위 버튼 선택 변경 이벤트 발생 (Toolbar/Toolbox에서 OnAction 이벤트 발생용)
|
||||
// _originalText는 AddExpandableButton에서 설정한 원본 텍스트
|
||||
OnSubButtonSelectionChanged?.Invoke(_originalText, selectedSubButton.Text);
|
||||
|
||||
// 선택된 하위 버튼 자체의 ClickCommand 실행은 여기서 하지 않습니다.
|
||||
// View에서 하위 버튼 UI 클릭 시 해당 하위 버튼의 ExecuteClick()이 직접 호출되는 것이 일반적입니다.
|
||||
// 만약 여기서 실행해야 한다면: selectedSubButton.ExecuteClick();
|
||||
@@ -148,6 +210,7 @@ namespace UVC.UI.Toolbar.Model
|
||||
{
|
||||
base.ClearEventHandlers(); // 부모 클래스의 이벤트 정리 (OnStateChanged)
|
||||
OnSubButtonSelected = null;
|
||||
OnSubButtonSelectionChanged = null;
|
||||
|
||||
if (SubButtons != null)
|
||||
{
|
||||
|
||||
@@ -200,10 +200,12 @@ namespace UVC.UI.Toolbar.Model
|
||||
/// <param name="iconSpritePath">주 버튼의 기본 아이콘 경로입니다 (선택 사항).</param>
|
||||
/// <param name="command">주 버튼 클릭 시 실행될 ICommand 객체입니다 (선택 사항, 하위 메뉴 토글과는 별개일 수 있음).</param>
|
||||
/// <param name="tooltip">주 버튼 툴팁의 텍스트 또는 다국어 키입니다 (선택 사항).</param>
|
||||
/// <param name="updateIconOnSelection">서브 버튼 선택 시 주 버튼의 아이콘을 변경할지 여부입니다 (기본값: true).</param>
|
||||
/// <returns>생성되고 추가된 ToolbarExpandableButton 객체입니다.</returns>
|
||||
public ToolbarExpandableButton AddExpandableButton(string text, string iconSpritePath = null, ICommand command = null, string tooltip = null)
|
||||
public ToolbarExpandableButton AddExpandableButton(string text, string iconSpritePath = null, ICommand command = null, string tooltip = null, bool updateIconOnSelection = true)
|
||||
{
|
||||
var button = new ToolbarExpandableButton { Text = text, IconSpritePath = iconSpritePath, ClickCommand = command, Tooltip = tooltip };
|
||||
var button = new ToolbarExpandableButton { Text = text, IconSpritePath = iconSpritePath, ClickCommand = command, Tooltip = tooltip, UpdateIconOnSelection = updateIconOnSelection };
|
||||
button.SetOriginalText(text); // 원본 텍스트 저장 (OnSubButtonSelectionChanged 이벤트에서 사용)
|
||||
AddItem(button);
|
||||
return button;
|
||||
}
|
||||
@@ -216,6 +218,127 @@ namespace UVC.UI.Toolbar.Model
|
||||
AddItem(new ToolbarSeparator());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 이름의 라디오 버튼 그룹을 가져옵니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <returns>해당 이름의 ToolbarRadioButtonGroup 객체입니다. 존재하지 않으면 null을 반환합니다.</returns>
|
||||
public ToolbarRadioButtonGroup GetRadioButtonGroup(string groupName)
|
||||
{
|
||||
if (_radioGroups.TryGetValue(groupName, out var group))
|
||||
{
|
||||
return group;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 그룹 내에서 특정 라디오 버튼을 선택하거나, 모든 선택을 해제합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="buttonToSelect">선택할 라디오 버튼입니다. null을 전달하면 그룹 내 모든 버튼의 선택이 해제됩니다.</param>
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트(OnToggle, OnStateChanged 등)를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 그룹이 존재하지 않으면 false를 반환합니다.</returns>
|
||||
public bool SetRadioButtonSelection(string groupName, ToolbarRadioButton buttonToSelect, bool raiseEvent = true)
|
||||
{
|
||||
if (!_radioGroups.TryGetValue(groupName, out var group))
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"SetRadioButtonSelection: 그룹 '{groupName}'을 찾을 수 없습니다.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buttonToSelect == null)
|
||||
{
|
||||
group.ClearSelection(raiseEvent);
|
||||
}
|
||||
else
|
||||
{
|
||||
group.SetSelected(buttonToSelect, raiseEvent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 이름으로 라디오 버튼 그룹 내 모든 선택을 해제합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트(OnToggle, OnStateChanged 등)를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 그룹이 존재하지 않으면 false를 반환합니다.</returns>
|
||||
public bool ClearRadioButtonSelection(string groupName, bool raiseEvent = true)
|
||||
{
|
||||
return SetRadioButtonSelection(groupName, null, raiseEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 토글 버튼의 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="toggleButton">상태를 변경할 토글 버튼입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트(OnToggle, OnStateChanged 등)를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
public void SetToggleButtonState(ToolbarToggleButton toggleButton, bool isSelected, bool raiseEvent = true)
|
||||
{
|
||||
if (toggleButton == null)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning("SetToggleButtonState: toggleButton이 null입니다.");
|
||||
return;
|
||||
}
|
||||
toggleButton.SetSelected(isSelected, raiseEvent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 라디오 버튼을 찾아 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="buttonText">선택할 라디오 버튼의 텍스트입니다. null 또는 빈 문자열을 전달하면 그룹 내 모든 버튼의 선택이 해제됩니다.</param>
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>찾아서 선택한 라디오 버튼입니다. 그룹이 없거나 버튼을 찾지 못하면 null을 반환합니다.</returns>
|
||||
public ToolbarRadioButton SetRadioButtonSelectionByText(string groupName, string buttonText, bool raiseEvent = true)
|
||||
{
|
||||
if (!_radioGroups.TryGetValue(groupName, out var group))
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"SetRadioButtonSelectionByText: 그룹 '{groupName}'을 찾을 수 없습니다.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(buttonText))
|
||||
{
|
||||
group.ClearSelection(raiseEvent);
|
||||
return null;
|
||||
}
|
||||
|
||||
var button = group.FindButtonByText(buttonText);
|
||||
if (button == null)
|
||||
{
|
||||
UnityEngine.Debug.LogWarning($"SetRadioButtonSelectionByText: 그룹 '{groupName}'에서 텍스트 '{buttonText}'인 버튼을 찾을 수 없습니다.");
|
||||
return null;
|
||||
}
|
||||
|
||||
group.SetSelected(button, raiseEvent);
|
||||
return button;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 토글 버튼을 찾아 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonText">상태를 변경할 토글 버튼의 텍스트입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>찾아서 상태를 변경한 토글 버튼입니다. 찾지 못하면 null을 반환합니다.</returns>
|
||||
public ToolbarToggleButton SetToggleButtonStateByText(string buttonText, bool isSelected, bool raiseEvent = true)
|
||||
{
|
||||
foreach (var item in Items)
|
||||
{
|
||||
if (item is ToolbarToggleButton toggleButton && toggleButton.Text == buttonText)
|
||||
{
|
||||
toggleButton.SetSelected(isSelected, raiseEvent);
|
||||
return toggleButton;
|
||||
}
|
||||
}
|
||||
|
||||
UnityEngine.Debug.LogWarning($"SetToggleButtonStateByText: 텍스트 '{buttonText}'인 토글 버튼을 찾을 수 없습니다.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 만약 모든 라디오 버튼 그룹의 초기 선택 상태를 한 번에 설정하고 싶다면 다음과 같은 메서드를 추가할 수 있습니다.
|
||||
// /// <summary>
|
||||
// /// 모든 라디오 버튼 그룹에 대해 초기 선택 상태를 설정합니다.
|
||||
|
||||
@@ -87,7 +87,8 @@ namespace UVC.UI.Toolbar.Model
|
||||
/// 이전에 선택되었던 다른 버튼은 선택 해제 상태(IsSelected = false)로 변경됩니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonToSelect">선택할 ToolbarRadioButton입니다. 이 버튼은 반드시 그룹에 미리 등록되어 있어야 합니다.</param>
|
||||
public void SetSelected(ToolbarRadioButton buttonToSelect)
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트(OnToggle, OnStateChanged 등)를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
public void SetSelected(ToolbarRadioButton buttonToSelect, bool raiseEvent = true)
|
||||
{
|
||||
if (buttonToSelect == null || !_buttons.Contains(buttonToSelect))
|
||||
{
|
||||
@@ -109,8 +110,22 @@ namespace UVC.UI.Toolbar.Model
|
||||
// 현재 순회 중인 버튼이 선택하려는 버튼(buttonToSelect)과 동일한지 비교하여
|
||||
// IsSelected 상태를 설정합니다.
|
||||
// 이렇게 하면 buttonToSelect만 true가 되고 나머지는 false가 됩니다.
|
||||
// IsSelected 속성의 setter는 필요한 이벤트(OnToggle, OnStateChanged 등)를 발생시킵니다.
|
||||
buttonInGroup.IsSelected = (buttonInGroup == buttonToSelect);
|
||||
bool shouldBeSelected = (buttonInGroup == buttonToSelect);
|
||||
buttonInGroup.SetSelected(shouldBeSelected, raiseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 내 모든 라디오 버튼의 선택을 해제합니다.
|
||||
/// 이 메서드를 호출하면 그룹 내 어떤 버튼도 선택되지 않은 상태가 됩니다.
|
||||
/// </summary>
|
||||
/// <param name="raiseEvent">true이면 상태 변경 이벤트(OnToggle, OnStateChanged 등)를 발생시키고, false이면 이벤트 없이 상태만 변경합니다. 기본값은 true입니다.</param>
|
||||
public void ClearSelection(bool raiseEvent = true)
|
||||
{
|
||||
SelectedButton = null;
|
||||
foreach (var buttonInGroup in _buttons)
|
||||
{
|
||||
buttonInGroup.SetSelected(false, raiseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +138,16 @@ namespace UVC.UI.Toolbar.Model
|
||||
return _buttons.AsReadOnly();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 그룹 내 라디오 버튼을 찾습니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonText">찾을 버튼의 텍스트입니다.</param>
|
||||
/// <returns>해당 텍스트를 가진 라디오 버튼입니다. 찾지 못하면 null을 반환합니다.</returns>
|
||||
public ToolbarRadioButton FindButtonByText(string buttonText)
|
||||
{
|
||||
return _buttons.FirstOrDefault(b => b.Text == buttonText);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 내 버튼들의 초기 선택 상태를 설정합니다.
|
||||
/// 주로 ToolbarModel에서 라디오 버튼들을 추가한 후 호출될 수 있습니다.
|
||||
@@ -142,9 +167,8 @@ namespace UVC.UI.Toolbar.Model
|
||||
}
|
||||
else
|
||||
{
|
||||
// IsSelected가 true인 버튼이 하나도 없다면, 그룹의 첫 번째 버튼을 기본으로 선택합니다.
|
||||
// (라디오 그룹은 일반적으로 항상 하나가 선택되어 있는 상태를 유지하려 함)
|
||||
SetSelected(_buttons[0]);
|
||||
// IsSelected가 true인 버튼이 하나도 없다면
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,27 @@ namespace UVC.UI.Toolbar.Model
|
||||
/// </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 상태를 반전시키고,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#nullable enable
|
||||
using UnityEngine;
|
||||
using UVC.UI.List.ComponentList;
|
||||
using UVC.Factory.Playback;
|
||||
@@ -8,14 +9,84 @@ using UVC.UI.Toolbar.View;
|
||||
using UVC.UI.Window;
|
||||
using UVC.Factory.Component;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace UVC.UI.Toolbar
|
||||
{
|
||||
/// <summary>
|
||||
/// 툴바 액션 타입을 나타내는 열거형입니다.
|
||||
/// </summary>
|
||||
public enum ToolbarActionType
|
||||
{
|
||||
/// <summary>
|
||||
/// 일반 버튼 클릭
|
||||
/// </summary>
|
||||
Standard,
|
||||
/// <summary>
|
||||
/// 라디오 버튼 선택 변경
|
||||
/// </summary>
|
||||
Radio,
|
||||
/// <summary>
|
||||
/// 토글 버튼 상태 변경
|
||||
/// </summary>
|
||||
Toggle,
|
||||
/// <summary>
|
||||
/// 확장 버튼의 하위 버튼 선택 변경
|
||||
/// </summary>
|
||||
Expandable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 툴바 액션 정보를 담는 클래스입니다.
|
||||
/// </summary>
|
||||
public class ToolbarActionEventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 액션을 발생시킨 툴바 아이템의 텍스트입니다.
|
||||
/// </summary>
|
||||
public string Text { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 액션에 따른 값입니다.
|
||||
/// Standard: null
|
||||
/// Radio: 선택된 항목의 텍스트 (전부 해제 시 null)
|
||||
/// Toggle: true/false
|
||||
/// Expandable: 선택된 하위 버튼의 텍스트
|
||||
/// </summary>
|
||||
public object? Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 액션 타입입니다.
|
||||
/// </summary>
|
||||
public ToolbarActionType ActionType { get; set; }
|
||||
}
|
||||
|
||||
public class Toolbar : MonoBehaviour
|
||||
{
|
||||
protected ToolbarModel model;
|
||||
protected ToolbarView view;
|
||||
|
||||
/// <summary>
|
||||
/// 툴바의 버튼이 클릭되거나 상태가 변경될 때 발생하는 이벤트입니다.
|
||||
/// raiseEvent가 true일 때만 호출됩니다.
|
||||
/// </summary>
|
||||
public event Action<ToolbarActionEventArgs>? OnAction;
|
||||
|
||||
/// <summary>
|
||||
/// OnAction 이벤트를 발생시킵니다.
|
||||
/// </summary>
|
||||
/// <param name="text">액션을 발생시킨 툴바 아이템의 텍스트</param>
|
||||
/// <param name="actionType">액션 타입</param>
|
||||
/// <param name="value">액션에 따른 값 (Standard: null, Radio: 선택된 항목 텍스트 또는 null, Toggle: bool, Expandable: 선택된 하위 버튼 텍스트)</param>
|
||||
protected void RaiseOnAction(string text, ToolbarActionType actionType, object? value = null)
|
||||
{
|
||||
OnAction?.Invoke(new ToolbarActionEventArgs
|
||||
{
|
||||
Text = text,
|
||||
ActionType = actionType,
|
||||
Value = value
|
||||
});
|
||||
}
|
||||
|
||||
protected void Awake()
|
||||
{
|
||||
@@ -62,10 +133,61 @@ namespace UVC.UI.Toolbar
|
||||
return;
|
||||
}
|
||||
|
||||
// 모든 버튼 타입의 이벤트 구독
|
||||
SubscribeButtonEvents();
|
||||
|
||||
// ToolbarView 초기화 및 렌더링
|
||||
view.Initialize(model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모델 내의 모든 버튼에 대해 이벤트를 구독합니다.
|
||||
/// </summary>
|
||||
private void SubscribeButtonEvents()
|
||||
{
|
||||
if (model?.Items == null) return;
|
||||
|
||||
foreach (var item in model.Items)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case ToolbarRadioButton radioButton:
|
||||
// 라디오 버튼의 선택 상태 변경 이벤트 구독
|
||||
radioButton.OnToggleStateChanged += (isSelected) =>
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
RaiseOnAction(radioButton.GroupName, ToolbarActionType.Radio, radioButton.Text);
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
case ToolbarToggleButton toggleButton:
|
||||
// 토글 버튼의 상태 변경 이벤트 구독
|
||||
toggleButton.OnToggleStateChanged += (isSelected) =>
|
||||
{
|
||||
RaiseOnAction(toggleButton.Text, ToolbarActionType.Toggle, isSelected);
|
||||
};
|
||||
break;
|
||||
|
||||
case ToolbarExpandableButton expandableButton:
|
||||
// 확장 버튼의 하위 버튼 선택 변경 이벤트 구독
|
||||
expandableButton.OnSubButtonSelectionChanged += (expandableText, selectedSubButtonText) =>
|
||||
{
|
||||
RaiseOnAction(expandableText, ToolbarActionType.Expandable, selectedSubButtonText);
|
||||
};
|
||||
break;
|
||||
|
||||
case ToolbarStandardButton standardButton:
|
||||
// 표준 버튼의 클릭 이벤트 구독
|
||||
standardButton.OnClicked += () =>
|
||||
{
|
||||
RaiseOnAction(standardButton.Text, ToolbarActionType.Standard, null);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ToolbarModel generateModel()
|
||||
{
|
||||
@@ -175,6 +297,157 @@ namespace UVC.UI.Toolbar
|
||||
return toolbarModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 그룹 내에서 특정 라디오 버튼을 선택하거나, 모든 선택을 해제합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="buttonToSelect">선택할 라디오 버튼입니다. null을 전달하면 그룹 내 모든 버튼의 선택이 해제됩니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 그룹이 존재하지 않으면 false를 반환합니다.</returns>
|
||||
public bool SetRadioButtonSelection(string groupName, ToolbarRadioButton buttonToSelect, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbar: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
bool result = model.SetRadioButtonSelection(groupName, buttonToSelect, raiseEvent);
|
||||
if (result)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateRadioGroupIconColors(groupName, buttonToSelect);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(groupName, ToolbarActionType.Radio, buttonToSelect?.Text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 이름으로 라디오 버튼 그룹 내 모든 선택을 해제합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 그룹이 존재하지 않으면 false를 반환합니다.</returns>
|
||||
public bool ClearRadioButtonSelection(string groupName, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbar: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
bool result = model.ClearRadioButtonSelection(groupName, raiseEvent);
|
||||
if (result)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트 (모두 비선택)
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateRadioGroupIconColors(groupName, null);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(groupName, ToolbarActionType.Radio, null);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 토글 버튼의 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="toggleButton">상태를 변경할 토글 버튼입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
public void SetToggleButtonState(ToolbarToggleButton toggleButton, bool isSelected, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbar: ToolbarModel이 설정되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
model.SetToggleButtonState(toggleButton, isSelected, raiseEvent);
|
||||
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateIconColorState(toggleButton, isSelected);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(toggleButton.Text, ToolbarActionType.Toggle, isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 라디오 버튼을 찾아 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="buttonText">선택할 라디오 버튼의 텍스트입니다. null 또는 빈 문자열을 전달하면 그룹 내 모든 버튼의 선택이 해제됩니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 버튼을 찾지 못하면 false를 반환합니다.</returns>
|
||||
public bool SetRadioButtonSelection(string groupName, string buttonText, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbar: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
var button = model.SetRadioButtonSelectionByText(groupName, buttonText, raiseEvent);
|
||||
bool result = button != null || string.IsNullOrEmpty(buttonText);
|
||||
if (result)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateRadioGroupIconColors(groupName, button);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(groupName, ToolbarActionType.Radio, button?.Text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 토글 버튼을 찾아 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonText">상태를 변경할 토글 버튼의 텍스트입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 버튼을 찾지 못하면 false를 반환합니다.</returns>
|
||||
public bool SetToggleButtonState(string buttonText, bool isSelected, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbar: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
var button = model.SetToggleButtonStateByText(buttonText, isSelected, raiseEvent);
|
||||
if (button != null)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateIconColorState(button, isSelected);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(buttonText, ToolbarActionType.Toggle, isSelected);
|
||||
}
|
||||
}
|
||||
return button != null;
|
||||
}
|
||||
|
||||
protected void OnDestroy()
|
||||
{
|
||||
model = null;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#nullable enable
|
||||
using UnityEngine;
|
||||
using UVC.Factory.Playback;
|
||||
using UVC.Locale;
|
||||
@@ -48,6 +49,28 @@ namespace UVC.UI.ToolBar
|
||||
/// </summary>
|
||||
protected ToolbarView view;
|
||||
|
||||
/// <summary>
|
||||
/// 툴박스의 버튼이 클릭되거나 상태가 변경될 때 발생하는 이벤트입니다.
|
||||
/// raiseEvent가 true일 때만 호출됩니다.
|
||||
/// </summary>
|
||||
public event System.Action<ToolbarActionEventArgs> OnAction;
|
||||
|
||||
/// <summary>
|
||||
/// OnAction 이벤트를 발생시킵니다.
|
||||
/// </summary>
|
||||
/// <param name="text">액션을 발생시킨 툴바 아이템의 텍스트</param>
|
||||
/// <param name="actionType">액션 타입</param>
|
||||
/// <param name="value">액션에 따른 값 (Standard: null, Radio: 선택된 항목 텍스트 또는 null, Toggle: bool, Expandable: 선택된 하위 버튼 텍스트)</param>
|
||||
protected void RaiseOnAction(string text, ToolbarActionType actionType, object value = null)
|
||||
{
|
||||
OnAction?.Invoke(new ToolbarActionEventArgs
|
||||
{
|
||||
Text = text,
|
||||
ActionType = actionType,
|
||||
Value = value
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MonoBehaviour의 Awake 메서드입니다.
|
||||
/// 주로 현재 GameObject 또는 자식 GameObject에서 ToolbarView 컴포넌트를 찾아 mainToolbarView 필드에 할당합니다.
|
||||
@@ -101,10 +124,62 @@ namespace UVC.UI.ToolBar
|
||||
return;
|
||||
}
|
||||
|
||||
// 모든 버튼 타입의 이벤트 구독
|
||||
SubscribeButtonEvents();
|
||||
|
||||
// ToolbarView 초기화 및 렌더링
|
||||
view.Initialize(model);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모델 내의 모든 버튼에 대해 이벤트를 구독합니다.
|
||||
/// </summary>
|
||||
private void SubscribeButtonEvents()
|
||||
{
|
||||
if (model?.Items == null) return;
|
||||
|
||||
foreach (var item in model.Items)
|
||||
{
|
||||
switch (item)
|
||||
{
|
||||
case ToolbarRadioButton radioButton:
|
||||
// 라디오 버튼의 선택 상태 변경 이벤트 구독
|
||||
radioButton.OnToggleStateChanged += (isSelected) =>
|
||||
{
|
||||
if (isSelected)
|
||||
{
|
||||
RaiseOnAction(radioButton.GroupName, ToolbarActionType.Radio, radioButton.Text);
|
||||
}
|
||||
};
|
||||
break;
|
||||
|
||||
case ToolbarToggleButton toggleButton:
|
||||
// 토글 버튼의 상태 변경 이벤트 구독
|
||||
toggleButton.OnToggleStateChanged += (isSelected) =>
|
||||
{
|
||||
RaiseOnAction(toggleButton.Text, ToolbarActionType.Toggle, isSelected);
|
||||
};
|
||||
break;
|
||||
|
||||
case ToolbarExpandableButton expandableButton:
|
||||
// 확장 버튼의 하위 버튼 선택 변경 이벤트 구독
|
||||
expandableButton.OnSubButtonSelectionChanged += (expandableText, selectedSubButtonText) =>
|
||||
{
|
||||
RaiseOnAction(expandableText, ToolbarActionType.Expandable, selectedSubButtonText);
|
||||
};
|
||||
break;
|
||||
|
||||
case ToolbarStandardButton standardButton:
|
||||
// 표준 버튼의 클릭 이벤트 구독
|
||||
standardButton.OnClicked += () =>
|
||||
{
|
||||
RaiseOnAction(standardButton.Text, ToolbarActionType.Standard, null);
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MonoBehaviour의 Start 메서드입니다. 첫 번째 프레임 업데이트 전에 호출됩니다.
|
||||
/// ToolbarModel을 생성하고, 다양한 툴바 항목들을 모델에 추가한 후,
|
||||
@@ -220,6 +295,157 @@ namespace UVC.UI.ToolBar
|
||||
return toolbarModel;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 그룹 내에서 특정 라디오 버튼을 선택하거나, 모든 선택을 해제합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="buttonToSelect">선택할 라디오 버튼입니다. null을 전달하면 그룹 내 모든 버튼의 선택이 해제됩니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 그룹이 존재하지 않으면 false를 반환합니다.</returns>
|
||||
public bool SetRadioButtonSelection(string groupName, ToolbarRadioButton buttonToSelect, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbox: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
bool result = model.SetRadioButtonSelection(groupName, buttonToSelect, raiseEvent);
|
||||
if (result)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateRadioGroupIconColors(groupName, buttonToSelect);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(groupName, ToolbarActionType.Radio, buttonToSelect?.Text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 그룹 이름으로 라디오 버튼 그룹 내 모든 선택을 해제합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 그룹이 존재하지 않으면 false를 반환합니다.</returns>
|
||||
public bool ClearRadioButtonSelection(string groupName, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbox: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
bool result = model.ClearRadioButtonSelection(groupName, raiseEvent);
|
||||
if (result)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트 (모두 비선택)
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateRadioGroupIconColors(groupName, null);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(groupName, ToolbarActionType.Radio, null);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 지정된 토글 버튼의 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="toggleButton">상태를 변경할 토글 버튼입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
public void SetToggleButtonState(ToolbarToggleButton toggleButton, bool isSelected, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbox: ToolbarModel이 설정되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
model.SetToggleButtonState(toggleButton, isSelected, raiseEvent);
|
||||
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateIconColorState(toggleButton, isSelected);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(toggleButton.Text, ToolbarActionType.Toggle, isSelected);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 라디오 버튼을 찾아 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹의 이름입니다.</param>
|
||||
/// <param name="buttonText">선택할 라디오 버튼의 텍스트입니다. null 또는 빈 문자열을 전달하면 그룹 내 모든 버튼의 선택이 해제됩니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 버튼을 찾지 못하면 false를 반환합니다.</returns>
|
||||
public bool SetRadioButtonSelection(string groupName, string buttonText, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbox: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
var button = model.SetRadioButtonSelectionByText(groupName, buttonText, raiseEvent);
|
||||
bool result = button != null || string.IsNullOrEmpty(buttonText);
|
||||
if (result)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateRadioGroupIconColors(groupName, button);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(groupName, ToolbarActionType.Radio, button?.Text);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 텍스트로 토글 버튼을 찾아 선택 상태를 설정합니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonText">상태를 변경할 토글 버튼의 텍스트입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
/// <param name="raiseEvent">true이면 OnAction 이벤트를 발생시키고, false이면 UI만 업데이트합니다. 기본값은 true입니다.</param>
|
||||
/// <returns>작업 성공 여부입니다. 모델이 없거나 버튼을 찾지 못하면 false를 반환합니다.</returns>
|
||||
public bool SetToggleButtonState(string buttonText, bool isSelected, bool raiseEvent = false)
|
||||
{
|
||||
if (model == null)
|
||||
{
|
||||
Debug.LogError("Toolbox: ToolbarModel이 설정되지 않았습니다.");
|
||||
return false;
|
||||
}
|
||||
var button = model.SetToggleButtonStateByText(buttonText, isSelected, raiseEvent);
|
||||
if (button != null)
|
||||
{
|
||||
// Icon의 ImageColorChangeBehaviour 색상 상태 업데이트
|
||||
if (view != null)
|
||||
{
|
||||
view.UpdateIconColorState(button, isSelected);
|
||||
}
|
||||
|
||||
if (raiseEvent)
|
||||
{
|
||||
RaiseOnAction(buttonText, ToolbarActionType.Toggle, isSelected);
|
||||
}
|
||||
}
|
||||
return button != null;
|
||||
}
|
||||
|
||||
protected void OnDestroy()
|
||||
{
|
||||
model = null;
|
||||
|
||||
@@ -103,7 +103,7 @@ namespace UVC.UI.Toolbar.View
|
||||
|
||||
// ToggleGroup 컴포넌트를 추가합니다.
|
||||
group = groupObj.AddComponent<ToggleGroup>();
|
||||
group.allowSwitchOff = false; // 라디오 버튼 그룹은 일반적으로 항상 하나가 선택된 상태를 유지해야 하므로, 선택 해제를 허용하지 않습니다.
|
||||
group.allowSwitchOff = true; // 모든 버튼이 선택 해제된 상태를 허용합니다. false로 설정하면 Unity가 첫 번째 Toggle을 자동으로 선택합니다.
|
||||
|
||||
// LayoutElement를 추가하고 ignoreLayout을 true로 설정하여 부모의 LayoutGroup 계산에서 이 GameObject를 무시하도록 합니다.
|
||||
LayoutElement element = groupObj.AddComponent<LayoutElement>();
|
||||
|
||||
@@ -7,6 +7,7 @@ using UVC.Extension;
|
||||
using UVC.Locale;
|
||||
using UVC.UI.Toolbar.Model;
|
||||
using UVC.UI.Tooltip;
|
||||
using UVC.UI.Util;
|
||||
using UVC.Util;
|
||||
|
||||
namespace UVC.UI.Toolbar.View
|
||||
@@ -463,5 +464,44 @@ namespace UVC.UI.Toolbar.View
|
||||
TooltipManager.Instance.HideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 버튼 모델에 해당하는 UI GameObject의 Icon 자식에 있는 ImageColorChangeBehaviour의 선택 상태를 업데이트합니다.
|
||||
/// </summary>
|
||||
/// <param name="buttonModel">상태를 업데이트할 버튼 모델입니다.</param>
|
||||
/// <param name="isSelected">설정할 선택 상태입니다.</param>
|
||||
public void UpdateIconColorState(ToolbarButtonBase buttonModel, bool isSelected)
|
||||
{
|
||||
if (buttonModel == null) return;
|
||||
|
||||
if (_modelToGameObjectMap.TryGetValue(buttonModel, out GameObject buttonObj) && buttonObj != null)
|
||||
{
|
||||
ImageColorChangeBehaviour colorBehaviour = buttonObj.GetComponentInChildren<ImageColorChangeBehaviour>();
|
||||
if (colorBehaviour != null)
|
||||
{
|
||||
colorBehaviour.SetSelected(isSelected);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 라디오 버튼 그룹 내 모든 버튼의 Icon 색상 상태를 업데이트합니다.
|
||||
/// </summary>
|
||||
/// <param name="groupName">라디오 버튼 그룹 이름입니다.</param>
|
||||
/// <param name="selectedButton">선택된 버튼입니다. null이면 모든 버튼이 비선택 상태가 됩니다.</param>
|
||||
public void UpdateRadioGroupIconColors(string groupName, ToolbarRadioButton? selectedButton)
|
||||
{
|
||||
if (ToolbarModel == null) return;
|
||||
|
||||
var group = ToolbarModel.GetRadioButtonGroup(groupName);
|
||||
if (group == null) return;
|
||||
|
||||
foreach (var button in group.GetButtons())
|
||||
{
|
||||
bool isSelected = (selectedButton != null && button == selectedButton);
|
||||
UpdateIconColorState(button, isSelected);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user