Files
XRLib/Assets/Sample/UIToolkit/UTKStyleGuideSample.Menu.cs
2026-02-19 18:40:37 +09:00

345 lines
14 KiB
C#

#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit;
using UVC.UI.Commands;
/// <summary>
/// UTKStyleGuideSample의 Menu 카테고리 Initialize 메서드들
/// </summary>
public partial class UTKStyleGuideSample
{
#region Menu Fields
private UTKTopMenu? _sampleMenuHorizontal;
private UTKTopMenuModel? _sampleModelHorizontal;
private UTKTopMenu? _sampleMenuIcon;
private UTKTopMenuModel? _sampleModelIcon;
private UTKTopMenu? _sampleMenuVertical;
private UTKTopMenuModel? _sampleModelVertical;
#endregion
#region Menu Initializers
private void InitializeTopMenuSample(VisualElement root)
{
InitializeHorizontalMenu(root);
InitializeIconMenu(root);
InitializeVerticalMenu(root);
InitializeApiTest(root);
SetCodeSamples(root,
csharpCode: @"// === 기본 가로 메뉴 ===
var menuView = new UTKTopMenu();
var menuModel = new UTKTopMenuModel();
// 메뉴 아이템 추가
var fileMenu = new UTKMenuItemData(""file"", ""파일"");
fileMenu.AddSubMenuItem(new UTKMenuItemData(
""file_new"", ""새 파일"",
new DebugLogCommand(""새 파일 생성""),
shortcut: ""Ctrl+N""
));
fileMenu.AddSubMenuItem(UTKMenuItemData.CreateSeparator());
fileMenu.AddSubMenuItem(new UTKMenuItemData(
""file_save"", ""저장"",
new DebugLogCommand(""저장""),
shortcut: ""Ctrl+S""
));
menuModel.AddMenuItem(fileMenu);
// View에 메뉴 생성
menuView.CreateMenuItems(
menuModel.MenuItems, menuView.MenuContainer);
// 클릭 이벤트
menuView.OnMenuItemClicked += (data) =>
Debug.Log($""클릭: {data.ItemId}"");
// === 세로 메뉴 ===
var vertMenu = new UTKTopMenu();
vertMenu.Orientation = UTKMenuOrientation.Vertical;
vertMenu.ItemSpacing = 4f;
// === 아이콘 메뉴 ===
var iconMenu = new UTKMenuImageItemData(
""settings"",
UTKMaterialIcons.Settings,
useMaterialIcon: true,
imageSize: 24f
);
// === API ===
// ItemId로 Command 실행
bool ok = menuView.ExecuteCommand(""file_new"");
// ItemId로 데이터 조회
if (menuView.TryGetMenuItemData(""file_save"", out var d))
Debug.Log($""Enabled: {d?.IsEnabled}"");",
uxmlCode: @"<!-- 네임스페이스 선언 -->
<ui:UXML xmlns:utk=""UVC.UIToolkit"">
<!-- 기본 가로 메뉴 (C#에서 동적 생성) -->
<utk:UTKTopMenu />
<!-- UXML 어트리뷰트로 설정 -->
<utk:UTKTopMenu
orientation=""Vertical""
item-spacing=""4"" />
</ui:UXML>");
}
/// <summary>
/// 가로 메뉴 초기화
/// </summary>
private void InitializeHorizontalMenu(VisualElement root)
{
var container = root.Q<VisualElement>("horizontal-menu-container");
if (container == null) return;
_sampleMenuHorizontal = new UTKTopMenu();
_sampleModelHorizontal = new UTKTopMenuModel();
// 파일 메뉴
var fileMenu = new UTKMenuItemData("s_file", "파일");
fileMenu.AddSubMenuItem(new UTKMenuItemData("s_file_new", "새 파일", new DebugLogCommand("새 파일 생성"), shortcut: "Ctrl+N"));
fileMenu.AddSubMenuItem(new UTKMenuItemData("s_file_open", "열기", new DebugLogCommand("파일 열기"), shortcut: "Ctrl+O"));
fileMenu.AddSubMenuItem(UTKMenuItemData.CreateSeparator());
fileMenu.AddSubMenuItem(new UTKMenuItemData("s_file_save", "저장", new DebugLogCommand("파일 저장"), shortcut: "Ctrl+S"));
fileMenu.AddSubMenuItem(new UTKMenuItemData("s_file_exit", "종료", new DebugLogCommand("종료"), shortcut: "Alt+F4"));
_sampleModelHorizontal.AddMenuItem(fileMenu);
// 편집 메뉴
var editMenu = new UTKMenuItemData("s_edit", "편집");
editMenu.AddSubMenuItem(new UTKMenuItemData("s_edit_undo", "실행 취소", new DebugLogCommand("실행 취소"), shortcut: "Ctrl+Z"));
editMenu.AddSubMenuItem(new UTKMenuItemData("s_edit_redo", "다시 실행", new DebugLogCommand("다시 실행"), shortcut: "Ctrl+Y"));
editMenu.AddSubMenuItem(UTKMenuItemData.CreateSeparator());
editMenu.AddSubMenuItem(new UTKMenuItemData("s_edit_copy", "복사", new DebugLogCommand("복사"), shortcut: "Ctrl+C"));
editMenu.AddSubMenuItem(new UTKMenuItemData("s_edit_paste", "붙여넣기", new DebugLogCommand("붙여넣기"), shortcut: "Ctrl+V"));
_sampleModelHorizontal.AddMenuItem(editMenu);
// 보기 메뉴 (2 depth)
var viewMenu = new UTKMenuItemData("s_view", "보기");
var layoutMenu = new UTKMenuItemData("s_view_layout", "레이아웃");
layoutMenu.AddSubMenuItem(new UTKMenuItemData("s_view_layout_default", "기본", new DebugLogCommand("기본 레이아웃")));
layoutMenu.AddSubMenuItem(new UTKMenuItemData("s_view_layout_wide", "와이드", new DebugLogCommand("와이드 레이아웃")));
viewMenu.AddSubMenuItem(layoutMenu);
viewMenu.AddSubMenuItem(new UTKMenuItemData("s_view_fullscreen", "전체 화면", new DebugLogCommand("전체 화면"), shortcut: "F11"));
_sampleModelHorizontal.AddMenuItem(viewMenu);
// 도움말 메뉴
var helpMenu = new UTKMenuItemData("s_help", "도움말");
helpMenu.AddSubMenuItem(new UTKMenuItemData("s_help_doc", "문서", new DebugLogCommand("문서 열기"), shortcut: "F1"));
helpMenu.AddSubMenuItem(new UTKMenuItemData("s_help_about", "정보", new DebugLogCommand("정보")));
_sampleModelHorizontal.AddMenuItem(helpMenu);
// View에 메뉴 생성
if (_sampleMenuHorizontal.MenuContainer != null)
{
_sampleMenuHorizontal.CreateMenuItems(_sampleModelHorizontal.MenuItems, _sampleMenuHorizontal.MenuContainer);
}
_sampleMenuHorizontal.OnMenuItemClicked += OnSampleMenuClicked;
container.Add(_sampleMenuHorizontal);
}
/// <summary>
/// 아이콘 메뉴 초기화 (ItemSpacing 적용)
/// </summary>
private void InitializeIconMenu(VisualElement root)
{
var container = root.Q<VisualElement>("icon-menu-container");
if (container == null) return;
_sampleMenuIcon = new UTKTopMenu();
_sampleMenuIcon.ItemSpacing = 4f;
_sampleModelIcon = new UTKTopMenuModel();
// 홈 아이콘
var homeMenu = new UTKMenuImageItemData("s_icon_home", UTKMaterialIcons.Home, useMaterialIcon: true, imageSize: 24f);
homeMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_home_dashboard", "대시보드", new DebugLogCommand("대시보드")));
homeMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_home_recent", "최근 항목", new DebugLogCommand("최근 항목")));
_sampleModelIcon.AddMenuItem(homeMenu);
// 설정 아이콘
var settingsMenu = new UTKMenuImageItemData("s_icon_settings", UTKMaterialIcons.Settings, useMaterialIcon: true, imageSize: 24f);
settingsMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_settings_general", "일반", new DebugLogCommand("일반 설정")));
settingsMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_settings_display", "화면", new DebugLogCommand("화면 설정")));
_sampleModelIcon.AddMenuItem(settingsMenu);
// 알림 아이콘
var notifMenu = new UTKMenuImageItemData("s_icon_notif", UTKMaterialIcons.Notifications, useMaterialIcon: true, imageSize: 24f);
notifMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_notif_all", "전체 알림", new DebugLogCommand("전체 알림")));
notifMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_notif_clear", "알림 지우기", new DebugLogCommand("알림 지우기")));
_sampleModelIcon.AddMenuItem(notifMenu);
// 계정 아이콘
var accountMenu = new UTKMenuImageItemData("s_icon_account", UTKMaterialIcons.AccountCircle, useMaterialIcon: true, imageSize: 24f);
accountMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_account_profile", "프로필", new DebugLogCommand("프로필")));
accountMenu.AddSubMenuItem(new UTKMenuItemData("s_icon_account_logout", "로그아웃", new DebugLogCommand("로그아웃")));
_sampleModelIcon.AddMenuItem(accountMenu);
if (_sampleMenuIcon.MenuContainer != null)
{
_sampleMenuIcon.CreateMenuItems(_sampleModelIcon.MenuItems, _sampleMenuIcon.MenuContainer);
}
_sampleMenuIcon.OnMenuItemClicked += OnSampleMenuClicked;
container.Add(_sampleMenuIcon);
}
/// <summary>
/// 세로 메뉴 초기화
/// </summary>
private void InitializeVerticalMenu(VisualElement root)
{
var container = root.Q<VisualElement>("vertical-menu-container");
if (container == null) return;
_sampleMenuVertical = new UTKTopMenu();
_sampleMenuVertical.Orientation = UTKMenuOrientation.Vertical;
_sampleMenuVertical.ItemSpacing = 2f;
_sampleMenuVertical.SubMenuOffsetX = -10f;
_sampleMenuVertical.SubMenuOffsetY = 4f;
_sampleModelVertical = new UTKTopMenuModel();
// 파일
var fileMenu = new UTKMenuItemData("sv_file", "파일");
fileMenu.AddSubMenuItem(new UTKMenuItemData("sv_file_new", "새 파일", new DebugLogCommand("세로: 새 파일"), shortcut: "Ctrl+N"));
fileMenu.AddSubMenuItem(new UTKMenuItemData("sv_file_open", "열기", new DebugLogCommand("세로: 열기"), shortcut: "Ctrl+O"));
fileMenu.AddSubMenuItem(UTKMenuItemData.CreateSeparator());
fileMenu.AddSubMenuItem(new UTKMenuItemData("sv_file_save", "저장", new DebugLogCommand("세로: 저장"), shortcut: "Ctrl+S"));
_sampleModelVertical.AddMenuItem(fileMenu);
// 편집
var editMenu = new UTKMenuItemData("sv_edit", "편집");
editMenu.AddSubMenuItem(new UTKMenuItemData("sv_edit_undo", "실행 취소", new DebugLogCommand("세로: 실행 취소"), shortcut: "Ctrl+Z"));
editMenu.AddSubMenuItem(new UTKMenuItemData("sv_edit_redo", "다시 실행", new DebugLogCommand("세로: 다시 실행"), shortcut: "Ctrl+Y"));
_sampleModelVertical.AddMenuItem(editMenu);
// 보기
var viewMenu = new UTKMenuItemData("sv_view", "보기");
viewMenu.AddSubMenuItem(new UTKMenuItemData("sv_view_fullscreen", "전체 화면", new DebugLogCommand("세로: 전체 화면"), shortcut: "F11"));
_sampleModelVertical.AddMenuItem(viewMenu);
// 도움말
var helpMenu = new UTKMenuItemData("sv_help", "도움말");
helpMenu.AddSubMenuItem(new UTKMenuItemData("sv_help_about", "정보", new DebugLogCommand("세로: 정보")));
_sampleModelVertical.AddMenuItem(helpMenu);
if (_sampleMenuVertical.MenuContainer != null)
{
_sampleMenuVertical.CreateMenuItems(_sampleModelVertical.MenuItems, _sampleMenuVertical.MenuContainer);
}
_sampleMenuVertical.OnMenuItemClicked += OnSampleMenuClicked;
container.Add(_sampleMenuVertical);
}
/// <summary>
/// API 테스트 버튼 초기화
/// </summary>
private void InitializeApiTest(VisualElement root)
{
var container = root.Q<VisualElement>("api-test-container");
var resultLabel = root.Q<Label>("api-result-label");
if (container == null || resultLabel == null) return;
// ExecuteCommand 테스트
var executeBtn = new UTKButton("ExecuteCommand");
executeBtn.OnClicked += () =>
{
if (_sampleMenuHorizontal == null) return;
bool result = _sampleMenuHorizontal.ExecuteCommand("s_file_new");
resultLabel.text = $"ExecuteCommand(\"s_file_new\"): {result}";
};
container.Add(executeBtn);
// TryGetMenuItemData 테스트
var getDataBtn = new UTKButton("TryGetMenuItemData");
getDataBtn.OnClicked += () =>
{
if (_sampleMenuHorizontal == null) return;
if (_sampleMenuHorizontal.TryGetMenuItemData("s_file_save", out var data))
{
resultLabel.text = $"TryGetMenuItemData(\"s_file_save\"): " +
$"DisplayName={data?.DisplayName}, " +
$"IsEnabled={data?.IsEnabled}, " +
$"Shortcut={data?.Shortcut}";
}
else
{
resultLabel.text = "TryGetMenuItemData(\"s_file_save\"): 찾을 수 없음";
}
};
container.Add(getDataBtn);
// CloseAllOpenSubMenus 테스트
var closeBtn = new UTKButton("CloseAll");
closeBtn.OnClicked += () =>
{
_sampleMenuHorizontal?.CloseAllOpenSubMenus();
_sampleMenuIcon?.CloseAllOpenSubMenus();
_sampleMenuVertical?.CloseAllOpenSubMenus();
resultLabel.text = "모든 서브메뉴 닫기 완료";
};
container.Add(closeBtn);
}
/// <summary>
/// 샘플 메뉴 클릭 핸들러
/// </summary>
private void OnSampleMenuClicked(UTKMenuItemData itemData)
{
if (itemData == null) return;
Debug.Log($"[UTKTopMenu Sample] 클릭: {itemData.ItemId} - {itemData.DisplayName}");
if (itemData.Command != null)
{
itemData.Command.Execute(itemData.CommandParameter);
}
}
/// <summary>
/// 메뉴 샘플 리소스 정리
/// </summary>
private void CleanupTopMenuSample()
{
if (_sampleMenuHorizontal != null)
{
_sampleMenuHorizontal.OnMenuItemClicked -= OnSampleMenuClicked;
_sampleMenuHorizontal.Dispose();
_sampleMenuHorizontal = null;
}
if (_sampleMenuIcon != null)
{
_sampleMenuIcon.OnMenuItemClicked -= OnSampleMenuClicked;
_sampleMenuIcon.Dispose();
_sampleMenuIcon = null;
}
if (_sampleMenuVertical != null)
{
_sampleMenuVertical.OnMenuItemClicked -= OnSampleMenuClicked;
_sampleMenuVertical.Dispose();
_sampleMenuVertical = null;
}
_sampleModelHorizontal?.Dispose();
_sampleModelHorizontal = null;
_sampleModelIcon?.Dispose();
_sampleModelIcon = null;
_sampleModelVertical?.Dispose();
_sampleModelVertical = null;
}
#endregion
}