116 lines
7.4 KiB
C#
116 lines
7.4 KiB
C#
|
|
using UnityEngine;
|
||
|
|
using UnityEngine.UI;
|
||
|
|
using UVC.UI.Toolbar.Model;
|
||
|
|
|
||
|
|
namespace UVC.UI.Toolbar.View
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// 확장 가능한 툴바 버튼(ToolbarExpandableButton)의 UI 생성, 이벤트 연결, 시각적 업데이트를 처리하는 클래스입니다.
|
||
|
|
/// IButtonViewProcessor 인터페이스를 구현하여 ToolbarView가 확장 버튼을 일관된 방식으로 다룰 수 있도록 합니다.
|
||
|
|
/// 확장 버튼은 클릭 시 하위 메뉴(SubButtons)를 표시하거나 숨기는 기능을 가집니다.
|
||
|
|
/// </summary>
|
||
|
|
/// <remarks>
|
||
|
|
/// 이 클래스의 주요 역할:
|
||
|
|
/// 1. UI 생성: ToolbarView에 설정된 '확장 버튼 프리팹'을 사용하여 주 버튼의 GameObject를 만듭니다.
|
||
|
|
/// 2. 상호작용 설정: 생성된 주 버튼 UI(UnityEngine.UI.Button)가 클릭되었을 때,
|
||
|
|
/// - 연결된 ToolbarExpandableButton 모델의 ExecuteClick 메서드가 호출되도록 설정합니다.
|
||
|
|
/// - ToolbarView의 ToggleSubMenu 메서드를 호출하여 하위 메뉴의 표시/숨김을 처리하도록 합니다.
|
||
|
|
/// 3. 시각적 업데이트: 주 버튼 모델의 상태(텍스트, 아이콘, 활성화 상태 등)가 변경되면,
|
||
|
|
/// 화면에 보이는 주 버튼의 모습도 그에 맞게 업데이트합니다. 하위 메뉴 자체의 렌더링은 ToolbarView가 담당합니다.
|
||
|
|
/// </remarks>
|
||
|
|
/// <example>
|
||
|
|
/// <code>
|
||
|
|
/// // ToolbarView 내에서 이 프로세서가 사용되는 방식 (간략화된 예시):
|
||
|
|
/// // 1. ToolbarModel로부터 ToolbarExpandableButton 객체를 가져옵니다.
|
||
|
|
/// // ToolbarExpandableButton expandableModel = new ToolbarExpandableButton { Text = "Brush", ... };
|
||
|
|
/// // expandableModel.SubButtons.AddChild(new ToolbarStandardButton { Text = "Small Brush", ... });
|
||
|
|
///
|
||
|
|
/// // 2. ToolbarView는 해당 모델 타입에 맞는 Processor를 찾습니다.
|
||
|
|
/// // IButtonViewProcessor processor = GetButtonViewProcessor(typeof(ToolbarExpandableButton));
|
||
|
|
///
|
||
|
|
/// // 3. UI 생성 요청 (주 버튼만 생성)
|
||
|
|
/// // GameObject buttonUI = processor.CreateButtonUI(expandableModel, toolbarContainer, this);
|
||
|
|
///
|
||
|
|
/// // 4. 상호작용 및 초기 시각적 요소 설정 요청
|
||
|
|
/// // processor.SetupButtonInteractions(expandableModel, buttonUI, this);
|
||
|
|
/// // 이 과정에서 주 버튼 클릭 시 expandableModel.ExecuteClick()과 viewContext.ToggleSubMenu()가 연결됩니다.
|
||
|
|
///
|
||
|
|
/// // 5. 주 버튼 모델의 상태가 변경되면(예: 하위 버튼 선택으로 아이콘 변경 시),
|
||
|
|
/// // OnStateChanged 이벤트가 발생하고, ToolbarView는 processor.UpdateCommonButtonVisuals()를 호출합니다.
|
||
|
|
/// </code>
|
||
|
|
/// </example>
|
||
|
|
public class ToolbarExpandableButtonViewProcessor : IButtonViewProcessor
|
||
|
|
{
|
||
|
|
/// <summary>
|
||
|
|
/// ToolbarExpandableButton 모델에 해당하는 주 버튼 UI GameObject를 생성합니다.
|
||
|
|
/// ToolbarView에 있는 expandableButtonPrefab을 복제하여 사용합니다.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="buttonModel">UI를 생성할 기반이 되는 버튼 데이터 모델 (ToolbarExpandableButton으로 간주됨).</param>
|
||
|
|
/// <param name="parentContainer">생성된 버튼 UI가 자식으로 추가될 부모 Transform 객체입니다.</param>
|
||
|
|
/// <param name="viewContext">현재 ToolbarView의 인스턴스. 프리팹 참조 및 하위 메뉴 토글 기능에 접근할 때 사용됩니다.</param>
|
||
|
|
/// <returns>성공적으로 생성된 주 버튼의 GameObject. 프리팹이 없으면 null을 반환합니다.</returns>
|
||
|
|
public GameObject CreateButtonUI(ToolbarButtonBase buttonModel, Transform parentContainer, ToolbarView viewContext)
|
||
|
|
{
|
||
|
|
if (viewContext.expandableButtonPrefab == null)
|
||
|
|
{
|
||
|
|
Debug.LogError("ExpandableButtonViewProcessor: expandableButtonPrefab이 ToolbarView에 할당되지 않았습니다.", viewContext);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return Object.Instantiate(viewContext.expandableButtonPrefab, parentContainer);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 생성된 확장 버튼(주 버튼) UI GameObject에 필요한 상호작용을 설정하고 초기 시각적 상태를 업데이트합니다.
|
||
|
|
/// - 주 버튼 UI 클릭 시 모델의 ExecuteClick 메서드 호출 및 ToolbarView의 ToggleSubMenu 메서드 호출 설정.
|
||
|
|
/// - 모델의 초기 텍스트, 아이콘, 활성화 상태를 주 버튼 UI에 반영.
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="buttonModel">설정 대상 버튼의 데이터 모델 (ToolbarExpandableButton으로 캐스팅하여 사용).</param>
|
||
|
|
/// <param name="buttonUIObject">화면에 표시된, 설정할 주 버튼의 UI GameObject.</param>
|
||
|
|
/// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
|
||
|
|
public void SetupButtonInteractions(ToolbarButtonBase buttonModel, GameObject buttonUIObject, ToolbarView viewContext)
|
||
|
|
{
|
||
|
|
ToolbarExpandableButton expandableModel = buttonModel as ToolbarExpandableButton;
|
||
|
|
if (expandableModel == null) return;
|
||
|
|
|
||
|
|
Button uiButton = buttonUIObject.GetComponent<Button>();
|
||
|
|
if (uiButton != null)
|
||
|
|
{
|
||
|
|
// 주 버튼 클릭 시 두 가지 동작을 수행합니다:
|
||
|
|
// 1. 모델 자체의 클릭 로직 실행 (선택적)
|
||
|
|
// 2. ToolbarView를 통해 하위 메뉴를 열거나 닫음
|
||
|
|
uiButton.onClick.AddListener(() =>
|
||
|
|
{
|
||
|
|
expandableModel.ExecuteClick(); // 모델의 기본 클릭 액션 실행
|
||
|
|
viewContext.ToggleSubMenu(expandableModel, buttonUIObject); // 하위 메뉴 표시/숨김 처리
|
||
|
|
});
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
Debug.LogError($"ExpandableButtonViewProcessor: ExpandableButton '{expandableModel.Text}'의 GameObject에 Button 컴포넌트가 없습니다.", buttonUIObject);
|
||
|
|
}
|
||
|
|
UpdateCommonButtonVisuals(buttonModel, buttonUIObject, viewContext);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 주 버튼 모델의 공통적인 시각적 속성(텍스트, 아이콘, 활성화 상태)이 변경되었을 때 UI를 업데이트합니다.
|
||
|
|
/// </summary>
|
||
|
|
public void UpdateCommonButtonVisuals(ToolbarButtonBase buttonModel, GameObject buttonUIObject, ToolbarView viewContext)
|
||
|
|
{
|
||
|
|
viewContext.InternalUpdateCommonButtonVisuals(buttonModel, buttonUIObject);
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 확장 버튼은 전통적인 의미의 '토글 선택 상태'를 가지지 않습니다.
|
||
|
|
/// 하위 메뉴의 표시 여부는 별도의 메커니즘(ToolbarView의 currentSubMenu)으로 관리되므로,
|
||
|
|
/// 이 메서드는 아무 작업도 수행하지 않습니다.
|
||
|
|
/// IButtonViewProcessor 인터페이스를 구현하기 위해 필요합니다.
|
||
|
|
/// </summary>
|
||
|
|
public void UpdateToggleStateVisuals(ToolbarToggleButton toggleButtonModel, GameObject buttonUIObject, bool isSelected, ToolbarView viewContext)
|
||
|
|
{
|
||
|
|
// 확장 버튼의 주 버튼 자체는 켜고 끄는 토글 상태를 직접적으로 가지지 않습니다.
|
||
|
|
// (예: IsSelected 같은 속성으로 UI가 바뀌지 않음)
|
||
|
|
// 하위 메뉴가 열려있는지 여부는 ToolbarView에서 관리합니다.
|
||
|
|
// 따라서 이 메서드는 비워둡니다.
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|