Files
XRLib/Assets/Scripts/Factory/FactorySceneMain.cs
2025-12-15 20:17:38 +09:00

420 lines
19 KiB
C#

using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using UnityEngine;
using UVC.Core;
using UVC.Data;
using UVC.Data.Core;
using UVC.Factory;
using UVC.Factory.Alarm;
using UVC.Factory.Cameras;
using UVC.Factory.Component;
using UVC.Factory.Modal;
using UVC.Factory.Modal.Settings;
using UVC.Factory.Playback;
using UVC.Locale;
using UVC.UI.Commands;
using UVC.UI.Loading;
using UVC.UI.Menu;
using UVC.UI.Modal;
using UVC.UI.Toolbar.Model;
using UVC.UI.ToolBar;
using UVC.UI.Tooltip;
using UVC.UI.Window.PropertyWindow;
namespace Factory
{
[DefaultExecutionOrder(90)]
public class FactorySceneMain : SingletonScene<FactorySceneMain>
{
[SerializeField]
private TopMenuController topMenu;
[SerializeField]
private Toolbox toolBox;
[SerializeField]
private FactorySideTabBar sideTabBar;
[SerializeField] private PropertyWindow propertyWindow;
public Action Initialized;
/// <summary>
/// 초기 화 메서드입니다.
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
/// </summary>
protected override void Init()
{
if (!TooltipManager.Instance.IsInitialized) TooltipManager.Instance.Initialize();
FactoryAppMain.Instance.Initialized += OnAppInitialized;
}
private async void OnAppInitialized()
{
// AGVManager 생성 시 이벤트 처리
AGVManager.Instance.OnCreated += OnAGVCreated;
PlaybackService.Instance.OnStartPlayback += OnStartPlayback;
PlaybackService.Instance.OnExitPlayback += OnExitPlayback;
PlaybackService.Instance.OnChangedTime += OnChangedTimePlayback;
await requestDataAsync();
SetupTopMenu();
SetupToolBox();
SetupPropertyWindow();
if (Initialized != null)
{
Initialized.Invoke();
}
await UniTask.Delay(2000);
sideTabBar.InitTab();
}
/// <summary>
/// AGV 관리자가 생성될 때 발생하는 이벤트를 처리합니다.
/// </summary>
/// <remarks>이 메서드는 AGV 관리자 생성과 관련된 필요한 초기화 또는 설정 작업을 수행하기 위한 것입니다.
/// 내부적으로 호출되며 외부 코드에서 직접 사용하도록 의도된 것이 아닙니다.
///</remarks>
internal void OnAGVCreated()
{
AlarmManager.Instance.Run();
UILoading.Hide();
FactoryCameraController.Instance.Enable = true;
}
private async UniTask requestDataAsync()
{
Debug.Log("requestDataAsync");
UILoading.Show();
//Debug.Log("Requesting BaseInfo data...");
//var httpFetcher = DataRepository.Instance.HttpFetcher;
//var splitRequest = new HttpRequestConfig(URLList.Get("baseinfo"))
// .SetSplitResponseByKey(true) // 응답을 키별로 분할
// .AddSplitConfig("AGV", DataMapperValidator.Get("AGV")) // "AGV" 키에 대한 매퍼, Validator 설정
// .AddSplitConfig("ALARM", DataMapperValidator.Get("ALARM")); // "ALARM" 키에 대한 매퍼, Validator 설정
//httpFetcher.AddChild("baseInfo", splitRequest);
//await httpFetcher.Excute("baseInfo");
//Debug.Log("BaseInfo data request completed.");
//UILoading.Hide();
//MqttReceiver 시작
DataRepository.Instance.MqttReceiver.Start();
if (AGVManager.Instance.Created)
{
await UniTask.Delay(1000);
UILoading.Hide();
}
}
private void OnStartPlayback()
{
FactoryObjectSelectionManager.Instance.DeselectAll();
InfoWindow.Instance.Hide();
}
private async void OnExitPlayback()
{
FactoryObjectSelectionManager.Instance.DeselectAll();
InfoWindow.Instance.Hide();
await requestDataAsync();
}
private void OnChangedTimePlayback()
{
}
private void SetupTopMenu()
{
if (topMenu == null)
{
Debug.LogWarning("TopMenuController is not assigned in SceneMain.");
return;
}
topMenu.AddMenuItem(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("[FactorySample] 새 파일 선택됨")))
}),
new MenuItemData("file_open", "menu_file_open",
new ActionCommand<string>((path) => Debug.Log($"[FactorySample] 파일 열기 선택됨: {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()) // 애플리케이션 종료 명령 연결
}));
topMenu.AddMenuItem(new MenuItemData("Playback", "Playback", new PlaybackCommand()));
// pool 로그
topMenu.AddMenuItem(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", "Pool", new ActionCommand(() => Debug.Log($"Pool stats: {AGVManager.Instance.Pool.GetStats()}"))),
}));
topMenu.AddMenuItem(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("확인", "이것은 간단한 알림 메시지입니다.");
Debug.Log($"사용자가 확인 버튼을 눌렀나요? {result}");
result = await Confirm.Show("경고", "데이터를 저장할 수 없습니다.", "알겠습니다~~~~", "아니요");
Debug.Log($"사용자가 알림을 확인했나요? {result}");
result = await Confirm.Show("error", "error_network_not", "button_retry", "button_cancel");
Debug.Log($"사용자가 네트워크 오류 알림을 확인했나요? {result}");
}))
}));
topMenu.AddMenuItem(new MenuItemData("Settings", "Settings", new SettingOpenCommand()));
topMenu.AddMenuItem(new MenuItemData("PropertyWindow", "PropertyWindow", new ActionCommand(async () =>
{
propertyWindow.Show();
})));
topMenu.Initialize();
}
private void SetupToolBox()
{
// ToolbarModel 인스턴스 생성
var toolbarModel = new ToolbarModel();
// --- 툴바 모델 구성 시작 ---
// 화면 캡처
toolbarModel.AddStandardButton("button_capture_screen",
"Prefabs/UI/Toolbar/images/ic_menu_capture",
new ActionCommand(() => Debug.Log("화면 캡처 버튼 클릭됨")),
"tooltip_capture_screen");
// 화면 녹화 시작/중지 (ToggleButton)
toolbarModel.AddToggleButton("button_record_screen", false,
"Prefabs/UI/Toolbar/images/ic_menu_camera_on",
"Prefabs/UI/Toolbar/images/ic_menu_camera_off",
(isSelected) => Debug.Log($"화면 녹화 상태: {(isSelected ? " " : "")} (OnToggle 콜백)"),
new ActionCommand<bool>((isRecording) => Debug.Log($"화면 녹화 Command 실행: {(isRecording ? " " : " ")}")),
"tooltip_record_screen");
// 화면 확대
toolbarModel.AddStandardButton("화면 확대",
"Prefabs/UI/Toolbar/images/ic_menu_zoom_in",
new ActionCommand(() => Debug.Log("화면 확대 버튼 클릭됨")),
"화면을 한 단계 확대 합니다.");
//화면 축소
toolbarModel.AddStandardButton("화면 축소",
"Prefabs/UI/Toolbar/images/ic_menu_zoom_out",
new ActionCommand(() => Debug.Log("화면 축소 버튼 클릭됨")),
"화면을 한 단계 축소 합니다.");
// 구분선
toolbarModel.AddSeparator();
// RadioButtonGroup 샘플
toolbarModel.AddRadioButton("CameraControlGroup", "Top View", true,
"Prefabs/UI/Toolbar/images/ic_camera_top_on",
"Prefabs/UI/Toolbar/images/ic_camera_top_off_white",
(isSelected) => { if (isSelected) Debug.Log("탑뷰 카메라 선택됨"); },
new ActionCommand(() => Debug.Log("탑뷰 카메라 Command 실행")),
"Top View 시점으로 변경합니다.");
toolbarModel.AddRadioButton("CameraControlGroup", "Quarter View", false,
"Prefabs/UI/Toolbar/images/ic_camera_quarter_on",
"Prefabs/UI/Toolbar/images/ic_camera_quarter_off_white",
(isSelected) => { if (isSelected) Debug.Log("쿼터뷰 카메라 선택됨"); },
new ActionCommand(() => Debug.Log("쿼터뷰 카메라 Command 실행")),
"Quarter View 시점으로 변경합니다.");
toolbarModel.AddRadioButton("CameraControlGroup", "Front View", false,
"Prefabs/UI/Toolbar/images/ic_camera_top_on",
"Prefabs/UI/Toolbar/images/ic_camera_top_off_white",
(isSelected) => { if (isSelected) Debug.Log("프런트뷰 카메라 선택됨"); },
new ActionCommand(() => Debug.Log("프런트뷰 카메라 Command 실행")),
"Front View 시점으로 변경합니다.");
toolbarModel.AddSeparator();
// 예시 : 확장 버튼 (브러시 크기 선택)
// AddExpandableButton으로 주 버튼을 만들고, 반환된 객체의 SubButtons 리스트에 하위 버튼들을 추가합니다.
var expandableBtnModel = toolbarModel.AddExpandableButton("button_brush_size", // 주 버튼 텍스트/키
"Prefabs/UI/Toolbar/images/ic_brush_default_white", // 주 버튼 기본 아이콘
new ActionCommand(() => Debug.Log("브러시 크기 주 버튼 클릭됨 (Command)")), // 주 버튼 자체의 커맨드
"붓 사이즈 선택 합니다."); // 주 버튼 툴팁
// 하위 버튼1: 작은 브러시 (ToolbarStandardButton 사용)
var smallBrushCmd = new ActionCommand(() => Debug.Log($"작은 브러시 선택됨"));
var smallBrush = new ToolbarStandardButton
{
Text = "brush_size_small", // 하위 버튼 텍스트/키
IconSpritePath = "Prefabs/UI/Toolbar/images/ic_brush_small_white", // 하위 버튼 아이콘
Tooltip = "tooltip_brush_small", // 하위 버튼 툴팁
ClickCommand = smallBrushCmd
};
expandableBtnModel.SubButtons.Add(smallBrush); // 확장 버튼 모델에 하위 버튼 추가
// 하위 버튼2: 중간 브러시
var mediumBrush = new ToolbarStandardButton
{
Text = "brush_size_medium",
IconSpritePath = "Prefabs/UI/Toolbar/images/ic_brush_medium_white",
Tooltip = "tooltip_brush_medium",
ClickCommand = new ActionCommand(() => Debug.Log("중간 브러시 선택됨 (Sub-Command 실행)"))
};
expandableBtnModel.SubButtons.Add(mediumBrush);
// 확장 버튼의 하위 버튼이 선택되었을 때 호출될 콜백 설정
expandableBtnModel.OnSubButtonSelected = (selectedSubButtonModel) =>
{
// LocalizationManager를 사용하여 텍스트를 현재 언어에 맞게 가져올 수 있습니다.
string localizedSubButtonText = LocalizationManager.Instance != null ? LocalizationManager.Instance.GetString(selectedSubButtonModel.Text) : selectedSubButtonModel.Text;
Debug.Log($"브러시 크기 '{localizedSubButtonText}' 선택됨 (OnSubButtonSelected 콜백). 주 버튼 업데이트 로직 실행 가능.");
};
// --- 툴바 모델 구성 끝 ---
toolBox.SetData(toolbarModel);
toolBox.Initialize();
}
private void SetupPropertyWindow()
{
propertyWindow.LoadProperties(new List<IPropertyItem>
{
new StringProperty("prop1", "String Property", "Initial Value")
{
Description = "This is a sample string property.",
Tooltip = "Enter a string value here.",
IsReadOnly = false
},
new IntProperty("prop2", "Int Property", 42, true)
{
Description = "This is a sample integer property.",
Tooltip = "Enter an integer value here.",
IsReadOnly = false
},
new IntRangeProperty("prop2_range", "Int Range Property", new Tuple<int, int>(0, 100))
{
Description = "This is a sample integer range property.",
Tooltip = "Select an integer value within the range here.",
IsReadOnly = false
},
new FloatRangeProperty("prop3_range", "Float Range Property", new Tuple<float, float>(0.0f, 1.0f))
{
Description = "This is a sample float range property.",
Tooltip = "Select a float value within the range here.",
IsReadOnly = false
},
new FloatProperty("prop3", "Float Property", 0.5f, true)
{
Description = "This is a sample float property.",
Tooltip = "Enter an float value here.",
IsReadOnly = false
},
new BoolProperty("prop4", "Boolean Property", true)
{
Description = "This is a sample boolean property.",
Tooltip = "Toggle the boolean value here.",
IsReadOnly = false
},
new ColorProperty("prop5", "Color Property", Color.red)
{
Description = "This is a sample color property.",
Tooltip = "Select a color here.",
IsReadOnly = false
},
new Vector2Property("prop6_vec2", "Vector2 Property", new Vector2(1, 2))
{
Description = "This is a sample Vector2 property.",
Tooltip = "Enter a Vector2 value here.",
IsReadOnly = false
},
new Vector3Property("prop6_vec3", "Vector3 Property", new Vector3(1, 2, 3))
{
Description = "This is a sample Vector3 property.",
Tooltip = "Enter a Vector3 value here.",
IsReadOnly = false
},
new DateProperty("prop6_date", "Date Property", System.DateTime.Now)
{
//Description = "This is a sample date property.",
Tooltip = "Select a date here.",
IsReadOnly = false
},
new DateTimeProperty("prop6_datetime", "DateTime Property", System.DateTime.Now)
{
Description = "This is a sample date-time property.",
Tooltip = "Select a date and time here.",
IsReadOnly = false
},
new DateRangeProperty("prop6_daterange", "Date Range Property", new Tuple<DateTime, DateTime>(DateTime.Now.AddDays(-7), DateTime.Now))
{
Description = "This is a sample date range property.",
Tooltip = "Select a date range here.",
IsReadOnly = false
},
new DateTimeRangeProperty("prop6_datetimerange", "DateTime Range Property", new Tuple<DateTime, DateTime>(DateTime.Now.AddHours(-1), DateTime.Now))
{
Description = "This is a sample date-time range property.",
Tooltip = "Select a date-time range here.",
IsReadOnly = false
},
new EnumProperty("prop6", "Enum Property", SampleEnum.Option1)
{
Description = "This is a sample enum property.",
Tooltip = "Select an option here.",
IsReadOnly = false
},
new ListProperty("prop7", "List Property", new List<string> { "Item1", "Item2", "Item3" }, "Item1")
{
Description = "This is a sample list property.",
Tooltip = "Manage the list items here.",
IsReadOnly = false
},
new RadioGroupProperty("prop8", "Radio Group Property", new List<string> { "Option1", "Option2", "Option3" }, "Option1")
{
Description = "This is a sample radio group property.",
Tooltip = "Select one option here.",
IsReadOnly = false
}
});
propertyWindow.PropertyValueChanged += (sender, e) =>
{
Debug.Log($"Property Id:{e.PropertyId}, type:{e.PropertyType}, newValue: {e.NewValue}");
};
}
enum SampleEnum
{
Option1,
Option2,
Option3
}
}
}