Simulator 샘플 추가

This commit is contained in:
logonkhi
2025-09-29 19:16:23 +09:00
parent 607eb6a659
commit 09c4c9adc1
42 changed files with 45942 additions and 44993 deletions

View File

@@ -65,9 +65,6 @@ namespace SampleProject
}
/// <summary>
/// AGV 관리자가 생성될 때 발생하는 이벤트를 처리합니다.
/// </summary>

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1e9a82ed9be6ddd4c8355a888b5e5e99
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 7541ba42b52c10145acede92d1dd57f5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,96 @@
using Newtonsoft.Json;
using System.IO;
using UnityEngine;
using static UVC.Util.WindowTools;
namespace Simulator.Config
{
/// <summary>
/// 애플리케이션의 설정을 관리하는 클래스입니다. AppConfig.json 파일에서 설정을 로드합니다.
/// </summary>
public class AppConfig
{
/// <summary>
/// 로드된 애플리케이션 설정을 담고 있는 정적 인스턴스입니다.
/// </summary>
public static AppConfig Config { get; private set; }
/// <summary>
/// Windows 런타임 환경에서 StreamingAssets 폴더의 AppConfig.json 파일로부터 설정을 로드합니다.
/// </summary>
/// <returns>설정 로드 성공 여부를 반환합니다.</returns>
public static bool LoadConfig()
{
string path = Path.Combine(Application.streamingAssetsPath, "AppConfig.json");
if (File.Exists(path))
{
string json = File.ReadAllText(path);
Config = JsonConvert.DeserializeObject<AppConfig>(json);
Debug.Log($"AppConfig loaded from {path}");
return Config != null;
}
else
{
Debug.LogError($"File not found: {path}");
}
return false;
}
/// <summary>
/// 애플리케이션의 언어 설정입니다.
/// </summary>
[JsonProperty("language")]
public string Language { get; set; }
/// <summary>
/// 목표 프레임 레이트 설정입니다.
/// </summary>
[JsonProperty("targetFrameRate")]
public int TargetFrameRate { get; set; }
/// <summary>
/// 애플리케이션의 창 관련 설정입니다.
/// </summary>
[JsonProperty("window")]
public WindowInfoData Window { get; set; }
/// <summary>
/// API 도메인 설정입니다.
/// </summary>
[JsonProperty("api")]
public string Api { get; set; }
/// <summary>
/// Mqtt 도메인 설정입니다.
/// </summary>
[JsonProperty("mqtt")]
public MQTTConfig Mqtt { get; set; }
}
public class MQTTConfig
{
/// <summary>
/// MQTT 도메인 설정입니다.
/// </summary>
[JsonProperty("host")]
public string Domain { get; set; }
/// <summary>
/// MQTT 포트 설정입니다.
/// </summary>
[JsonProperty("port")]
public int Port { get; set; }
/// <summary>
/// MQTT JSON에서 데이터를 가지고 있는 키입니다.
/// </summary>
[JsonProperty("dataKey")]
public string DataKey { get; set; }
/// <summary>
/// MQTT MessagePack 디코딩 사용할지 설정입니다.
/// </summary>
[JsonProperty("messagePack")]
public bool MessagePack { get; set; }
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1f76d6c4a9949834a820cfc6bee82cf4

View File

@@ -0,0 +1,14 @@
namespace Simulator.Config
{
public static class Constants
{
public static string API_DOMAIN = "http://localhost:8888";
public static string MQTT_DOMAIN = "localhost";
public static int MQTT_PORT = 1883;
public static string MQTT_DATA_KEY = "data";
/// <summary>
/// MQTT MessagePack 인코딩 사용 여부
/// </summary>
public static bool MQTT_MESSAGEPACK_ENABLED = false;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ee34ae9a68eb62d408cc48ba6e764b62

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: cff7d86115cf0ad4db190fd784a4b375
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,126 @@
#nullable enable
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using UnityEngine;
using UVC.Factory.Component;
using UVC.UI.Commands;
using UVC.UI.List.ComponentList;
using UVC.UI.Menu;
using UVC.UI.Tab;
namespace Simulator.LNB
{
public class LNBExplorer : MonoBehaviour, ITabContent
{
// 이 창이 실제로 제어할 리스트 UI 컴포넌트를 가리킵니다.
[Tooltip("실제 데이터 리스트를 표시하는 ComponentList UI 컴포넌트입니다.")]
[SerializeField]
protected ComponentList? componentList = null;
private string category = "ALL";
/// <summary>
/// 이 컴포넌트가 처음 초기화될 때 호출됩니다. (SingletonScene의 일부)
/// 'componentList' 변수에 필요한 컴포넌트를 찾아 할당하는 역할을 합니다.
/// </summary>
protected void Start()
{
if (componentList == null)
{
componentList = GetComponentInChildren<ComponentList>();
}
if (componentList == null)
{
Debug.LogError("InfiniteScroll component is not assigned or found in children.");
return;
}
}
/// <summary>
/// 리스트에 표시할 데이터를 설정하고 UI를 구성합니다.
/// FactoryObjectManager로부터 모든 객체 정보를 가져와 리스트에 넘겨줍니다.
/// </summary>
public void SetupData()
{
// 팩토리 내 모든 객체 정보를 카테고리별로 정렬하여 가져옵니다.
var infos = FactoryObjectManager.Instance.GetFactoryObjectInfosByCategory();
// 가져온 데이터를 ComponentList 컴포넌트에 전달하여 실제 UI 리스트를 생성하도록 합니다.
if (category != "ALL" && infos.ContainsKey(category))
{
var filteredInfos = new SortedDictionary<string, List<FactoryObjectInfo>>
{
{ category, infos[category] }
};
componentList?.SetupData(filteredInfos);
return;
}
componentList?.SetupData(infos);
}
/// <summary>
/// '필터' 버튼을 클릭했을 때 호출되는 메서드입니다.
/// 사용자가 쉽게 검색할 수 있도록 도와주는 필터 키워드 메뉴를 보여줍니다.
/// </summary>
public void ShowFilter()
{
Debug.Log("필터 버튼 클릭됨.");
// 컨텍스트 메뉴에 표시할 항목들을 정의합니다.
var menuItems = new List<ContextMenuItemData>
{
// "카테고리" 메뉴: 클릭 시 검색창에 "@Category "를 자동으로 입력해줍니다.
// 생성자: (itemId, displayName, command, commandParameter)
new ContextMenuItemData("Menu1", "카테고리", new ActionCommand(()=>{ componentList?.SetSearchText("@Category "); })),
new ContextMenuItemData(isSeparator: true), // 구분선 추가
new ContextMenuItemData("Menu2", "구역", new ActionCommand(()=>{ componentList?.SetSearchText("@Area "); })),
new ContextMenuItemData(isSeparator: true), // 구분선 추가
new ContextMenuItemData("Menu3", "층", new ActionCommand(()=>{ componentList?.SetSearchText("@Floor "); })),
};
// ContextMenuManager를 통해 마우스 위치에 메뉴를 표시합니다.
ContextMenuManager.Instance.ShowMenu(menuItems, Input.mousePosition);
}
/// <summary>
/// 새로고침 버튼 클릭 시 호출됩니다.
/// 리스트의 모든 데이터를 지우고 SetupData를 다시 호출하여 목록을 갱신합니다.
/// </summary>
public void Refresh()
{
SetupData();
}
/// <summary>
/// 탭 콘텐츠에 데이터를 전달합니다.
/// </summary>
/// <param name="data">전달할 데이터 객체</param>
public void SetContentData(object? data)
{
Debug.Log($"TabContentComponentList: SetContentData called. data:{data}");
category = data as string ?? "ALL";
SetupData();
}
/// <summary>
/// 탭 전환 시 데이터가 있는 경우 전달 되는 데이터. SetContentData 이후 호출 됨
/// </summary>
/// <param name="data">전달할 데이터 객체</param>
public void UpdateContentData(object? data)
{
}
/// <summary>
/// 닫힐 때 실행되는 로직을 처리합니다.
/// </summary>
/// <returns>비동기 닫기 작업을 나타내는 <see cref="UniTask"/>입니다.</returns>
public UniTask OnCloseAsync()
{
Debug.Log("TabContentComponentList: OnClose called");
return UniTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 25af9688d9a6e2646b4c334a49c442ff

View File

@@ -0,0 +1,106 @@
#nullable enable
using Cysharp.Threading.Tasks;
using System.Collections.Generic;
using UnityEngine;
using UVC.UI.List;
using UVC.UI.Tab;
namespace Simulator.LNB
{
public class LNBLibrary : MonoBehaviour, ITabContent
{
[SerializeField]
private PrefabGrid? prefabGrid;
protected void Awake()
{
if (prefabGrid == null)
{
prefabGrid = GetComponentInChildren<PrefabGrid>();
}
if (prefabGrid == null)
{
Debug.LogError("InfiniteScroll component is not assigned or found in children.");
return;
}
}
public void Start()
{
SetupData();
}
public void SetupData()
{
List<string> imagePath = new List<string>()
{
"Images/lib_forklift_400x300",
"Images/lib_pallet_400x300",
"Images/lib_worker_400x300",
};
List<string> prefabPath = new List<string>()
{
"Prefabs/Forklift",
"Prefabs/PalletEmpty",
"Prefabs/Male Young Guy",
};
List<PrefabGridItemData> list = new List<PrefabGridItemData>();
for (int i = 0; i < 20; i++)
{
list.Add(new PrefabGridItemData()
{
Id = i.ToString(),
ItemName = $"Item {i}",
ImagePrefabPath = imagePath[i % 3],
ObjectPrefabPath = prefabPath[i % 3]
});
}
prefabGrid?.SetupData(list);
}
/// <summary>
/// 새로고침 버튼 클릭 시 호출됩니다.
/// 리스트의 모든 데이터를 지우고 SetupData를 다시 호출하여 목록을 갱신합니다.
/// </summary>
public void Refresh()
{
}
/// <summary>
/// 탭 콘텐츠에 데이터를 전달합니다.
/// </summary>
/// <param name="data">전달할 데이터 객체</param>
public void SetContentData(object? data)
{
Debug.Log("TabContentTabComponentList: SetContentData called");
}
/// <summary>
/// 탭 전환 시 데이터가 있는 경우 전달 되는 데이터. SetContentData 이후 호출 됨
/// </summary>
/// <param name="data">전달할 데이터 객체</param>
public void UpdateContentData(object? data)
{
}
/// <summary>
/// 닫힐 때 실행되는 로직을 처리합니다.
/// </summary>
/// <returns>비동기 닫기 작업을 나타내는 <see cref="UniTask"/>입니다.</returns>
public UniTask OnCloseAsync()
{
Debug.Log("TabContentTabComponentList: OnClose called");
return UniTask.CompletedTask;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 7dde72181a54a6645a75b8d427049edb

View File

@@ -0,0 +1,64 @@
#nullable enable
using UnityEngine;
using UnityEngine.EventSystems;
using UVC.Core;
using UVC.Factory;
using UVC.UI.Tab;
namespace Simulator.LNB
{
public class SimulatorLNB : SingletonScene<SimulatorLNB>, IPointerEnterHandler, IPointerExitHandler
{
[SerializeField]
private TabController? tabController;
protected override void Init()
{
if (tabController == null)
{
Debug.LogError("SideTabBar: TabController가 할당되지 않았습니다.");
return;
}
}
public void Start()
{
// 1. TabConfig 설정
tabController?.AddTabConfig("Explorer", "탐색기", "Prefabs/Simulator/SimulatorLNBExplorer", "Prefabs/UI/Images/icon_side_tab_explorer_128", "탐색기", true);
tabController?.AddTabConfig("Library", "라이브러리", "Prefabs/Simulator/SimulatorLNBLibrary", "Prefabs/UI/Images/icon_side_tab_library_128", "라이브러리", true);
tabController?.AddTabConfig("ResourceExplorer", "자원 탐색기", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/Images/icon_side_tab_resource_128", "자원 탐색기", true);
tabController?.AddTabConfig("FleetManager", "이동기 관리", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/Images/icon_side_tab_fleet_128", "이동기 관리", true);
// 2. 컨트롤러 초기화
tabController?.Initialize();
if (tabController != null)
{
tabController.OnTabChanged += (index) =>
{
Debug.Log($"탭이 변경되었습니다: {index}");
};
}
}
/// <summary>
/// 마우스 포인터가 이 UI 요소의 영역 안으로 들어왔을 때 호출됩니다.
/// UI와 상호작용하는 동안 3D 뷰의 카메라가 움직이지 않도록 컨트롤러를 비활성화합니다.
/// </summary>
public virtual void OnPointerEnter(PointerEventData eventData)
{
FactoryCameraController.Instance.Enable = false; // 카메라 컨트롤러 비활성화
}
/// <summary>
/// 마우스 포인터가 이 UI 요소의 영역 밖으로 나갔을 때 호출됩니다.
/// 카메라 컨트롤을 다시 활성화하여 3D 뷰를 조작할 수 있도록 합니다.
/// </summary>
public virtual void OnPointerExit(PointerEventData eventData)
{
FactoryCameraController.Instance.Enable = true; // 카메라 컨트롤러 활성화
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 42dfd1026d76a1b46b925f706732e840

View File

@@ -0,0 +1,101 @@
using Assets.Scripts.UVC.Log;
using Cysharp.Threading.Tasks;
using SampleProject.Config;
using System;
using UnityEngine;
using UVC.Core;
using UVC.Data;
using UVC.Data.Mqtt;
using UVC.Locale;
using UVC.Util;
namespace Simulator
{
[DefaultExecutionOrder(100)]
public class SimulatorAppMain : SingletonApp<SimulatorAppMain>
{
public Action Initialized;
/// <summary>
/// 초기 화 메서드입니다.
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
/// </summary>
protected override async void Init()
{
// 플레이 모드가 아닐 경우, 초기화 로직을 실행하지 않습니다.
if (!Application.isPlaying) return;
//로깅 설정
Log4netCodeConfigurator.Setup();
await SettupConfigAsync();
SetNetworkConfig();
if (Initialized != null)
{
Initialized.Invoke();
}
}
void Start()
{
//Tester.RunAllTests();
}
private async UniTask SettupConfigAsync()
{
if (AppConfig.LoadConfig())
{
Application.targetFrameRate = AppConfig.Config.TargetFrameRate;
//기본 언어 설정
bool success = LocalizationManager.Instance.LoadDefaultLocalizationData(AppConfig.Config.Language);
Debug.Log($"LocalizationManager: LoadDefaultLocalizationData success: {success}");
if (!Application.isEditor && Application.platform == RuntimePlatform.WindowsPlayer)
{
//창 설정
if (AppConfig.Config.Window != null)
{
WindowTools.Instance.Init(AppConfig.Config.Window);
}
}
Constants.API_DOMAIN = AppConfig.Config.Api;
Constants.MQTT_DOMAIN = AppConfig.Config.Mqtt.Domain;
Constants.MQTT_PORT = AppConfig.Config.Mqtt.Port;
Constants.MQTT_DATA_KEY = AppConfig.Config.Mqtt.DataKey;
Constants.MQTT_MESSAGEPACK_ENABLED = AppConfig.Config.Mqtt.MessagePack;
}
//사용자 DataMask 설정 AppData에서 로드
await UserSetting.LoadFromAppData();
}
private void SetNetworkConfig()
{
URLList.Add("baseinfo", $"{Constants.API_DOMAIN}/baseinfo");
URLList.Add("playbackList", $"{Constants.API_DOMAIN}/playback/list");
URLList.Add("playbackFile", $"{Constants.API_DOMAIN}/playback");
//DataRepository.Instance.MqttReceiver.SetDomainPort("mqtt-input.flexing.ai", 3000);//VTM 외부망
//DataRepository.Instance.MqttReceiver.SetDomainPort("localhost", 1883);
DataRepository.Instance.MqttReceiver.SetDataPicker(new MqttDataPicker(Constants.MQTT_DATA_KEY, Constants.MQTT_MESSAGEPACK_ENABLED));
DataRepository.Instance.MqttReceiver.SetDomainPort(Constants.MQTT_DOMAIN, Constants.MQTT_PORT);
//DataRepository.Instance.MqttReceiver.AddTopic("AGV");
//DataRepository.Instance.MqttReceiver.AddTopic("ALARM");
//DataRepository.Instance.MqttReceiver.AddTopic("PORT");
//DataRepository.Instance.MqttReceiver.AddTopic("AGV_RECIPE");
//10초 후 정지
//UniTask.Delay(TimeSpan.FromSeconds(10)).ContinueWith(() =>
//{
// DataRepository.Instance.MqttReceiver.Exit();
//});
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: aae876b328d7f5c4f9342a8390ed92d6

View File

@@ -0,0 +1,227 @@
using Cysharp.Threading.Tasks;
using System;
using System.Collections.Generic;
using UnityEngine;
using UVC.Core;
using UVC.UI.Commands;
using UVC.UI.Menu;
using UVC.UI.Tooltip;
using UVC.UI.Window.PropertyWindow;
namespace Simulator
{
[DefaultExecutionOrder(90)]
public class SimulatorSceneMain : SingletonScene<SimulatorSceneMain>
{
[SerializeField]
private TopMenuController GNB;
public Action Initialized;
/// <summary>
/// 초기 화 메서드입니다.
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
/// </summary>
protected override void Init()
{
if (!TooltipManager.Instance.IsInitialized) TooltipManager.Instance.Initialize();
SimulatorAppMain.Instance.Initialized += OnAppInitialized;
}
private async void OnAppInitialized()
{
await requestDataAsync();
SetupLNB();
SetupPropertyWindow();
if (Initialized != null)
{
Initialized.Invoke();
}
}
private async UniTask requestDataAsync()
{
Debug.Log("requestDataAsync");
//UILoading.Show();
//UILoading.Hide();
}
private void SetupLNB()
{
if (GNB == null)
{
Debug.LogError("SideMenuController is not assigned in SceneMain.");
return;
}
GNB.AddMenuItem(new MenuItemData("menu", "menu", new DebugLogCommand("[SampleProject] 프로젝트 설정 선택됨"), subMenuItems: new List<MenuItemData>
{
new MenuItemData("simulation", "시뮬레이션", subMenuItems: new List<MenuItemData>
{
new MenuItemData("simulation_create", "시뮬레이션 생성", new DebugLogCommand("시뮬레이션 생성")),
new MenuItemData("simulation_open", "시뮬레이션 열기", new DebugLogCommand("시뮬레이션 열기")),
new MenuItemData("simulation_save", "시뮬레이션 저장", new DebugLogCommand("시뮬레이션 저장")),
new MenuItemData("simulation_save_as", "시뮬레이션 복제", new DebugLogCommand("시뮬레이션 복제")),
new MenuItemData("simulation_delete", "시뮬레이션 삭제", new DebugLogCommand("시뮬레이션 삭제")),
new MenuItemData("simulation_history", "시뮬레이션 이력", new DebugLogCommand("시뮬레이션 이력"))
}),
new MenuItemData("scenario", "시나리오", subMenuItems: new List<MenuItemData>
{
new MenuItemData("scenario_create", "시나리오 생성", new DebugLogCommand("시나리오 생성")),
new MenuItemData("scenario_run", "시나리오 실행", new DebugLogCommand("시나리오 실행")),
new MenuItemData("scenario_save_as", "시나리오 복제", new DebugLogCommand("시나리오 복제")),
new MenuItemData("scenario_delete", "시나리오 삭제", new DebugLogCommand("시나리오 삭제")),
new MenuItemData("scenario_history", "시나리오 이력", new DebugLogCommand("시나리오 이력"))
}),
new MenuItemData("scenario", "WHAT-IF 분석", subMenuItems: new List<MenuItemData>
{
new MenuItemData("whatif_create", "WHAT-IF 생성", new DebugLogCommand("WHAT-IF 생성")),
new MenuItemData("whatif_run", "WHAT-IF 실행", new DebugLogCommand("WHAT-IF 실행")),
new MenuItemData("whatif_save_as", "WHAT-IF 복제", new DebugLogCommand("WHAT-IF 복제")),
new MenuItemData("whatif_delete", "WHAT-IF 삭제", new DebugLogCommand("WHAT-IF 삭제")),
new MenuItemData("whatif_history", "WHAT-IF 이력", new DebugLogCommand("WHAT-IF 이력"))
}),
new MenuItemData("visible", "보기", subMenuItems: new List<MenuItemData>
{
new MenuItemData("explorer_window", "탐색창", new ActionCommand(()=> Debug.Log("탐색창"))),
new MenuItemData("property_window", "속성창", new ActionCommand(()=> {
if(PropertyWindow.Instance.IsVisible) PropertyWindow.Instance.Hide();
else PropertyWindow.Instance.Show();
})),
}),
new MenuItemData("help", "도움말", subMenuItems: new List<MenuItemData>
{
new MenuItemData("guide", "가이드", new ActionCommand(()=> Debug.Log("가이드"))),
}),
}));
GNB.Initialize();
}
private void SetupPropertyWindow()
{
PropertyWindow.Instance.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 = true
},
new Vector2Property("prop6_vec2", "Vector2 Property", new Vector2(1, 2))
{
Description = "This is a sample Vector2 property.",
Tooltip = "Enter a Vector2 value here.",
IsReadOnly = true
},
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 = true
},
new DateProperty("prop6_date", "Date Property", System.DateTime.Now)
{
//Description = "This is a sample date property.",
Tooltip = "Select a date here.",
IsReadOnly = true
},
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 = true
},
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 = true
},
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 = true
},
new EnumProperty("prop6", "Enum Property", SampleEnum.Option1)
{
Description = "This is a sample enum property.",
Tooltip = "Select an option here.",
IsReadOnly = true
},
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 = true
},
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 = true
}
});
PropertyWindow.Instance.PropertyValueChanged += (sender, e) =>
{
Debug.Log($"Property Id:{e.PropertyId}, type:{e.PropertyType}, newValue: {e.NewValue}");
};
}
enum SampleEnum
{
Option1,
Option2,
Option3
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 91bba3e317b9f294f9a4efd9ab20a32f

View File

@@ -5,6 +5,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using UVC.Data.Core;
using UVC.Data.Http;
using UVC.Data.Mqtt;

View File

@@ -9,6 +9,9 @@ using UVC.UI.Tab;
namespace UVC.Factory.Modal.Settings
{
/// <summary>
/// 객체 속성 순서 및 표시 설정 탭 콘텐츠
/// </summary>
public class DisplayDataOrderTabContent : MonoBehaviour, ITabContent
{
@@ -33,6 +36,7 @@ namespace UVC.Factory.Modal.Settings
public void SetContentData(object? data)
{
Debug.Log($"DisplayDataOrderTabContent.SetContentData: {data}");
if (data is string key)
{
this.key = key;
@@ -115,6 +119,7 @@ namespace UVC.Factory.Modal.Settings
/// <param name="data">전달할 데이터 객체</param>
public void UpdateContentData(object? data)
{
Debug.Log($"DisplayDataOrderTabContent.UpdateContentData: {data}");
}
/// <summary>

View File

@@ -19,14 +19,17 @@ namespace UVC.Factory.Modal.Settings
/// <param name="data">전달할 데이터 객체</param>
public void SetContentData(object? data)
{
Debug.Log($"SetContentData: {data}");
if (tabController != null)
{
var dic = DataMask.DataMasks;
foreach (var item in dic)
//mask 설정을 않한 경우 데이터를 보여줄 수 없음 -> DataRepository에서 가져와서 처리
var keys = DataRepository.Instance.GetAllKeys();// DataMask.DataMasks;
foreach (var item in keys)
{
Debug.Log($"Key: {item.Key}, Value: {item.Value}");
Debug.Log($"Key: {item}, Value: {item}");
// 1. TabConfig 설정
tabController.AddTabConfig(item.Key, item.Key, "Prefabs/UI/Modal/Setting/DisplayDataOrderTabContent", "", item.Key, true);
tabController.AddTabConfig(item, item, "Prefabs/UI/Modal/Setting/DisplayDataOrderTabContent", "", item, true);
}
// 2. 컨트롤러 초기화

View File

@@ -30,10 +30,10 @@ namespace UVC.Factory.Modal.Settings
private void SetupTabs(ModalContent content)
{
// 1. TabConfig 설정
tabController?.AddTabConfig("GeneralInfo", "일반 정보", "Prefabs/UI/Modal/Setting/GeneralInfoTabContent", "Prefabs/UI/images/icon_info", null, true);
tabController?.AddTabConfig("DisplaySetting", "표시 설정", "Prefabs/UI/Modal/Setting/DisplaySettingTabContent", "Prefabs/UI/images/icon_eye", null, true);
tabController?.AddTabConfig("AlarmSetting", "알람 설정", "Prefabs/UI/Modal/Setting/AlarmSettingTabContent", "Prefabs/UI/images/icon_alarm", null, true);
tabController?.AddTabConfig("InputSetting", "입력 설정", "Prefabs/UI/Modal/Setting/InputSettingTabContent", "Prefabs/UI/images/icon_mouse", null, true);
tabController?.AddTabConfig("GeneralInfo", "일반 정보", "Prefabs/UI/Modal/Setting/GeneralInfoTabContent", "Prefabs/UI/Images/icon_info", null, true);
tabController?.AddTabConfig("DisplaySetting", "표시 설정", "Prefabs/UI/Modal/Setting/DisplaySettingTabContent", "Prefabs/UI/Images/icon_eye", null, true);
tabController?.AddTabConfig("AlarmSetting", "알람 설정", "Prefabs/UI/Modal/Setting/AlarmSettingTabContent", "Prefabs/UI/Images/icon_alarm", null, true);
tabController?.AddTabConfig("InputSetting", "입력 설정", "Prefabs/UI/Modal/Setting/InputSettingTabContent", "Prefabs/UI/Images/icon_mouse", null, true);
// 2. 컨트롤러 초기화
tabController?.Initialize();

View File

@@ -26,10 +26,10 @@ namespace UVC.Factory.Tab
public void Start()
{
// 1. TabConfig 설정
tabController?.AddTabConfig("Explorer", "탐색기", "Prefabs/UI/Tab/TabContentTabComponentList", "Prefabs/UI/images/icon_side_tab_explorer_128", "탐색기", true);
tabController?.AddTabConfig("Library", "라이브러리", "Prefabs/UI/Tab/TabContentPrefabGrid", "Prefabs/UI/images/icon_side_tab_library_128", "라이브러리", true);
tabController?.AddTabConfig("ResourceExplorer", "자원 탐색기", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/images/icon_side_tab_resource_128", "자원 탐색기", true);
tabController?.AddTabConfig("FleetManager", "이동기 관리", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/images/icon_side_tab_fleet_128", "이동기 관리", true);
tabController?.AddTabConfig("Explorer", "탐색기", "Prefabs/UI/Tab/TabContentTabComponentList", "Prefabs/UI/Images/icon_side_tab_explorer_128", "탐색기", true);
tabController?.AddTabConfig("Library", "라이브러리", "Prefabs/UI/Tab/TabContentPrefabGrid", "Prefabs/UI/Images/icon_side_tab_library_128", "라이브러리", true);
tabController?.AddTabConfig("ResourceExplorer", "자원 탐색기", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/Images/icon_side_tab_resource_128", "자원 탐색기", true);
tabController?.AddTabConfig("FleetManager", "이동기 관리", "Prefabs/UI/Tab/TabContentSample", "Prefabs/UI/Images/icon_side_tab_fleet_128", "이동기 관리", true);
// 2. 컨트롤러 초기화
tabController?.Initialize();

View File

@@ -29,13 +29,13 @@ namespace UVC.UI.Modal
/// 🏷️ 모달 창의 제목이에요. 여기에 글자를 적으면 모달 창 맨 위에 크게 보여요.
/// 예: "알림", "게임 저장", "친구 요청"
/// </summary>
public string Title { get; set; }
public string Title { get; set; } = "";
/// <summary>
/// 💬 모달 창에 보여줄 주요 메시지 내용이에요. 사용자에게 전달하고 싶은 말을 여기에 적어요.
/// 예: "게임 설정을 저장했습니다.", "정말로 아이템을 구매하시겠어요?"
/// </summary>
public string Message { get; set; }
public string Message { get; set; } = "";
private string _confirmButtonText = "확인";
/// <summary>

View File

@@ -91,10 +91,7 @@ namespace UVC.UI.Window.PropertyWindow
public bool IsVisible()
{
return gameObject.activeSelf;
}
public bool IsVisible => gameObject.activeSelf;
public void Show()
{