2026-03-10 11:35:30 +09:00
|
|
|
|
#nullable enable
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using Cysharp.Threading.Tasks;
|
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
using UnityEngine.UIElements;
|
|
|
|
|
|
using UVC.UIToolkit;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UTKStyleGuideSample의 Window 카테고리 Initialize 메서드들
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public partial class UTKStyleGuideSample
|
|
|
|
|
|
{
|
|
|
|
|
|
#region Window Initializers
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeAccordionListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("accordion-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var accordionWindow = new UTKAccordionListWindow();
|
|
|
|
|
|
accordionWindow.Title = "프리팹 라이브러리";
|
|
|
|
|
|
accordionWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
var data = new UTKAccordionData();
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 수평 레이아웃 섹션 1: Settings
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
var settingsSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Settings",
|
|
|
|
|
|
IsExpanded = true,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Horizontal,
|
|
|
|
|
|
HorizontalItems = new List<UTKAccordionHorizontalItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Head = UTKAccordionContentSpec.FromImage(UTKMaterialIcons.LibraryAdd),
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText("Graphics", "open_graphics"),
|
|
|
|
|
|
Tail = new List<UTKAccordionContentSpec>
|
|
|
|
|
|
{
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_graphics", "새로고침"),
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Settings, 12, "setting_graphics", "설정"),
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Head = UTKAccordionContentSpec.FromImage(UTKMaterialIcons.AudioFile),
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText("Audio", "open_audio"),
|
|
|
|
|
|
Tail = new List<UTKAccordionContentSpec>
|
|
|
|
|
|
{
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_audio", "새로고침"),
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Settings, 12, "setting_audio", "설정"),
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Head = UTKAccordionContentSpec.FromImage(UTKMaterialIcons.Explore),
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText("Network", "open_network"),
|
|
|
|
|
|
Tail = new List<UTKAccordionContentSpec>
|
|
|
|
|
|
{
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, "refresh_network", "새로고침"),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(settingsSection);
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 수평 레이아웃 섹션 2: Components
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
var componentsSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Components",
|
|
|
|
|
|
IsExpanded = false,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Horizontal,
|
|
|
|
|
|
HorizontalItems = new List<UTKAccordionHorizontalItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText("Transform", "open_transform"),
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText("Rigidbody", "open_rigidbody"),
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText("Collider", "open_collider"),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(componentsSection);
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 그리드 레이아웃 섹션 1: Vehicles
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
var vehiclesSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Vehicles",
|
|
|
|
|
|
IsExpanded = true,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Grid,
|
|
|
|
|
|
GridItems = new List<UTKAccordionGridItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Forklift",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_forklift_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift",
|
|
|
|
|
|
Tag = "vehicle"
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Truck",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_forklift_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift",
|
|
|
|
|
|
Tag = "vehicle"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(vehiclesSection);
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 그리드 레이아웃 섹션 2: Objects
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
var objectsSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Objects",
|
|
|
|
|
|
IsExpanded = true,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Grid,
|
|
|
|
|
|
GridItems = new List<UTKAccordionGridItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Pallet",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_pallet_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty",
|
|
|
|
|
|
Tag = "object"
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Pallet (Full)",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_pallet_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty",
|
|
|
|
|
|
Tag = "object"
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Box",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_pallet_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty",
|
|
|
|
|
|
Tag = "object"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(objectsSection);
|
|
|
|
|
|
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
// 그리드 레이아웃 섹션 3: Characters
|
|
|
|
|
|
// ========================================
|
|
|
|
|
|
var charactersSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = "Characters",
|
|
|
|
|
|
IsExpanded = true,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Grid,
|
|
|
|
|
|
GridItems = new List<UTKAccordionGridItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Worker",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_worker_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/CharCrafter – Free Preset Characters Pack (Vol. 1)/Prefabs/Male Young Guy",
|
|
|
|
|
|
Tag = "character"
|
|
|
|
|
|
},
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = "Manager",
|
|
|
|
|
|
ImagePath = "Simulator/Images/lib_worker_400x300",
|
|
|
|
|
|
PrefabPath = "Simulator/CharCrafter – Free Preset Characters Pack (Vol. 1)/Prefabs/Male Young Guy",
|
|
|
|
|
|
Tag = "character"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(charactersSection);
|
|
|
|
|
|
accordionWindow.SetData(data);
|
|
|
|
|
|
accordionWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(accordionWindow);
|
|
|
|
|
|
|
|
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// 아코디언 리스트 윈도우 생성
|
|
|
|
|
|
var accordionWindow = new UTKAccordionListWindow();
|
|
|
|
|
|
accordionWindow.Title = ""프리펍 라이브러리"";
|
|
|
|
|
|
accordionWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
var data = new UTKAccordionData();
|
|
|
|
|
|
|
|
|
|
|
|
// 수평 레이아웃 섹션
|
|
|
|
|
|
var settingsSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = ""Settings"",
|
|
|
|
|
|
IsExpanded = true,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Horizontal,
|
|
|
|
|
|
HorizontalItems = new List<UTKAccordionHorizontalItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionHorizontalItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Head = UTKAccordionContentSpec.FromImage(UTKMaterialIcons.LibraryAdd),
|
|
|
|
|
|
Content = UTKAccordionContentSpec.FromText(""Graphics"", ""open_graphics""),
|
|
|
|
|
|
Tail = new List<UTKAccordionContentSpec>
|
|
|
|
|
|
{
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Refresh, 12, ""refresh_graphics"", ""새로고침""),
|
|
|
|
|
|
UTKAccordionContentSpec.FromIconButton(UTKMaterialIcons.Settings, 12, ""setting_graphics"", ""설정""),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(settingsSection);
|
|
|
|
|
|
|
|
|
|
|
|
// 그리드 레이아웃 섹션
|
|
|
|
|
|
var vehiclesSection = new UTKAccordionSectionData
|
|
|
|
|
|
{
|
|
|
|
|
|
Title = ""Vehicles"",
|
|
|
|
|
|
IsExpanded = true,
|
|
|
|
|
|
LayoutType = UTKAccordionLayoutType.Grid,
|
|
|
|
|
|
GridItems = new List<UTKAccordionGridItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKAccordionGridItemData
|
|
|
|
|
|
{
|
|
|
|
|
|
Caption = ""Forklift"",
|
|
|
|
|
|
ImagePath = ""Simulator/Images/lib_forklift_400x300"",
|
|
|
|
|
|
PrefabPath = ""Simulator/FreeForkLift/Prefabs/Forklift"",
|
|
|
|
|
|
Tag = ""vehicle""
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
data.Sections.Add(vehiclesSection);
|
|
|
|
|
|
|
|
|
|
|
|
accordionWindow.SetData(data);
|
|
|
|
|
|
accordionWindow.Show();");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeComponentListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("component-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var componentWindow = new UTKComponentListWindow();
|
|
|
|
|
|
componentWindow.Title = "모델 리스트";
|
|
|
|
|
|
componentWindow.ShowCloseButton = true;
|
|
|
|
|
|
componentWindow.OnItemIconClicked += (itemType, itemData) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"아이콘 클릭됨: {itemType}, {itemData.name})");
|
|
|
|
|
|
};
|
|
|
|
|
|
componentWindow.OnItemVisibilityChanged += (itemData, isVisible) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"가시성 변경됨: {itemData.name}, IsVisible={isVisible})");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var category1 = new UTKComponentListCategoryData { name = "캐릭터", isExpanded = true };
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = "플레이어", ExternalKey = "player_001", IsVisible = true });
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = "NPC_01", ExternalKey = "npc_001", IsVisible = true });
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = "NPC_02", ExternalKey = "npc_002", IsVisible = false });
|
|
|
|
|
|
|
|
|
|
|
|
var category2 = new UTKComponentListCategoryData { name = "환경", isExpanded = false };
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = "나무", ExternalKey = "tree_001", IsVisible = true });
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = "바위", ExternalKey = "rock_001", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var data = new List<UTKComponentListItemDataBase> { category1, category2 };
|
|
|
|
|
|
componentWindow.SetData(data);
|
|
|
|
|
|
componentWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(componentWindow);
|
|
|
|
|
|
|
|
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// 컴포넌트 리스트 윈도우 생성
|
|
|
|
|
|
var componentWindow = new UTKComponentListWindow();
|
|
|
|
|
|
componentWindow.Title = ""모델 리스트"";
|
|
|
|
|
|
componentWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var category1 = new UTKComponentListCategoryData { name = ""캐릭터"", isExpanded = true };
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = ""플레이어"", ExternalKey = ""player_001"", IsVisible = true });
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = ""NPC_01"", ExternalKey = ""npc_001"", IsVisible = true });
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = ""NPC_02"", ExternalKey = ""npc_002"", IsVisible = false });
|
|
|
|
|
|
|
|
|
|
|
|
var category2 = new UTKComponentListCategoryData { name = ""환경"", isExpanded = false };
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = ""나무"", ExternalKey = ""tree_001"", IsVisible = true });
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = ""바위"", ExternalKey = ""rock_001"", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var data = new List<UTKComponentListItemDataBase> { category1, category2 };
|
|
|
|
|
|
componentWindow.SetData(data);
|
|
|
|
|
|
componentWindow.Show();");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeComponentTabListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("component-tab-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var tabWindow = new UTKComponentTabListWindow();
|
|
|
|
|
|
tabWindow.Title = "모델 라이브러리";
|
|
|
|
|
|
tabWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터 (카테고리가 탭으로 자동 생성됨)
|
|
|
|
|
|
var category1 = new UTKComponentListCategoryData { name = "캐릭터", isExpanded = true };
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = "플레이어", IsVisible = true });
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = "몬스터", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var category2 = new UTKComponentListCategoryData { name = "환경", isExpanded = true };
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = "나무", IsVisible = true });
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = "풀", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var category3 = new UTKComponentListCategoryData { name = "아이템", isExpanded = true };
|
|
|
|
|
|
category3.Add(new UTKComponentListItemData { name = "검", IsVisible = true });
|
|
|
|
|
|
category3.Add(new UTKComponentListItemData { name = "방패", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var data = new List<UTKComponentListItemDataBase> { category1, category2, category3 };
|
|
|
|
|
|
tabWindow.SetData(data);
|
|
|
|
|
|
tabWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(tabWindow);
|
|
|
|
|
|
|
|
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// 컴포넌트 탭 리스트 윈도우 생성
|
|
|
|
|
|
var tabWindow = new UTKComponentTabListWindow();
|
|
|
|
|
|
tabWindow.Title = ""모델 라이브러리"";
|
|
|
|
|
|
tabWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터 (카테고리가 탭으로 자동 생성됨)
|
|
|
|
|
|
var category1 = new UTKComponentListCategoryData { name = ""캐릭터"", isExpanded = true };
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = ""플레이어"", IsVisible = true });
|
|
|
|
|
|
category1.Add(new UTKComponentListItemData { name = ""몬스터"", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var category2 = new UTKComponentListCategoryData { name = ""환경"", isExpanded = true };
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = ""나무"", IsVisible = true });
|
|
|
|
|
|
category2.Add(new UTKComponentListItemData { name = ""풀"", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var category3 = new UTKComponentListCategoryData { name = ""아이템"", isExpanded = true };
|
|
|
|
|
|
category3.Add(new UTKComponentListItemData { name = ""검"", IsVisible = true });
|
|
|
|
|
|
category3.Add(new UTKComponentListItemData { name = ""방패"", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var data = new List<UTKComponentListItemDataBase> { category1, category2, category3 };
|
|
|
|
|
|
tabWindow.SetData(data);
|
|
|
|
|
|
tabWindow.Show();");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeImageListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("image-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var imageWindow = new UTKImageListWindow();
|
|
|
|
|
|
imageWindow.Title = "텍스처 라이브러리";
|
|
|
|
|
|
imageWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var data = new List<UTKImageListItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKImageListItemData { itemName = "Texture_01", externalId = "tex_001", imagePath = "Simulator/Images/lib_forklift_400x300", objectPrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift" },
|
|
|
|
|
|
new UTKImageListItemData { itemName = "Texture_02", externalId = "tex_002", imagePath = "Simulator/Images/lib_pallet_400x300", objectPrefabPath = "Simulator/FreeForkLift/Prefabs/PalletEmpty" },
|
|
|
|
|
|
new UTKImageListItemData { itemName = "Texture_03", externalId = "tex_003", imagePath = "Simulator/Images/lib_worker_400x300", objectPrefabPath = "Simulator/CharCrafter – Free Preset Characters Pack (Vol. 1)/Prefabs/Male Young Guy" },
|
|
|
|
|
|
new UTKImageListItemData { itemName = "Texture_04", externalId = "tex_004", imagePath = "Simulator/Images/lib_forklift_400x300", objectPrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift" }
|
|
|
|
|
|
};
|
|
|
|
|
|
imageWindow.SetData(data);
|
|
|
|
|
|
imageWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(imageWindow);
|
|
|
|
|
|
|
|
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// 이미지 리스트 윈도우 생성
|
|
|
|
|
|
var imageWindow = new UTKImageListWindow();
|
|
|
|
|
|
imageWindow.Title = ""텍스처 라이브러리"";
|
|
|
|
|
|
imageWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var data = new List<UTKImageListItemData>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKImageListItemData { itemName = ""Texture_01"", externalId = ""tex_001"", imagePath = ""Simulator/Images/lib_forklift_400x300"", objectPrefabPath = ""Simulator/FreeForkLift/Prefabs/Forklift"" },
|
|
|
|
|
|
new UTKImageListItemData { itemName = ""Texture_02"", externalId = ""tex_002"", imagePath = ""Simulator/Images/lib_pallet_400x300"", objectPrefabPath = ""Simulator/FreeForkLift/Prefabs/PalletEmpty"" },
|
|
|
|
|
|
new UTKImageListItemData { itemName = ""Texture_03"", externalId = ""tex_003"", imagePath = ""Simulator/Images/lib_worker_400x300"", objectPrefabPath = ""Simulator/CharCrafter – Free Preset Characters Pack (Vol. 1)/Prefabs/Male Young Guy"" },
|
|
|
|
|
|
new UTKImageListItemData { itemName = ""Texture_04"", externalId = ""tex_004"", imagePath = ""Simulator/Images/lib_forklift_400x300"", objectPrefabPath = ""Simulator/FreeForkLift/Prefabs/Forklift"" }
|
|
|
|
|
|
};
|
|
|
|
|
|
imageWindow.SetData(data);
|
|
|
|
|
|
imageWindow.Show();");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeTreeListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("tree-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var treeWindow = new UTKTreeListWindow();
|
|
|
|
|
|
treeWindow.Title = "씬 계층 구조";
|
|
|
|
|
|
treeWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
treeWindow.OnItemSelected += (itemDataList) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"선택된 아이템: {string.Join(", ", itemDataList.ConvertAll(i => i.name))}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var environment = new UTKTreeListItemData { name = "Environment", isExpanded = true };
|
|
|
|
|
|
environment.Add(new UTKTreeListItemData { name = "Terrain", ExternalKey = "terrain_001", IsVisible = true });
|
|
|
|
|
|
environment.Add(new UTKTreeListItemData { name = "Trees", ExternalKey = "trees_001", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var characters = new UTKTreeListItemData { name = "Characters", isExpanded = false };
|
|
|
|
|
|
characters.Add(new UTKTreeListItemData { name = "Player", ExternalKey = "player_001", IsVisible = true });
|
|
|
|
|
|
characters.Add(new UTKTreeListItemData { name = "Enemies", ExternalKey = "enemies_001", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var rootNode = new UTKTreeListItemData { name = "Root", isExpanded = true };
|
|
|
|
|
|
rootNode.Add(environment);
|
|
|
|
|
|
rootNode.Add(characters);
|
|
|
|
|
|
|
|
|
|
|
|
var data = new List<UTKTreeListItemData> { rootNode };
|
|
|
|
|
|
treeWindow.SetData(data);
|
|
|
|
|
|
treeWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(treeWindow);
|
|
|
|
|
|
|
|
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// 트리 리스트 윈도우 생성
|
|
|
|
|
|
var treeWindow = new UTKTreeListWindow();
|
|
|
|
|
|
treeWindow.Title = ""씬 계층 구조"";
|
|
|
|
|
|
treeWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var environment = new UTKTreeListItemData { name = ""Environment"", isExpanded = true };
|
|
|
|
|
|
environment.Add(new UTKTreeListItemData { name = ""Terrain"", ExternalKey = ""terrain_001"", IsVisible = true });
|
|
|
|
|
|
environment.Add(new UTKTreeListItemData { name = ""Trees"", ExternalKey = ""trees_001"", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var characters = new UTKTreeListItemData { name = ""Characters"", isExpanded = false };
|
|
|
|
|
|
characters.Add(new UTKTreeListItemData { name = ""Player"", ExternalKey = ""player_001"", IsVisible = true });
|
|
|
|
|
|
characters.Add(new UTKTreeListItemData { name = ""Enemies"", ExternalKey = ""enemies_001"", IsVisible = true });
|
|
|
|
|
|
|
|
|
|
|
|
var rootNode = new UTKTreeListItemData { name = ""Root"", isExpanded = true };
|
|
|
|
|
|
rootNode.Add(environment);
|
|
|
|
|
|
rootNode.Add(characters);
|
|
|
|
|
|
|
|
|
|
|
|
var data = new List<UTKTreeListItemData> { rootNode };
|
|
|
|
|
|
treeWindow.SetData(data);
|
|
|
|
|
|
treeWindow.Show();");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializePropertyListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("property-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var propertyWindow = new UTKPropertyListWindow();
|
|
|
|
|
|
propertyWindow.Title = "속성 편집기";
|
|
|
|
|
|
propertyWindow.ShowCloseButton = true;
|
|
|
|
|
|
propertyWindow.style.width = 320;
|
|
|
|
|
|
propertyWindow.style.height = 600;
|
|
|
|
|
|
|
|
|
|
|
|
// 이벤트 구독
|
|
|
|
|
|
propertyWindow.OnCloseClicked += () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("Property Window Close clicked");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
propertyWindow.OnPropertyValueChanged += args =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"Property Changed: {args.PropertyId} = {args.NewValue}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
propertyWindow.OnPropertyClicked += args =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"Property Clicked: {args.Id} {args.DisplayName}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
propertyWindow.OnPropertyButtonClicked += (id, actionName) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"Button Clicked: {id} - Action: {actionName}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터 생성 (모든 PropertyItem 종류 포함)
|
|
|
|
|
|
var entries = CreatePropertyListSampleEntries();
|
|
|
|
|
|
propertyWindow.LoadMixedProperties(entries);
|
|
|
|
|
|
propertyWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(propertyWindow);
|
|
|
|
|
|
|
|
|
|
|
|
// PropertyTabListWindow 샘플도 함께 초기화 (동일 UXML 내)
|
|
|
|
|
|
InitializePropertyTabListWindowSample(root);
|
|
|
|
|
|
|
2026-03-10 16:16:01 +09:00
|
|
|
|
// Vertical 레이아웃 샘플 초기화
|
|
|
|
|
|
InitializePropertyListWindowVerticalSample(root);
|
|
|
|
|
|
InitializePropertyTabListWindowVerticalSample(root);
|
|
|
|
|
|
|
2026-03-10 11:35:30 +09:00
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// 속성 윈도우 생성
|
|
|
|
|
|
var propertyWindow = new UTKPropertyListWindow();
|
|
|
|
|
|
propertyWindow.Title = ""속성 편집기"";
|
|
|
|
|
|
propertyWindow.ShowCloseButton = true;
|
|
|
|
|
|
|
|
|
|
|
|
// 이벤트 구독
|
|
|
|
|
|
propertyWindow.OnPropertyValueChanged += args =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($""{args.PropertyId} = {args.NewValue}"");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 데이터
|
|
|
|
|
|
var entries = new List<IUTKPropertyEntry>();
|
|
|
|
|
|
|
|
|
|
|
|
// String
|
|
|
|
|
|
entries.Add(new UTKStringPropertyItem(""name"", ""Name"", ""Sample Object""));
|
|
|
|
|
|
|
|
|
|
|
|
// Bool
|
|
|
|
|
|
entries.Add(new UTKBoolPropertyItem(""active"", ""Is Active"", true));
|
|
|
|
|
|
|
|
|
|
|
|
// Int (Slider)
|
|
|
|
|
|
entries.Add(new UTKIntPropertyItem(""count"", ""Count"", 10, 0, 100, useSlider: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Float (Slider + Stepper)
|
|
|
|
|
|
entries.Add(new UTKFloatPropertyItem(""speed"", ""Speed"", 1.5f, 0f, 10f, useSlider: true, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Vector2/Vector3
|
|
|
|
|
|
entries.Add(new UTKVector2PropertyItem(""offset"", ""Offset"", Vector2.zero));
|
|
|
|
|
|
entries.Add(new UTKVector3PropertyItem(""position"", ""Position"", Vector3.zero));
|
|
|
|
|
|
|
|
|
|
|
|
// Color
|
|
|
|
|
|
entries.Add(new UTKColorPropertyItem(""color"", ""Color"", Color.red));
|
|
|
|
|
|
|
|
|
|
|
|
// Date/DateTime
|
|
|
|
|
|
entries.Add(new UTKDatePropertyItem(""date"", ""Date"", DateTime.Today));
|
|
|
|
|
|
entries.Add(new UTKDateTimePropertyItem(""datetime"", ""DateTime"", DateTime.Now));
|
|
|
|
|
|
|
|
|
|
|
|
// Range
|
|
|
|
|
|
entries.Add(new UTKIntRangePropertyItem(""range"", ""Range"", 10, 90));
|
|
|
|
|
|
entries.Add(new UTKFloatRangePropertyItem(""floatRange"", ""Float Range"", 1.5f, 8.5f));
|
|
|
|
|
|
|
|
|
|
|
|
// Dropdown
|
|
|
|
|
|
entries.Add(new UTKDropdownPropertyItem(""dropdown"", ""Dropdown"",
|
|
|
|
|
|
new List<string> { ""Option A"", ""Option B"", ""Option C"" }, ""Option A""));
|
|
|
|
|
|
|
|
|
|
|
|
// Enum
|
|
|
|
|
|
entries.Add(new UTKEnumPropertyItem(""layer"", ""Layer"", LayerMask.NameToLayer(""Default"")));
|
|
|
|
|
|
|
|
|
|
|
|
// Group
|
|
|
|
|
|
var group = new UTKPropertyGroup(""transform"", ""Transform"");
|
|
|
|
|
|
group.AddItem(new UTKVector3PropertyItem(""pos"", ""Position"", Vector3.zero));
|
|
|
|
|
|
group.AddItem(new UTKVector3PropertyItem(""rot"", ""Rotation"", Vector3.zero));
|
|
|
|
|
|
entries.Add(group);
|
|
|
|
|
|
|
|
|
|
|
|
propertyWindow.LoadMixedProperties(entries);
|
|
|
|
|
|
propertyWindow.Show();",
|
|
|
|
|
|
uxmlCode: @"<?xml version=""1.0"" encoding=""utf-8""?>
|
|
|
|
|
|
<UXML xmlns=""UnityEngine.UIElements"" xmlns:utk=""UVC.UIToolkit"">
|
|
|
|
|
|
<utk:UTKPropertyListWindow name=""property-window"" />
|
|
|
|
|
|
</UXML>");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializePropertyTabListWindowSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("property-tab-list-window-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var tabWindow = new UTKPropertyTabListWindow("속성 탭 편집기", showAllTab: true);
|
|
|
|
|
|
tabWindow.ShowCloseButton = true;
|
|
|
|
|
|
tabWindow.style.width = 320;
|
|
|
|
|
|
tabWindow.style.height = 600;
|
|
|
|
|
|
|
|
|
|
|
|
// 이벤트 구독
|
|
|
|
|
|
tabWindow.OnCloseClicked += () =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log("PropertyTabListWindow Close clicked");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
tabWindow.OnTabChanged += (index, tabData) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"Tab Changed: index={index}, name={tabData?.Name}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
tabWindow.OnPropertyValueChanged += args =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"Property Changed: {args.PropertyId} = {args.NewValue}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 1: 기본 속성 (Flat) =====
|
|
|
|
|
|
var generalTab = new TabPropertyData("일반");
|
|
|
|
|
|
generalTab.SetFlatData(new List<IUTKPropertyItem>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKStringPropertyItem("name", "Name", "Sample Object"),
|
|
|
|
|
|
new UTKBoolPropertyItem("active", "Is Active", true),
|
|
|
|
|
|
new UTKIntPropertyItem("count", "Count", 10, 0, 100, useSlider: true),
|
|
|
|
|
|
new UTKFloatPropertyItem("speed", "Speed", 1.5f, 0f, 10f, useSlider: true, useStepper: true),
|
|
|
|
|
|
new UTKDropdownPropertyItem("type", "Type",
|
|
|
|
|
|
new List<string> { "Static", "Dynamic", "Kinematic" }, "Static"),
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 2: Transform (Grouped) =====
|
|
|
|
|
|
var transformTab = new TabPropertyData("트랜스폼");
|
|
|
|
|
|
var posGroup = new UTKPropertyGroup("position", "Position");
|
|
|
|
|
|
posGroup.AddItem(new UTKVector3PropertyItem("pos", "Position", Vector3.zero));
|
|
|
|
|
|
posGroup.AddItem(new UTKVector3PropertyItem("rot", "Rotation", Vector3.zero));
|
|
|
|
|
|
posGroup.AddItem(new UTKVector3PropertyItem("scl", "Scale", Vector3.one));
|
|
|
|
|
|
|
|
|
|
|
|
var physicsGroup = new UTKPropertyGroup("physics", "Physics");
|
|
|
|
|
|
physicsGroup.AddItem(new UTKFloatPropertyItem("mass", "Mass", 1.0f, 0f, 100f, useSlider: true));
|
|
|
|
|
|
physicsGroup.AddItem(new UTKBoolPropertyItem("gravity", "Use Gravity", true));
|
|
|
|
|
|
physicsGroup.AddItem(new UTKDropdownPropertyItem("collision", "Collision",
|
|
|
|
|
|
new List<string> { "Discrete", "Continuous", "ContinuousDynamic" }, "Discrete"));
|
|
|
|
|
|
|
|
|
|
|
|
transformTab.SetGroupedData(new List<IUTKPropertyGroup> { posGroup, physicsGroup });
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 3: 외형 (Mixed) =====
|
|
|
|
|
|
var appearanceTab = new TabPropertyData("외형");
|
|
|
|
|
|
var mixedEntries = new List<IUTKPropertyEntry>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKColorPropertyItem("mainColor", "Main Color", Color.blue),
|
|
|
|
|
|
new UTKColorPropertyItem("emissionColor", "Emission", Color.yellow, useAlpha: true),
|
|
|
|
|
|
new UTKFloatPropertyItem("alpha", "Alpha", 1f, 0f, 1f, useSlider: true),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var materialGroup = new UTKPropertyGroup("material", "Material");
|
|
|
|
|
|
materialGroup.AddItem(new UTKStringPropertyItem("shader", "Shader", "Standard"));
|
|
|
|
|
|
materialGroup.AddItem(new UTKDropdownPropertyItem("renderQueue", "Render Queue",
|
|
|
|
|
|
new List<string> { "Geometry", "AlphaTest", "Transparent" }, "Geometry"));
|
|
|
|
|
|
mixedEntries.Add(materialGroup);
|
|
|
|
|
|
|
|
|
|
|
|
appearanceTab.SetMixedData(mixedEntries);
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 4: 비활성 탭 =====
|
|
|
|
|
|
var disabledTab = new TabPropertyData("비활성") { IsEnabled = false, Tooltip = "이 탭은 비활성 상태입니다" };
|
|
|
|
|
|
disabledTab.SetFlatData(new List<IUTKPropertyItem>());
|
|
|
|
|
|
|
|
|
|
|
|
// 탭 데이터 설정
|
|
|
|
|
|
tabWindow.SetTabData(new List<TabPropertyData> { generalTab, transformTab, appearanceTab, disabledTab });
|
|
|
|
|
|
tabWindow.Show();
|
|
|
|
|
|
|
2026-03-10 16:16:01 +09:00
|
|
|
|
container.Add(tabWindow);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UTKPropertyListWindow의 Vertical 레이아웃 샘플을 초기화합니다.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void InitializePropertyListWindowVerticalSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("property-list-window-vertical-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var propertyWindow = new UTKPropertyListWindow();
|
|
|
|
|
|
propertyWindow.Title = "속성 편집기 (Vertical)";
|
|
|
|
|
|
propertyWindow.ShowCloseButton = true;
|
|
|
|
|
|
propertyWindow.Layout = UTKPropertyLayout.Vertical;
|
|
|
|
|
|
propertyWindow.style.height = 600;
|
|
|
|
|
|
|
|
|
|
|
|
propertyWindow.OnPropertyValueChanged += args =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"[Vertical] Property Changed: {args.PropertyId} = {args.NewValue}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var entries = CreatePropertyListSampleEntries();
|
|
|
|
|
|
propertyWindow.LoadMixedProperties(entries);
|
|
|
|
|
|
propertyWindow.Show();
|
|
|
|
|
|
|
|
|
|
|
|
container.Add(propertyWindow);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// UTKPropertyTabListWindow의 Vertical 레이아웃 샘플을 초기화합니다.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void InitializePropertyTabListWindowVerticalSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
var container = root.Q<VisualElement>("property-tab-list-window-vertical-container");
|
|
|
|
|
|
if (container == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
var tabWindow = new UTKPropertyTabListWindow("속성 탭 편집기 (Vertical)", showAllTab: true);
|
|
|
|
|
|
tabWindow.ShowCloseButton = true;
|
|
|
|
|
|
tabWindow.Layout = UTKPropertyLayout.Vertical;
|
|
|
|
|
|
tabWindow.style.height = 600;
|
|
|
|
|
|
|
|
|
|
|
|
tabWindow.OnTabChanged += (index, tabData) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"[Vertical] Tab Changed: index={index}, name={tabData?.Name}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
tabWindow.OnPropertyValueChanged += args =>
|
|
|
|
|
|
{
|
|
|
|
|
|
Debug.Log($"[Vertical] Property Changed: {args.PropertyId} = {args.NewValue}");
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 1: 기본 속성 (Flat) =====
|
|
|
|
|
|
var generalTab = new TabPropertyData("일반");
|
|
|
|
|
|
generalTab.SetFlatData(new List<IUTKPropertyItem>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKStringPropertyItem("name", "Name", "Sample Object"),
|
|
|
|
|
|
new UTKBoolPropertyItem("active", "Is Active", true),
|
|
|
|
|
|
new UTKIntPropertyItem("count", "Count", 10, 0, 100, useSlider: true),
|
|
|
|
|
|
new UTKFloatPropertyItem("speed", "Speed", 1.5f, 0f, 10f, useSlider: true, useStepper: true),
|
|
|
|
|
|
new UTKDropdownPropertyItem("type", "Type",
|
|
|
|
|
|
new List<string> { "Static", "Dynamic", "Kinematic" }, "Static"),
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 2: Transform (Grouped) =====
|
|
|
|
|
|
var transformTab = new TabPropertyData("트랜스폼");
|
|
|
|
|
|
var posGroup = new UTKPropertyGroup("position", "Position");
|
|
|
|
|
|
posGroup.AddItem(new UTKVector3PropertyItem("pos", "Position", Vector3.zero));
|
|
|
|
|
|
posGroup.AddItem(new UTKVector3PropertyItem("rot", "Rotation", Vector3.zero));
|
|
|
|
|
|
posGroup.AddItem(new UTKVector3PropertyItem("scl", "Scale", Vector3.one));
|
|
|
|
|
|
|
|
|
|
|
|
var physicsGroup = new UTKPropertyGroup("physics", "Physics");
|
|
|
|
|
|
physicsGroup.AddItem(new UTKFloatPropertyItem("mass", "Mass", 1.0f, 0f, 100f, useSlider: true));
|
|
|
|
|
|
physicsGroup.AddItem(new UTKBoolPropertyItem("gravity", "Use Gravity", true));
|
|
|
|
|
|
physicsGroup.AddItem(new UTKDropdownPropertyItem("collision", "Collision",
|
|
|
|
|
|
new List<string> { "Discrete", "Continuous", "ContinuousDynamic" }, "Discrete"));
|
|
|
|
|
|
|
|
|
|
|
|
transformTab.SetGroupedData(new List<IUTKPropertyGroup> { posGroup, physicsGroup });
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 탭 3: 외형 (Mixed) =====
|
|
|
|
|
|
var appearanceTab = new TabPropertyData("외형");
|
|
|
|
|
|
var mixedEntries = new List<IUTKPropertyEntry>
|
|
|
|
|
|
{
|
|
|
|
|
|
new UTKColorPropertyItem("mainColor", "Main Color", Color.blue),
|
|
|
|
|
|
new UTKColorPropertyItem("emissionColor", "Emission", Color.yellow, useAlpha: true),
|
|
|
|
|
|
new UTKFloatPropertyItem("alpha", "Alpha", 1f, 0f, 1f, useSlider: true),
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
var materialGroup = new UTKPropertyGroup("material", "Material");
|
|
|
|
|
|
materialGroup.AddItem(new UTKStringPropertyItem("shader", "Shader", "Standard"));
|
|
|
|
|
|
materialGroup.AddItem(new UTKDropdownPropertyItem("renderQueue", "Render Queue",
|
|
|
|
|
|
new List<string> { "Geometry", "AlphaTest", "Transparent" }, "Geometry"));
|
|
|
|
|
|
mixedEntries.Add(materialGroup);
|
|
|
|
|
|
|
|
|
|
|
|
appearanceTab.SetMixedData(mixedEntries);
|
|
|
|
|
|
|
|
|
|
|
|
// 탭 데이터 설정
|
|
|
|
|
|
tabWindow.SetTabData(new List<TabPropertyData> { generalTab, transformTab, appearanceTab });
|
|
|
|
|
|
tabWindow.Show();
|
|
|
|
|
|
|
2026-03-10 11:35:30 +09:00
|
|
|
|
container.Add(tabWindow);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 모든 PropertyItem 종류를 포함하는 샘플 데이터를 생성합니다.
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private List<IUTKPropertyEntry> CreatePropertyListSampleEntries()
|
|
|
|
|
|
{
|
|
|
|
|
|
var entries = new List<IUTKPropertyEntry>();
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 개별 아이템들 =====
|
|
|
|
|
|
|
|
|
|
|
|
// String (편집 가능)
|
|
|
|
|
|
entries.Add(new UTKStringPropertyItem("string", "String", "Editable text"));
|
|
|
|
|
|
|
|
|
|
|
|
// String with Action Button
|
|
|
|
|
|
var stringWithButton = new UTKStringPropertyItem("string_btn", "String Button", "Click button");
|
|
|
|
|
|
stringWithButton.ActionButton = new UTKButtonItem("btn_search", "search", "", UTKMaterialIcons.Search,
|
|
|
|
|
|
UTKButton.ButtonVariant.OutlineNormal, UTKButton.ButtonSize.Small);
|
|
|
|
|
|
stringWithButton.ActionButton.IconOnly = true;
|
|
|
|
|
|
stringWithButton.ActionButton.IconSize = 14;
|
|
|
|
|
|
entries.Add(stringWithButton);
|
|
|
|
|
|
|
|
|
|
|
|
// String (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKStringPropertyItem("string_ro", "String (RO)", "Read-only", isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Bool (편집 가능)
|
|
|
|
|
|
entries.Add(new UTKBoolPropertyItem("bool", "Bool", true));
|
|
|
|
|
|
|
|
|
|
|
|
// Bool (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKBoolPropertyItem("bool_ro", "Bool (RO)", true, isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Int (Slider)
|
|
|
|
|
|
entries.Add(new UTKIntPropertyItem("int", "Int", 42, 0, 100, useSlider: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Int (Slider + Stepper)
|
|
|
|
|
|
entries.Add(new UTKIntPropertyItem("int_stepper", "Int Stepper", 50, 0, 100, useSlider: true, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Int (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKIntPropertyItem("int_ro", "Int (RO)", 99, 0, 100, useSlider: true, isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Float (Slider + Stepper)
|
|
|
|
|
|
entries.Add(new UTKFloatPropertyItem("float", "Float", 3.14f, 0f, 10f, useSlider: true, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Float (Stepper만)
|
|
|
|
|
|
entries.Add(new UTKFloatPropertyItem("float_stepper", "Float Stepper", 2.5f, 0f, 10f, useSlider: false, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Float (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKFloatPropertyItem("float_ro", "Float (RO)", 7.2f, 0f, 10f, useSlider: true, isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Vector2
|
|
|
|
|
|
entries.Add(new UTKVector2PropertyItem("vec2", "Vector2", new Vector2(1, 2)));
|
|
|
|
|
|
|
|
|
|
|
|
// Vector2 (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKVector2PropertyItem("vec2_ro", "Vector2 (RO)", new Vector2(3, 4)) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// Vector3
|
|
|
|
|
|
entries.Add(new UTKVector3PropertyItem("vec3", "Vector3", new Vector3(1, 2, 3)));
|
|
|
|
|
|
|
|
|
|
|
|
// Vector3 (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKVector3PropertyItem("vec3_ro", "Vector3 (RO)", new Vector3(4, 5, 6)) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// Color
|
|
|
|
|
|
entries.Add(new UTKColorPropertyItem("color", "Color", Color.red));
|
|
|
|
|
|
|
|
|
|
|
|
// Color (Alpha 포함)
|
|
|
|
|
|
entries.Add(new UTKColorPropertyItem("color_alpha", "Color (Alpha)", Color.blue, useAlpha: true));
|
|
|
|
|
|
|
|
|
|
|
|
// Color (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKColorPropertyItem("color_ro", "Color (RO)", Color.green) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// ColorState
|
|
|
|
|
|
entries.Add(new UTKColorStatePropertyItem("colorstate", "ColorState", new UTKColorState("Active", Color.green)));
|
|
|
|
|
|
|
|
|
|
|
|
// ColorState (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKColorStatePropertyItem("colorstate_ro", "ColorState (RO)", new UTKColorState("Locked", Color.gray)) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// Date
|
|
|
|
|
|
entries.Add(new UTKDatePropertyItem("date", "Date", DateTime.Today));
|
|
|
|
|
|
|
|
|
|
|
|
// Date (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKDatePropertyItem("date_ro", "Date (RO)", DateTime.Today.AddDays(7), isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// DateTime
|
|
|
|
|
|
entries.Add(new UTKDateTimePropertyItem("datetime", "DateTime", DateTime.Now));
|
|
|
|
|
|
|
|
|
|
|
|
// DateTime (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKDateTimePropertyItem("datetime_ro", "DateTime (RO)", DateTime.Now.AddHours(1), isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// DateRange
|
|
|
|
|
|
entries.Add(new UTKDateRangePropertyItem("daterange", "DateRange", DateTime.Today, DateTime.Today.AddDays(7)));
|
|
|
|
|
|
|
|
|
|
|
|
// DateRange (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKDateRangePropertyItem("daterange_ro", "DateRange (RO)", DateTime.Today.AddDays(10), DateTime.Today.AddDays(20)) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// DateTimeRange
|
|
|
|
|
|
entries.Add(new UTKDateTimeRangePropertyItem("datetimerange", "DateTimeRange", DateTime.Now, DateTime.Now.AddHours(2)));
|
|
|
|
|
|
|
|
|
|
|
|
// DateTimeRange (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKDateTimeRangePropertyItem("datetimerange_ro", "DateTimeRange (RO)", DateTime.Now.AddHours(3), DateTime.Now.AddHours(5)) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// Enum
|
|
|
|
|
|
entries.Add(new UTKEnumPropertyItem("enum", "Enum", SampleLayer.Default));
|
|
|
|
|
|
|
|
|
|
|
|
// Enum (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKEnumPropertyItem("enum_ro", "Enum (RO)", SampleLayer.Water) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// Dropdown
|
|
|
|
|
|
entries.Add(new UTKDropdownPropertyItem("dropdown", "Dropdown",
|
|
|
|
|
|
new List<string> { "Option A", "Option B", "Option C" }, "Option A"));
|
|
|
|
|
|
|
|
|
|
|
|
// Dropdown (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKDropdownPropertyItem("dropdown_ro", "Dropdown (RO)",
|
|
|
|
|
|
new List<string> { "Option X", "Option Y", "Option Z" }, "Option Y") { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// MultiSelectDropdown
|
|
|
|
|
|
entries.Add(new UTKMultiSelectDropdownPropertyItem("multiselect", "MultiSelect",
|
|
|
|
|
|
new List<string> { "Tag1", "Tag2", "Tag3", "Tag4" },
|
|
|
|
|
|
new List<string> { "Tag1", "Tag3" }));
|
|
|
|
|
|
|
|
|
|
|
|
// MultiSelectDropdown (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKMultiSelectDropdownPropertyItem("multiselect_ro", "MultiSelect (RO)",
|
|
|
|
|
|
new List<string> { "Feature A", "Feature B", "Feature C" },
|
|
|
|
|
|
new List<string> { "Feature B" }) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// Radio
|
|
|
|
|
|
entries.Add(new UTKRadioPropertyItem("radio", "Radio",
|
|
|
|
|
|
new List<string> { "Choice 1", "Choice 2", "Choice 3" }, 0));
|
|
|
|
|
|
|
|
|
|
|
|
// Radio (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKRadioPropertyItem("radio_ro", "Radio (RO)",
|
|
|
|
|
|
new List<string> { "Choice A", "Choice B", "Choice C" }, 1) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// IntRange
|
|
|
|
|
|
entries.Add(new UTKIntRangePropertyItem("intrange", "IntRange", 10, 90));
|
|
|
|
|
|
|
|
|
|
|
|
// IntRange (Stepper)
|
|
|
|
|
|
entries.Add(new UTKIntRangePropertyItem("intrange_stepper", "IntRange Stepper", 20, 80, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// IntRange (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKIntRangePropertyItem("intrange_ro", "IntRange (RO)", 30, 70, isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// FloatRange
|
|
|
|
|
|
entries.Add(new UTKFloatRangePropertyItem("floatrange", "FloatRange", 1.5f, 8.5f));
|
|
|
|
|
|
|
|
|
|
|
|
// FloatRange (Stepper)
|
|
|
|
|
|
entries.Add(new UTKFloatRangePropertyItem("floatrange_stepper", "FloatRange Stepper", 2.5f, 7.5f, stepperStep: 0.5f, stepperMinValue: 0f, stepperMaxValue: 100f, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// FloatRange (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKFloatRangePropertyItem("floatrange_ro", "FloatRange (RO)", 3.0f, 6.0f) { IsReadOnly = true });
|
|
|
|
|
|
|
|
|
|
|
|
// FloatDropdown
|
|
|
|
|
|
entries.Add(new UTKFloatDropdownPropertyItem("floatdropdown", "FloatDropdown",
|
|
|
|
|
|
1.5f, new List<string> { "mm", "cm", "m" }, "cm"));
|
|
|
|
|
|
|
|
|
|
|
|
// FloatDropdown (Stepper)
|
|
|
|
|
|
entries.Add(new UTKFloatDropdownPropertyItem("floatdropdown_stepper", "FloatDropdown Stepper",
|
|
|
|
|
|
10.0f, new List<string> { "mm", "cm", "m" }, "m",
|
|
|
|
|
|
floatMinValue: 0f, floatMaxValue: 1000f, stepperStep: 0.5f, useStepper: true));
|
|
|
|
|
|
|
|
|
|
|
|
// FloatDropdown (읽기 전용)
|
|
|
|
|
|
entries.Add(new UTKFloatDropdownPropertyItem("floatdropdown_ro", "FloatDropdown (RO)",
|
|
|
|
|
|
5.0f, new List<string> { "mm", "cm", "m" }, "m", isReadOnly: true));
|
|
|
|
|
|
|
|
|
|
|
|
// ===== 그룹에 속한 아이템들 =====
|
|
|
|
|
|
|
|
|
|
|
|
// Basic Properties 그룹
|
|
|
|
|
|
var basicGroup = new UTKPropertyGroup("basic", "Basic Properties");
|
|
|
|
|
|
basicGroup.AddItem(new UTKStringPropertyItem("name", "Name", "Sample Object"));
|
|
|
|
|
|
basicGroup.AddItem(new UTKBoolPropertyItem("active", "Is Active", true));
|
|
|
|
|
|
basicGroup.AddItem(new UTKIntPropertyItem("count", "Count", 10, 0, 100, useSlider: true));
|
|
|
|
|
|
entries.Add(basicGroup);
|
|
|
|
|
|
|
|
|
|
|
|
// Transform 그룹
|
|
|
|
|
|
var transformGroup = new UTKPropertyGroup("transform", "Transform");
|
|
|
|
|
|
transformGroup.AddItem(new UTKVector3PropertyItem("position", "Position", Vector3.zero));
|
|
|
|
|
|
transformGroup.AddItem(new UTKVector3PropertyItem("rotation", "Rotation", Vector3.zero));
|
|
|
|
|
|
transformGroup.AddItem(new UTKVector3PropertyItem("scale", "Scale", Vector3.one));
|
|
|
|
|
|
entries.Add(transformGroup);
|
|
|
|
|
|
|
|
|
|
|
|
// Appearance 그룹
|
|
|
|
|
|
var appearanceGroup = new UTKPropertyGroup("appearance", "Appearance");
|
|
|
|
|
|
appearanceGroup.AddItem(new UTKColorPropertyItem("mainColor", "Main Color", Color.blue));
|
|
|
|
|
|
appearanceGroup.AddItem(new UTKColorPropertyItem("emissionColor", "Emission", Color.yellow, useAlpha: true));
|
|
|
|
|
|
appearanceGroup.AddItem(new UTKFloatPropertyItem("alpha", "Alpha", 1f, 0f, 1f, useSlider: true));
|
|
|
|
|
|
entries.Add(appearanceGroup);
|
|
|
|
|
|
|
|
|
|
|
|
// Button 그룹
|
|
|
|
|
|
var buttonGroup = new UTKPropertyGroup("buttons", "Buttons");
|
|
|
|
|
|
buttonGroup.AddItem(new UTKButtonItem("btn_save", "save", "Save", UTKMaterialIcons.Save,
|
|
|
|
|
|
UTKButton.ButtonVariant.Primary, UTKButton.ButtonSize.Medium));
|
|
|
|
|
|
buttonGroup.AddItem(new UTKButtonItem("btn_load", "load", "Load", UTKMaterialIcons.Download,
|
|
|
|
|
|
UTKButton.ButtonVariant.Normal, UTKButton.ButtonSize.Medium));
|
|
|
|
|
|
buttonGroup.AddItem(new UTKButtonItem("btn_delete", "delete", "Delete", UTKMaterialIcons.Delete,
|
|
|
|
|
|
UTKButton.ButtonVariant.Danger, UTKButton.ButtonSize.Medium));
|
|
|
|
|
|
entries.Add(buttonGroup);
|
|
|
|
|
|
|
|
|
|
|
|
return entries;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void InitializeSideBarSample(VisualElement root)
|
|
|
|
|
|
{
|
|
|
|
|
|
// ── Left 사이드바 (UTKButton) ──────────────────────────────
|
|
|
|
|
|
var leftContainer = root.Q<VisualElement>("sidebar-left-container");
|
|
|
|
|
|
if (leftContainer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sidebarLeft = new UTKSideBar
|
|
|
|
|
|
{
|
|
|
|
|
|
Placement = UTKSideBar.SideBarPlacement.Left,
|
|
|
|
|
|
ButtonPaddingTop = 8,
|
|
|
|
|
|
ButtonPaddingBottom = 8,
|
|
|
|
|
|
ButtonGap = 0,
|
|
|
|
|
|
TailPaddingTop = 8,
|
|
|
|
|
|
TailPaddingBottom = 8,
|
|
|
|
|
|
TailGap = 4,
|
|
|
|
|
|
BarSize = 48,
|
|
|
|
|
|
};
|
|
|
|
|
|
sidebarLeft.style.position = Position.Absolute;
|
|
|
|
|
|
sidebarLeft.style.left = 0;
|
|
|
|
|
|
sidebarLeft.style.top = 0;
|
|
|
|
|
|
sidebarLeft.style.bottom = 0;
|
|
|
|
|
|
|
|
|
|
|
|
var content1 = new UTKAccordionListWindow { Title = "탐색기" };
|
|
|
|
|
|
var btn1 = new UTKButton("", UTKMaterialIcons.FolderOpen, UTKButton.ButtonVariant.Text, 24)
|
|
|
|
|
|
{ IconOnly = true, IconOnlyRadius = "0px", SizeVector = new Vector2Int(48, 48) };
|
|
|
|
|
|
sidebarLeft.AddItem(btn1, content1);
|
|
|
|
|
|
|
|
|
|
|
|
var content2 = new UTKComponentListWindow();
|
|
|
|
|
|
var btn2 = new UTKButton("", UTKMaterialIcons.WidgetMedium, UTKButton.ButtonVariant.Text, 24)
|
|
|
|
|
|
{ IconOnly = true, IconOnlyRadius = "0px", SizeVector = new Vector2Int(48, 48) };
|
|
|
|
|
|
sidebarLeft.AddItem(btn2, content2);
|
|
|
|
|
|
|
|
|
|
|
|
var settingsBtn = new UTKButton("", UTKMaterialIcons.Settings, UTKButton.ButtonVariant.Text, 18)
|
|
|
|
|
|
{ IconOnly = true, SizeVector = new Vector2Int(32, 32) };
|
|
|
|
|
|
settingsBtn.OnClicked += () => Debug.Log("[Sample] 설정 클릭");
|
|
|
|
|
|
sidebarLeft.AddTailItem(settingsBtn);
|
|
|
|
|
|
|
|
|
|
|
|
sidebarLeft.OnItemActivated += i => Debug.Log($"[Left] 활성화: {i}");
|
|
|
|
|
|
sidebarLeft.OnItemDeactivated += i => Debug.Log($"[Left] 비활성화: {i}");
|
|
|
|
|
|
|
|
|
|
|
|
leftContainer.Add(sidebarLeft);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ── Right 사이드바 (UTKImageToggleButton, ShowActiveBar=false) ─
|
|
|
|
|
|
var rightContainer = root.Q<VisualElement>("sidebar-right-container");
|
|
|
|
|
|
if (rightContainer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var sidebarRight = new UTKSideBar
|
|
|
|
|
|
{
|
|
|
|
|
|
Placement = UTKSideBar.SideBarPlacement.Right,
|
|
|
|
|
|
ButtonPaddingTop = 16,
|
|
|
|
|
|
ButtonPaddingBottom = 8,
|
|
|
|
|
|
ButtonGap = 0,
|
|
|
|
|
|
TailPaddingTop = 8,
|
|
|
|
|
|
TailPaddingBottom = 16,
|
|
|
|
|
|
TailGap = 4,
|
|
|
|
|
|
BarSize = 28,
|
|
|
|
|
|
ShowActiveBar = false,
|
|
|
|
|
|
};
|
|
|
|
|
|
sidebarRight.style.position = Position.Absolute;
|
|
|
|
|
|
sidebarRight.style.right = 0;
|
|
|
|
|
|
sidebarRight.style.top = 0;
|
|
|
|
|
|
sidebarRight.style.bottom = 0;
|
|
|
|
|
|
|
|
|
|
|
|
var content1 = new UTKAccordionListWindow { Title = "탐색기" };
|
|
|
|
|
|
content1.style.right = 0;
|
|
|
|
|
|
var toggleBtn1 = new UTKImageToggleButton(
|
|
|
|
|
|
onIcon: UTKMaterialIcons.FolderOpen,
|
|
|
|
|
|
offIcon: UTKMaterialIcons.Folder,
|
|
|
|
|
|
iconSize: 16
|
|
|
|
|
|
) { Size = new Vector2Int(20, 20) };
|
|
|
|
|
|
sidebarRight.AddItem(toggleBtn1, content1);
|
|
|
|
|
|
|
|
|
|
|
|
var content2 = new UTKComponentListWindow();
|
|
|
|
|
|
var toggleBtn2 = new UTKImageToggleButton(
|
|
|
|
|
|
onIcon: UTKImageIcons.IconEye22x16,
|
|
|
|
|
|
offIcon: UTKImageIcons.IconEyeClose22x16,
|
|
|
|
|
|
iconSize: 16
|
|
|
|
|
|
) { Size = new Vector2Int(20, 20) };
|
|
|
|
|
|
sidebarRight.AddItem(toggleBtn2, content2);
|
|
|
|
|
|
|
|
|
|
|
|
sidebarRight.OnItemActivated += i => Debug.Log($"[Right] 활성화: {i}");
|
|
|
|
|
|
sidebarRight.OnItemDeactivated += i => Debug.Log($"[Right] 비활성화: {i}");
|
|
|
|
|
|
sidebarRight.ActivateItem(0);
|
|
|
|
|
|
|
|
|
|
|
|
rightContainer.Add(sidebarRight);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SetCodeSamples(root,
|
|
|
|
|
|
csharpCode: @"// ── Left 사이드바 (UTKButton) ──────────────────────────
|
|
|
|
|
|
var sidebar = new UTKSideBar
|
|
|
|
|
|
{
|
|
|
|
|
|
Placement = UTKSideBar.SideBarPlacement.Left,
|
|
|
|
|
|
ButtonPaddingTop = 8,
|
|
|
|
|
|
ButtonPaddingBottom = 8,
|
|
|
|
|
|
ButtonGap = 0,
|
|
|
|
|
|
TailPaddingTop = 8,
|
|
|
|
|
|
TailPaddingBottom = 8,
|
|
|
|
|
|
TailGap = 4,
|
|
|
|
|
|
BarSize = 48, // ⚠️ AddItem 전에 반드시 설정
|
|
|
|
|
|
};
|
|
|
|
|
|
sidebar.style.position = Position.Absolute;
|
|
|
|
|
|
sidebar.style.left = sidebar.style.top = sidebar.style.bottom = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// 메인 아이템 (UTKButton + 콘텐츠)
|
|
|
|
|
|
var content1 = new UTKAccordionListWindow { Title = ""탐색기"" };
|
|
|
|
|
|
var btn1 = new UTKButton("""", UTKMaterialIcons.FolderOpen, UTKButton.ButtonVariant.Text, 24)
|
|
|
|
|
|
{ IconOnly = true, SizeVector = new Vector2Int(48, 48) };
|
|
|
|
|
|
sidebar.AddItem(btn1, content1);
|
|
|
|
|
|
|
|
|
|
|
|
// Tail 버튼
|
|
|
|
|
|
var settingsBtn = new UTKButton("""", UTKMaterialIcons.Settings, UTKButton.ButtonVariant.Text, 18)
|
|
|
|
|
|
{ IconOnly = true };
|
|
|
|
|
|
settingsBtn.OnClicked += () => Debug.Log(""설정 클릭"");
|
|
|
|
|
|
sidebar.AddTailItem(settingsBtn);
|
|
|
|
|
|
|
|
|
|
|
|
// 이벤트
|
|
|
|
|
|
sidebar.OnItemActivated += index => Debug.Log($""활성화: {index}"");
|
|
|
|
|
|
sidebar.OnItemDeactivated += index => Debug.Log($""비활성화: {index}"");
|
|
|
|
|
|
|
|
|
|
|
|
// 프로그래밍 제어
|
|
|
|
|
|
sidebar.ActivateItem(0);
|
|
|
|
|
|
sidebar.DeactivateAll();
|
|
|
|
|
|
|
|
|
|
|
|
// ── Right 사이드바 (UTKImageToggleButton) ───────────────
|
|
|
|
|
|
var sidebarRight = new UTKSideBar
|
|
|
|
|
|
{
|
|
|
|
|
|
Placement = UTKSideBar.SideBarPlacement.Right,
|
|
|
|
|
|
BarSize = 28,
|
|
|
|
|
|
ShowActiveBar = false, // 활성 하이라이트 바 숨김
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 메인 아이템 (UTKImageToggleButton + 콘텐츠)
|
|
|
|
|
|
var content2 = new UTKAccordionListWindow { Title = ""탐색기"" };
|
|
|
|
|
|
var toggleBtn = new UTKImageToggleButton(
|
|
|
|
|
|
onIcon: UTKMaterialIcons.FolderOpen,
|
|
|
|
|
|
offIcon: UTKMaterialIcons.Folder,
|
|
|
|
|
|
iconSize: 16
|
|
|
|
|
|
) { Size = new Vector2Int(20, 20) };
|
|
|
|
|
|
sidebarRight.AddItem(toggleBtn, content2);
|
|
|
|
|
|
|
|
|
|
|
|
// Image Icon 사용
|
|
|
|
|
|
var content3 = new UTKComponentListWindow();
|
|
|
|
|
|
var toggleBtn2 = new UTKImageToggleButton(
|
|
|
|
|
|
onIcon: UTKImageIcons.IconEye22x16,
|
|
|
|
|
|
offIcon: UTKImageIcons.IconEyeClose22x16,
|
|
|
|
|
|
iconSize: 16
|
|
|
|
|
|
) { Size = new Vector2Int(20, 20) };
|
|
|
|
|
|
sidebarRight.AddItem(toggleBtn2, content3);
|
|
|
|
|
|
|
|
|
|
|
|
// 초기 활성화
|
|
|
|
|
|
sidebarRight.ActivateItem(0);
|
|
|
|
|
|
|
|
|
|
|
|
// 반드시 Dispose 호출 (OnDestroy 등)
|
|
|
|
|
|
sidebar.Dispose();
|
|
|
|
|
|
sidebarRight.Dispose();",
|
|
|
|
|
|
uxmlCode: @"<!-- UTKSideBar는 C# 코드로 동적 생성을 권장합니다. -->
|
|
|
|
|
|
<!-- BarSize 설정 → AddItem 순서를 반드시 지켜야 합니다. -->
|
|
|
|
|
|
|
|
|
|
|
|
<!-- 컨테이너 (relative 기준) -->
|
|
|
|
|
|
<ui:VisualElement style=""position: relative; flex-grow: 1;"">
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Left 사이드바 -->
|
|
|
|
|
|
<utk:UTKSideBar
|
|
|
|
|
|
placement=""Left""
|
|
|
|
|
|
bar-size=""48""
|
|
|
|
|
|
button-padding-top=""8""
|
|
|
|
|
|
button-padding-bottom=""8""
|
|
|
|
|
|
button-gap=""0""
|
|
|
|
|
|
show-active-bar=""true""
|
|
|
|
|
|
style=""position: absolute; left: 0; top: 0; bottom: 0;"" />
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Right 사이드바 (활성 바 숨김) -->
|
|
|
|
|
|
<utk:UTKSideBar
|
|
|
|
|
|
placement=""Right""
|
|
|
|
|
|
bar-size=""28""
|
|
|
|
|
|
show-active-bar=""false""
|
|
|
|
|
|
style=""position: absolute; right: 0; top: 0; bottom: 0;"" />
|
|
|
|
|
|
|
|
|
|
|
|
</ui:VisualElement>");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 샘플 열거형 (UTKPropertyListWindowSample과 동일)
|
|
|
|
|
|
public enum SampleLayer
|
|
|
|
|
|
{
|
|
|
|
|
|
Default,
|
|
|
|
|
|
TransparentFX,
|
|
|
|
|
|
IgnoreRaycast,
|
|
|
|
|
|
Water,
|
|
|
|
|
|
UI
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|