스타일 가이드 1차 완성

This commit is contained in:
logonkhi
2026-01-29 20:14:39 +09:00
parent 097436a8b0
commit f2d0f3d423
29 changed files with 297 additions and 247 deletions

View File

@@ -17,7 +17,7 @@
- item-image-right: 썸네일 이미지 - item-image-right: 썸네일 이미지
- item-label-right: 캡션 텍스트 - item-label-right: 캡션 텍스트
--> -->
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionList.uss" /> <Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionListUss.uss" />
<ui:VisualElement name="row-container" class="accordion-grid-row"> <ui:VisualElement name="row-container" class="accordion-grid-row">
<!-- 왼쪽 아이템 --> <!-- 왼쪽 아이템 -->
<ui:VisualElement name="item-left" class="accordion-grid-item"> <ui:VisualElement name="item-left" class="accordion-grid-item">

View File

@@ -16,7 +16,7 @@
- content-label: 텍스트 라벨 - content-label: 텍스트 라벨
- tail-container: 테일 영역 (아이콘 버튼들) - tail-container: 테일 영역 (아이콘 버튼들)
--> -->
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionList.uss" /> <Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionListUss.uss" />
<ui:VisualElement name="horizontal-item" class="accordion-horizontal-item"> <ui:VisualElement name="horizontal-item" class="accordion-horizontal-item">
<!-- Head (이미지) --> <!-- Head (이미지) -->
<ui:VisualElement name="head-container" class="accordion-head-container"> <ui:VisualElement name="head-container" class="accordion-head-container">

View File

@@ -18,14 +18,15 @@
- search-result-label: 검색 결과 건수 표시 - search-result-label: 검색 결과 건수 표시
- accordion-tree-view: TreeView (가상화 지원) - accordion-tree-view: TreeView (가상화 지원)
--> -->
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionList.uss" /> <Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionListUss.uss" />
<ui:VisualElement name="container" class="accordion-list-container"> <ui:VisualElement name="container" class="accordion-list-container">
<!-- 검색 필드 --> <!-- 검색 필드 -->
<ui:TextField name="search-field" <ui:VisualElement name="search-container" class="accordion-search-container">
placeholder-text="검색" <ui:TextField name="search-field"
class="accordion-search-field"> placeholder-text="검색"
class="accordion-search-field" />
<utk:UTKButton name="clear-btn" variant="Text" icon-only="true" class="accordion-clear-button" /> <utk:UTKButton name="clear-btn" variant="Text" icon-only="true" class="accordion-clear-button" />
</ui:TextField> </ui:VisualElement>
<!-- 검색 결과 라벨 (기본 숨김) --> <!-- 검색 결과 라벨 (기본 숨김) -->
<ui:Label name="search-result-label" <ui:Label name="search-result-label"

View File

@@ -17,11 +17,18 @@
width: 100%; width: 100%;
} }
.accordion-search-field { .accordion-search-container {
height: 24px; flex-direction: row;
align-items: center;
margin: 0 0 var(--space-m) 0; margin: 0 0 var(--space-m) 0;
} }
.accordion-search-field {
flex-grow: 1;
height: 24px;
margin: 0;
}
/* ============================================ /* ============================================
Clear 버튼 (Clear Button) - UTKButton 스타일 오버라이드 Clear 버튼 (Clear Button) - UTKButton 스타일 오버라이드
============================================ */ ============================================ */
@@ -58,11 +65,11 @@
} }
.accordion-tree-view .unity-tree-view__item-toggle .unity-toggle__checkmark { .accordion-tree-view .unity-tree-view__item-toggle .unity-toggle__checkmark {
width: 22px; width: 20px;
height: 22px; height: 20px;
background-image: resource('UIToolkit/Images/icon_right_22'); background-image: resource('UIToolkit/Images/icon_right_22');
-unity-background-image-tint-color: var(--color-text-secondary); -unity-background-image-tint-color: var(--color-text-secondary);
rotate: 0; rotate: 0deg;
} }
.accordion-tree-view { .accordion-tree-view {
@@ -169,8 +176,8 @@
flex-grow: 1; flex-grow: 1;
color: var(--color-text-primary); color: var(--color-text-primary);
font-size: var(--font-size-body2); font-size: var(--font-size-body2);
-unity-font-style: bold; -unity-font-definition: resource('Fonts/Pretendard/Pretendard-Bold');
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-SemiBold'); -unity-text-align: middle-left;
padding-left: var(--space-s); padding-left: var(--space-s);
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
@@ -240,8 +247,8 @@
.accordion-content-label { .accordion-content-label {
color: var(--color-text-primary); color: var(--color-text-primary);
font-size: var(--font-size-body2); font-size: var(--font-size-label3);
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-Regular'); -unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
overflow: hidden; overflow: hidden;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;

View File

@@ -15,7 +15,7 @@
- section-title: 섹션 제목 - section-title: 섹션 제목
- section-body: 본문 영역 (아이템들이 동적으로 추가됨) - section-body: 본문 영역 (아이템들이 동적으로 추가됨)
--> -->
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionList.uss" /> <Style src="project://database/Assets/Resources/UIToolkit/List/UTKAccordionListUss.uss" />
<ui:VisualElement name="section-container" class="accordion-section"> <ui:VisualElement name="section-container" class="accordion-section">
<!-- 헤더 --> <!-- 헤더 -->
<ui:VisualElement name="section-header" class="accordion-section-header"> <ui:VisualElement name="section-header" class="accordion-section-header">

View File

@@ -1,35 +1,10 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:utk="UVC.UIToolkit" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
xmlns:ui="UnityEngine.UIElements" <Style src="project://database/Assets/Resources/UIToolkit/List/UTKComponentListUss.uss?fileID=7433441132597879392&amp;guid=71cac0276293ce2479851f572ffbda27&amp;type=3#UTKComponentListUss" />
xmlns:utk="UVC.UIToolkit"
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd"
editor-extension-mode="False">
<!--
UTKComponentList.uxml
컴포넌트 리스트의 메인 레이아웃입니다.
검색 필드와 TreeView로 구성됩니다.
구조:
- container: 메인 컨테이너
- search-field: 검색어 입력 필드
- clear-btn: UTKButton 검색어 지우기 버튼
- main-tree-view: 트리뷰
-->
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKComponentList.uss" />
<ui:VisualElement name="container" class="tree-menu-container"> <ui:VisualElement name="container" class="tree-menu-container">
<!-- 검색 필드 --> <ui:VisualElement name="search-container" class="search-container">
<ui:TextField name="search-field" <ui:TextField name="search-field" placeholder-text="검색" class="search-field" />
placeholder-text="검색"
class="search-field">
<utk:UTKButton name="clear-btn" variant="Text" icon-only="true" class="search-clear-button" /> <utk:UTKButton name="clear-btn" variant="Text" icon-only="true" class="search-clear-button" />
</ui:TextField> </ui:VisualElement>
<!-- 트리뷰 --> <ui:TreeView name="main-tree-view" view-data-key="model-tree-view" fixed-item-height="22" auto-expand="false" horizontal-scrolling="true" selection-type="None" style="flex-grow: 1;" />
<ui:TreeView name="main-tree-view"
view-data-key="model-tree-view"
fixed-item-height="18"
auto-expand="false"
horizontal-scrolling="true"
selection-type="Multiple"
style="flex-grow: 1;" />
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@@ -1,12 +1,8 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xmlns:utk="UVC.UIToolkit" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
xmlns:ui="UnityEngine.UIElements" <Style src="project://database/Assets/Resources/UIToolkit/List/UTKComponentListUss.uss?fileID=7433441132597879392&amp;guid=71cac0276293ce2479851f572ffbda27&amp;type=3#UTKComponentListUss" />
xmlns:uie="UnityEditor.UIElements" <ui:VisualElement name="item-root" class="tree-item-container">
xmlns:utk="UVC.UIToolkit" <ui:Label name="item-label" text="Item Name" class="item-label-style" />
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd"
editor-extension-mode="False">
<ui:VisualElement name="item-root" class="tree-item-container" style="flex-direction: row; justify-content: space-between; height: 22px; padding-left: 0; padding-right: 8px; align-items: center; padding-top: 0; padding-bottom: 0;">
<ui:Label name="item-label" text="Item Name" class="item-label-style" style="flex-grow: 1; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-left: 4px; padding-top: 0; padding-bottom: 0; padding-right: 4px; color: rgb(204, 204, 204); font-size: 12px; -unity-font-definition: resource(&apos;Fonts/Pretendard/Pretendard-Bold&apos;); -unity-text-align: middle-left; height: 22px;" />
<utk:UTKButton name="setting-btn" icon="settings" icon-size="12" icon-only="true" variant="Text" /> <utk:UTKButton name="setting-btn" icon="settings" icon-size="12" icon-only="true" variant="Text" />
<ui:Label name="badge-label" text="0" class="item-label-style" style="flex-grow: 0; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-left: 4px; padding-top: 0; padding-bottom: 0; padding-right: 4px; color: rgb(255, 255, 255); font-size: 9px; -unity-font-definition: resource(&apos;Fonts/Pretendard/Pretendard-Medium&apos;); min-width: 18px; height: 18px; -unity-text-align: middle-center; align-items: center; border-top-left-radius: 9px; border-top-right-radius: 9px; border-bottom-left-radius: 9px; border-bottom-right-radius: 9px; background-color: rgb(69, 69, 69);" /> <ui:Label name="badge-label" text="0" class="badge-label" />
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@@ -1,12 +1,8 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xmlns:utk="UVC.UIToolkit" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
xmlns:ui="UnityEngine.UIElements" <Style src="project://database/Assets/Resources/UIToolkit/List/UTKComponentListUss.uss?fileID=7433441132597879392&amp;guid=71cac0276293ce2479851f572ffbda27&amp;type=3#UTKComponentListUss" />
xmlns:uie="UnityEditor.UIElements" <ui:VisualElement name="item-root" class="tree-leaf-item-container">
xmlns:utk="UVC.UIToolkit" <ui:Label name="item-label" text="Item Name" class="item-label-style" />
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" <utk:UTKButton name="search-btn" icon="arrow_right_alt" icon-size="12" icon-only="true" variant="Text" />
editor-extension-mode="False">
<ui:VisualElement name="item-root" class="tree-item-container" style="flex-direction: row; justify-content: space-between; height: 22px; padding-left: 0; padding-right: 8px; align-items: center; padding-top: 0; padding-bottom: 0;">
<ui:Label name="item-label" text="Item Name" class="item-label-style" style="flex-grow: 1; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-left: 4px; padding-top: 0; padding-bottom: 0; padding-right: 4px; color: rgb(204, 204, 204); font-size: 11px; -unity-font-definition: resource(&apos;Fonts/Pretendard/Pretendard-Medium&apos;); -unity-text-align: middle-left;" />
<utk:UTKButton name="search-btn" icon="arrow_right_alt" icon-size="12" icon-only="true" variant="Text"/>
<utk:UTKButton name="visibility-btn" icon="visibility" icon-size="12" icon-only="true" variant="Text" /> <utk:UTKButton name="visibility-btn" icon="visibility" icon-size="12" icon-only="true" variant="Text" />
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@@ -16,11 +16,15 @@
flex-grow: 1; flex-grow: 1;
} }
.search-field { .search-container {
flex-direction: row;
align-items: center;
margin-bottom: 20px; margin-bottom: 20px;
margin-top: 0; }
margin-right: 0;
margin-left: 0; .search-field {
flex-grow: 1;
margin: 0;
height: 24px; height: 24px;
} }
@@ -44,8 +48,6 @@
/* 카테고리 확장/축소 토글 화살표 스타일 */ /* 카테고리 확장/축소 토글 화살표 스타일 */
.unity-tree-view__item-toggle #unity-checkmark { .unity-tree-view__item-toggle #unity-checkmark {
background-image: resource('UIToolkit/Images/icon_down_22'); background-image: resource('UIToolkit/Images/icon_down_22');
transition-property: rotate;
transition-duration: 0.15s;
} }
/* 카테고리 항목: hover 시 배경 색상 변경 없음 */ /* 카테고리 항목: hover 시 배경 색상 변경 없음 */
@@ -62,10 +64,70 @@
background-color: rgba(0, 0, 0, 0); background-color: rgba(0, 0, 0, 0);
} }
.visibility-on { /* ============================================
background-image: resource('UIToolkit/Images/icon_eye_22x16'); TreeView 아이템 컨테이너 (TreeView Item Container)
============================================ */
.unity-tree-view__item-content TemplateContainer {
flex-grow: 1;
} }
.visibility-off { /* ============================================
background-image: resource('UIToolkit/Images/icon_eye_close_22x16'); 그룹 아이템 (Group Item) - UTKComponentListGroupItem
============================================ */
.tree-item-container {
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 22px;
padding: 0 8px 0 0;
}
.tree-item-container .item-label-style {
flex-grow: 1;
margin: 0;
padding: 0 4px;
height: 22px;
color: var(--color-text-primary);
font-size: var(--font-size-body2);
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-Bold');
-unity-text-align: middle-left;
}
.tree-item-container .badge-label {
flex-grow: 0;
margin: 0;
padding: 0 4px;
min-width: 18px;
height: 18px;
color: var(--color-text-on-primary);
font-size: var(--font-size-label4);
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
-unity-text-align: middle-center;
align-items: center;
border-radius: 9px;
background-color: var(--color-bg-tertiary);
}
/* ============================================
리프 아이템 (Leaf Item) - UTKComponentListItem
============================================ */
.tree-leaf-item-container {
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 22px;
padding: 0 8px 0 0;
}
.tree-leaf-item-container .item-label-style {
flex-grow: 1;
margin: 0;
padding: 0 4px;
color: var(--color-text-primary);
font-size: var(--font-size-label3);
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
-unity-text-align: middle-left;
} }

View File

@@ -16,7 +16,7 @@
- search-result-label: 검색 결과 건수 표시 - search-result-label: 검색 결과 건수 표시
- main-list-view: 아이템 목록 표시 - main-list-view: 아이템 목록 표시
--> -->
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKImageList.uss" /> <Style src="project://database/Assets/Resources/UIToolkit/List/UTKImageListUss.uss" />
<ui:VisualElement name="container" class="image-list-container"> <ui:VisualElement name="container" class="image-list-container">
<!-- 검색 필드 --> <!-- 검색 필드 -->
<ui:TextField name="search-field" <ui:TextField name="search-field"

View File

@@ -1,5 +1,5 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/Resources/UIToolkit/List/UTKImageList.uss?fileID=7433441132597879392&amp;guid=c23a2fd187fa1014c8fb969c6ec23122&amp;type=3#UTKImageList" /> <Style src="project://database/Assets/Resources/UIToolkit/List/UTKImageListUss.uss?fileID=7433441132597879392&amp;guid=c23a2fd187fa1014c8fb969c6ec23122&amp;type=3#UTKImageList" />
<ui:VisualElement name="row-container" class="image-list-row"> <ui:VisualElement name="row-container" class="image-list-row">
<ui:VisualElement name="item-left" class="image-list-item"> <ui:VisualElement name="item-left" class="image-list-item">
<ui:VisualElement name="item-image-left" picking-mode="Ignore" class="item-image" /> <ui:VisualElement name="item-image-left" picking-mode="Ignore" class="item-image" />

View File

@@ -94,15 +94,15 @@
} }
.image-list-item:hover { .image-list-item:hover {
background-color: rgb(60, 60, 64); background-color: var(--color-collection-item-hover);
} }
.image-list-item:checked { .image-list-item:checked {
background-color: rgb(0, 92, 174); background-color: var(--color-collection-item-selected);
} }
.image-list-item:checked:hover { .image-list-item:checked:hover {
background-color: rgb(0, 102, 184); background-color: var(--color-collection-item-selected-hover);
} }
.image-list-item--hidden { .image-list-item--hidden {
@@ -114,8 +114,8 @@
height: 87px; height: 87px;
min-width: 100px; min-width: 100px;
min-height: 75px; min-height: 75px;
background-color: rgb(40, 40, 42); background-color: var(--color-bg-input);
border-radius: 4px; border-radius: var(--radius-m);
margin-bottom: 0; margin-bottom: 0;
-unity-background-scale-mode: scale-to-fit; -unity-background-scale-mode: scale-to-fit;
flex-shrink: 0; flex-shrink: 0;
@@ -139,7 +139,7 @@
} }
.image-list-item:checked .item-label { .image-list-item:checked .item-label {
color: rgb(255, 255, 255); color: var(--color-base-01);
} }
.drag-ghost { .drag-ghost {

View File

@@ -1,7 +1,7 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False"> <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xmlns:utk="UVC.UIToolkit" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
<Style src="project://database/Assets/Resources/UIToolkit/Window/UTKTreeListWindow.uss?fileID=7433441132597879392&amp;guid=b0076250b40d2ac45ab1bff4cd47920c&amp;type=3#UTKTreeListWindow" /> <Style src="project://database/Assets/Resources/UIToolkit/Window/UTKTreeListWindowUss.uss" />
<ui:VisualElement name="item-root" class="tree-item-container" style="flex-direction: row; justify-content: space-between; height: 18px; padding-left: 0; padding-right: 8px; align-items: center;"> <ui:VisualElement name="item-root" class="tree-list-item-container">
<ui:Label name="item-label" text="Item Name" class="item-label-style" style="flex-grow: 1; margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; padding-left: 4px; padding-top: 0; padding-bottom: 0; padding-right: 4px; color: rgb(204, 204, 204); font-size: 11px; -unity-font-definition: resource(&apos;Fonts/Pretendard/Pretendard-Bold&apos;);" /> <ui:Label name="item-label" text="Item Name" class="item-label-style" />
<ui:Button name="visibility-btn" class="visibility-toggle" style="width: 22px;" /> <utk:UTKButton name="visibility-btn" icon="visibility" icon-size="12" icon-only="true" variant="Text" />
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@@ -61,6 +61,7 @@
<!-- Circle icon buttons will be set via C# --> <!-- Circle icon buttons will be set via C# -->
<utk:UTKButton icon="settings" icon-only="true" icon-size="12" variant="Text" /> <utk:UTKButton icon="settings" icon-only="true" icon-size="12" variant="Text" />
<utk:UTKButton icon="\ue8b8" icon-only="true" icon-size="12" variant="Text" /> <utk:UTKButton icon="\ue8b8" icon-only="true" icon-size="12" variant="Text" />
<utk:UTKButton icon="visibility" icon-size="12" icon-only="true" variant="Text" />
</VisualElement> </VisualElement>
</VisualElement> </VisualElement>

View File

@@ -47,6 +47,7 @@
<VisualElement class="utk-sample-section"> <VisualElement class="utk-sample-section">
<Label class="utk-sample-section__title" text="Material Icon Only" /> <Label class="utk-sample-section__title" text="Material Icon Only" />
<VisualElement class="utk-sample-row" name="material-icon-only-row"> <VisualElement class="utk-sample-row" name="material-icon-only-row">
<utk:UTKLabel material-icon="visibility" />
<!-- Icon-only labels will be created via C# --> <!-- Icon-only labels will be created via C# -->
</VisualElement> </VisualElement>
</VisualElement> </VisualElement>

View File

@@ -10,12 +10,11 @@
=================================== */ =================================== */
.utk-window-sample-container { .utk-window-sample-container {
width: 350px; width: 300px;
height: 400px; height: 400px;
border-width: 1px; border-width: 1px;
border-color: var(--color-border-light); border-color: var(--color-border-light);
border-radius: 8px; border-radius: 8px;
background-color: var(--color-bg-tertiary);
overflow: hidden; overflow: hidden;
} }

View File

@@ -128,6 +128,7 @@
=================================== */ =================================== */
--color-bg-base: var(--color-base-20); --color-bg-base: var(--color-base-20);
--color-bg-secondary: var(--color-base-19); --color-bg-secondary: var(--color-base-19);
--color-bg-tertiary: var(--color-base-13);
--color-bg-elevated: var(--color-base-18); --color-bg-elevated: var(--color-base-18);
--color-bg-modal: var(--color-base-18); --color-bg-modal: var(--color-base-18);
--color-bg-panel: var(--color-base-20); --color-bg-panel: var(--color-base-20);

View File

@@ -135,6 +135,7 @@
=================================== */ =================================== */
--color-bg-base: var(--color-base-01); --color-bg-base: var(--color-base-01);
--color-bg-secondary: var(--color-base-03); --color-bg-secondary: var(--color-base-03);
--color-bg-tertiary: var(--color-base-08);
--color-bg-elevated: var(--color-base-02); --color-bg-elevated: var(--color-base-02);
--color-bg-modal: var(--color-base-02); --color-bg-modal: var(--color-base-02);
--color-bg-panel: var(--color-base-01); --color-bg-panel: var(--color-base-01);

View File

@@ -7,18 +7,12 @@
UTKComponentListWindow { UTKComponentListWindow {
height: 100%; height: 100%;
position: absolute; flex-grow: 1;
top: 0;
left: 0;
bottom: 0;
} }
UTKComponentTabListWindow { UTKComponentTabListWindow {
height: 100%; height: 100%;
position: absolute; flex-grow: 1;
top: 0;
left: 400px;
bottom: 0;
} }
.container { .container {
@@ -41,7 +35,7 @@ UTKComponentTabListWindow {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 5px; margin-bottom: 10px;
height: 24px; height: 24px;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -73,36 +67,38 @@ UTKComponentTabListWindow {
} }
/* ============================================ /* ============================================
탭 버튼 (Tab Buttons) 탭 버튼 (Tab Buttons) - UTKTabView 스타일 적용
============================================ */ ============================================ */
.tab-button { .tab-button {
background-color: var(--color-base-03); background-color: transparent;
border-width: 0; border-width: 0;
border-radius: 0px; border-bottom-width: 2px;
padding-left: 12px; border-bottom-color: transparent;
padding-right: 12px; padding: var(--space-s) var(--space-l);
padding-top: 4px; margin-right: var(--space-s);
padding-bottom: 4px;
margin-right: 1px;
margin-left: 0; margin-left: 0;
margin-top: 0; margin-top: 0;
margin-bottom: 0; margin-bottom: 0;
color: var(--color-text-secondary); color: var(--color-text-secondary);
font-size: var(--font-size-label3); font-size: var(--font-size-body2);
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium'); -unity-font-definition: resource('Fonts/Pretendard/Pretendard-Medium');
flex-shrink: 0; flex-shrink: 0;
transition-duration: var(--anim-fast);
transition-property: background-color, border-color, color;
} }
.tab-button:hover { .tab-button:hover {
background-color: var(--color-base-05); background-color: var(--color-btn-hover);
} }
.tab-button-selected { .tab-button-selected {
background-color: var(--color-base-07); background-color: transparent;
color: var(--color-text-primary); color: var(--color-btn-primary);
border-bottom-color: var(--color-btn-primary);
-unity-font-style: bold;
} }
.tab-button-selected:hover { .tab-button-selected:hover {
background-color: var(--color-base-09); background-color: var(--color-btn-hover);
} }

View File

@@ -1,33 +1,13 @@
<ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <ui:UXML xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" xmlns:utk="UVC.UIToolkit" noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd" editor-extension-mode="False">
xmlns:ui="UnityEngine.UIElements" <Style src="project://database/Assets/Resources/UIToolkit/Window/UTKTreeListWindowUss.uss?fileID=7433441132597879392&amp;guid=94bace9f4fd4e854b80330dc68b0ebed&amp;type=3#UTKTreeListWindowUss" />
xmlns:uie="UnityEditor.UIElements"
xmlns:utk="UVC.UIToolkit"
noNamespaceSchemaLocation="../../../../../UIElementsSchema/UIElements.xsd"
editor-extension-mode="False">
<!--
UTKTreeListWindow.uxml
TreeView 기반의 계층 리스트 윈도우 컴포넌트입니다.
헤더(타이틀, 닫기 버튼), 검색 필드, TreeView로 구성됩니다.
구조:
- container: 메인 컨테이너
- header: 윈도우 헤더
- title: 윈도우 제목
- close-btn: UTKButton 닫기 버튼
- search-field: 검색 입력 필드
- clear-btn: UTKButton 검색어 지우기 버튼
- main-tree-view: TreeView
-->
<!-- Style은 C# 코드에서 테마 적용 후 로드됩니다 -->
<ui:VisualElement name="container" class="tree-menu-container"> <ui:VisualElement name="container" class="tree-menu-container">
<ui:VisualElement name="header" class="tree-window-header"> <ui:VisualElement name="header" class="tree-window-header">
<ui:Label name="title" text="HIERARCHY" class="tree-window-title" /> <ui:Label name="title" text="HIERARCHY" class="tree-window-title" />
<utk:UTKButton name="close-btn" variant="Ghost" icon-only="true" class="tree-window-close-button" /> <utk:UTKButton name="close-btn" variant="Text" icon-only="true" class="tree-window-close-button" />
</ui:VisualElement> </ui:VisualElement>
<ui:TextField name="search-field" placeholder-text="검색" class="search-field"> <ui:TextField name="search-field" placeholder-text="검색" class="search-field">
<utk:UTKButton name="clear-btn" variant="Text" icon-only="true" class="search-clear-button" /> <utk:UTKButton name="clear-btn" variant="Text" icon-only="true" class="search-clear-button" />
</ui:TextField> </ui:TextField>
<ui:TreeView name="main-tree-view" view-data-key="model-tree-view" fixed-item-height="18" auto-expand="false" item-template="project://database/Assets/Resources/UIToolkit/List/UTKTreeListItem.uxml" horizontal-scrolling="true" selection-type="Multiple" style="flex-grow: 1;" /> <ui:TreeView name="main-tree-view" view-data-key="model-tree-view" fixed-item-height="20" auto-expand="false" item-template="project://database/Assets/Resources/UIToolkit/List/UTKTreeListItem.uxml" horizontal-scrolling="true" selection-type="Multiple" style="flex-grow: 1;" />
</ui:VisualElement> </ui:VisualElement>
</ui:UXML> </ui:UXML>

View File

@@ -32,7 +32,7 @@ UTKTreeListWindow {
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 5px; margin-bottom: 10px;
height: 24px; height: 24px;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -93,32 +93,31 @@ UTKTreeListWindow {
} }
/* ============================================ /* ============================================
Visibility 토글 (Visibility Toggle) TreeView 아이템 컨테이너 (TreeView Item Container)
============================================ */ ============================================ */
.visibility-toggle { .unity-tree-view__item-content TemplateContainer {
background-color: rgba(0, 0, 0, 0); flex-grow: 1;
border-width: 0; }
width: 16px;
height: 16px; /* ============================================
margin-top: 0; 트리 리스트 아이템 (Tree List Item) - UTKTreeListItem
margin-bottom: 0; ============================================ */
padding-top: 0;
padding-bottom: 0; .tree-list-item-container {
margin-right: 0; flex-direction: row;
justify-content: space-between;
align-items: center; align-items: center;
justify-content: center; height: 18px;
padding-right: 0; padding: 0 8px 0 0;
padding-left: 0;
margin-left: 0;
flex-shrink: 0;
background-image: resource('UIToolkit/Images/icon_eye_22x16');
} }
.visibility-on { .tree-list-item-container .item-label-style {
background-image: resource('UIToolkit/Images/icon_eye_22x16'); flex-grow: 1;
} margin: 0;
padding: 0 4px;
.visibility-off { color: var(--color-text-primary);
background-image: resource('UIToolkit/Images/icon_eye_close_22x16'); font-size: var(--font-size-label3);
-unity-font-definition: resource('Fonts/Pretendard/Pretendard-Bold');
-unity-text-align: middle-left;
} }

View File

@@ -249,9 +249,15 @@ accordionWindow.Show();");
var componentWindow = new UTKComponentListWindow(); var componentWindow = new UTKComponentListWindow();
componentWindow.Title = "모델 리스트"; componentWindow.Title = "모델 리스트";
componentWindow.ShowCloseButton = true; componentWindow.ShowCloseButton = true;
componentWindow.OnItemIconClicked += (itemType, itemData) =>
{
Debug.Log($"아이콘 클릭됨: {itemType}, {itemData.name})");
};
componentWindow.OnItemVisibilityChanged += (itemData, isVisible) =>
{
Debug.Log($"가시성 변경됨: {itemData.name}, IsVisible={isVisible})");
};
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(componentWindow);
// 샘플 데이터 // 샘플 데이터
var category1 = new UTKComponentListCategoryData { name = "캐릭터", isExpanded = true }; var category1 = new UTKComponentListCategoryData { name = "캐릭터", isExpanded = true };
@@ -275,9 +281,6 @@ var componentWindow = new UTKComponentListWindow();
componentWindow.Title = ""모델 리스트""; componentWindow.Title = ""모델 리스트"";
componentWindow.ShowCloseButton = true; componentWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(componentWindow);
// 샘플 데이터 // 샘플 데이터
var category1 = new UTKComponentListCategoryData { name = ""캐릭터"", isExpanded = true }; var category1 = new UTKComponentListCategoryData { name = ""캐릭터"", isExpanded = true };
category1.Add(new UTKComponentListItemData { name = ""플레이어"", ExternalKey = ""player_001"", IsVisible = true }); category1.Add(new UTKComponentListItemData { name = ""플레이어"", ExternalKey = ""player_001"", IsVisible = true });
@@ -302,9 +305,6 @@ componentWindow.Show();");
tabWindow.Title = "모델 라이브러리"; tabWindow.Title = "모델 라이브러리";
tabWindow.ShowCloseButton = true; tabWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(tabWindow);
// 샘플 데이터 (카테고리가 탭으로 자동 생성됨) // 샘플 데이터 (카테고리가 탭으로 자동 생성됨)
var category1 = new UTKComponentListCategoryData { name = "캐릭터", isExpanded = true }; var category1 = new UTKComponentListCategoryData { name = "캐릭터", isExpanded = true };
category1.Add(new UTKComponentListItemData { name = "플레이어", IsVisible = true }); category1.Add(new UTKComponentListItemData { name = "플레이어", IsVisible = true });
@@ -330,9 +330,6 @@ var tabWindow = new UTKComponentTabListWindow();
tabWindow.Title = ""모델 라이브러리""; tabWindow.Title = ""모델 라이브러리"";
tabWindow.ShowCloseButton = true; tabWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(tabWindow);
// 샘플 데이터 (카테고리가 탭으로 자동 생성됨) // 샘플 데이터 (카테고리가 탭으로 자동 생성됨)
var category1 = new UTKComponentListCategoryData { name = ""캐릭터"", isExpanded = true }; var category1 = new UTKComponentListCategoryData { name = ""캐릭터"", isExpanded = true };
category1.Add(new UTKComponentListItemData { name = ""플레이어"", IsVisible = true }); category1.Add(new UTKComponentListItemData { name = ""플레이어"", IsVisible = true });
@@ -360,16 +357,13 @@ tabWindow.Show();");
imageWindow.Title = "텍스처 라이브러리"; imageWindow.Title = "텍스처 라이브러리";
imageWindow.ShowCloseButton = true; imageWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(imageWindow);
// 샘플 데이터 // 샘플 데이터
var data = new List<UTKImageListItemData> var data = new List<UTKImageListItemData>
{ {
new UTKImageListItemData { itemName = "Texture_01", externalId = "tex_001" }, 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" }, 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" }, 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" } new UTKImageListItemData { itemName = "Texture_04", externalId = "tex_004", imagePath = "Simulator/Images/lib_forklift_400x300", objectPrefabPath = "Simulator/FreeForkLift/Prefabs/Forklift" }
}; };
imageWindow.SetData(data); imageWindow.SetData(data);
imageWindow.Show(); imageWindow.Show();
@@ -382,16 +376,13 @@ var imageWindow = new UTKImageListWindow();
imageWindow.Title = ""텍스처 라이브러리""; imageWindow.Title = ""텍스처 라이브러리"";
imageWindow.ShowCloseButton = true; imageWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(imageWindow);
// 샘플 데이터 // 샘플 데이터
var data = new List<UTKImageListItemData> var data = new List<UTKImageListItemData>
{ {
new UTKImageListItemData { itemName = ""Texture_01"", externalId = ""tex_001"" }, 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"" }, 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"" }, 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"" } new UTKImageListItemData { itemName = ""Texture_04"", externalId = ""tex_004"", imagePath = ""Simulator/Images/lib_forklift_400x300"", objectPrefabPath = ""Simulator/FreeForkLift/Prefabs/Forklift"" }
}; };
imageWindow.SetData(data); imageWindow.SetData(data);
imageWindow.Show();"); imageWindow.Show();");
@@ -406,8 +397,10 @@ imageWindow.Show();");
treeWindow.Title = "씬 계층 구조"; treeWindow.Title = "씬 계층 구조";
treeWindow.ShowCloseButton = true; treeWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독 treeWindow.OnItemSelected += (itemDataList) =>
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(treeWindow); {
Debug.Log($"선택된 아이템: {string.Join(", ", itemDataList.ConvertAll(i => i.name))}");
};
// 샘플 데이터 // 샘플 데이터
var environment = new UTKTreeListItemData { name = "Environment", isExpanded = true }; var environment = new UTKTreeListItemData { name = "Environment", isExpanded = true };
@@ -434,9 +427,6 @@ var treeWindow = new UTKTreeListWindow();
treeWindow.Title = ""씬 계층 구조""; treeWindow.Title = ""씬 계층 구조"";
treeWindow.ShowCloseButton = true; treeWindow.ShowCloseButton = true;
// 테마 변경 이벤트 구독
UTKThemeManager.Instance.OnThemeChanged += _ => UTKThemeManager.Instance.ApplyThemeToElement(treeWindow);
// 샘플 데이터 // 샘플 데이터
var environment = new UTKTreeListItemData { name = ""Environment"", isExpanded = 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 = ""Terrain"", ExternalKey = ""terrain_001"", IsVisible = true });

View File

@@ -94,11 +94,11 @@ namespace UVC.UIToolkit
/// var circleBtn6 = new UTKButton("", UTKMaterialIcons.Edit, ButtonVariant.Text, 12) { IconOnly = true }; /// var circleBtn6 = new UTKButton("", UTKMaterialIcons.Edit, ButtonVariant.Text, 12) { IconOnly = true };
/// ///
/// // UXML 태그 /// // UXML 태그
/// // <utk:UTKButton icon="home;" icon-only="true" icon-size="12" variant="Text" /> /// // <utk:UTKButton icon="home" icon-only="true" icon-size="12" variant="Text" />
/// // <utk:UTKButton icon="close;" icon-only="true" icon-size="12" variant="Text" /> /// // <utk:UTKButton icon="close" icon-only="true" icon-size="12" variant="Text" />
/// // <utk:UTKButton icon="check;" icon-only="true" icon-size="12" variant="Text" /> /// // <utk:UTKButton icon="check" icon-only="true" icon-size="12" variant="Text" />
/// // <utk:UTKButton icon="search;" icon-only="true" icon-size="12" variant="Text" /> /// // <utk:UTKButton icon="search" icon-only="true" icon-size="12" variant="Text" />
/// // <utk:UTKButton icon="edit;" icon-only="true" icon-size="12" variant="Text" /> /// // <utk:UTKButton icon="edit" icon-only="true" icon-size="12" variant="Text" />
/// </code> /// </code>
/// ///
/// <para><b>7. Disabled (비활성화)</b></para> /// <para><b>7. Disabled (비활성화)</b></para>
@@ -303,7 +303,6 @@ namespace UVC.UIToolkit
//if(iconSizeValue == value) return; //if(iconSizeValue == value) return;
iconSizeValue = value; iconSizeValue = value;
string iconChar = UTKMaterialIcons.GetIcon(iconValue); string iconChar = UTKMaterialIcons.GetIcon(iconValue);
Debug.Log($"[UTKButton] Update Icon Size: {iconSizeValue} {iconValue} -> {iconChar}");
if (iconChar != string.Empty) if (iconChar != string.Empty)
{ {
UpdateMaterialIconSize(iconSizeValue); UpdateMaterialIconSize(iconSizeValue);
@@ -473,10 +472,21 @@ namespace UVC.UIToolkit
private void SubscribeToThemeChanges() private void SubscribeToThemeChanges()
{ {
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged; UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback<DetachFromPanelEvent>(_ => RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
{ RegisterCallback<AttachToPanelEvent>(OnReattachToPanel);
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged; }
});
private void OnDetachFromPanel(DetachFromPanelEvent evt)
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
}
private void OnReattachToPanel(AttachToPanelEvent evt)
{
// TreeView 가상화로 인해 재연결 시 테마 재적용
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged; // 중복 방지
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
UTKThemeManager.Instance.ApplyThemeToElement(this);
} }
private void OnThemeChanged(UTKTheme theme) private void OnThemeChanged(UTKTheme theme)
@@ -641,11 +651,7 @@ namespace UVC.UIToolkit
{ {
ClearImageIcon(); ClearImageIcon();
Icon = icon; Icon = icon;
UpdateMaterialIconSize(fontSize);
if (_iconLabel != null)
{
UTKMaterialIcons.ApplyIconStyle(_iconLabel, fontSize ?? GetDefaultIconSize());
}
} }
private void UpdateMaterialIconSize(int? fontSize) private void UpdateMaterialIconSize(int? fontSize)

View File

@@ -468,10 +468,21 @@ namespace UVC.UIToolkit
private void SubscribeToThemeChanges() private void SubscribeToThemeChanges()
{ {
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged; UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback<DetachFromPanelEvent>(_ => RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
{ RegisterCallback<AttachToPanelEvent>(OnReattachToPanel);
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged; }
});
private void OnDetachFromPanel(DetachFromPanelEvent evt)
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
}
private void OnReattachToPanel(AttachToPanelEvent evt)
{
// TreeView 가상화로 인해 재연결 시 테마 재적용
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged; // 중복 방지
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
UTKThemeManager.Instance.ApplyThemeToElement(this);
} }
private void OnThemeChanged(UTKTheme theme) private void OnThemeChanged(UTKTheme theme)

View File

@@ -120,7 +120,7 @@ namespace UVC.UIToolkit
/// <item>Resources/UIToolkit/List/UTKAccordionSection.uxml - 섹션 템플릿</item> /// <item>Resources/UIToolkit/List/UTKAccordionSection.uxml - 섹션 템플릿</item>
/// <item>Resources/UIToolkit/List/UTKAccordionHorizontalItem.uxml - 수평 아이템 템플릿</item> /// <item>Resources/UIToolkit/List/UTKAccordionHorizontalItem.uxml - 수평 아이템 템플릿</item>
/// <item>Resources/UIToolkit/List/UTKAccordionGridItem.uxml - 그리드 아이템 템플릿</item> /// <item>Resources/UIToolkit/List/UTKAccordionGridItem.uxml - 그리드 아이템 템플릿</item>
/// <item>Resources/UIToolkit/List/UTKAccordionList.uss - 스타일</item> /// <item>Resources/UIToolkit/List/UTKAccordionListUss.uss - 스타일</item>
/// </list> /// </list>
/// </summary> /// </summary>
[UxmlElement] [UxmlElement]
@@ -1010,13 +1010,10 @@ namespace UVC.UIToolkit
private void SetupContentImage(VisualElement imageElement, UTKAccordionContentSpec spec) private void SetupContentImage(VisualElement imageElement, UTKAccordionContentSpec spec)
{ {
if (spec.Kind == UTKAccordionContentKind.Image && !string.IsNullOrEmpty(spec.ImagePath)) if (spec.Kind == UTKAccordionContentKind.Image && !string.IsNullOrEmpty(spec.ImagePath))
{ {
string iconChar = UTKMaterialIcons.GetIcon(spec.ImagePath); string iconChar = UTKMaterialIcons.GetIcon(spec.ImagePath);
Debug.Log($"[UTKAccordionList] Content image path: '{spec.ImagePath} ' → icon char: '{iconChar}'");
if (iconChar != string.Empty) if (iconChar != string.Empty)
{ {
Debug.Log($"[UTKAccordionList] Using material icon '{spec.ImagePath}' for content image.");
// 머티리얼 아이콘 사용 // 머티리얼 아이콘 사용
Label iconLabel = new Label(iconChar); Label iconLabel = new Label(iconChar);
UTKMaterialIcons.ApplyIconStyle(iconLabel, null); //uss에서 설정하기에 null 전달 UTKMaterialIcons.ApplyIconStyle(iconLabel, null); //uss에서 설정하기에 null 전달

View File

@@ -1284,6 +1284,9 @@ namespace UVC.UIToolkit
treeViewItem.UnregisterCallback(oldHandler, TrickleDown.TrickleDown); treeViewItem.UnregisterCallback(oldHandler, TrickleDown.TrickleDown);
} }
// setting-btn 참조 캡처 (클릭 영역 확인용)
var settingBtnForHandler = element.Q<UTKButton>("setting-btn");
EventCallback<PointerDownEvent> categoryClickHandler = (evt) => EventCallback<PointerDownEvent> categoryClickHandler = (evt) =>
{ {
// 토글(화살표) 영역 클릭은 허용 (펼치기/접기 기능 유지) // 토글(화살표) 영역 클릭은 허용 (펼치기/접기 기능 유지)
@@ -1292,6 +1295,12 @@ namespace UVC.UIToolkit
return; // 토글 클릭은 통과 return; // 토글 클릭은 통과
} }
// setting-btn 클릭 영역은 허용 (버튼 이벤트가 처리되도록)
if (settingBtnForHandler != null && settingBtnForHandler.worldBound.Contains(evt.position))
{
return; // setting-btn 클릭은 통과
}
// 카테고리 클릭 시 이벤트 전파 완전 차단 // 카테고리 클릭 시 이벤트 전파 완전 차단
// 이렇게 하면 TreeView의 선택 로직이 실행되지 않음 // 이렇게 하면 TreeView의 선택 로직이 실행되지 않음
evt.StopImmediatePropagation(); evt.StopImmediatePropagation();
@@ -1451,11 +1460,11 @@ namespace UVC.UIToolkit
{ {
if (isVisible) if (isVisible)
{ {
btn.SetMaterialIcon("visibility"); btn.SetMaterialIcon(UTKMaterialIcons.Visibility, 12);
} }
else else
{ {
btn.SetMaterialIcon("visibility_off"); btn.SetMaterialIcon(UTKMaterialIcons.VisibilityOff, 12);
} }
} }
#endregion #endregion

View File

@@ -147,7 +147,7 @@ namespace UVC.UIToolkit
/// <list type="bullet"> /// <list type="bullet">
/// <item>Resources/UIToolkit/List/UTKImageList.uxml - 메인 레이아웃</item> /// <item>Resources/UIToolkit/List/UTKImageList.uxml - 메인 레이아웃</item>
/// <item>Resources/UIToolkit/List/UTKImageListItem.uxml - 행 템플릿 (2열)</item> /// <item>Resources/UIToolkit/List/UTKImageListItem.uxml - 행 템플릿 (2열)</item>
/// <item>Resources/UIToolkit/List/UTKImageList.uss - 스타일</item> /// <item>Resources/UIToolkit/List/UTKImageListUss.uss - 스타일</item>
/// </list> /// </list>
/// </summary> /// </summary>
[UxmlElement] [UxmlElement]

View File

@@ -46,13 +46,13 @@ namespace UVC.UIToolkit
/// { /// {
/// itemName = "의자", /// itemName = "의자",
/// imagePath = "Prefabs/Thumbnails/chair", /// imagePath = "Prefabs/Thumbnails/chair",
/// prefabPath = "Prefabs/Furniture/Chair" /// objectPrefabPath = "Prefabs/Furniture/Chair"
/// }, /// },
/// new UTKImageListItemData /// new UTKImageListItemData
/// { /// {
/// itemName = "책상", /// itemName = "책상",
/// imagePath = "Prefabs/Thumbnails/desk", /// imagePath = "Prefabs/Thumbnails/desk",
/// prefabPath = "Prefabs/Furniture/Desk" /// objectPrefabPath = "Prefabs/Furniture/Desk"
/// } /// }
/// }; /// };
/// imageWindow.SetData(data); /// imageWindow.SetData(data);
@@ -84,9 +84,9 @@ namespace UVC.UIToolkit
/// // 8. 드롭 이벤트 (프리팹 인스턴스화) /// // 8. 드롭 이벤트 (프리팹 인스턴스화)
/// imageWindow.OnItemDrop = (item) => /// imageWindow.OnItemDrop = (item) =>
/// { /// {
/// if (!string.IsNullOrEmpty(item.prefabPath)) /// if (!string.IsNullOrEmpty(item.objectPrefabPath))
/// { /// {
/// var prefab = Resources.Load<GameObject>(item.prefabPath); /// var prefab = Resources.Load<GameObject>(item.objectPrefabPath);
/// Instantiate(prefab, dropPosition, Quaternion.identity); /// Instantiate(prefab, dropPosition, Quaternion.identity);
/// } /// }
/// }; /// };
@@ -95,7 +95,7 @@ namespace UVC.UIToolkit
/// imageWindow.OnDragExitList = (item, screenPos) => /// imageWindow.OnDragExitList = (item, screenPos) =>
/// { /// {
/// // 리스트 밖 = 3D 씬 영역 /// // 리스트 밖 = 3D 씬 영역
/// Show3DPreview(item.prefabPath, screenPos); /// Show3DPreview(item.objectPrefabPath, screenPos);
/// }; /// };
/// ///
/// // 10. 리스트 영역으로 다시 들어오면 미리보기 숨김 /// // 10. 리스트 영역으로 다시 들어오면 미리보기 숨김

View File

@@ -293,6 +293,7 @@ namespace UVC.UIToolkit
// 2. 테마 적용 // 2. 테마 적용
UTKThemeManager.Instance.ApplyThemeToElement(this); UTKThemeManager.Instance.ApplyThemeToElement(this);
SubscribeToThemeChanges();
// USS 로드 (테마 변수 스타일시트 이후에 로드되어야 변수가 해석됨) // USS 로드 (테마 변수 스타일시트 이후에 로드되어야 변수가 해석됨)
var uss = Resources.Load<StyleSheet>(USS_PATH); var uss = Resources.Load<StyleSheet>(USS_PATH);
@@ -1153,29 +1154,31 @@ namespace UVC.UIToolkit
if (label != null) label.text = item.name; if (label != null) label.text = item.name;
// 2. 가시성 아이콘 버튼 설정 // 2. 가시성 아이콘 버튼 설정
var toggleBtn = element.Q<Button>("visibility-btn"); var toggleBtn = element.Q<UTKButton>("visibility-btn");
if (toggleBtn != null) UpdateVisibilityIcon(toggleBtn, item.IsVisible); if (toggleBtn != null) {
// 3. 가시성 버튼 클릭 이벤트 연결
// 주의: bindItem은 스크롤 시 재호출되므로 기존 이벤트 제거 후 재등록
if (toggleBtn.userData is Action oldAction) toggleBtn.clicked -= oldAction;
System.Action clickAction = () =>
{
// 가시성 상태 토글
item.IsVisible = !item.IsVisible;
UpdateVisibilityIcon(toggleBtn, item.IsVisible); UpdateVisibilityIcon(toggleBtn, item.IsVisible);
// 자식들에게 동일 상태 전파 // 3. 가시성 버튼 클릭 이벤트 연결
SetChildrenVisibility(item, item.IsVisible); // 주의: bindItem은 스크롤 시 재호출되므로 기존 이벤트 제거 후 재등록
if (toggleBtn.userData is Action oldAction) toggleBtn.OnClicked -= oldAction;
System.Action clickAction = () =>
{
// 가시성 상태 토글
item.IsVisible = !item.IsVisible;
UpdateVisibilityIcon(toggleBtn, item.IsVisible);
// 화면에 보이는 자식 아이콘도 갱신 // 자식들에게 동일 상태 전파
_treeView.RefreshItems(); SetChildrenVisibility(item, item.IsVisible);
// 외부에 이벤트 발송 (3D 모델 가시성 동기화) // 화면에 보이는 자식 아이콘도 갱신
OnItemVisibilityChanged?.Invoke(item, item.IsVisible); _treeView.RefreshItems();
};
toggleBtn.userData = clickAction; // 외부에 이벤트 발송 (3D 모델 가시성 동기화)
toggleBtn.clicked += clickAction; OnItemVisibilityChanged?.Invoke(item, item.IsVisible);
};
toggleBtn.userData = clickAction;
toggleBtn.OnClicked += clickAction;
}
} }
#endregion #endregion
@@ -1204,17 +1207,15 @@ namespace UVC.UIToolkit
/// </summary> /// </summary>
/// <param name="btn">가시성 토글 버튼</param> /// <param name="btn">가시성 토글 버튼</param>
/// <param name="isVisible">현재 가시성 상태</param> /// <param name="isVisible">현재 가시성 상태</param>
private void UpdateVisibilityIcon(Button btn, bool isVisible) private void UpdateVisibilityIcon(UTKButton btn, bool isVisible)
{ {
if (isVisible) if (isVisible)
{ {
btn.RemoveFromClassList("visibility-off"); btn.SetMaterialIcon(UTKMaterialIcons.Visibility, 12);
btn.AddToClassList("visibility-on");
} }
else else
{ {
btn.RemoveFromClassList("visibility-on"); btn.SetMaterialIcon(UTKMaterialIcons.VisibilityOff, 12);
btn.AddToClassList("visibility-off");
} }
} }
#endregion #endregion
@@ -1394,6 +1395,24 @@ namespace UVC.UIToolkit
} }
#endregion #endregion
#region (Theme)
private void SubscribeToThemeChanges()
{
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback<DetachFromPanelEvent>(_ =>
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
});
}
private void OnThemeChanged(UTKTheme theme)
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
}
#endregion
#region IDisposable #region IDisposable
/// <summary> /// <summary>
/// 리소스를 해제하고 이벤트 핸들러를 정리합니다. /// 리소스를 해제하고 이벤트 핸들러를 정리합니다.
@@ -1403,6 +1422,9 @@ namespace UVC.UIToolkit
if (_disposed) return; if (_disposed) return;
_disposed = true; _disposed = true;
// 테마 변경 이벤트 해제
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
// 검색 필드 이벤트 해제 // 검색 필드 이벤트 해제
if (_searchField != null) if (_searchField != null)
{ {