UIToolkit Sample uxml로 전환

This commit is contained in:
logonkhi
2026-01-20 20:18:47 +09:00
parent ee86f93814
commit fd8f8c6de0
202 changed files with 3614 additions and 1440 deletions

View File

@@ -123,14 +123,15 @@ namespace UVC.UIToolkit
private Label? _textLabel;
private VisualElement? _imageIcon;
private string _text = "";
private string _icon = "";
private ButtonVariant _variant = ButtonVariant.Normal;
private ButtonSize _size = ButtonSize.Medium;
// UXML 직렬화용 backing field - 이름을 소스 생성기가 인식하지 못하게 변경
private string textValue = "";
private string iconValue = "";
private ButtonVariant variantValue = ButtonVariant.Normal;
private ButtonSize sizeValue = ButtonSize.Medium;
private Color? _backgroundColor;
private int _borderWidth = -1;
private bool _iconOnly;
private bool _isEnabled = true;
private int borderWidthValue = -1;
private bool iconOnlyValue;
private bool isEnabledValue = true;
#endregion
#region Events
@@ -140,49 +141,49 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>버튼 텍스트</summary>
[UxmlAttribute]
[UxmlAttribute("text")]
public string Text
{
get => _text;
get => textValue;
set
{
_text = value;
textValue = value;
UpdateContent();
}
}
/// <summary>아이콘 (유니코드 문자 또는 텍스트)</summary>
[UxmlAttribute]
[UxmlAttribute("icon")]
public string Icon
{
get => _icon;
get => iconValue;
set
{
_icon = value;
iconValue = value;
UpdateContent();
}
}
/// <summary>버튼 스타일 변형</summary>
[UxmlAttribute]
[UxmlAttribute("variant")]
public ButtonVariant Variant
{
get => _variant;
get => variantValue;
set
{
_variant = value;
variantValue = value;
UpdateVariant();
}
}
/// <summary>버튼 크기</summary>
[UxmlAttribute]
[UxmlAttribute("size")]
public ButtonSize Size
{
get => _size;
get => sizeValue;
set
{
_size = value;
sizeValue = value;
UpdateSize();
}
}
@@ -199,37 +200,37 @@ namespace UVC.UIToolkit
}
/// <summary>외곽선 굵기 (-1이면 기본값 사용)</summary>
[UxmlAttribute]
[UxmlAttribute("border-width")]
public int BorderWidth
{
get => _borderWidth;
get => borderWidthValue;
set
{
_borderWidth = value;
borderWidthValue = value;
UpdateCustomStyles();
}
}
/// <summary>아이콘만 표시 모드</summary>
[UxmlAttribute]
[UxmlAttribute("icon-only")]
public bool IconOnly
{
get => _iconOnly;
get => iconOnlyValue;
set
{
_iconOnly = value;
iconOnlyValue = value;
UpdateContent();
}
}
/// <summary>버튼 활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;
get => isEnabledValue;
set
{
_isEnabled = value;
isEnabledValue = value;
SetEnabled(value);
EnableInClassList("utk-button--disabled", !value);
}
@@ -275,12 +276,9 @@ namespace UVC.UIToolkit
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(_ =>
{
UpdateContent();
UpdateVariant();
UpdateSize();
});
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
/// <summary>
@@ -298,9 +296,9 @@ namespace UVC.UIToolkit
/// </remarks>
public UTKButton(string text, string icon = "", ButtonVariant variant = ButtonVariant.Normal, int? iconSize = null) : this()
{
_text = text;
_icon = icon;
_variant = variant;
textValue = text;
iconValue = icon;
variantValue = variant;
UpdateContent();
UpdateVariant();
@@ -372,16 +370,30 @@ namespace UVC.UIToolkit
#endregion
#region Event Handlers
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
UpdateContent();
UpdateVariant();
UpdateSize();
UpdateCustomStyles();
// IsEnabled 상태 적용
SetEnabled(isEnabledValue);
EnableInClassList("utk-button--disabled", !isEnabledValue);
}
private void OnClick(ClickEvent evt)
{
if (!_isEnabled) return;
if (!isEnabledValue) return;
OnClicked?.Invoke();
evt.StopPropagation();
}
private void OnKeyDown(KeyDownEvent evt)
{
if (!_isEnabled) return;
if (!isEnabledValue) return;
if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.Space)
{
OnClicked?.Invoke();
@@ -393,23 +405,23 @@ namespace UVC.UIToolkit
#region Update Methods
private void UpdateContent()
{
bool hasIcon = !string.IsNullOrEmpty(_icon);
bool hasText = !string.IsNullOrEmpty(_text);
bool hasIcon = !string.IsNullOrEmpty(iconValue);
bool hasText = !string.IsNullOrEmpty(textValue);
if (_iconLabel != null)
{
_iconLabel.text = _icon;
_iconLabel.text = iconValue;
_iconLabel.style.display = hasIcon ? DisplayStyle.Flex : DisplayStyle.None;
}
if (_textLabel != null)
{
_textLabel.text = _text;
_textLabel.style.display = (_iconOnly || !hasText) ? DisplayStyle.None : DisplayStyle.Flex;
_textLabel.text = textValue;
_textLabel.style.display = (iconOnlyValue || !hasText) ? DisplayStyle.None : DisplayStyle.Flex;
}
EnableInClassList("utk-button--icon-only", _iconOnly || (hasIcon && !hasText));
EnableInClassList("utk-button--has-icon", hasIcon && hasText && !_iconOnly);
EnableInClassList("utk-button--icon-only", iconOnlyValue || (hasIcon && !hasText));
EnableInClassList("utk-button--has-icon", hasIcon && hasText && !iconOnlyValue);
}
private void UpdateVariant()
@@ -424,7 +436,7 @@ namespace UVC.UIToolkit
RemoveFromClassList("utk-button--outline-danger");
RemoveFromClassList("utk-button--text");
var variantClass = _variant switch
var variantClass = variantValue switch
{
ButtonVariant.Primary => "utk-button--primary",
ButtonVariant.Secondary => "utk-button--secondary",
@@ -445,7 +457,7 @@ namespace UVC.UIToolkit
RemoveFromClassList("utk-button--medium");
RemoveFromClassList("utk-button--large");
var sizeClass = _size switch
var sizeClass = sizeValue switch
{
ButtonSize.Small => "utk-button--small",
ButtonSize.Large => "utk-button--large",
@@ -465,12 +477,12 @@ namespace UVC.UIToolkit
style.backgroundColor = StyleKeyword.Null;
}
if (_borderWidth >= 0)
if (borderWidthValue >= 0)
{
style.borderTopWidth = _borderWidth;
style.borderBottomWidth = _borderWidth;
style.borderLeftWidth = _borderWidth;
style.borderRightWidth = _borderWidth;
style.borderTopWidth = borderWidthValue;
style.borderBottomWidth = borderWidthValue;
style.borderLeftWidth = borderWidthValue;
style.borderRightWidth = borderWidthValue;
}
else
{
@@ -645,7 +657,7 @@ namespace UVC.UIToolkit
private int GetDefaultIconSize()
{
return _size switch
return sizeValue switch
{
ButtonSize.Small => 16,
ButtonSize.Large => 24,

View File

@@ -2,7 +2,6 @@
using System;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Common;
namespace UVC.UIToolkit
{
@@ -62,7 +61,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>라벨 텍스트</summary>
[UxmlAttribute]
[UxmlAttribute("text")]
public string Text
{
get => _text;
@@ -74,7 +73,7 @@ namespace UVC.UIToolkit
}
/// <summary>체크 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-checked")]
public bool IsChecked
{
get => _isChecked;
@@ -82,7 +81,7 @@ namespace UVC.UIToolkit
}
/// <summary>불확정 상태 (일부 선택됨)</summary>
[UxmlAttribute]
[UxmlAttribute("is-indeterminate")]
public bool IsIndeterminate
{
get => _isIndeterminate;
@@ -94,7 +93,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;
@@ -123,11 +122,9 @@ namespace UVC.UIToolkit
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(_ =>
{
if (_label != null) _label.text = _text;
UpdateState();
});
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
public UTKCheckBox(string text, bool isChecked = false) : this()
@@ -182,6 +179,18 @@ namespace UVC.UIToolkit
#endregion
#region Event Handlers
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
if (_label != null) _label.text = _text;
UpdateState();
// IsEnabled 상태 적용
SetEnabled(_isEnabled);
EnableInClassList("utk-checkbox--disabled", !_isEnabled);
}
private void OnClick(ClickEvent evt)
{
if (!_isEnabled) return;

View File

@@ -55,6 +55,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>라벨 텍스트</summary>
[UxmlAttribute("text")]
public string Text
{
get => text;
@@ -62,6 +63,7 @@ namespace UVC.UIToolkit
}
/// <summary>체크 상태</summary>
[UxmlAttribute("is-checked")]
public bool IsChecked
{
get => value;
@@ -69,7 +71,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -51,7 +51,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>토글 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-on")]
public bool IsOn
{
get => value;
@@ -59,7 +59,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -35,15 +35,15 @@ namespace UVC.UIToolkit
/// <code>
/// <ui:UXML xmlns:utk="UVC.UIToolkit">
/// <!-- 기본 카드 -->
/// <utk:UTKCard Title="제목" Subtitle="부제목" Variant="Elevated">
/// <utk:UTKCard title="제목" subtitle="부제목" variant="Elevated">
/// <ui:Label text="카드 내용" />
/// </utk:UTKCard>
///
///
/// <!-- 클릭 가능 카드 -->
/// <utk:UTKCard Title="클릭해보세요" IsClickable="true" />
///
/// <utk:UTKCard title="클릭해보세요" is-clickable="true" />
///
/// <!-- 외곽선 카드 -->
/// <utk:UTKCard Title="외곽선" Variant="Outlined" />
/// <utk:UTKCard title="외곽선" variant="Outlined" />
/// </ui:UXML>
/// </code>
/// </example>
@@ -77,7 +77,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>카드 제목</summary>
[UxmlAttribute]
[UxmlAttribute("title")]
public string Title
{
get => _title;
@@ -94,7 +94,7 @@ namespace UVC.UIToolkit
}
/// <summary>카드 부제목</summary>
[UxmlAttribute]
[UxmlAttribute("subtitle")]
public string Subtitle
{
get => _subtitle;
@@ -122,7 +122,7 @@ namespace UVC.UIToolkit
}
/// <summary>카드 스타일</summary>
[UxmlAttribute]
[UxmlAttribute("variant")]
public CardVariant Variant
{
get => _variant;
@@ -134,7 +134,7 @@ namespace UVC.UIToolkit
}
/// <summary>클릭 가능 여부</summary>
[UxmlAttribute]
[UxmlAttribute("is-clickable")]
public bool IsClickable
{
get => _isClickable;
@@ -178,21 +178,9 @@ namespace UVC.UIToolkit
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(_ =>
{
if (_titleLabel != null)
{
_titleLabel.text = _title;
_titleLabel.style.display = string.IsNullOrEmpty(_title) ? DisplayStyle.None : DisplayStyle.Flex;
}
if (_subtitleLabel != null)
{
_subtitleLabel.text = _subtitle;
_subtitleLabel.style.display = string.IsNullOrEmpty(_subtitle) ? DisplayStyle.None : DisplayStyle.Flex;
}
UpdateVariant();
UpdateHeaderVisibility();
});
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
public UTKCard(string title, string subtitle = "") : this()
@@ -265,6 +253,28 @@ namespace UVC.UIToolkit
#endregion
#region Event Handlers
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
if (_titleLabel != null)
{
_titleLabel.text = _title;
_titleLabel.style.display = string.IsNullOrEmpty(_title) ? DisplayStyle.None : DisplayStyle.Flex;
}
if (_subtitleLabel != null)
{
_subtitleLabel.text = _subtitle;
_subtitleLabel.style.display = string.IsNullOrEmpty(_subtitle) ? DisplayStyle.None : DisplayStyle.Flex;
}
UpdateVariant();
UpdateHeaderVisibility();
// IsClickable 상태 적용
EnableInClassList("utk-card--clickable", _isClickable);
focusable = _isClickable;
}
private void OnClick(ClickEvent evt)
{
if (!_isClickable) return;

View File

@@ -60,6 +60,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>메시지 텍스트</summary>
[UxmlAttribute("text")]
public string Message
{
get => text;
@@ -67,7 +68,8 @@ namespace UVC.UIToolkit
}
/// <summary>메시지 타입</summary>
public new HelpBoxMessageType messageType
[UxmlAttribute("message-type")]
public new HelpBoxMessageType MessageType
{
get => base.messageType;
set
@@ -95,8 +97,8 @@ namespace UVC.UIToolkit
public UTKHelpBox(string message, HelpBoxMessageType type = HelpBoxMessageType.Info) : this()
{
text = message;
messageType = type;
Message = message;
MessageType = type;
}
#endregion

View File

@@ -1,7 +1,7 @@
#nullable enable
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Common
namespace UVC.UIToolkit
{
/// <summary>
/// VisualElement에 대한 툴팁 확장 메서드

View File

@@ -7,7 +7,7 @@ using UnityEngine;
using UnityEngine.UIElements;
using UVC.Locale;
namespace UVC.UIToolkit.Common
namespace UVC.UIToolkit
{
/// <summary>
/// UIToolkit 기반 툴팁 매니저

View File

@@ -35,7 +35,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -56,7 +56,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -84,7 +84,7 @@ namespace UVC.UIToolkit
}
/// <summary>플레이스홀더 텍스트</summary>
[UxmlAttribute]
[UxmlAttribute("placeholder")]
public string Placeholder
{
get => textEdition.placeholder;
@@ -92,7 +92,7 @@ namespace UVC.UIToolkit
}
/// <summary>에러 메시지</summary>
[UxmlAttribute]
[UxmlAttribute("error-message")]
public string ErrorMessage
{
get => _errorMessage;
@@ -104,7 +104,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;
@@ -139,7 +139,7 @@ namespace UVC.UIToolkit
}
/// <summary>스타일 변형</summary>
[UxmlAttribute]
[UxmlAttribute("variant")]
public InputFieldVariant Variant
{
get => _variant;
@@ -176,10 +176,9 @@ namespace UVC.UIToolkit
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(_ =>
{
UpdateVariant();
});
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
public UTKInputField(string label, string placeholder = "") : this()
@@ -237,6 +236,17 @@ namespace UVC.UIToolkit
#endregion
#region Event Handlers
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
UpdateVariant();
// IsEnabled 상태 적용
SetEnabled(_isEnabled);
EnableInClassList("utk-input--disabled", !_isEnabled);
}
private void OnTextValueChanged(ChangeEvent<string> evt)
{
OnValueChanged?.Invoke(evt.newValue);

View File

@@ -56,7 +56,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -35,7 +35,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -2,9 +2,8 @@
using System;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Common;
namespace UVC.UIToolkit.Input
namespace UVC.UIToolkit
{
/// <summary>
/// 숫자 입력 필드에 위/아래 스테퍼 버튼이 붙은 컴포넌트
@@ -19,14 +18,14 @@ namespace UVC.UIToolkit.Input
#endregion
#region UXML Attributes
[UxmlAttribute]
[UxmlAttribute("value")]
public int Value
{
get => _value;
set => SetValue(value);
}
[UxmlAttribute]
[UxmlAttribute("min-value")]
public int MinValue
{
get => _minValue;
@@ -37,7 +36,7 @@ namespace UVC.UIToolkit.Input
}
}
[UxmlAttribute]
[UxmlAttribute("max-value")]
public int MaxValue
{
get => _maxValue;
@@ -48,14 +47,14 @@ namespace UVC.UIToolkit.Input
}
}
[UxmlAttribute]
[UxmlAttribute("step")]
public int Step
{
get => _step;
set => _step = Math.Max(1, value);
}
[UxmlAttribute]
[UxmlAttribute("wrap-around")]
public bool WrapAround
{
get => _wrapAround;
@@ -185,6 +184,13 @@ namespace UVC.UIToolkit.Input
ClampValue();
}
/// <summary>컴포넌트의 활성화 상태를 설정합니다.</summary>
public new void SetEnabled(bool enabled)
{
base.SetEnabled(enabled);
EnableInClassList("utk-number-stepper--disabled", !enabled);
}
/// <summary>텍스트 필드에 포커스를 설정합니다.</summary>
public new void Focus()
{

View File

@@ -105,7 +105,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>텍스트</summary>
[UxmlAttribute]
[UxmlAttribute("text")]
public string Text
{
get => _text;
@@ -117,7 +117,7 @@ namespace UVC.UIToolkit
}
/// <summary>텍스트 크기</summary>
[UxmlAttribute]
[UxmlAttribute("size")]
public LabelSize Size
{
get => _size;
@@ -129,7 +129,7 @@ namespace UVC.UIToolkit
}
/// <summary>텍스트 변형</summary>
[UxmlAttribute]
[UxmlAttribute("variant")]
public LabelVariant Variant
{
get => _variant;
@@ -141,7 +141,7 @@ namespace UVC.UIToolkit
}
/// <summary>굵은 글꼴</summary>
[UxmlAttribute]
[UxmlAttribute("is-bold")]
public bool IsBold
{
get => _isBold;
@@ -153,7 +153,7 @@ namespace UVC.UIToolkit
}
/// <summary>기울임 글꼴</summary>
[UxmlAttribute]
[UxmlAttribute("is-italic")]
public bool IsItalic
{
get => _isItalic;
@@ -165,7 +165,7 @@ namespace UVC.UIToolkit
}
/// <summary>텍스트 정렬</summary>
[UxmlAttribute]
[UxmlAttribute("text-alignment")]
public TextAlign TextAlignment
{
get => _textAlign;
@@ -177,7 +177,7 @@ namespace UVC.UIToolkit
}
/// <summary>텍스트 선택 가능 여부</summary>
[UxmlAttribute]
[UxmlAttribute("is-selectable")]
public bool IsSelectable
{
get => _isSelectable;
@@ -192,7 +192,7 @@ namespace UVC.UIToolkit
}
/// <summary>아이콘 위치 (텍스트 기준 왼쪽/오른쪽)</summary>
[UxmlAttribute]
[UxmlAttribute("icon-placement")]
public IconPosition IconPlacement
{
get => _iconPosition;
@@ -204,7 +204,7 @@ namespace UVC.UIToolkit
}
/// <summary>아이콘 크기 (0이면 텍스트 크기에 맞춤)</summary>
[UxmlAttribute]
[UxmlAttribute("icon-size")]
public int IconSize
{
get => _iconSize;
@@ -216,7 +216,7 @@ namespace UVC.UIToolkit
}
/// <summary>아이콘과 텍스트 사이 간격 (px)</summary>
[UxmlAttribute]
[UxmlAttribute("gap")]
public int Gap
{
get => _gap;
@@ -228,7 +228,7 @@ namespace UVC.UIToolkit
}
/// <summary>Material Icon 이름 (예: "settings", "home")</summary>
[UxmlAttribute]
[UxmlAttribute("material-icon")]
public string MaterialIcon
{
get => _materialIconName;
@@ -247,7 +247,7 @@ namespace UVC.UIToolkit
}
/// <summary>Image Icon 이름 (예: "icon_setting_22", "btn_close_16")</summary>
[UxmlAttribute]
[UxmlAttribute("image-icon")]
public string ImageIcon
{
get => _imageIconName;
@@ -320,13 +320,9 @@ namespace UVC.UIToolkit
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(_ =>
{
if (_label != null) _label.text = _text;
UpdateSize();
UpdateVariant();
UpdateTextAlign();
});
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
/// <summary>
@@ -436,6 +432,28 @@ namespace UVC.UIToolkit
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
}
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
if (_label != null) _label.text = _text;
UpdateSize();
UpdateVariant();
UpdateTextAlign();
EnableInClassList("utk-label--bold", _isBold);
EnableInClassList("utk-label--italic", _isItalic);
// 아이콘 속성이 설정된 경우 적용
if (!string.IsNullOrEmpty(_materialIconName))
{
SetMaterialIconByName(_materialIconName);
}
else if (!string.IsNullOrEmpty(_imageIconName))
{
SetImageIconByName(_imageIconName);
}
}
#endregion
#region Update Methods

View File

@@ -8,7 +8,7 @@ using UnityEngine;
using UnityEngine.UIElements;
using UVC.Util;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// TreeView 기반 아코디언 리스트를 표시하는 UIToolkit 컴포넌트입니다.

View File

@@ -3,7 +3,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// 콘텐츠 종류를 정의합니다.

View File

@@ -7,7 +7,7 @@ using UnityEngine.UIElements;
using UVC.Locale;
using static UVC.UIToolkit.UTKStyleGuide;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// 계층적 트리 구조를 표시하는 커스텀 UI Toolkit 컴포넌트입니다.

View File

@@ -2,7 +2,7 @@
using System;
using System.Collections.Generic;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// 트리 구조 리스트의 항목 데이터를 위한 추상 기본 클래스입니다.

View File

@@ -8,7 +8,7 @@ using UnityEngine;
using UnityEngine.UIElements;
using UVC.Util;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// 이미지가 포함된 그리드/리스트를 표시하는 UIToolkit 컴포넌트입니다.

View File

@@ -1,7 +1,7 @@
#nullable enable
using System;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// UTKImageList의 아이템 데이터 클래스입니다.

View File

@@ -2,7 +2,7 @@
using System;
using System.Collections.Generic;
namespace UVC.UIToolkit.List
namespace UVC.UIToolkit
{
/// <summary>
/// 트리 구조 리스트의 개별 항목 데이터를 나타내는 클래스입니다.

View File

@@ -3,7 +3,6 @@ using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit
{

View File

@@ -4,9 +4,7 @@ using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Common;
namespace UVC.UIToolkit.Modal
namespace UVC.UIToolkit
{
/// <summary>
/// UIToolkit 기반 컬러 피커 모달

View File

@@ -5,10 +5,8 @@ using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.Locale;
using UVC.UIToolkit.Common;
using UVC.UIToolkit.Input;
namespace UVC.UIToolkit.Modal
namespace UVC.UIToolkit
{
/// <summary>
/// UIToolkit 기반 날짜/시간 피커 모달

View File

@@ -2,7 +2,6 @@
using System;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit
{

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Modal
namespace UVC.UIToolkit
{
/// <summary>
/// 모달 뒤의 배경을 차단하고 클릭 시 닫힘 처리를 담당하는 컴포넌트

View File

@@ -3,7 +3,6 @@ using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Common;
namespace UVC.UIToolkit
{
@@ -163,12 +162,9 @@ namespace UVC.UIToolkit
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(_ =>
{
if (_titleLabel != null) _titleLabel.text = _title;
if (_messageLabel != null) _messageLabel.text = _message;
UpdateType();
});
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
public UTKNotification(string title, string message, NotificationType type = NotificationType.Info) : this()
@@ -289,6 +285,15 @@ namespace UVC.UIToolkit
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
}
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
if (_titleLabel != null) _titleLabel.text = _title;
if (_messageLabel != null) _messageLabel.text = _message;
UpdateType();
}
#endregion
#region Methods

View File

@@ -35,17 +35,17 @@ namespace UVC.UIToolkit
/// <code>
/// <ui:UXML xmlns:utk="UVC.UIToolkit">
/// <!-- 기본 패널 -->
/// <utk:UTKPanel Title="제목">
/// <utk:UTKPanel title="제목">
/// <ui:Label text="패널 내용" />
/// </utk:UTKPanel>
///
///
/// <!-- 접을 수 있는 패널 -->
/// <utk:UTKPanel Title="고급 설정" IsCollapsible="true">
/// <utk:UTKPanel title="고급 설정" is-collapsible="true">
/// <ui:Label text="내용" />
/// </utk:UTKPanel>
///
///
/// <!-- 외곽선 스타일 -->
/// <utk:UTKPanel Title="외곽선" Variant="Outlined" />
/// <utk:UTKPanel title="외곽선" variant="Outlined" />
/// </ui:UXML>
/// </code>
/// </example>
@@ -79,7 +79,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>패널 제목</summary>
[UxmlAttribute]
[UxmlAttribute("title")]
public string Title
{
get => _title;
@@ -91,7 +91,7 @@ namespace UVC.UIToolkit
}
/// <summary>헤더 표시 여부</summary>
[UxmlAttribute]
[UxmlAttribute("show-header")]
public bool ShowHeader
{
get => _showHeader;
@@ -106,7 +106,7 @@ namespace UVC.UIToolkit
}
/// <summary>푸터 표시 여부</summary>
[UxmlAttribute]
[UxmlAttribute("show-footer")]
public bool ShowFooter
{
get => _showFooter;
@@ -121,7 +121,7 @@ namespace UVC.UIToolkit
}
/// <summary>패널 스타일</summary>
[UxmlAttribute]
[UxmlAttribute("variant")]
public PanelVariant Variant
{
get => _variant;
@@ -133,7 +133,7 @@ namespace UVC.UIToolkit
}
/// <summary>접기 가능 여부</summary>
[UxmlAttribute]
[UxmlAttribute("is-collapsible")]
public bool IsCollapsible
{
get => _isCollapsible;
@@ -145,15 +145,18 @@ namespace UVC.UIToolkit
}
/// <summary>접힘 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-collapsed")]
public bool IsCollapsed
{
get => _isCollapsed;
set => SetCollapsed(value, true);
}
/// <summary>콘텐츠 영역</summary>
public VisualElement? ContentContainer => _content;
/// <summary>
/// UXML에서 자식 요소가 추가될 컨테이너.
/// 이 속성을 오버라이드하여 자식 요소들이 _content 영역에 추가되도록 합니다.
/// </summary>
public override VisualElement contentContainer => _content ?? this;
/// <summary>푸터 영역</summary>
public VisualElement? FooterContainer => _footer;
@@ -175,8 +178,10 @@ namespace UVC.UIToolkit
#region Constructor
public UTKPanel()
{
// 1. 먼저 테마 스타일시트 적용 (변수 정의)
UTKThemeManager.Instance.ApplyThemeToElement(this);
// 2. 컴포넌트 USS 적용 (변수 사용)
var uss = Resources.Load<StyleSheet>(USS_PATH);
if (uss != null)
{
@@ -186,6 +191,9 @@ namespace UVC.UIToolkit
CreateUI();
SetupEvents();
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
public UTKPanel(string title) : this()
@@ -215,6 +223,7 @@ namespace UVC.UIToolkit
// Content
_content = new VisualElement { name = "content" };
_content.AddToClassList("utk-panel__content");
_content.RegisterCallback<GeometryChangedEvent>(OnContentGeometryChanged);
hierarchy.Add(_content);
// Footer
@@ -226,6 +235,25 @@ namespace UVC.UIToolkit
UpdateVariant();
}
private void OnContentGeometryChanged(GeometryChangedEvent evt)
{
// Content 영역 내 Label 요소에 스타일 클래스 추가
ApplyContentLabelStyles();
}
private void ApplyContentLabelStyles()
{
if (_content == null) return;
foreach (var child in _content.Children())
{
if (child is Label label && !label.ClassListContains("utk-panel__content-label"))
{
label.AddToClassList("utk-panel__content-label");
}
}
}
private void SetupEvents()
{
_header?.RegisterCallback<ClickEvent>(OnHeaderClick);
@@ -247,6 +275,49 @@ namespace UVC.UIToolkit
#endregion
#region Event Handlers
private void OnAttachToPanel(AttachToPanelEvent evt)
{
// UXML 속성이 설정된 후 한 번만 UI 갱신
UnregisterCallback<AttachToPanelEvent>(OnAttachToPanel);
// Title 적용
if (_titleLabel != null)
{
_titleLabel.text = _title;
}
// Header 표시 상태 적용
if (_header != null)
{
_header.style.display = _showHeader ? DisplayStyle.Flex : DisplayStyle.None;
}
// Footer 표시 상태 적용
if (_footer != null)
{
_footer.style.display = _showFooter ? DisplayStyle.Flex : DisplayStyle.None;
}
// Variant 적용
UpdateVariant();
// Collapsible 상태 적용
EnableInClassList("utk-panel--collapsible", _isCollapsible);
// Collapsed 상태 적용
if (_isCollapsed)
{
EnableInClassList("utk-panel--collapsed", true);
if (_content != null)
{
_content.style.display = DisplayStyle.None;
}
}
// UXML 자식 요소 스타일 적용 (지연 실행)
schedule.Execute(ApplyContentLabelStyles);
}
private void OnHeaderClick(ClickEvent evt)
{
if (!_isCollapsible) return;
@@ -298,14 +369,6 @@ namespace UVC.UIToolkit
AddToClassList(variantClass);
}
/// <summary>
/// 콘텐츠 추가
/// </summary>
public new void Add(VisualElement element)
{
_content?.Add(element);
}
/// <summary>
/// 헤더 액션 추가
/// </summary>

View File

@@ -1,6 +1,6 @@
#nullable enable
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// UTKPropertyList의 모든 엔트리(그룹/아이템)의 기본 인터페이스

View File

@@ -2,7 +2,7 @@
using System;
using System.Collections.Generic;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 속성 그룹 인터페이스

View File

@@ -2,7 +2,7 @@
using System;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 개별 속성 아이템의 인터페이스

View File

@@ -2,7 +2,7 @@
using System;
using System.Collections.Generic;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 속성 그룹 구현 클래스

View File

@@ -1,6 +1,6 @@
#nullable enable
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// UTKPropertyWindow에서 지원하는 속성 타입

View File

@@ -1,7 +1,7 @@
#nullable enable
using System;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 속성 값 변경 이벤트 인자

View File

@@ -2,7 +2,7 @@
using System;
using UnityEngine;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 상태 + 색상 복합 타입

View File

@@ -1,7 +1,7 @@
#nullable enable
using System;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 범위 값을 나타내는 제네릭 구조체

View File

@@ -4,9 +4,8 @@ using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Common;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 모든 PropertyItem의 기본 추상 클래스

View File

@@ -1,7 +1,7 @@
#nullable enable
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 불리언 속성 아이템

View File

@@ -1,9 +1,8 @@
#nullable enable
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 색상 속성 아이템

View File

@@ -1,9 +1,8 @@
#nullable enable
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 상태 + 색상 복합 속성 아이템

View File

@@ -1,9 +1,8 @@
#nullable enable
using System;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 날짜 속성 아이템

View File

@@ -1,9 +1,8 @@
#nullable enable
using System;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 날짜 범위 속성 아이템

View File

@@ -1,9 +1,8 @@
#nullable enable
using System;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 날짜+시간 속성 아이템

View File

@@ -1,9 +1,8 @@
#nullable enable
using System;
using UnityEngine.UIElements;
using UVC.UIToolkit.Modal;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 날짜시간 범위 속성 아이템

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 드롭다운 목록 속성 아이템

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 열거형 속성 아이템

View File

@@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 실수 속성 아이템

View File

@@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 실수 범위 속성 아이템

View File

@@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 정수 속성 아이템

View File

@@ -1,7 +1,7 @@
#nullable enable
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 정수 범위 속성 아이템

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 라디오 그룹 속성 아이템

View File

@@ -1,7 +1,7 @@
#nullable enable
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 문자열 속성 아이템

View File

@@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 2D 벡터 속성 아이템

View File

@@ -2,7 +2,7 @@
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// 3D 벡터 속성 아이템

View File

@@ -5,7 +5,7 @@ using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// UTKPropertyWindow의 핵심 리스트 컴포넌트

View File

@@ -4,7 +4,7 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
namespace UVC.UIToolkit.Property
namespace UVC.UIToolkit
{
/// <summary>
/// UTKPropertyList를 감싸는 윈도우 래퍼

View File

@@ -65,7 +65,7 @@ namespace UVC.UIToolkit
}
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -89,7 +89,7 @@ namespace UVC.UIToolkit
}
/// <summary>값 표시 여부</summary>
[UxmlAttribute]
[UxmlAttribute("show-value")]
public bool ShowValue
{
get => _showValue;
@@ -101,7 +101,7 @@ namespace UVC.UIToolkit
}
/// <summary>퍼센트로 표시 여부</summary>
[UxmlAttribute]
[UxmlAttribute("show-percentage")]
public bool ShowPercentage
{
get => _showPercentage;
@@ -113,7 +113,7 @@ namespace UVC.UIToolkit
}
/// <summary>불확정 상태 (애니메이션)</summary>
[UxmlAttribute]
[UxmlAttribute("is-indeterminate")]
public bool IsIndeterminate
{
get => _isIndeterminate;
@@ -126,7 +126,7 @@ namespace UVC.UIToolkit
}
/// <summary>스타일 변형</summary>
[UxmlAttribute]
[UxmlAttribute("variant")]
public ProgressBarVariant Variant
{
get => _variant;

View File

@@ -53,7 +53,7 @@ namespace UVC.UIToolkit
#region Properties
/// <summary>활성화 상태</summary>
[UxmlAttribute]
[UxmlAttribute("is-enabled")]
public bool IsEnabled
{
get => _isEnabled;

View File

@@ -3,9 +3,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.List;
namespace UVC.UIToolkit.Window
namespace UVC.UIToolkit
{
/// <summary>
/// UTKAccordionList를 래핑하여 윈도우 형태로 제공하는 컴포넌트입니다.

View File

@@ -3,9 +3,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.List;
namespace UVC.UIToolkit.Window
namespace UVC.UIToolkit
{
/// <summary>
/// UTKComponentList를 래핑하여 윈도우 형태로 제공하는 컴포넌트입니다.

View File

@@ -4,9 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.List;
namespace UVC.UIToolkit.Window
namespace UVC.UIToolkit
{
/// <summary>
/// UTKComponentList와 탭 기능을 결합하여 윈도우 형태로 제공하는 컴포넌트입니다.

View File

@@ -3,9 +3,7 @@ using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.List;
namespace UVC.UIToolkit.Window
namespace UVC.UIToolkit
{
/// <summary>
/// UTKImageList를 래핑하여 윈도우 형태로 제공하는 컴포넌트입니다.

View File

@@ -4,10 +4,9 @@ using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.UIToolkit.List;
using static UVC.UIToolkit.UTKStyleGuide;
namespace UVC.UIToolkit.Window
namespace UVC.UIToolkit
{
/// <summary>
/// 계층적 트리 구조를 표시하는 커스텀 UI Toolkit 컴포넌트입니다.