using System.Collections.Generic; using UnityEngine; using UnityEngine.UIElements; using UVC.UIToolkit; /// /// UTKReordableList의 기능을 테스트하기 위한 샘플 MonoBehaviour입니다. /// Dictionary 기반 SetData/ToDictionary, 이벤트 핸들러, 데이터 CRUD를 확인합니다. /// public class UTKReordableListSample : MonoBehaviour { [SerializeField] public UIDocument uiDocument; [SerializeField] [Tooltip("시작 시 적용할 테마")] private UTKTheme initialTheme = UTKTheme.Dark; private UTKToggle _themeToggle; private UTKReordableList _reordableList; private UTKReordableTabList _reordableTabList; void Start() { // UIDocument 참조 확인 var doc = GetComponent(); if (doc == null) { Debug.LogError("UIDocument가 할당되지 않았습니다."); return; } uiDocument = doc; var root = uiDocument.rootVisualElement; // 테마 토글 _themeToggle = root.Q("toggle"); if (_themeToggle == null) { Debug.LogError("UXML에서 UTKToggle을 찾을 수 없습니다."); return; } // ReordableList _reordableList = root.Q("window"); if (_reordableList == null) { Debug.LogError("UXML에서 UTKReordableList를 찾을 수 없습니다."); return; } // ReordableTabList _reordableTabList = root.Q("tab-list"); if (_reordableTabList == null) { Debug.LogError("UXML에서 UTKReordableTabList를 찾을 수 없습니다."); return; } // 테마 초기화 UTKThemeManager.Instance.RegisterRoot(root); UTKThemeManager.Instance.SetTheme(initialTheme); _themeToggle.OnValueChanged += (isOn) => { UTKThemeManager.Instance.SetTheme(!isOn ? UTKTheme.Dark : UTKTheme.Light); }; // 이벤트 핸들러 등록 _reordableList.OnOrderChanged += () => Debug.Log("[Sample] 순서 변경됨"); _reordableList.OnDataChanged += () => Debug.Log("[Sample] 데이터 변경됨"); // 샘플 데이터 설정 (Dictionary 방식) SetSampleData(); SetTabListSampleData(); // 이벤트 핸들러 등록 (TabList) _reordableTabList.OnOrderChanged += (tabName, tabIndex) => Debug.Log($"[TabList] [{tabName}] (탭 {tabIndex}) 순서 변경됨"); _reordableTabList.OnDataChanged += (tabName, tabIndex) => Debug.Log($"[TabList] [{tabName}] (탭 {tabIndex}) 데이터 변경됨"); // 하단 버튼 영역 생성 CreateButtons(root); } /// /// Dictionary 기반으로 샘플 데이터를 설정합니다. /// private void SetSampleData() { var listDict = new List> { new() { ["order"] = "0", ["active"] = "True", ["text"] = "온도" }, new() { ["order"] = "1", ["active"] = "False", ["text"] = "습도" }, new() { ["order"] = "2", ["active"] = "True", ["text"] = "압력" }, new() { ["order"] = "3", ["active"] = "True", ["text"] = "풍속" }, new() { ["order"] = "4", ["active"] = "False", ["text"] = "조도" }, }; _reordableList.SetData(listDict); } /// /// UTKReordableTabList에 탭별 샘플 데이터를 설정합니다. /// private void SetTabListSampleData() { var data = new Dictionary>> { ["센서"] = new() { new() { ["order"] = "0", ["active"] = "True", ["text"] = "온도 센서" }, new() { ["order"] = "1", ["active"] = "True", ["text"] = "습도 센서" }, new() { ["order"] = "2", ["active"] = "False", ["text"] = "압력 센서" }, }, ["장비"] = new() { new() { ["order"] = "0", ["active"] = "True", ["text"] = "컨베이어" }, new() { ["order"] = "1", ["active"] = "False", ["text"] = "로봇암" }, new() { ["order"] = "2", ["active"] = "True", ["text"] = "CNC" }, new() { ["order"] = "3", ["active"] = "True", ["text"] = "AGV" }, }, ["알림"] = new() { new() { ["order"] = "0", ["active"] = "True", ["text"] = "경고" }, new() { ["order"] = "1", ["active"] = "True", ["text"] = "에러" }, } }; _reordableTabList.SetData(data); } /// /// 테스트 버튼들을 생성합니다. /// private void CreateButtons(VisualElement root) { var buttonContainer = new VisualElement(); buttonContainer.style.flexDirection = FlexDirection.Row; buttonContainer.style.justifyContent = Justify.Center; buttonContainer.style.paddingTop = 8; buttonContainer.style.paddingBottom = 8; // ToDictionary 버튼 var toDictBtn = new UTKButton("ToDictionary", variant: UTKButton.ButtonVariant.Primary); toDictBtn.OnClicked += OnToDictionaryClicked; toDictBtn.style.marginRight = 4; buttonContainer.Add(toDictBtn); // 데이터 리셋 버튼 var resetBtn = new UTKButton("리셋", variant: UTKButton.ButtonVariant.Normal); resetBtn.OnClicked += () => SetSampleData(); resetBtn.style.marginRight = 4; buttonContainer.Add(resetBtn); // 아이템 추가 버튼 var addBtn = new UTKButton("추가", variant: UTKButton.ButtonVariant.OutlinePrimary); addBtn.OnClicked += OnAddItemClicked; buttonContainer.Add(addBtn); // TabList ToDictionary 버튼 var tabDictBtn = new UTKButton("TabList ToDictionary", variant: UTKButton.ButtonVariant.Primary); tabDictBtn.OnClicked += OnTabListToDictionaryClicked; tabDictBtn.style.marginLeft = 16; tabDictBtn.style.marginRight = 4; buttonContainer.Add(tabDictBtn); // TabList 리셋 버튼 var tabResetBtn = new UTKButton("TabList 리셋", variant: UTKButton.ButtonVariant.Normal); tabResetBtn.OnClicked += () => SetTabListSampleData(); buttonContainer.Add(tabResetBtn); root.Add(buttonContainer); } /// /// ToDictionary를 호출하여 현재 데이터를 콘솔에 출력합니다. /// private void OnToDictionaryClicked() { var result = _reordableList.ToDictionary(); Debug.Log($"[Sample] ToDictionary 결과 ({result.Count}건):"); foreach (var dict in result) { Debug.Log($" order={dict["order"]}, active={dict["active"]}, text={dict["text"]}"); } } /// /// TabList의 ToDictionary를 호출하여 탭별 데이터를 콘솔에 출력합니다. /// private void OnTabListToDictionaryClicked() { var result = _reordableTabList.ToDictionary(); Debug.Log($"[TabList] ToDictionary 결과 ({result.Count}개 탭):"); foreach (var kvp in result) { Debug.Log($" 탭 [{kvp.Key}] ({kvp.Value.Count}건):"); foreach (var dict in kvp.Value) { Debug.Log($" order={dict["order"]}, active={dict["active"]}, text={dict["text"]}"); } } } /// /// 새 아이템을 추가합니다. /// private void OnAddItemClicked() { var currentData = _reordableList.ToDictionary(); var newIndex = currentData.Count; currentData.Add(new Dictionary { ["order"] = newIndex.ToString(), ["active"] = "True", ["text"] = $"항목 {newIndex}" }); _reordableList.SetData(currentData); Debug.Log($"[Sample] 아이템 추가됨 (총 {currentData.Count}건)"); } private void OnDestroy() { _reordableList?.Dispose(); _reordableTabList?.Dispose(); } }