Files
EnglewoodLAB/Assets/Sample/UIToolkit/UTKStyleGuideSample.Window.cs

1129 lines
49 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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);
// Vertical 레이아웃 샘플 초기화
InitializePropertyListWindowVerticalSample(root);
InitializePropertyTabListWindowVerticalSample(root);
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();
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();
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
}