Component List 개발 중
This commit is contained in:
@@ -20,68 +20,17 @@ namespace UVC.UI.Menu
|
||||
/// Inspector에서 <see cref="TopMenuController"/>와 <see cref="TopMenuView"/> 추가해서 사용합니다.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// 다음은 TopMenuController를 상속받아 특정 기능을 확장하는 예제입니다.
|
||||
/// 다음은 TopMenuController를 사용해 메뉴를 구성하는 예제 입니다.
|
||||
/// <code>
|
||||
/// public class CustomTopMenuController : TopMenuController
|
||||
/// private TopMenuController topMenu;
|
||||
///
|
||||
/// // 예: '도움말' 메뉴 추가
|
||||
/// topMenu.AddMenuItem(new MenuItemData("help", "menu_help", subMenuItems: new List<MenuItemData>;
|
||||
/// {
|
||||
/// protected override void InitializeMenuItems()
|
||||
/// {
|
||||
/// // 기본 메뉴 아이템 초기화 로직 호출
|
||||
/// base.InitializeMenuItems();
|
||||
///
|
||||
/// // 기존 모델에 새로운 메뉴 아이템 추가 또는 수정
|
||||
/// // 예: '도움말' 메뉴 추가
|
||||
/// model.MenuItems.Add(new MenuItemData("help", "menu_help", subMenuItems: new List<MenuItemData>;
|
||||
/// {
|
||||
/// new MenuItemData("help_about", "menu_help_about", new DebugLogCommand("도움말 > 정보 선택됨"))
|
||||
/// }));
|
||||
///
|
||||
/// // 변경된 모델을 기반으로 뷰를 다시 생성하거나 업데이트해야 할 수 있습니다.
|
||||
/// // (이미 Start 메서드에서 CreateMenuItems가 호출되므로, InitializeMenuItems 시점에서는 모델만 수정)
|
||||
/// ULog.Debug("CustomTopMenuController: '도움말' 메뉴가 추가되었습니다.");
|
||||
/// }
|
||||
///
|
||||
/// protected override void HandleMenuItemClicked(MenuItemData clickedItemData)
|
||||
/// {
|
||||
/// // 기본 클릭 처리 로직 호출
|
||||
/// base.HandleMenuItemClicked(clickedItemData);
|
||||
///
|
||||
/// // 특정 메뉴 아이템에 대한 추가적인 커스텀 로직 수행
|
||||
/// if (clickedItemData.ItemId == "file_exit")
|
||||
/// {
|
||||
/// ULog.Debug("CustomTopMenuController: 애플리케이션 종료 메뉴가 선택되었습니다. 추가 확인 로직을 여기에 넣을 수 있습니다.");
|
||||
/// // 예: 사용자에게 정말 종료할 것인지 확인하는 팝업 표시 등
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // 새로운 기능을 추가할 수도 있습니다.
|
||||
/// public void AddCustomMenuOption(string parentItemId, MenuItemData newItem)
|
||||
/// {
|
||||
/// if (model == null || model.MenuItems == null) return;
|
||||
///
|
||||
/// MenuItemData parentItem = FindMenuItemRecursive(model.MenuItems, parentItemId);
|
||||
/// if (parentItem != null)
|
||||
/// {
|
||||
/// if (parentItem.IsSeparator)
|
||||
/// {
|
||||
/// ULog.Warning($"구분선('{parentItemId}')에는 하위 메뉴를 추가할 수 없습니다.");
|
||||
/// return;
|
||||
/// }
|
||||
/// parentItem.AddSubMenuItem(newItem);
|
||||
/// ULog.Debug($"'{parentItemId}'에 새로운 하위 메뉴 '{newItem.ItemId}'가 추가되었습니다.");
|
||||
///
|
||||
/// // 중요: 모델 변경 후에는 뷰를 업데이트해야 합니다.
|
||||
/// // 예를 들어, 메뉴를 전부 다시 그리거나 특정 부분만 업데이트하는 메서드를 호출합니다.
|
||||
/// // view.ClearMenuItems();
|
||||
/// // view.CreateMenuItems(model.MenuItems, view.MenuContainer);
|
||||
/// // 또는 더 정교한 뷰 업데이트 메서드가 필요할 수 있습니다.
|
||||
/// }
|
||||
/// else
|
||||
/// {
|
||||
/// ULog.Warning($"ID가 '{parentItemId}'인 부모 메뉴 아이템을 찾을 수 없습니다.");
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// new MenuItemData("help_about", "menu_help_about", new DebugLogCommand("도움말 > 정보 선택됨"))
|
||||
/// }));
|
||||
///
|
||||
/// topMenu.Initialize(); // 메뉴 초기화 및 생성 요청
|
||||
/// </code>
|
||||
/// </example>
|
||||
public class TopMenuController : MonoBehaviour
|
||||
@@ -104,6 +53,8 @@ namespace UVC.UI.Menu
|
||||
/// </summary>
|
||||
protected LocalizationManager _locManager;
|
||||
|
||||
protected bool isInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
/// MonoBehaviour의 Awake 메시지입니다. 스크립트 인스턴스가 로드될 때 호출됩니다.
|
||||
/// 주로 <see cref="view"/> 컴포넌트를 찾는 데 사용됩니다.
|
||||
@@ -120,7 +71,11 @@ namespace UVC.UI.Menu
|
||||
view = GetComponentInChildren<TopMenuView>();
|
||||
}
|
||||
|
||||
// view가 여전히 null이라면, Start 메서드에서 오류를 기록할 것입니다.
|
||||
// 메뉴 데이터 모델 인스턴스 생성
|
||||
model = new TopMenuModel();
|
||||
|
||||
// 다국어 관리자 인스턴스 가져오기
|
||||
_locManager = LocalizationManager.Instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -130,18 +85,12 @@ namespace UVC.UI.Menu
|
||||
/// </summary>
|
||||
protected virtual void Start()
|
||||
{
|
||||
// 메뉴 데이터 모델 인스턴스 생성
|
||||
model = new TopMenuModel();
|
||||
// 다국어 관리자 인스턴스 가져오기
|
||||
_locManager = LocalizationManager.Instance;
|
||||
|
||||
// View 컴포넌트가 할당되었는지 확인
|
||||
if (view == null)
|
||||
{
|
||||
ULog.Error("TopMenuView가 Inspector에서 할당되지 않았거나 찾을 수 없습니다. TopMenuController가 정상적으로 작동하지 않습니다.");
|
||||
return; // View가 없으면 더 이상 진행할 수 없음
|
||||
}
|
||||
|
||||
// LocalizationManager 인스턴스 확인
|
||||
if (_locManager == null)
|
||||
{
|
||||
@@ -149,24 +98,6 @@ namespace UVC.UI.Menu
|
||||
// _locManager가 null이어도 메뉴 구조 자체는 생성될 수 있도록 계속 진행합니다.
|
||||
// TopMenuView와 이 클래스의 다른 부분에서 _locManager null 체크를 통해 안전하게 처리합니다.
|
||||
}
|
||||
|
||||
// 메뉴 아이템 데이터 초기화 (모델 채우기)
|
||||
InitializeMenuItems();
|
||||
|
||||
// View에 기존 메뉴 아이템들을 지우도록 요청
|
||||
view.ClearMenuItems();
|
||||
// View에 현재 모델 데이터를 기반으로 메뉴 UI를 생성하도록 요청
|
||||
// view.MenuContainer는 TopMenuView에서 메뉴 UI 요소들이 배치될 부모 Transform을 가리킵니다.
|
||||
view.CreateMenuItems(model.MenuItems, view.menuContainer);
|
||||
|
||||
// View에서 발생하는 메뉴 아이템 클릭 이벤트에 대한 핸들러 등록
|
||||
view.OnMenuItemClicked += HandleMenuItemClicked;
|
||||
|
||||
// LocalizationManager가 존재하고, 언어 변경 이벤트를 지원한다면 핸들러 등록
|
||||
if (_locManager != null)
|
||||
{
|
||||
_locManager.OnLanguageChanged += HandleLanguageChanged;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -188,64 +119,82 @@ namespace UVC.UI.Menu
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메뉴 아이템 데이터를 초기화하고 <see cref="model"/>에 추가합니다.
|
||||
/// 이 메서드에서 메뉴의 전체 구조(항목, 하위 항목, 구분선, 연결된 명령 등)를 정의합니다.
|
||||
/// 상속 클래스에서 이 메서드를 오버라이드하여 메뉴 구성을 변경하거나 확장할 수 있습니다.
|
||||
/// 모델 초기화, <see cref="LocalizationManager"/> 인스턴스 가져오기, 메뉴 아이템 데이터 설정,
|
||||
/// View에 메뉴 생성 요청, 이벤트 핸들러 등록 등의 주요 초기화 작업을 수행합니다.
|
||||
/// </summary>
|
||||
protected virtual void InitializeMenuItems()
|
||||
public virtual void Initialize()
|
||||
{
|
||||
// 기존 메뉴 아이템 목록을 비웁니다.
|
||||
model.MenuItems.Clear();
|
||||
if (isInitialized) {
|
||||
Debug.LogWarning("TopMenuController가 이미 초기화되었습니다. 중복 초기화를 방지합니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// "파일" 메뉴 및 하위 메뉴들 정의
|
||||
model.MenuItems.Add(new MenuItemData("file", "menu_file", subMenuItems: new List<MenuItemData>
|
||||
{
|
||||
new MenuItemData("file_new", "menu_file_new", subMenuItems: new List<MenuItemData>
|
||||
{
|
||||
new MenuItemData("file_new_project", "menu_file_new_project", new DebugLogCommand("새 프로젝트 선택됨 (Command 실행)")),
|
||||
new MenuItemData("file_new_file", "menu_file_new_file",
|
||||
new ActionCommand(() => Debug.Log("[SampleProject] 새 파일 선택됨")))
|
||||
}),
|
||||
new MenuItemData("file_open", "menu_file_open",
|
||||
new ActionCommand<string>((path) => Debug.Log($"[SampleProject] 파일 열기 선택됨: {path}"), "sample.txt"),
|
||||
commandParameter: "another_sample.txt", // 이 파라미터가 HandleMenuItemClicked에서 사용됨
|
||||
isEnabled: false), // "파일 열기"는 비활성화 상태로 시작
|
||||
MenuItemData.CreateSeparator("file_sep1"), // 구분선 추가
|
||||
new MenuItemData("file_save", "menu_file_save", command: new DebugLogCommand("저장 선택됨 (Command 실행)") , subMenuItems: new List<MenuItemData>
|
||||
{
|
||||
new MenuItemData("file_save_as", "menu_file_save_as", new DebugLogCommand("다른 이름으로 저장 선택됨 (Command 실행)"))
|
||||
}),
|
||||
MenuItemData.CreateSeparator("file_sep2"), // 또 다른 구분선 추가
|
||||
new MenuItemData("file_exit", "menu_file_exit", new QuitApplicationCommand()) // 애플리케이션 종료 명령 연결
|
||||
}));
|
||||
model.MenuItems.Add(new MenuItemData("Playback", "Playback", new PlaybackCommand()));
|
||||
// pool 로그
|
||||
model.MenuItems.Add(new MenuItemData("log", "Log", subMenuItems: new List<MenuItemData>
|
||||
{
|
||||
new MenuItemData("dataArray", "DataArray", new ActionCommand(() => Debug.Log($"DataArrayPool stats: {DataArrayPool.GetStats()}"))),
|
||||
new MenuItemData("dataObject", "DataObjet", new ActionCommand(() => Debug.Log($"DataObjectPool stats: {DataObjectPool.GetStats()}"))),
|
||||
new MenuItemData("agv", "AGVPool", new ActionCommand(() => Debug.Log($"AGVPool stats: {AGVManager.Instance.AGVPool.GetStats()}"))),
|
||||
}));
|
||||
model.MenuItems.Add(new MenuItemData("modal", "모달", subMenuItems: new List<MenuItemData>
|
||||
{
|
||||
new MenuItemData("alert", "Alert", new ActionCommand(async () => {
|
||||
await Alert.Show("알림", "이것은 간단한 알림 메시지입니다.");
|
||||
await Alert.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다");
|
||||
await Alert.Show("error", "error_network_not", "button_retry");
|
||||
})),
|
||||
new MenuItemData("confirm", "Confirm", new ActionCommand(async () => {
|
||||
bool result = await Confirm.Show("확인", "이것은 간단한 알림 메시지입니다.");
|
||||
ULog.Debug($"사용자가 확인 버튼을 눌렀나요? {result}");
|
||||
result = await Confirm.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다~~~~", "아니요");
|
||||
ULog.Debug($"사용자가 알림을 확인했나요? {result}");
|
||||
result = await Confirm.Show("error", "error_network_not", "button_retry", "button_cancel");
|
||||
ULog.Debug($"사용자가 네트워크 오류 알림을 확인했나요? {result}");
|
||||
}))
|
||||
}));
|
||||
// View에 기존 메뉴 아이템들을 지우도록 요청
|
||||
view.ClearMenuItems();
|
||||
// View에 현재 모델 데이터를 기반으로 메뉴 UI를 생성하도록 요청
|
||||
// view.MenuContainer는 TopMenuView에서 메뉴 UI 요소들이 배치될 부모 Transform을 가리킵니다.
|
||||
view.CreateMenuItems(model.MenuItems, view.menuContainer);
|
||||
|
||||
model.MenuItems.Add(new MenuItemData("Settings", "Settings", new SettingOpenCommand()));
|
||||
// View에서 발생하는 메뉴 아이템 클릭 이벤트에 대한 핸들러 등록
|
||||
view.OnMenuItemClicked += HandleMenuItemClicked;
|
||||
|
||||
// LocalizationManager가 존재하고, 언어 변경 이벤트를 지원한다면 핸들러 등록
|
||||
if (_locManager != null)
|
||||
{
|
||||
_locManager.OnLanguageChanged += HandleLanguageChanged;
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 메뉴 아이템을 추가합니다.
|
||||
/// </summary>
|
||||
/// <param name="newItem">추가할 아이템</param>
|
||||
public void AddMenuItem(MenuItemData newItem)
|
||||
{
|
||||
if (model == null || model.MenuItems == null)
|
||||
{
|
||||
ULog.Warning("모델이 초기화되지 않아 메뉴 아이템을 추가할 수 없습니다.");
|
||||
return;
|
||||
}
|
||||
// 모델에 새 메뉴 아이템 추가
|
||||
model.MenuItems.Add(newItem);
|
||||
ULog.Debug($"새로운 메뉴 아이템 '{newItem.ItemId}'가 모델에 추가되었습니다.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 추가 된 아이템을 제거 합니다.
|
||||
/// </summary>
|
||||
/// <param name="itemId">삭제 할 아이템의 ID</param>
|
||||
public void RemoveMenuItem(string itemId)
|
||||
{
|
||||
if (model == null || model.MenuItems == null)
|
||||
{
|
||||
ULog.Warning("모델이 초기화되지 않아 메뉴 아이템을 제거할 수 없습니다.");
|
||||
return;
|
||||
}
|
||||
// 모델에서 해당 ID를 가진 메뉴 아이템을 재귀적으로 검색
|
||||
MenuItemData targetItem = FindMenuItemRecursive(model.MenuItems, itemId);
|
||||
if (targetItem != null)
|
||||
{
|
||||
// 구분선은 제거할 수 없음
|
||||
if (targetItem.IsSeparator)
|
||||
{
|
||||
ULog.Warning($"구분선('{itemId}')은 제거할 수 없습니다. 작업이 무시됩니다.");
|
||||
return;
|
||||
}
|
||||
// 모델에서 아이템 제거
|
||||
model.MenuItems.Remove(targetItem);
|
||||
ULog.Debug($"ID가 '{itemId}'인 메뉴 아이템이 모델에서 제거되었습니다.");
|
||||
}
|
||||
else
|
||||
{
|
||||
ULog.Warning($"ID가 '{itemId}'인 메뉴 아이템을 모델에서 찾을 수 없어 제거할 수 없습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="TopMenuView.OnMenuItemClicked"/> 이벤트가 발생했을 때 호출되는 핸들러입니다.
|
||||
/// 클릭된 메뉴 아이템(<paramref name="clickedItemData"/>)의 유효성을 검사하고,
|
||||
|
||||
Reference in New Issue
Block a user