Files

861 lines
30 KiB
C#

#nullable enable
using System;
using System.Threading;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.UIElements;
using UVC.Extention;
namespace UVC.UIToolkit
{
/// <summary>
/// 텍스트 라벨 컴포넌트.
/// 다양한 스타일과 크기의 텍스트를 표시합니다.
/// Material Icon 또는 Image Icon을 텍스트와 함께 또는 단독으로 표시할 수 있습니다.
/// </summary>
/// <remarks>
/// <para><b>라벨(Label)이란?</b></para>
/// <para>
/// 라벨은 화면에 텍스트를 표시하는 가장 기본적인 UI 컴포넌트입니다.
/// 제목, 본문, 설명, 상태 메시지 등 다양한 용도로 사용됩니다.
/// UTKLabel은 Unity의 기본 Label에 스타일 시스템과 아이콘 기능을 추가한 확장 버전입니다.
/// </para>
///
/// <para><b>텍스트 크기 (LabelSize):</b></para>
/// <list type="bullet">
/// <item><description><c>H1</c> - 가장 큰 제목 (28px)</description></item>
/// <item><description><c>H2</c> - 중간 제목 (24px)</description></item>
/// <item><description><c>H3</c> - 작은 제목 (20px)</description></item>
/// <item><description><c>Body1</c> - 기본 본문 (16px, 기본값)</description></item>
/// <item><description><c>Body2</c> - 작은 본문 (14px)</description></item>
/// <item><description><c>Label1</c> - 필드 라벨 (14px)</description></item>
/// <item><description><c>Label2</c>, <c>Label3</c> - 작은 라벨 (12px)</description></item>
/// <item><description><c>Caption</c> - 캡션, 힌트 텍스트 (12px)</description></item>
/// </list>
///
/// <para><b>텍스트 색상 (LabelVariant):</b></para>
/// <list type="bullet">
/// <item><description><c>Primary</c> - 기본 색상 (가장 진한 텍스트)</description></item>
/// <item><description><c>Secondary</c> - 보조 색상 (흐린 텍스트)</description></item>
/// <item><description><c>Disabled</c> - 비활성화 색상</description></item>
/// <item><description><c>Success</c> - 성공 (녹색)</description></item>
/// <item><description><c>Warning</c> - 경고 (주황색)</description></item>
/// <item><description><c>Error</c> - 오류 (빨간색)</description></item>
/// <item><description><c>Info</c> - 정보 (파란색)</description></item>
/// </list>
///
/// <para><b>아이콘 사용 방법:</b></para>
/// <list type="number">
/// <item><description>Material Icon: 폰트 기반 벡터 아이콘 (권장, <c>UTKMaterialIcons</c> 클래스 사용)</description></item>
/// <item><description>Image Icon: 이미지 기반 아이콘 (<c>UTKImageIcons</c> 클래스 사용)</description></item>
/// </list>
///
/// <para><b>실제 활용 예시:</b></para>
/// <list type="bullet">
/// <item><description>페이지 제목, 섹션 헤더</description></item>
/// <item><description>버튼/입력 필드의 라벨</description></item>
/// <item><description>상태 메시지, 오류 메시지</description></item>
/// <item><description>네비게이션 메뉴 항목 (아이콘 + 텍스트)</description></item>
/// <item><description>아이콘 버튼 (아이콘만)</description></item>
/// </list>
/// </remarks>
/// <example>
/// <para><b>C# 코드에서 사용:</b></para>
/// <code>
/// // 기본 라벨
/// var label = new UTKLabel();
/// label.Text = "안녕하세요";
/// label.Size = UTKLabel.LabelSize.Body1;
/// label.Variant = UTKLabel.LabelVariant.Primary;
///
/// // 제목 스타일
/// var title = new UTKLabel();
/// title.Text = "제목";
/// title.Size = UTKLabel.LabelSize.Heading1;
/// title.IsBold = true;
///
/// // 스타일 적용
/// label.IsItalic = true;
/// label.TextAlignment = UTKLabel.TextAlign.Center;
///
/// // Material Icon과 텍스트 함께 사용
/// var iconLabel = new UTKLabel("설정", UTKMaterialIcons.Settings);
///
/// // Image Icon과 텍스트 함께 사용
/// var imgLabel = new UTKLabel("닫기", UTKImageIcons.BtnClose16, isImageIcon: true);
///
/// // Material Icon만 사용 (iconSize 파라미터)
/// var iconOnly = new UTKLabel(UTKMaterialIcons.Home, 12);
///
/// // Image Icon만 사용
/// var imgOnly = new UTKLabel(UTKImageIcons.IconSetting22, isImageIcon: true, iconSize: 0);
///
/// // 메서드로 아이콘 설정
/// label.SetMaterialIcon(UTKMaterialIcons.Search);
/// label.SetImageIcon(UTKImageIcons.IconSetting22);
/// </code>
/// <para><b>UXML에서 사용:</b></para>
/// <code>
/// <ui:UXML xmlns:utk="UVC.UIToolkit">
/// <!-- 기본 라벨 -->
/// <utk:UTKLabel text="일반 텍스트" />
///
/// <!-- 제목 -->
/// <utk:UTKLabel text="제목" size="H1" is-bold="true" />
///
/// <!-- 보조 텍스트 -->
/// <utk:UTKLabel text="설명" size="Caption" variant="Secondary" />
///
/// <!-- Material Icon과 텍스트 -->
/// <utk:UTKLabel text="설정" material-icon="settings" />
///
/// <!-- Image Icon과 텍스트 -->
/// <utk:UTKLabel text="닫기" image-icon="btn_close_16" />
///
/// <!-- 아이콘만 (Material) -->
/// <utk:UTKLabel material-icon="home" icon-size="24" />
///
/// <!-- 아이콘만 (Image) -->
/// <utk:UTKLabel image-icon="icon_setting_22" icon-size="22" />
///
/// <!-- 아이콘 오른쪽 배치 -->
/// <utk:UTKLabel text="다음" material-icon="arrow_forward" icon-placement="right" />
/// </ui:UXML>
/// </code>
/// </example>
[UxmlElement]
public partial class UTKLabel : VisualElement, IDisposable
{
#region Constants
private const string USS_PATH = "UIToolkit/Label/UTKLabel";
#endregion
#region Fields
private bool _disposed;
private Label? _label;
private Label? _iconLabel;
private VisualElement? _imageIcon;
private string _text = "";
private LabelSize _size = LabelSize.Body1;
private LabelVariant _variant = LabelVariant.Primary;
private bool _isBold;
private bool _isItalic;
private TextAlign _textAlign = TextAlign.Left;
private bool _isSelectable;
private IconPosition _iconPosition = IconPosition.Left;
private int _iconSize;
private int _gap = 4;
private string _materialIconName = "";
private string _imageIconName = "";
#endregion
#region Properties
/// <summary>텍스트</summary>
[UxmlAttribute("text")]
public string Text
{
get => _text;
set
{
_text = value;
if (_label != null) _label.text = value;
}
}
/// <summary>텍스트 크기</summary>
[UxmlAttribute("size")]
public LabelSize Size
{
get => _size;
set
{
_size = value;
UpdateSize();
}
}
/// <summary>텍스트 변형</summary>
[UxmlAttribute("variant")]
public LabelVariant Variant
{
get => _variant;
set
{
_variant = value;
UpdateVariant();
}
}
/// <summary>굵은 글꼴</summary>
[UxmlAttribute("is-bold")]
public bool IsBold
{
get => _isBold;
set
{
_isBold = value;
EnableInClassList("utk-label--bold", value);
}
}
/// <summary>기울임 글꼴</summary>
[UxmlAttribute("is-italic")]
public bool IsItalic
{
get => _isItalic;
set
{
_isItalic = value;
EnableInClassList("utk-label--italic", value);
}
}
/// <summary>텍스트 정렬</summary>
[UxmlAttribute("text-alignment")]
public TextAlign TextAlignment
{
get => _textAlign;
set
{
_textAlign = value;
UpdateTextAlign();
}
}
/// <summary>텍스트 선택 가능 여부</summary>
[UxmlAttribute("is-selectable")]
public bool IsSelectable
{
get => _isSelectable;
set
{
_isSelectable = value;
if (_label != null)
{
_label.selection.isSelectable = value;
_label.pickingMode = value ? PickingMode.Position : PickingMode.Ignore;
}
}
}
/// <summary>아이콘 위치 (텍스트 기준 왼쪽/오른쪽)</summary>
[UxmlAttribute("icon-placement")]
public IconPosition IconPlacement
{
get => _iconPosition;
set
{
_iconPosition = value;
UpdateIconPosition();
}
}
/// <summary>아이콘 크기 (0이면 텍스트 크기에 맞춤)</summary>
[UxmlAttribute("icon-size")]
public int IconSize
{
get => _iconSize;
set
{
_iconSize = value;
UpdateIconSize();
}
}
/// <summary>아이콘과 텍스트 사이 간격 (px)</summary>
[UxmlAttribute("gap")]
public int Gap
{
get => _gap;
set
{
_gap = value;
UpdateGap();
}
}
/// <summary>Material Icon 이름 (예: "settings", "home")</summary>
[UxmlAttribute("material-icon")]
public string MaterialIcon
{
get => _materialIconName;
set
{
_materialIconName = value;
if (!string.IsNullOrEmpty(value))
{
SetMaterialIconByName(value);
}
else
{
ClearIcon();
}
}
}
/// <summary>Image Icon 이름 (예: "icon_setting_22", "btn_close_16")</summary>
[UxmlAttribute("image-icon")]
public string ImageIcon
{
get => _imageIconName;
set
{
_imageIconName = value;
if (!string.IsNullOrEmpty(value))
{
SetImageIconByName(value);
}
else
{
ClearIcon();
}
}
}
#endregion
#region Enums
public enum LabelSize
{
H1,
H2,
H3,
Body1,
Body2,
Label1,
Label2,
Label3,
Label4,
Caption
}
public enum LabelVariant
{
Primary,
Secondary,
Disabled,
Success,
Warning,
Error,
Info
}
public enum TextAlign
{
Left,
Center,
Right
}
public enum IconPosition
{
Left,
Right
}
#endregion
#region Constructor
public UTKLabel()
{
UTKThemeManager.Instance.ApplyThemeToElement(this);
var uss = Resources.Load<StyleSheet>(USS_PATH);
if (uss != null)
{
styleSheets.Add(uss);
}
CreateUI();
SubscribeToThemeChanges();
// UXML에서 로드될 때 속성이 설정된 후 UI 갱신
// Unity 6의 소스 생성기는 Deserialize에서 필드에 직접 값을 할당하므로
// AttachToPanelEvent를 사용하여 패널에 연결된 후 UI를 갱신
RegisterCallback<AttachToPanelEvent>(OnAttachToPanel);
}
/// <summary>
/// 텍스트와 크기를 지정하여 라벨을 생성합니다.
/// </summary>
/// <param name="text">표시할 텍스트</param>
/// <param name="size">텍스트 크기</param>
public UTKLabel(string text, LabelSize size = LabelSize.Body1) : this()
{
Text = text;
Size = size;
}
/// <summary>
/// Material Icon과 텍스트를 함께 표시하는 라벨을 생성합니다.
/// </summary>
/// <param name="text">표시할 텍스트</param>
/// <param name="materialIcon">Material Icon 유니코드 문자 (예: UTKMaterialIcons.Settings)</param>
/// <param name="iconPosition">아이콘 위치 (기본: 왼쪽)</param>
/// <param name="size">텍스트 크기</param>
public UTKLabel(string text, string materialIcon, IconPosition iconPosition = IconPosition.Left, LabelSize size = LabelSize.Body1) : this()
{
Text = text;
Size = size;
IconPlacement = iconPosition;
SetMaterialIcon(materialIcon);
}
/// <summary>
/// Image Icon과 텍스트를 함께 표시하는 라벨을 생성합니다.
/// </summary>
/// <param name="text">표시할 텍스트</param>
/// <param name="imageIconPath">Image Icon 리소스 경로 (예: UTKImageIcons.IconSetting22)</param>
/// <param name="isImageIcon">true로 설정해야 합니다 (Image Icon 생성자 구분용)</param>
/// <param name="iconPosition">아이콘 위치 (기본: 왼쪽)</param>
/// <param name="size">텍스트 크기</param>
public UTKLabel(string text, string imageIconPath, bool isImageIcon, IconPosition iconPosition = IconPosition.Left, LabelSize size = LabelSize.Body1) : this()
{
Text = text;
Size = size;
IconPlacement = iconPosition;
if (isImageIcon)
{
SetImageIcon(imageIconPath);
}
else
{
SetMaterialIcon(imageIconPath);
}
}
/// <summary>
/// Material Icon만 표시하는 라벨을 생성합니다.
/// </summary>
/// <param name="materialIcon">Material Icon 유니코드 문자 (예: UTKMaterialIcons.Home)</param>
/// <param name="iconSize">아이콘 크기 (0이면 기본 크기)</param>
public UTKLabel(string materialIcon, int iconSize = 0) : this()
{
IconSize = iconSize;
SetMaterialIcon(materialIcon);
}
/// <summary>
/// Image Icon만 표시하는 라벨을 생성합니다.
/// </summary>
/// <param name="imageIconPath">Image Icon 리소스 경로 (예: UTKImageIcons.IconSetting22)</param>
/// <param name="isImageIcon">true로 설정해야 합니다 (Image Icon 생성자 구분용)</param>
/// <param name="iconSize">아이콘 크기 (0이면 기본 크기)</param>
public UTKLabel(string imageIconPath, bool isImageIcon, int iconSize = 0) : this()
{
IconSize = iconSize;
if (isImageIcon)
{
SetImageIcon(imageIconPath);
}
else
{
SetMaterialIcon(imageIconPath);
}
}
#endregion
#region UI Creation
private void CreateUI()
{
AddToClassList("utk-label");
_label = new Label { name = "label", pickingMode = PickingMode.Ignore };
_label.AddToClassList("utk-label__text");
Add(_label);
UpdateSize();
UpdateVariant();
UpdateTextAlign();
}
private void SubscribeToThemeChanges()
{
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)
{
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
private void UpdateSize()
{
RemoveFromClassList("utk-label--h1");
RemoveFromClassList("utk-label--h2");
RemoveFromClassList("utk-label--h3");
RemoveFromClassList("utk-label--body1");
RemoveFromClassList("utk-label--body2");
RemoveFromClassList("utk-label--label1");
RemoveFromClassList("utk-label--label2");
RemoveFromClassList("utk-label--label3");
RemoveFromClassList("utk-label--label4");
RemoveFromClassList("utk-label--caption");
var sizeClass = _size switch
{
LabelSize.H1 => "utk-label--h1",
LabelSize.H2 => "utk-label--h2",
LabelSize.H3 => "utk-label--h3",
LabelSize.Body2 => "utk-label--body2",
LabelSize.Label1 => "utk-label--label1",
LabelSize.Label2 => "utk-label--label2",
LabelSize.Label3 => "utk-label--label3",
LabelSize.Label4 => "utk-label--label4",
LabelSize.Caption => "utk-label--caption",
_ => "utk-label--body1"
};
AddToClassList(sizeClass);
}
private void UpdateVariant()
{
RemoveFromClassList("utk-label--primary");
RemoveFromClassList("utk-label--secondary");
RemoveFromClassList("utk-label--disabled");
RemoveFromClassList("utk-label--success");
RemoveFromClassList("utk-label--warning");
RemoveFromClassList("utk-label--error");
RemoveFromClassList("utk-label--info");
var variantClass = _variant switch
{
LabelVariant.Secondary => "utk-label--secondary",
LabelVariant.Disabled => "utk-label--disabled",
LabelVariant.Success => "utk-label--success",
LabelVariant.Warning => "utk-label--warning",
LabelVariant.Error => "utk-label--error",
LabelVariant.Info => "utk-label--info",
_ => "utk-label--primary"
};
AddToClassList(variantClass);
}
private void UpdateTextAlign()
{
RemoveFromClassList("utk-label--left");
RemoveFromClassList("utk-label--center");
RemoveFromClassList("utk-label--right");
var alignClass = _textAlign switch
{
TextAlign.Center => "utk-label--center",
TextAlign.Right => "utk-label--right",
_ => "utk-label--left"
};
AddToClassList(alignClass);
}
private void UpdateIconPosition()
{
if (_iconLabel != null)
{
_iconLabel.SendToBack();
if (_iconPosition == IconPosition.Right)
{
_iconLabel.BringToFront();
}
}
if (_imageIcon != null)
{
_imageIcon.SendToBack();
if (_iconPosition == IconPosition.Right)
{
_imageIcon.BringToFront();
}
}
}
private void UpdateIconSize()
{
var size = GetEffectiveIconSize();
if (_iconLabel != null && _iconLabel.style.display == DisplayStyle.Flex)
{
_iconLabel.style.fontSize = size;
}
if (_imageIcon != null && _imageIcon.style.display == DisplayStyle.Flex)
{
_imageIcon.style.width = size;
_imageIcon.style.height = size;
}
}
private void UpdateGap()
{
// 아이콘과 텍스트 사이의 간격을 적용
if (_iconLabel != null)
{
_iconLabel.style.marginRight = _iconPosition == IconPosition.Left ? (_text.IsNullOrEmpty() ? 0 : _gap) : 0;
_iconLabel.style.marginLeft = _iconPosition == IconPosition.Right ? (_text.IsNullOrEmpty() ? 0 : _gap) : 0;
}
if (_imageIcon != null)
{
_imageIcon.style.marginRight = _iconPosition == IconPosition.Left ? (_text.IsNullOrEmpty() ? 0 : _gap) : 0;
_imageIcon.style.marginLeft = _iconPosition == IconPosition.Right ? (_text.IsNullOrEmpty() ? 0 : _gap) : 0;
}
}
private int GetEffectiveIconSize()
{
if (_iconSize > 0) return _iconSize;
return _size switch
{
LabelSize.H1 => 28,
LabelSize.H2 => 24,
LabelSize.H3 => 20,
LabelSize.Body1 => 16,
LabelSize.Body2 => 14,
LabelSize.Label1 => 14,
LabelSize.Label2 => 12,
LabelSize.Label3 => 12,
LabelSize.Caption => 12,
_ => 16
};
}
#endregion
#region Icon Methods
/// <summary>
/// Material Icon을 설정합니다.
/// </summary>
/// <param name="icon">Material Icon 유니코드 문자 (예: UTKMaterialIcons.Settings)</param>
/// <param name="fontSize">아이콘 폰트 크기 (null이면 텍스트 크기에 맞춤)</param>
public void SetMaterialIcon(string icon, int? fontSize = null)
{
ClearImageIcon();
EnsureIconLabel();
if (_iconLabel != null)
{
_iconLabel.text = icon;
_iconLabel.style.display = DisplayStyle.Flex;
UTKMaterialIcons.ApplyIconStyle(_iconLabel, fontSize ?? GetEffectiveIconSize());
}
if(_text.IsNullOrEmpty()) TextAlignment = TextAlign.Center; // 텍스트가 없는 경우 아이콘 중앙 정렬
EnableInClassList("utk-label--has-icon", true);
UpdateIconPosition();
UpdateGap();
}
/// <summary>
/// Material Icon을 비동기로 설정합니다.
/// </summary>
/// <param name="icon">Material Icon 유니코드 문자 (예: UTKMaterialIcons.Settings)</param>
/// <param name="ct">취소 토큰</param>
/// <param name="fontSize">아이콘 폰트 크기 (null이면 텍스트 크기에 맞춤)</param>
public async UniTask SetMaterialIconAsync(string icon, CancellationToken ct = default, int? fontSize = null)
{
ClearImageIcon();
EnsureIconLabel();
if (_iconLabel != null)
{
_iconLabel.text = icon;
_iconLabel.style.display = DisplayStyle.Flex;
await UTKMaterialIcons.ApplyIconStyleAsync(_iconLabel, ct, fontSize ?? GetEffectiveIconSize());
}
if(_text.IsNullOrEmpty()) TextAlignment = TextAlign.Center; // 텍스트가 없는 경우 아이콘 중앙 정렬
EnableInClassList("utk-label--has-icon", true);
UpdateIconPosition();
UpdateGap();
}
/// <summary>
/// 아이콘 이름으로 Material Icon을 설정합니다.
/// </summary>
/// <param name="iconName">아이콘 이름 (예: "settings", "home")</param>
/// <param name="fontSize">아이콘 폰트 크기 (null이면 텍스트 크기에 맞춤)</param>
public void SetMaterialIconByName(string iconName, int? fontSize = null)
{
string iconChar = UTKMaterialIcons.GetIcon(iconName);
if (iconChar != string.Empty)
{
SetMaterialIcon(iconChar, fontSize);
}
else
{
Debug.LogWarning($"[UTKLabel] Material icon '{iconName}'을(를) 찾을 수 없습니다.");
}
}
/// <summary>
/// Image Icon을 설정합니다.
/// </summary>
/// <param name="resourcePath">이미지 리소스 경로 (예: UTKImageIcons.IconSetting22)</param>
/// <param name="iconSize">아이콘 크기 (null이면 텍스트 크기에 맞춤)</param>
public void SetImageIcon(string resourcePath, int? iconSize = null)
{
var texture = UTKImageIcons.LoadTexture(resourcePath);
if (texture != null)
{
ApplyImageIcon(texture, iconSize);
}
else
{
Debug.LogWarning($"[UTKLabel] Image icon '{resourcePath}'을(를) 로드할 수 없습니다.");
}
}
/// <summary>
/// Image Icon을 비동기로 설정합니다.
/// </summary>
/// <param name="resourcePath">이미지 리소스 경로 (예: UTKImageIcons.IconSetting22)</param>
/// <param name="ct">취소 토큰</param>
/// <param name="iconSize">아이콘 크기 (null이면 텍스트 크기에 맞춤)</param>
public async UniTask SetImageIconAsync(string resourcePath, CancellationToken ct = default, int? iconSize = null)
{
var texture = await UTKImageIcons.LoadTextureAsync(resourcePath, ct);
if (texture != null)
{
ApplyImageIcon(texture, iconSize);
}
else
{
Debug.LogWarning($"[UTKLabel] Image icon '{resourcePath}'을(를) 로드할 수 없습니다.");
}
}
/// <summary>
/// 아이콘 이름으로 Image Icon을 설정합니다.
/// </summary>
/// <param name="iconName">아이콘 이름 (예: "icon_setting_22", "btn_close_16")</param>
/// <param name="iconSize">아이콘 크기 (null이면 텍스트 크기에 맞춤)</param>
public void SetImageIconByName(string iconName, int? iconSize = null)
{
var texture = UTKImageIcons.LoadTextureByName(iconName);
if (texture != null)
{
ApplyImageIcon(texture, iconSize);
}
else
{
Debug.LogWarning($"[UTKLabel] Image icon '{iconName}'을(를) 찾을 수 없습니다.");
}
}
/// <summary>
/// 모든 아이콘을 제거합니다.
/// </summary>
public void ClearIcon()
{
ClearMaterialIcon();
ClearImageIcon();
EnableInClassList("utk-label--has-icon", false);
}
private void EnsureIconLabel()
{
if (_iconLabel != null) return;
_iconLabel = new Label
{
name = "icon",
pickingMode = PickingMode.Ignore
};
_iconLabel.AddToClassList("utk-label__icon");
_iconLabel.style.display = DisplayStyle.None;
Insert(0, _iconLabel);
}
private void ApplyImageIcon(Texture2D texture, int? iconSize)
{
ClearMaterialIcon();
if (_imageIcon == null)
{
_imageIcon = new VisualElement
{
name = "image-icon",
pickingMode = PickingMode.Ignore
};
_imageIcon.AddToClassList("utk-label__image-icon");
Insert(0, _imageIcon);
}
var size = iconSize ?? GetEffectiveIconSize();
_imageIcon.style.width = size;
_imageIcon.style.height = size;
_imageIcon.style.backgroundImage = new StyleBackground(texture);
_imageIcon.style.display = DisplayStyle.Flex;
if(_text.IsNullOrEmpty()) TextAlignment = TextAlign.Center; // 텍스트가 없는 경우 아이콘 중앙 정렬
EnableInClassList("utk-label--has-icon", true);
UpdateIconPosition();
UpdateGap();
}
private void ClearMaterialIcon()
{
if (_iconLabel != null)
{
_iconLabel.text = "";
_iconLabel.style.display = DisplayStyle.None;
}
}
private void ClearImageIcon()
{
if (_imageIcon != null)
{
_imageIcon.style.backgroundImage = StyleKeyword.None;
_imageIcon.style.display = DisplayStyle.None;
}
}
#endregion
#region IDisposable
public void Dispose()
{
if (_disposed) return;
_disposed = true;
UTKThemeManager.Instance.OnThemeChanged -= OnThemeChanged;
}
#endregion
}
}