사용자 정보 표시 관리 팝업 완료
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
|
using Cysharp.Threading.Tasks;
|
||||||
using SampleProject.Config;
|
using SampleProject.Config;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UVC.Core;
|
using UVC.Core;
|
||||||
using UVC.Data;
|
using UVC.Data;
|
||||||
@@ -20,9 +22,9 @@ namespace SampleProject
|
|||||||
/// 초기 화 메서드입니다.
|
/// 초기 화 메서드입니다.
|
||||||
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
|
/// Awake 메서드에서 호출되며, MonoBehaviour가 생성될 때 한 번만 실행됩니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected override void Init()
|
protected override async void Init()
|
||||||
{
|
{
|
||||||
SettupConfig();
|
await SettupConfigAsync();
|
||||||
SetNetworkConfig();
|
SetNetworkConfig();
|
||||||
if (Initialized != null)
|
if (Initialized != null)
|
||||||
{
|
{
|
||||||
@@ -35,7 +37,7 @@ namespace SampleProject
|
|||||||
//Tester.RunAllTests();
|
//Tester.RunAllTests();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SettupConfig()
|
private async UniTask SettupConfigAsync()
|
||||||
{
|
{
|
||||||
if (AppConfig.LoadConfig())
|
if (AppConfig.LoadConfig())
|
||||||
{
|
{
|
||||||
@@ -53,6 +55,10 @@ namespace SampleProject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//사용자 DataMask 설정 AppData에서 로드
|
||||||
|
await DataMask.LoadUserMasksFromAppData();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetNetworkConfig()
|
private void SetNetworkConfig()
|
||||||
@@ -82,7 +88,7 @@ namespace SampleProject
|
|||||||
agvDataMask["JOB_ID"] = "";
|
agvDataMask["JOB_ID"] = "";
|
||||||
agvDataMask["TIMESTAMP"] = DateTime.Now;
|
agvDataMask["TIMESTAMP"] = DateTime.Now;
|
||||||
|
|
||||||
DataMask.AddMask("AGV", agvDataMask);
|
DataMask.AddMask("AGV", agvDataMask, true);
|
||||||
|
|
||||||
DataMapperValidator.Add("AGV", new DataMapperValidator(
|
DataMapperValidator.Add("AGV", new DataMapperValidator(
|
||||||
new DataMapper(agvDataMask)
|
new DataMapper(agvDataMask)
|
||||||
@@ -91,7 +97,7 @@ namespace SampleProject
|
|||||||
// 데이터 마스크(DataMask) 정의:
|
// 데이터 마스크(DataMask) 정의:
|
||||||
// 수신할 데이터의 구조를 미리 정의합니다. 여기서 정의된 키(Key)들을 기준으로 데이터를 파싱합니다.
|
// 수신할 데이터의 구조를 미리 정의합니다. 여기서 정의된 키(Key)들을 기준으로 데이터를 파싱합니다.
|
||||||
var alarmDataMask = new DataMask();
|
var alarmDataMask = new DataMask();
|
||||||
alarmDataMask.ObjectName = "Alarm"; // Alarm 객체의 이름을 설정합니다.
|
alarmDataMask.ObjectName = "ALARM"; // Alarm 객체의 이름을 설정합니다.
|
||||||
alarmDataMask.ObjectIdKey = "ID"; // Alarm의 고유 식별자로 사용할 키를 설정합니다.
|
alarmDataMask.ObjectIdKey = "ID"; // Alarm의 고유 식별자로 사용할 키를 설정합니다.
|
||||||
alarmDataMask["ID"] = "";
|
alarmDataMask["ID"] = "";
|
||||||
alarmDataMask["ALARM_TYPE"] = "";
|
alarmDataMask["ALARM_TYPE"] = "";
|
||||||
@@ -112,7 +118,7 @@ namespace SampleProject
|
|||||||
alarmDataMask["UPDATE_TIME"] = DateTime.Now;
|
alarmDataMask["UPDATE_TIME"] = DateTime.Now;
|
||||||
alarmDataMask["TIMESTAMP"] = DateTime.Now;
|
alarmDataMask["TIMESTAMP"] = DateTime.Now;
|
||||||
|
|
||||||
DataMask.AddMask("ALARM", alarmDataMask);
|
DataMask.AddMask("ALARM", alarmDataMask, true);
|
||||||
|
|
||||||
// 데이터 유효성 검사기(DataValidator) 설정:
|
// 데이터 유효성 검사기(DataValidator) 설정:
|
||||||
// 수신된 데이터가 유효한지 검사하는 규칙을 추가합니다.
|
// 수신된 데이터가 유효한지 검사하는 규칙을 추가합니다.
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
using Cysharp.Threading.Tasks;
|
using Cysharp.Threading.Tasks;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UVC.Core;
|
using UVC.Core;
|
||||||
using UVC.Data;
|
using UVC.Data;
|
||||||
using UVC.Data.Core;
|
|
||||||
using UVC.Data.Http;
|
|
||||||
using UVC.Factory;
|
using UVC.Factory;
|
||||||
using UVC.Factory.Alarm;
|
using UVC.Factory.Alarm;
|
||||||
using UVC.Factory.Component;
|
using UVC.Factory.Component;
|
||||||
@@ -31,8 +28,6 @@ namespace SampleProject
|
|||||||
AppMain.Instance.Initialized += OnAppInitialized;
|
AppMain.Instance.Initialized += OnAppInitialized;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private async void OnAppInitialized()
|
private async void OnAppInitialized()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -62,7 +57,7 @@ namespace SampleProject
|
|||||||
FactoryCameraController.Instance.Enable = true;
|
FactoryCameraController.Instance.Enable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task requestDataAsync()
|
private async UniTask requestDataAsync()
|
||||||
{
|
{
|
||||||
|
|
||||||
Debug.Log("requestDataAsync");
|
Debug.Log("requestDataAsync");
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
|
||||||
|
using Cysharp.Threading.Tasks;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using UnityEngine;
|
||||||
using UVC.Extention;
|
using UVC.Extention;
|
||||||
|
|
||||||
namespace UVC.Data.Core
|
namespace UVC.Data.Core
|
||||||
@@ -17,6 +21,8 @@ namespace UVC.Data.Core
|
|||||||
/// DataMask는 주로 DataMapper 클래스와 함께 사용되어 서로 다른 JSON 형식 간의
|
/// DataMask는 주로 DataMapper 클래스와 함께 사용되어 서로 다른 JSON 형식 간의
|
||||||
/// 데이터 변환 및 매핑 규칙을 정의합니다. 기본 JSON 구조 외에도 추가 속성들을
|
/// 데이터 변환 및 매핑 규칙을 정의합니다. 기본 JSON 구조 외에도 추가 속성들을
|
||||||
/// 통해 매핑 과정에서 필요한 메타데이터를 제공합니다.
|
/// 통해 매핑 과정에서 필요한 메타데이터를 제공합니다.
|
||||||
|
/// 또한 AppData 폴더(AppData/Company Name/Product Name)에서 JSON 파일을 로드하고 저장하는 기능을 제공하여,
|
||||||
|
/// 그 기능은 FactoryObject의 정보를 InfoWindow로 보여줄때 사용됩니다.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// 기본 사용 예시:
|
/// 기본 사용 예시:
|
||||||
@@ -58,6 +64,10 @@ namespace UVC.Data.Core
|
|||||||
private static Dictionary<string, DataMask> _dataMasks = new Dictionary<string, DataMask>();
|
private static Dictionary<string, DataMask> _dataMasks = new Dictionary<string, DataMask>();
|
||||||
public static IReadOnlyDictionary<string, DataMask> DataMasks => _dataMasks;
|
public static IReadOnlyDictionary<string, DataMask> DataMasks => _dataMasks;
|
||||||
|
|
||||||
|
// 사용자 데이터 마스크를 저장하는 컬렉션입니다.
|
||||||
|
private static Dictionary<string, DataMask> _userDataMasks = new Dictionary<string, DataMask>();
|
||||||
|
public static IReadOnlyDictionary<string, DataMask> UserDataMasks => _userDataMasks;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 컬렉션에 데이터 마스크를 추가하고 지정된 키와 연결합니다.
|
/// 컬렉션에 데이터 마스크를 추가하고 지정된 키와 연결합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -65,10 +75,16 @@ namespace UVC.Data.Core
|
|||||||
///</remarks>
|
///</remarks>
|
||||||
/// <param name="key">데이터 마스크에 연결할 키입니다. <see langword="null"/>이거나 비어 있을 수 없습니다.</param>
|
/// <param name="key">데이터 마스크에 연결할 키입니다. <see langword="null"/>이거나 비어 있을 수 없습니다.</param>
|
||||||
/// <param name="mask">추가할 <see cref="DataMask"/>입니다. <see langword="null"/>일 수 없습니다.</param>
|
/// <param name="mask">추가할 <see cref="DataMask"/>입니다. <see langword="null"/>일 수 없습니다.</param>
|
||||||
public static void AddMask(string key, DataMask mask)
|
/// <param name="withUser">사용자 데이터 마스크도 함께 추가할지 여부를 지정합니다. 기본값은 false입니다.</param>
|
||||||
|
public static void AddMask(string key, DataMask mask, bool withUser = false)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(key) || mask == null) return;
|
if (string.IsNullOrEmpty(key) || mask == null) return;
|
||||||
_dataMasks[key] = mask;
|
_dataMasks[key] = mask;
|
||||||
|
if (withUser && !_userDataMasks.ContainsKey(key))
|
||||||
|
{
|
||||||
|
// 사용자 데이터 마스크로 시작하는 키는 _userDataMasks에 추가
|
||||||
|
AddUserMask(key, mask.CreateUserMask());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -76,10 +92,16 @@ namespace UVC.Data.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks> <paramref name="key"/>가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다.</remarks>
|
/// <remarks> <paramref name="key"/>가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다.</remarks>
|
||||||
/// <param name="key">제거할 데이터 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다.</param>
|
/// <param name="key">제거할 데이터 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다.</param>
|
||||||
public static void RemoveMask(string key)
|
/// <param name="withUser">사용자 데이터 마스크도 함께 제거할지 여부를 지정합니다. 기본값은 false입니다.</param>
|
||||||
|
public static void RemoveMask(string key, bool withUser = false)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(key)) return;
|
if (string.IsNullOrEmpty(key)) return;
|
||||||
_dataMasks.Remove(key);
|
_dataMasks.Remove(key);
|
||||||
|
if(withUser)
|
||||||
|
{
|
||||||
|
// 사용자 데이터 마스크로 시작하는 키는 _userDataMasks에서 제거
|
||||||
|
RemoveUserMask(key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -95,7 +117,127 @@ namespace UVC.Data.Core
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 내부 컬렉션에서 모든 데이터 마스크를 지웁니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>이 메서드는 내부 데이터 마스크 컬렉션에서 모든 항목을 제거하고
|
||||||
|
/// 빈 상태로 재설정합니다. 이전에 추가된 모든 마스크를 지워야 할 때 이 메서드를 사용하세요.</remarks>
|
||||||
|
public static void ClearMask()
|
||||||
|
{
|
||||||
|
_dataMasks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 사용자 정의 키를 지정된 데이터 마스크에 연결합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>동일한 키를 가진 데이터 마스크가 이미 있는 경우 새
|
||||||
|
/// 마스크로 대체됩니다.</remarks>
|
||||||
|
/// <param name="key">데이터 마스크의 고유 식별자입니다. <see langword="null"/>이거나 비어 있을 수 없습니다.</param>
|
||||||
|
/// <param name="mask">지정된 키와 연결할 <see cref="DataMask"/> 객체입니다. <see langword="null"/>일 수 없습니다.</param>
|
||||||
|
public static void AddUserMask(string key, DataMask mask)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key) || mask == null) return;
|
||||||
|
_userDataMasks[key] = mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 지정된 키와 연관된 사용자 마스크를 제거합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks> <paramref name="key"/>가 null이거나 비어 있으면 메서드는 아무 작업도 수행하지 않습니다.
|
||||||
|
///</remarks>
|
||||||
|
/// <param name="key">제거할 사용자 마스크를 식별하는 키입니다. null이거나 비어 있으면 안 됩니다.</param>
|
||||||
|
public static void RemoveUserMask(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key)) return;
|
||||||
|
_userDataMasks.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 지정된 키와 연관된 <see cref="DataMask"/>를 검색합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">연관된 <see cref="DataMask"/>를 찾는 데 사용되는 키입니다. null이거나 비어 있을 수 없습니다.</param>
|
||||||
|
/// <returns>지정된 키와 연관된 <see cref="DataMask"/> 또는 키를 찾을 수 없거나 null이거나 비어 있는 경우 <see langword="null"/>을 반환합니다.
|
||||||
|
///</returns>
|
||||||
|
public static DataMask? GetUserMask(string key)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(key)) return null;
|
||||||
|
_userDataMasks.TryGetValue(key, out var mask);
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 내부 컬렉션에서 모든 사용자 데이터 마스크를 지웁니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>이 메서드는 사용자 데이터 마스크 컬렉션에서 모든 항목을 제거하고 빈 상태로 재설정합니다.
|
||||||
|
/// 일반적으로 새 마스크를 적용하기 전에 이전에 적용된 마스크를 지우는 데 사용됩니다.
|
||||||
|
///</remarks>
|
||||||
|
public static void ClearUserMask()
|
||||||
|
{
|
||||||
|
_userDataMasks.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 애플리케이션의 영구 데이터 디렉터리(AppData/Company Name/Product Name)에서 사용자 마스크 데이터를 로드합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>이 메서드는 애플리케이션의 영구 데이터 경로에 있는 "user" 하위 디렉터리에서 JSON 파일을 검색합니다.
|
||||||
|
/// 각 JSON 파일을 읽고 그 내용을 사용하여 <see cref="DataMask"/>
|
||||||
|
/// 객체를 생성한 후 애플리케이션의 사용자 마스크 컬렉션에 추가합니다. 이 메서드는 메인 스레드를 차단하지 않도록 백그라운드
|
||||||
|
/// 스레드에서 실행됩니다.</remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async UniTask LoadUserMasksFromAppData()
|
||||||
|
{
|
||||||
|
string persistentDataPath = UnityEngine.Application.persistentDataPath;
|
||||||
|
await UniTask.RunOnThreadPool(() =>
|
||||||
|
{
|
||||||
|
string folderPath = System.IO.Path.Combine(persistentDataPath, "user");
|
||||||
|
DirectoryInfo directory = new DirectoryInfo(folderPath);
|
||||||
|
if (!directory.Exists) return;
|
||||||
|
FileInfo[] files = directory.GetFiles("*.json");
|
||||||
|
foreach (FileInfo file in files)
|
||||||
|
{
|
||||||
|
string filePath = file.FullName;
|
||||||
|
string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath);
|
||||||
|
if (string.IsNullOrEmpty(fileName)) continue;
|
||||||
|
string jsonString = System.IO.File.ReadAllText(filePath);
|
||||||
|
AddUserMask(fileName, new DataMask(jsonString));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 사용자 데이터 마스크를 애플리케이션의 영구 데이터 경로(AppData/Company Name/Product Name)에 저장합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>이 메서드는 모든 사용자 데이터 마스크를 반복하며 각 마스크를 JSON 파일로 저장합니다.
|
||||||
|
/// 애플리케이션의 영구 데이터 경로에 있는 "user" 하위 디렉터리에 디렉터리가 없으면
|
||||||
|
/// 생성됩니다. 각 파일의 이름은 해당 키와 ".json" 확장자를 사용하여 지정됩니다. 저장 과정에서 발생하는 모든 오류는
|
||||||
|
/// Unity 콘솔에 기록됩니다.</remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async UniTask SaveUserMasksToAppData()
|
||||||
|
{
|
||||||
|
string persistentDataPath = UnityEngine.Application.persistentDataPath;
|
||||||
|
await UniTask.RunOnThreadPool(() =>
|
||||||
|
{
|
||||||
|
foreach (var keyValue in _userDataMasks)
|
||||||
|
{
|
||||||
|
string key = keyValue.Key;
|
||||||
|
if (string.IsNullOrEmpty(key)) continue;
|
||||||
|
if (!_userDataMasks.TryGetValue(key, out var mask)) return;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string folderPath = System.IO.Path.Combine(persistentDataPath, "user");
|
||||||
|
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
|
||||||
|
string filePath = System.IO.Path.Combine(folderPath, $"{key}.json");
|
||||||
|
string jsonString = mask.ToJsonString();
|
||||||
|
System.IO.File.WriteAllText(filePath, jsonString);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.LogError($"DataMask SaveToStreamingAssets Error: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// DataObject의 Id에 해당하는 key 문자열입니다.
|
/// DataObject의 Id에 해당하는 key 문자열입니다.
|
||||||
@@ -354,6 +496,23 @@ namespace UVC.Data.Core
|
|||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 현재 컬렉션의 각 키가 자기 자신에게 매핑되는 새로운 <see cref="DataMask"/> 인스턴스를 생성합니다.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>이 메서드는 현재 컬렉션을 반복하고 컬렉션의 각 키가 결과 마스크의 키와 값으로 모두 사용되는 새로운 <see
|
||||||
|
/// cref="DataMask"/>를 생성합니다.
|
||||||
|
///</remarks>
|
||||||
|
/// <returns>각 키가 자기 자신에게 매핑되는 키-값 쌍을 포함하는 <see cref="DataMask"/> 객체를 반환합니다.</returns>
|
||||||
|
public DataMask CreateUserMask()
|
||||||
|
{
|
||||||
|
DataMask userMask = new DataMask();
|
||||||
|
foreach (var pair in this)
|
||||||
|
{
|
||||||
|
userMask[pair.Key] = pair.Key;
|
||||||
|
}
|
||||||
|
return userMask;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Json 문자열로 변환합니다.
|
/// Json 문자열로 변환합니다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using TMPro;
|
#nullable enable
|
||||||
|
using TMPro;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.UI;
|
using UnityEngine.UI;
|
||||||
using UVC.Data.Core;
|
using UVC.Data.Core;
|
||||||
@@ -36,12 +37,24 @@ namespace UVC.Factory.Alarm
|
|||||||
public void Show(DataObject data)
|
public void Show(DataObject data)
|
||||||
{
|
{
|
||||||
string combinedString = string.Empty;
|
string combinedString = string.Empty;
|
||||||
|
|
||||||
combinedString += $"ALARM_TYPE<indent=40%>{data.GetString("ALARM_TYPE") ?? "null"}</indent>\n";
|
DataMask? userMask = DataMask.GetUserMask("UserALARM");
|
||||||
combinedString += $"CODE<indent=40%>{data.GetString("CODE") ?? "null"}</indent>\n";
|
if (userMask != null)
|
||||||
combinedString += $"MACHINENAME<indent=40%>{data.GetString("MACHINENAME") ?? "null"}</indent>\n";
|
{
|
||||||
combinedString += $"MESSAGE<indent=40%>{data.GetString("MESSAGE") ?? "null"}</indent>\n";
|
foreach (var item in userMask)
|
||||||
combinedString += $"TIMESTAMP<indent=40%>{data.GetString("TIMESTAMP") ?? "null"}</indent>\n";
|
{
|
||||||
|
// DataObject에서 해당 키의 값을 가져와서 표시합니다.
|
||||||
|
combinedString += $"{item.Key}<indent=40%>{data.GetString(item.Key) ?? "null"}</indent>\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
combinedString += $"ALARM_TYPE<indent=40%>{data.GetString("ALARM_TYPE") ?? "null"}</indent>\n";
|
||||||
|
combinedString += $"CODE<indent=40%>{data.GetString("CODE") ?? "null"}</indent>\n";
|
||||||
|
combinedString += $"MACHINENAME<indent=40%>{data.GetString("MACHINENAME") ?? "null"}</indent>\n";
|
||||||
|
combinedString += $"MESSAGE<indent=40%>{data.GetString("MESSAGE") ?? "null"}</indent>\n";
|
||||||
|
combinedString += $"TIMESTAMP<indent=40%>{data.GetString("TIMESTAMP") ?? "null"}</indent>\n";
|
||||||
|
}
|
||||||
|
|
||||||
combinedString = combinedString.TrimEnd('\n'); // 마지막 줄바꿈 제거
|
combinedString = combinedString.TrimEnd('\n'); // 마지막 줄바꿈 제거
|
||||||
detailTxt.text = combinedString;
|
detailTxt.text = combinedString;
|
||||||
|
|||||||
@@ -72,8 +72,8 @@ namespace UVC.Factory.Component
|
|||||||
|
|
||||||
public override void OnPointerClick(PointerEventData eventData)
|
public override void OnPointerClick(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
// 사용자가 AGV를 클릭했을 때 정보창에 표시될 데이터 항목과 순서를 정의합니다.
|
// 사용자가 AGV를 클릭했을 때 정보창에 표시될 데이터 항목과 순서를 정의합니다. User+TOPIC 이름
|
||||||
DataOrderedMask = DataMask.Get("ConfigAGV");
|
if(dataOrderedMask == null) dataOrderedMask = DataMask.GetUserMask("AGV");
|
||||||
base.OnPointerClick(eventData);
|
base.OnPointerClick(eventData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ namespace UVC.Factory.Modal.Config
|
|||||||
var dic = DataMask.DataMasks;
|
var dic = DataMask.DataMasks;
|
||||||
foreach (var item in dic)
|
foreach (var item in dic)
|
||||||
{
|
{
|
||||||
|
if(item.Key.StartsWith("User")) continue; // "User"로 시작하지 않는 키만 처리합니다.
|
||||||
Debug.Log($"Key: {item.Key}, Value: {item.Value}");
|
Debug.Log($"Key: {item.Key}, Value: {item.Value}");
|
||||||
// 1. TabConfig 설정
|
// 1. TabConfig 설정
|
||||||
tabController.AddTabConfig(item.Key, item.Key, "Prefabs/UI/Tab/ConfigDataOrderTabContent", null, item.Key, true);
|
tabController.AddTabConfig(item.Key, item.Key, "Prefabs/UI/Tab/ConfigDataOrderTabContent", null, item.Key, true);
|
||||||
@@ -49,7 +50,7 @@ namespace UVC.Factory.Modal.Config
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public override async UniTask OnClose(ModalContent content)
|
public override async UniTask OnClose(ModalContent content)
|
||||||
{
|
{
|
||||||
|
await DataMask.SaveUserMasksToAppData(); // 데이터 마스크를 앱 데이터에 저장합니다.
|
||||||
await base.OnClose(content);
|
await base.OnClose(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEditor.Rendering.LookDev;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UVC.Data.Core;
|
using UVC.Data.Core;
|
||||||
|
using UVC.Extention;
|
||||||
using UVC.UI.List.Draggable;
|
using UVC.UI.List.Draggable;
|
||||||
using UVC.UI.Tab;
|
using UVC.UI.Tab;
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ namespace UVC.Factory.Modal.Config
|
|||||||
private DraggableList? draggableList;
|
private DraggableList? draggableList;
|
||||||
|
|
||||||
private string key = string.Empty;
|
private string key = string.Empty;
|
||||||
private string configKey = string.Empty;
|
|
||||||
|
|
||||||
private DataMask? totalData = null;
|
private DataMask? totalData = null;
|
||||||
private DataMask? viewData = null;
|
private DataMask? viewData = null;
|
||||||
@@ -36,18 +35,15 @@ namespace UVC.Factory.Modal.Config
|
|||||||
if (data is string key)
|
if (data is string key)
|
||||||
{
|
{
|
||||||
this.key = key;
|
this.key = key;
|
||||||
configKey = $"Config{key}";
|
totalData = DataMask.Get(key);
|
||||||
DataMask? mask = DataMask.Get(key);
|
|
||||||
if (mask != null) totalData = mask;
|
|
||||||
|
|
||||||
viewData = DataMask.Get(configKey);
|
|
||||||
if (totalData != null)
|
if (totalData != null)
|
||||||
{
|
{
|
||||||
|
viewData = DataMask.GetUserMask(key);
|
||||||
//저장 되 있는 데이터가 없으면 전체 아이템을 체크된 상태로 추가
|
//저장 되 있는 데이터가 없으면 전체 아이템을 체크된 상태로 추가
|
||||||
if (viewData == null)
|
if (viewData == null)
|
||||||
{
|
{
|
||||||
viewData = totalData.DeepClone();
|
viewData = totalData.CreateUserMask();
|
||||||
DataMask.AddMask(configKey, viewData);
|
DataMask.AddUserMask(key, viewData);
|
||||||
}
|
}
|
||||||
List<ConfigDataOrderListItemData> dataList = new List<ConfigDataOrderListItemData>();
|
List<ConfigDataOrderListItemData> dataList = new List<ConfigDataOrderListItemData>();
|
||||||
|
|
||||||
@@ -55,7 +51,7 @@ namespace UVC.Factory.Modal.Config
|
|||||||
foreach (var item in totalData)
|
foreach (var item in totalData)
|
||||||
{
|
{
|
||||||
bool isChecked = viewData!.ContainsKey(item.Key);
|
bool isChecked = viewData!.ContainsKey(item.Key);
|
||||||
dataList.Add(new ConfigDataOrderListItemData(item.Key, item.Key, isChecked));
|
dataList.Add(new ConfigDataOrderListItemData(item.Key, (isChecked ? viewData[item.Key].ToString() : item.Key), isChecked));
|
||||||
}
|
}
|
||||||
//드래그 가능한 리스트에 데이터 설정
|
//드래그 가능한 리스트에 데이터 설정
|
||||||
draggableList?.SetData<ConfigDataOrderListItemData>(dataList);
|
draggableList?.SetData<ConfigDataOrderListItemData>(dataList);
|
||||||
@@ -76,9 +72,10 @@ namespace UVC.Factory.Modal.Config
|
|||||||
|
|
||||||
private void UpdateData()
|
private void UpdateData()
|
||||||
{
|
{
|
||||||
Debug.Log($"UpdateData: draggableList != null:{draggableList != null}, viewData != null:{viewData != null}, configKey:{configKey}");
|
Debug.Log($"UpdateData: draggableList != null:{draggableList != null}, viewData != null:{viewData != null}, configKey:{key}");
|
||||||
if (draggableList != null && viewData != null && configKey.Length > 0)
|
if (draggableList != null && viewData != null && key.Length > 0)
|
||||||
{
|
{
|
||||||
|
viewData.Clear();
|
||||||
foreach (var item in draggableList.DataList)
|
foreach (var item in draggableList.DataList)
|
||||||
{
|
{
|
||||||
if (item is ConfigDataOrderListItemData listItemData)
|
if (item is ConfigDataOrderListItemData listItemData)
|
||||||
@@ -87,14 +84,10 @@ namespace UVC.Factory.Modal.Config
|
|||||||
{
|
{
|
||||||
viewData[listItemData.Id] = listItemData.DisplayName;
|
viewData[listItemData.Id] = listItemData.DisplayName;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
viewData.Remove(listItemData.Id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Debug.Log($"UpdateData: {configKey} - {viewData.ToJsonString()} items");
|
Debug.Log($"UpdateData: {key} - {viewData.ToJsonString()} items");
|
||||||
DataMask.AddMask(configKey, viewData);
|
DataMask.AddUserMask(key, viewData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ namespace UVC.Factory.Playback
|
|||||||
/// await PlaybackService.Instance.StartAsync(itemData);
|
/// await PlaybackService.Instance.StartAsync(itemData);
|
||||||
/// </code>
|
/// </code>
|
||||||
/// </example>
|
/// </example>
|
||||||
public async Task StartAsync(UIPlaybackListItemData data)
|
public async UniTask StartAsync(UIPlaybackListItemData data)
|
||||||
{
|
{
|
||||||
timeScale = 1.0f; //기본 시간 스케일 설정
|
timeScale = 1.0f; //기본 시간 스케일 설정
|
||||||
UIPlayback.Instance.Show();
|
UIPlayback.Instance.Show();
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
// 구독자들에게 드래그 종료를 알립니다
|
// 구독자들에게 드래그 종료를 알립니다
|
||||||
OnDragEnded?.Invoke(eventData);
|
OnDragEnded?.Invoke(eventData);
|
||||||
|
|
||||||
Debug.Log($"[DragBehavior] 드래그 종료 - 아이템: {dragTarget.name}");
|
//Debug.Log($"[DragBehavior] 드래그 종료 - 아이템: {dragTarget.name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -135,7 +135,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
originalIndex = dragTarget.GetSiblingIndex();
|
originalIndex = dragTarget.GetSiblingIndex();
|
||||||
originalPosition = dragTarget.position;
|
originalPosition = dragTarget.position;
|
||||||
|
|
||||||
Debug.Log($"[DragBehavior] 위치 정보 업데이트 - 새 인덱스: {originalIndex}");
|
//Debug.Log($"[DragBehavior] 위치 정보 업데이트 - 새 인덱스: {originalIndex}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
if (reorderHandler == null)
|
if (reorderHandler == null)
|
||||||
{
|
{
|
||||||
reorderHandler = content.gameObject.AddComponent<ListReorderHandler>();
|
reorderHandler = content.gameObject.AddComponent<ListReorderHandler>();
|
||||||
Debug.Log("[DraggableList] ListReorderHandler를 자동으로 추가했습니다.");
|
//Debug.Log("[DraggableList] ListReorderHandler를 자동으로 추가했습니다.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScrollRectHandler 추가 또는 가져오기
|
// ScrollRectHandler 추가 또는 가져오기
|
||||||
@@ -152,7 +152,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
if (scrollHandler == null)
|
if (scrollHandler == null)
|
||||||
{
|
{
|
||||||
scrollHandler = scrollRect.gameObject.AddComponent<ScrollRectHandler>();
|
scrollHandler = scrollRect.gameObject.AddComponent<ScrollRectHandler>();
|
||||||
Debug.Log("[DraggableList] ScrollRectHandler를 자동으로 추가했습니다.");
|
//Debug.Log("[DraggableList] ScrollRectHandler를 자동으로 추가했습니다.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -249,6 +249,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
var item = dataList[oldIndex];
|
var item = dataList[oldIndex];
|
||||||
dataList.RemoveAt(oldIndex);
|
dataList.RemoveAt(oldIndex);
|
||||||
dataList.Insert(newIndex, item);
|
dataList.Insert(newIndex, item);
|
||||||
|
Debug.Log($"[DraggableList] 순서 변경: {oldIndex} -> {newIndex}");
|
||||||
|
|
||||||
// 이벤트 발생
|
// 이벤트 발생
|
||||||
OnOrderChanged?.Invoke((item as ListItemData)!, oldIndex, newIndex);
|
OnOrderChanged?.Invoke((item as ListItemData)!, oldIndex, newIndex);
|
||||||
@@ -259,7 +260,6 @@ namespace UVC.UI.List.Draggable
|
|||||||
// SaveOrder();
|
// SaveOrder();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
Debug.Log($"[DraggableList] 순서 변경: {oldIndex} -> {newIndex}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
private void HandleItemClick(object data)
|
private void HandleItemClick(object data)
|
||||||
{
|
{
|
||||||
OnItemClicked?.Invoke((data as ListItemData)!);
|
OnItemClicked?.Invoke((data as ListItemData)!);
|
||||||
Debug.Log($"[DraggableList] 아이템 클릭: {(data as ListItemData)?.DisplayName}");
|
//Debug.Log($"[DraggableList] 아이템 클릭: {(data as ListItemData)?.DisplayName}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void HandleDragEnd(PointerEventData eventData)
|
private void HandleDragEnd(PointerEventData eventData)
|
||||||
{
|
{
|
||||||
Debug.Log($"[ListItemController] 드래그 종료 처리 - {gameObject.name}");
|
//Debug.Log($"[ListItemController] 드래그 종료 처리 - {gameObject.name}");
|
||||||
|
|
||||||
// 1. 아이템을 원래 투명도로 복원합니다
|
// 1. 아이템을 원래 투명도로 복원합니다
|
||||||
if (canvasGroup != null)
|
if (canvasGroup != null)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
boundData = data;
|
boundData = data;
|
||||||
UpdateUI();
|
UpdateUI();
|
||||||
|
|
||||||
Debug.Log($"[ListItemView] 데이터 바인딩 완료 - {gameObject.name}");
|
//Debug.Log($"[ListItemView] 데이터 바인딩 완료 - {gameObject.name}");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
|
|
||||||
// 마우스 위치에서 가장 가까운 인덱스를 계산합니다
|
// 마우스 위치에서 가장 가까운 인덱스를 계산합니다
|
||||||
int targetIndex = CalculateTargetIndex(position);
|
int targetIndex = CalculateTargetIndex(position);
|
||||||
Debug.Log($"[ListReorderHandler] 드래그 위치 업데이트 - 타겟 인덱스: {targetIndex}");
|
//Debug.Log($"[ListReorderHandler] 드래그 위치 업데이트 - 타겟 인덱스: {targetIndex}");
|
||||||
if (targetIndex >= 0)
|
if (targetIndex >= 0)
|
||||||
{
|
{
|
||||||
// 현재 플레이스홀더의 인덱스와 다를 때만 이동
|
// 현재 플레이스홀더의 인덱스와 다를 때만 이동
|
||||||
@@ -116,7 +116,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
if (item.OriginalIndex != newIndex)
|
if (item.OriginalIndex != newIndex)
|
||||||
{
|
{
|
||||||
OnOrderChanged?.Invoke(item.OriginalIndex, newIndex);
|
OnOrderChanged?.Invoke(item.OriginalIndex, newIndex);
|
||||||
Debug.Log($"[ListReorderHandler] 순서 변경됨: {item.OriginalIndex} -> {newIndex}");
|
//Debug.Log($"[ListReorderHandler] 순서 변경됨: {item.OriginalIndex} -> {newIndex}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
if (autoScrollCoroutine == null)
|
if (autoScrollCoroutine == null)
|
||||||
{
|
{
|
||||||
autoScrollCoroutine = StartCoroutine(AutoScrollRoutine());
|
autoScrollCoroutine = StartCoroutine(AutoScrollRoutine());
|
||||||
Debug.Log("[ScrollRectHandler] 자동 스크롤 시작");
|
//Debug.Log("[ScrollRectHandler] 자동 스크롤 시작");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -86,7 +86,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
{
|
{
|
||||||
StopCoroutine(autoScrollCoroutine);
|
StopCoroutine(autoScrollCoroutine);
|
||||||
autoScrollCoroutine = null;
|
autoScrollCoroutine = null;
|
||||||
Debug.Log("[ScrollRectHandler] 자동 스크롤 중지");
|
//Debug.Log("[ScrollRectHandler] 자동 스크롤 중지");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
float normalizedDistance = (topY - mouseY) / scrollZoneHeight;
|
float normalizedDistance = (topY - mouseY) / scrollZoneHeight;
|
||||||
scrollDelta = scrollSpeed * (1f - normalizedDistance) * Time.deltaTime;
|
scrollDelta = scrollSpeed * (1f - normalizedDistance) * Time.deltaTime;
|
||||||
|
|
||||||
Debug.Log($"[ScrollRectHandler] 위로 스크롤 중... 속도: {scrollDelta}");
|
//Debug.Log($"[ScrollRectHandler] 위로 스크롤 중... 속도: {scrollDelta}");
|
||||||
}
|
}
|
||||||
// 마우스가 아래쪽 가장자리 근처에 있으면 아래로 스크롤
|
// 마우스가 아래쪽 가장자리 근처에 있으면 아래로 스크롤
|
||||||
else if (mouseY < bottomY + scrollZoneHeight && mouseY >= bottomY)
|
else if (mouseY < bottomY + scrollZoneHeight && mouseY >= bottomY)
|
||||||
@@ -132,7 +132,7 @@ namespace UVC.UI.List.Draggable
|
|||||||
float normalizedDistance = (mouseY - bottomY) / scrollZoneHeight;
|
float normalizedDistance = (mouseY - bottomY) / scrollZoneHeight;
|
||||||
scrollDelta = -scrollSpeed * (1f - normalizedDistance) * Time.deltaTime;
|
scrollDelta = -scrollSpeed * (1f - normalizedDistance) * Time.deltaTime;
|
||||||
|
|
||||||
Debug.Log($"[ScrollRectHandler] 아래로 스크롤 중... 속도: {scrollDelta}");
|
//Debug.Log($"[ScrollRectHandler] 아래로 스크롤 중... 속도: {scrollDelta}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 스크롤 적용
|
// 스크롤 적용
|
||||||
|
|||||||
@@ -136,7 +136,6 @@ namespace UVC.UI.Loading
|
|||||||
{
|
{
|
||||||
// 이미 애니메이션이 진행 중이고, 목표가 '나타나기(target=1)'라면 중복 실행을 방지합니다.
|
// 이미 애니메이션이 진행 중이고, 목표가 '나타나기(target=1)'라면 중복 실행을 방지합니다.
|
||||||
if (animatting && target == 1) return;
|
if (animatting && target == 1) return;
|
||||||
|
|
||||||
target = 1; // 목표 알파 값을 1(불투명)로 설정
|
target = 1; // 목표 알파 값을 1(불투명)로 설정
|
||||||
animatting = true; // 애니메이션 시작 상태로 변경
|
animatting = true; // 애니메이션 시작 상태로 변경
|
||||||
StopCoroutine("Animate"); // 이전에 실행 중이던 Animate 코루틴이 있다면 중지
|
StopCoroutine("Animate"); // 이전에 실행 중이던 Animate 코루틴이 있다면 중지
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ namespace UVC.UI.Modal
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 📜 모달 창에 어떤 내용을 보여줄지, 어떻게 행동할지 정하는 '레시피' 또는 '주문서' 같은 친구예요.
|
/// 📜 모달 창에 어떤 내용을 보여줄지, 어떻게 행동할지 정하는 '레시피' 또는 '주문서' 같은 친구예요.
|
||||||
/// 이 클래스의 객체를 만들어서 Modal.Open()에 전달하면, 여기에 적힌 대로 모달 창이 만들어져요.
|
/// 이 클래스의 객체를 만들어서 Modal.Open()에 전달하면, 여기에 적힌 대로 모달 창이 만들어져요.
|
||||||
|
/// 커스텀 모달 창을 만들 때는 ModalView를 상속받아서 Prefab으로 만들고 ModalContent 생성자에 Prefab 경로를 전달해야 한다.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <example>
|
/// <example>
|
||||||
/// <code>
|
/// <code>
|
||||||
|
|||||||
Reference in New Issue
Block a user