스타일 가이드 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

@@ -94,11 +94,11 @@ namespace UVC.UIToolkit
/// var circleBtn6 = new UTKButton("", UTKMaterialIcons.Edit, ButtonVariant.Text, 12) { IconOnly = true };
///
/// // UXML 태그
/// // <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="check;" 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="home" 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="search" icon-only="true" icon-size="12" variant="Text" />
/// // <utk:UTKButton icon="edit" icon-only="true" icon-size="12" variant="Text" />
/// </code>
///
/// <para><b>7. Disabled (비활성화)</b></para>
@@ -303,7 +303,6 @@ namespace UVC.UIToolkit
//if(iconSizeValue == value) return;
iconSizeValue = value;
string iconChar = UTKMaterialIcons.GetIcon(iconValue);
Debug.Log($"[UTKButton] Update Icon Size: {iconSizeValue} {iconValue} -> {iconChar}");
if (iconChar != string.Empty)
{
UpdateMaterialIconSize(iconSizeValue);
@@ -473,10 +472,21 @@ namespace UVC.UIToolkit
private void SubscribeToThemeChanges()
{
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback<DetachFromPanelEvent>(_ =>
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
});
RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
RegisterCallback<AttachToPanelEvent>(OnReattachToPanel);
}
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)
@@ -641,11 +651,7 @@ namespace UVC.UIToolkit
{
ClearImageIcon();
Icon = icon;
if (_iconLabel != null)
{
UTKMaterialIcons.ApplyIconStyle(_iconLabel, fontSize ?? GetDefaultIconSize());
}
UpdateMaterialIconSize(fontSize);
}
private void UpdateMaterialIconSize(int? fontSize)

View File

@@ -468,10 +468,21 @@ namespace UVC.UIToolkit
private void SubscribeToThemeChanges()
{
UTKThemeManager.Instance.OnThemeChanged += OnThemeChanged;
RegisterCallback<DetachFromPanelEvent>(_ =>
{
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
});
RegisterCallback<DetachFromPanelEvent>(OnDetachFromPanel);
RegisterCallback<AttachToPanelEvent>(OnReattachToPanel);
}
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)

View File

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

View File

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

View File

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

View File

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

View File

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