클래스 생성

This commit is contained in:
logonkhi
2025-11-04 20:09:18 +09:00
parent 68c5d51884
commit 0885f02871
20 changed files with 1634 additions and 3 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2b427b9e85de96047aa7cfd700a09a2e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,145 @@
#nullable enable
using System;
using System.Collections.Generic;
using UnityEngine;
namespace UVC.UI.List.Accordion
{
/// <summary>
/// 섹션 내 아이템 배치 타입.
/// Horizontal: head-content-tail3영역 수평 배치
/// Grid: 이미지+캡션2열 그리드
/// </summary>
public enum AccordionItemLayoutType
{
Horizontal,
Grid
}
/// <summary>
/// 수평 아이템 영역에 들어갈 콘텐츠 종류.
/// </summary>
public enum AccordionContentKind
{
None,
Image,
Text,
IconButton
}
/// <summary>
/// 수평 아이템의 단일 영역(head/content/tail)을 기술하는 데이터.
/// </summary>
[Serializable]
public class AccordionContentSpec
{
public AccordionContentKind Kind = AccordionContentKind.None;
// Text
public string? Text;
public UnityEngine.Object? Font; // TMP_FontAsset 또는 Font
public Color TextColor = Color.white;
public int FontSize = 22;
// Image
public Sprite? Sprite;
public Color ImageColor = Color.white;
// IconButton
public Sprite? Icon;
public Action? OnClick;
public string? Tooltip;
public static AccordionContentSpec FromText(string text, Color? color = null, int fontSize = 22, UnityEngine.Object? font = null)
=> new AccordionContentSpec
{
Kind = AccordionContentKind.Text,
Text = text,
TextColor = color ?? Color.white,
FontSize = fontSize,
Font = font
};
public static AccordionContentSpec FromImage(Sprite? sprite, Color? color = null)
=> new AccordionContentSpec
{
Kind = AccordionContentKind.Image,
Sprite = sprite,
ImageColor = color ?? Color.white
};
public static AccordionContentSpec FromIconButton(Sprite? icon, Action onClick, string? tooltip = null)
=> new AccordionContentSpec
{
Kind = AccordionContentKind.IconButton,
Icon = icon,
OnClick = onClick,
Tooltip = tooltip
};
}
/// <summary>
/// 아코디언 항목 데이터 인터페이스.
/// </summary>
public interface IAccordionItemData
{
AccordionItemLayoutType LayoutType { get; }
}
/// <summary>
/// head-content-tail 수평 아이템 데이터.
/// </summary>
[Serializable]
public class AccordionHorizontalItemData : IAccordionItemData
{
public AccordionItemLayoutType LayoutType => AccordionItemLayoutType.Horizontal;
public AccordionContentSpec Head = new AccordionContentSpec();
public AccordionContentSpec Content = new AccordionContentSpec();
public AccordionContentSpec Tail = new AccordionContentSpec();
/// <summary>
/// 임의의 태그/키 값.
/// </summary>
public string? Tag;
}
/// <summary>
/// 그리드 셀(이미지+캡션) 데이터.
/// </summary>
[Serializable]
public class AccordionGridItemData : IAccordionItemData
{
public AccordionItemLayoutType LayoutType => AccordionItemLayoutType.Grid;
public Sprite? Image;
public string Caption = string.Empty;
public Color CaptionColor = Color.white;
public int CaptionSize = 20;
public Action? OnClick;
public string? Tag;
}
/// <summary>
/// 단일 섹션 데이터(제목/펼침/아이템 컬렉션).
/// </summary>
[Serializable]
public class AccordionSectionData
{
public string Title = string.Empty;
public bool IsExpanded = false;
public AccordionItemLayoutType LayoutType = AccordionItemLayoutType.Horizontal;
// 아이템 리스트. LayoutType에 따라 타입을 일치시켜 사용합니다.
public List<IAccordionItemData> Items = new List<IAccordionItemData>();
}
/// <summary>
/// 아코디언 전체 데이터 루트.
/// </summary>
[Serializable]
public class AccordionData
{
public List<AccordionSectionData> Sections = new List<AccordionSectionData>();
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 29fe5d846fc771e418d6d0090157dbfd

View File

@@ -0,0 +1,65 @@
#nullable enable
using UnityEngine;
using UnityEngine.UI;
namespace UVC.UI.List.Accordion
{
/// <summary>
/// 그리드 셀 항목(이미지+캡션). 셀 크기는 상위 GridLayoutGroup에서 결정.
/// </summary>
public class AccordionGridItemView : MonoBehaviour
{
[SerializeField] private Image image = default!;
[SerializeField] private Component caption = default!; // TMP or Text
[SerializeField] private Button button = default!;
private void Reset()
{
EnsureLayout();
}
private void Awake()
{
EnsureLayout();
}
private void EnsureLayout()
{
if (image == null)
{
var imgGO = new GameObject("Image", typeof(RectTransform), typeof(Image));
imgGO.transform.SetParent(transform, false);
image = imgGO.GetComponent<Image>();
image.preserveAspect = true;
}
if (caption == null)
{
caption = TMPProxy.CreateTextGO(transform, "Caption");
TMPProxy.SetAlignment(caption, "TopLeft");
}
if (button == null)
{
var btn = gameObject.GetComponent<Button>();
if (btn == null) btn = gameObject.AddComponent<Button>();
button = btn;
}
var v = GetComponent<VerticalLayoutGroup>();
if (v == null) v = gameObject.AddComponent<VerticalLayoutGroup>();
v.childControlHeight = true;
v.childForceExpandHeight = true;
v.spacing = 2f;
var pad = 4;
v.padding = new RectOffset(pad, pad, pad, pad);
}
public void Initialize(AccordionGridItemData data)
{
image.sprite = data.Image;
TMPProxy.SetText(caption, data.Caption);
TMPProxy.SetColor(caption, data.CaptionColor);
TMPProxy.SetFontSize(caption, data.CaptionSize);
button.onClick.RemoveAllListeners();
if (data.OnClick != null) button.onClick.AddListener(() => data.OnClick());
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: bbb82949b2c1f134dbb493c71bbec615

View File

@@ -0,0 +1,132 @@
#nullable enable
using UnityEngine;
using UnityEngine.UI;
namespace UVC.UI.List.Accordion
{
/// <summary>
/// 수평 아이템(Head-Content-Tail) 뷰. 고정 높이35.
/// 각 영역은 Text, Image, IconButton를 지원합니다.
/// </summary>
public class AccordionItemView : MonoBehaviour
{
[SerializeField] private RectTransform headRoot = default!;
[SerializeField] private RectTransform contentRoot = default!;
[SerializeField] private RectTransform tailRoot = default!;
private void Reset()
{
EnsureLayout();
}
private void Awake()
{
EnsureLayout();
}
private void EnsureLayout()
{
var rt = (RectTransform)transform;
rt.sizeDelta = new Vector2(AccordionList.Width, AccordionList.ItemHeight);
var h = GetComponent<HorizontalLayoutGroup>();
if (h == null) h = gameObject.AddComponent<HorizontalLayoutGroup>();
h.childControlHeight = true;
h.childForceExpandHeight = true;
h.childControlWidth = true;
h.childForceExpandWidth = true;
h.spacing = 4f;
h.padding = new RectOffset(6, 6, 0, 0);
if (headRoot == null)
{
headRoot = CreateSlot("Head", 0.25f);
}
if (contentRoot == null)
{
contentRoot = CreateSlot("Content", 0.5f);
}
if (tailRoot == null)
{
tailRoot = CreateSlot("Tail", 0.25f);
}
}
private RectTransform CreateSlot(string name, float flexible)
{
var go = new GameObject(name, typeof(RectTransform));
go.transform.SetParent(transform, false);
var layout = go.AddComponent<LayoutElement>();
layout.flexibleWidth = flexible;
layout.minHeight = AccordionList.ItemHeight;
var rt = (RectTransform)go.transform;
return rt;
}
public void Initialize(AccordionHorizontalItemData data)
{
BuildArea(headRoot, data.Head);
BuildArea(contentRoot, data.Content);
BuildArea(tailRoot, data.Tail);
}
private void BuildArea(RectTransform parent, AccordionContentSpec spec)
{
// clear
for (int i = parent.childCount - 1; i >= 0; i--)
{
Destroy(parent.GetChild(i).gameObject);
}
switch (spec.Kind)
{
case AccordionContentKind.Text:
BuildText(parent, spec.Text ?? string.Empty, spec.Font, spec.TextColor, spec.FontSize);
break;
case AccordionContentKind.Image:
BuildImage(parent, spec.Sprite, spec.ImageColor);
break;
case AccordionContentKind.IconButton:
BuildIconButton(parent, spec.Icon, spec.OnClick);
break;
default:
break;
}
}
private void BuildText(RectTransform parent, string text, UnityEngine.Object? fontAsset, Color color, int size)
{
var comp = TMPProxy.CreateTextGO(parent, "Text");
TMPProxy.SetText(comp, text);
TMPProxy.SetColor(comp, color);
TMPProxy.SetFontSize(comp, size);
TMPProxy.SetFont(comp, fontAsset);
TMPProxy.SetAlignment(comp, "MidlineLeft");
}
private void BuildImage(RectTransform parent, Sprite? sprite, Color color)
{
var go = new GameObject("Image", typeof(RectTransform), typeof(Image));
go.transform.SetParent(parent, false);
var img = go.GetComponent<Image>();
img.sprite = sprite;
img.color = color;
img.preserveAspect = true;
var le = go.AddComponent<LayoutElement>();
le.minHeight = AccordionList.ItemHeight;
}
private void BuildIconButton(RectTransform parent, Sprite? icon, System.Action? onClick)
{
var go = new GameObject("IconButton", typeof(RectTransform), typeof(Image), typeof(Button));
go.transform.SetParent(parent, false);
var img = go.GetComponent<Image>();
img.sprite = icon;
img.preserveAspect = true;
var btn = go.GetComponent<Button>();
btn.onClick.RemoveAllListeners();
if (onClick != null) btn.onClick.AddListener(() => onClick());
var le = go.AddComponent<LayoutElement>();
le.minHeight = AccordionList.ItemHeight;
le.minWidth = AccordionList.ItemHeight;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3c7296b1c3a691547ac7714fde688237

View File

@@ -0,0 +1,124 @@
#nullable enable
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
namespace UVC.UI.List.Accordion
{
/// <summary>
/// 아코디언 전체 리스트 뷰. 섹션 헤더(48)와 항목(35)을 생성/관리합니다.
/// 가로 너비는250으로 고정합니다.
/// </summary>
[DisallowMultipleComponent]
public class AccordionList : MonoBehaviour
{
// Layout constants
public const float Width = 250f;
public const float HeaderHeight = 48f;
public const float ItemHeight = 35f;
public const int GridColumns = 2;
[Header("Prefabs")]
[SerializeField] private AccordionSection sectionPrefab = default!;
[SerializeField] private AccordionItemView horizontalItemPrefab = default!;
[SerializeField] private AccordionGridItemView gridItemPrefab = default!;
[Header("Root")]
[SerializeField] private RectTransform contentRoot = default!; // VerticalLayoutGroup 권장
[Header("Style")]
[SerializeField] private Color sectionHeaderColor = new Color(0.16f, 0.16f, 0.16f);
[SerializeField] private Color itemBgColor = new Color(0.10f, 0.10f, 0.10f);
public AccordionData? Data { get; private set; }
private readonly List<AccordionSection> _sections = new();
private void Reset()
{
EnsureRootLayout();
EnsurePrefabs();
}
private void Awake()
{
EnsureRootLayout();
EnsurePrefabs();
}
private void EnsureRootLayout()
{
if (contentRoot == null)
{
var go = new GameObject("ContentRoot", typeof(RectTransform));
go.transform.SetParent(transform, false);
contentRoot = (RectTransform)go.transform;
}
var rt = (RectTransform)transform;
rt.sizeDelta = new Vector2(Width, rt.sizeDelta.y);
var v = contentRoot.GetComponent<VerticalLayoutGroup>();
if (v == null) v = contentRoot.gameObject.AddComponent<VerticalLayoutGroup>();
v.childForceExpandHeight = false;
v.childControlHeight = true;
v.childForceExpandWidth = true;
v.childControlWidth = true;
v.spacing = 0f;
var fitter = contentRoot.GetComponent<ContentSizeFitter>();
if (fitter == null) fitter = contentRoot.gameObject.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.Unconstrained;
}
private void EnsurePrefabs()
{
if (sectionPrefab == null)
{
var proto = new GameObject("SectionPrototype", typeof(RectTransform), typeof(AccordionSection));
proto.transform.SetParent(transform, false);
proto.SetActive(false);
sectionPrefab = proto.GetComponent<AccordionSection>();
}
if (horizontalItemPrefab == null)
{
var proto = new GameObject("HorizontalItemPrototype", typeof(RectTransform), typeof(AccordionItemView));
proto.transform.SetParent(transform, false);
proto.SetActive(false);
horizontalItemPrefab = proto.GetComponent<AccordionItemView>();
}
if (gridItemPrefab == null)
{
var proto = new GameObject("GridItemPrototype", typeof(RectTransform), typeof(AccordionGridItemView));
proto.transform.SetParent(transform, false);
proto.SetActive(false);
gridItemPrefab = proto.GetComponent<AccordionGridItemView>();
}
}
public void SetData(AccordionData data)
{
EnsureRootLayout();
EnsurePrefabs();
Clear();
Data = data;
foreach (var sectionData in data.Sections)
{
var section = Instantiate(sectionPrefab, contentRoot);
section.gameObject.SetActive(true);
section.Initialize(sectionData, this, horizontalItemPrefab, gridItemPrefab);
_sections.Add(section);
}
}
public void Clear()
{
foreach (var s in _sections)
{
if (s != null) Destroy(s.gameObject);
}
_sections.Clear();
Data = null;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 3da2a3205a856104cbeff1d2a234d19f

View File

@@ -0,0 +1,158 @@
#nullable enable
using UnityEngine;
using UnityEngine.UI;
namespace UVC.UI.List.Accordion
{
/// <summary>
/// 단일 섹션 헤더(48높이)와 본문을 관리합니다.
/// </summary>
public class AccordionSection : MonoBehaviour
{
[SerializeField] private Button headerButton = default!;
[SerializeField] private Image headerBg = default!;
[SerializeField] private Component titleText = default!; // TMP or Text
[SerializeField] private RectTransform bodyRoot = default!; // items parent
[SerializeField] private GameObject bodyContainer = default!; // active toggle
private AccordionSectionData? _data;
private AccordionList? _list;
private AccordionItemView? _horizontalItemPrefab;
private AccordionGridItemView? _gridItemPrefab;
private void Reset()
{
EnsureRuntimeComponents();
}
private void Awake()
{
EnsureRuntimeComponents();
}
private void EnsureRuntimeComponents()
{
var rt = (RectTransform)transform;
if (headerButton == null)
{
var headerGO = new GameObject("Header", typeof(RectTransform), typeof(Image), typeof(Button));
headerGO.transform.SetParent(transform, false);
var headerRT = (RectTransform)headerGO.transform;
headerRT.anchorMin = new Vector2(0, 1);
headerRT.anchorMax = new Vector2(1, 1);
headerRT.pivot = new Vector2(0.5f, 1);
headerRT.sizeDelta = new Vector2(0, AccordionList.HeaderHeight);
headerBg = headerGO.GetComponent<Image>();
headerButton = headerGO.GetComponent<Button>();
var textComp = TMPProxy.CreateTextGO(headerGO.transform, "Title");
var textRT = (RectTransform)textComp.transform;
textRT.anchorMin = new Vector2(0, 0);
textRT.anchorMax = new Vector2(1, 1);
textRT.offsetMin = new Vector2(12, 0);
textRT.offsetMax = new Vector2(-12, 0);
titleText = textComp;
TMPProxy.SetAlignment(titleText, "MidlineLeft");
}
if (bodyContainer == null)
{
var bodyGO = new GameObject("BodyContainer", typeof(RectTransform));
bodyGO.transform.SetParent(transform, false);
bodyContainer = bodyGO;
bodyRoot = (RectTransform)bodyGO.transform;
var v = bodyGO.AddComponent<VerticalLayoutGroup>();
v.childControlHeight = true;
v.childForceExpandHeight = false;
v.spacing = 0f;
var fitter = bodyGO.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
}
var layout = GetComponent<VerticalLayoutGroup>();
if (layout == null) layout = gameObject.AddComponent<VerticalLayoutGroup>();
layout.childControlHeight = true;
layout.childForceExpandHeight = false;
layout.spacing = 0f;
}
public void Initialize(AccordionSectionData data, AccordionList list, AccordionItemView horizontalItemPrefab, AccordionGridItemView gridItemPrefab)
{
_data = data;
_list = list;
_horizontalItemPrefab = horizontalItemPrefab;
_gridItemPrefab = gridItemPrefab;
// Appearance
var rt = (RectTransform)transform;
rt.sizeDelta = new Vector2(AccordionList.Width, rt.sizeDelta.y);
headerBg.color = new Color(0.18f, 0.18f, 0.18f);
TMPProxy.SetText(titleText, data.Title);
headerButton.onClick.RemoveAllListeners();
headerButton.onClick.AddListener(() => Toggle());
bodyContainer.SetActive(_data.IsExpanded);
BuildItems();
}
private void Toggle()
{
if (_data == null) return;
_data.IsExpanded = !_data.IsExpanded;
bodyContainer.SetActive(_data.IsExpanded);
}
private void ClearItems()
{
for (int i = bodyRoot.childCount - 1; i >= 0; i--)
{
var ch = bodyRoot.GetChild(i);
Destroy(ch.gameObject);
}
}
private void BuildItems()
{
if (_data == null || _list == null) return;
ClearItems();
if (_data.LayoutType == AccordionItemLayoutType.Horizontal)
{
foreach (var item in _data.Items)
{
if (item is AccordionHorizontalItemData h)
{
var view = Object.Instantiate(_horizontalItemPrefab!, bodyRoot);
view.Initialize(h);
}
}
}
else // Grid
{
// Wrap to2 columns using GridLayoutGroup
var containerGO = new GameObject("Grid", typeof(RectTransform), typeof(GridLayoutGroup), typeof(ContentSizeFitter));
containerGO.transform.SetParent(bodyRoot, false);
var gridRT = (RectTransform)containerGO.transform;
gridRT.sizeDelta = new Vector2(AccordionList.Width, gridRT.sizeDelta.y);
var grid = containerGO.GetComponent<GridLayoutGroup>();
float padding = 6f;
grid.cellSize = new Vector2((AccordionList.Width - padding * 3) / 2f, AccordionList.ItemHeight * 2f);
grid.spacing = new Vector2(padding, padding);
grid.constraint = GridLayoutGroup.Constraint.FixedColumnCount;
grid.constraintCount = AccordionList.GridColumns;
var fitter = containerGO.GetComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
fitter.horizontalFit = ContentSizeFitter.FitMode.PreferredSize;
foreach (var item in _data.Items)
{
if (item is AccordionGridItemData g)
{
var view = Object.Instantiate(_gridItemPrefab!, gridRT);
view.Initialize(g);
}
}
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 17ca068f38574f84a969ad833b66e699

View File

@@ -0,0 +1,105 @@
#nullable enable
using System;
using UnityEngine;
using UnityEngine.UI;
namespace UVC.UI.List.Accordion
{
internal static class TMPProxy
{
private static Type? _tmpTextType;
private static Type? _tmpFontType;
private static Type? _tmpAlignType;
private static Type? TMPTextType => _tmpTextType ??= Type.GetType("TMPro.TextMeshProUGUI, Unity.TextMeshPro");
private static Type? TMPFontType => _tmpFontType ??= Type.GetType("TMPro.TMP_FontAsset, Unity.TextMeshPro");
private static Type? TMPAlignType => _tmpAlignType ??= Type.GetType("TMPro.TextAlignmentOptions, Unity.TextMeshPro");
public static Component CreateTextGO(Transform parent, string name)
{
var go = new GameObject(name, typeof(RectTransform));
go.transform.SetParent(parent, false);
if (TMPTextType != null)
{
go.AddComponent(TMPTextType);
return (Component)go.GetComponent(TMPTextType);
}
else
{
var text = go.AddComponent<Text>();
text.alignment = TextAnchor.MiddleLeft;
text.text = string.Empty;
return text;
}
}
public static void SetText(Component comp, string text)
{
if (TMPTextType != null && TMPTextType.IsInstanceOfType(comp))
{
TMPTextType.GetProperty("text")?.SetValue(comp, text);
}
else if (comp is Text uText)
{
uText.text = text;
}
}
public static void SetColor(Component comp, Color color)
{
if (TMPTextType != null && TMPTextType.IsInstanceOfType(comp))
{
TMPTextType.GetProperty("color")?.SetValue(comp, color);
}
else if (comp is Text uText)
{
uText.color = color;
}
}
public static void SetFontSize(Component comp, int size)
{
if (TMPTextType != null && TMPTextType.IsInstanceOfType(comp))
{
TMPTextType.GetProperty("fontSize")?.SetValue(comp, (float)size);
}
else if (comp is Text uText)
{
uText.fontSize = size;
}
}
public static void SetFont(Component comp, UnityEngine.Object? fontAsset)
{
if (fontAsset == null) return;
if (TMPTextType != null && TMPTextType.IsInstanceOfType(comp) && TMPFontType != null && TMPFontType.IsInstanceOfType(fontAsset))
{
TMPTextType.GetProperty("font")?.SetValue(comp, fontAsset);
}
else if (comp is Text uText && fontAsset is Font uFont)
{
uText.font = uFont;
}
}
public static void SetAlignment(Component comp, string alignment)
{
if (TMPTextType != null && TMPTextType.IsInstanceOfType(comp) && TMPAlignType != null)
{
try
{
var enumVal = Enum.Parse(TMPAlignType, alignment);
TMPTextType.GetProperty("alignment")?.SetValue(comp, enumVal);
}
catch { }
}
else if (comp is Text uText)
{
if (string.Equals(alignment, "TopLeft", StringComparison.OrdinalIgnoreCase))
uText.alignment = TextAnchor.UpperLeft;
else
uText.alignment = TextAnchor.MiddleLeft;
}
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d2968af399993f94f8aa265253691829

View File

@@ -0,0 +1,68 @@
#nullable enable
using System;
using UnityEngine;
using UnityEngine.UI;
using UVC.UI.List.Accordion;
namespace UVC.UI.Window
{
public class AccordionWindow : MonoBehaviour
{
[SerializeField] private RectTransform root = default!;
[SerializeField] private AccordionList? accordionListPrefab = null;
private AccordionList? _instance;
private void Reset()
{
EnsureRoot();
EnsureInstance();
}
private void Awake()
{
EnsureRoot();
EnsureInstance();
}
private void EnsureRoot()
{
if (root == null)
{
var go = new GameObject("AccordionRoot", typeof(RectTransform));
go.transform.SetParent(transform, false);
root = (RectTransform)go.transform;
var v = go.AddComponent<VerticalLayoutGroup>();
v.childControlHeight = true;
v.childForceExpandHeight = false;
v.spacing = 0f;
var fitter = go.AddComponent<ContentSizeFitter>();
fitter.verticalFit = ContentSizeFitter.FitMode.PreferredSize;
}
}
private void EnsureInstance()
{
if (_instance == null)
{
if (accordionListPrefab != null)
{
_instance = Instantiate(accordionListPrefab, root);
_instance.gameObject.SetActive(true);
}
else
{
var go = new GameObject("AccordionList", typeof(RectTransform), typeof(AccordionList));
go.transform.SetParent(root, false);
_instance = go.GetComponent<AccordionList>();
}
}
}
public void SetData(AccordionData data)
{
EnsureRoot();
EnsureInstance();
_instance!.SetData(data);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 6ad50e65d5080f04c99dd7606a8a4d70

View File

@@ -24,9 +24,9 @@ namespace UVC.UI.Window
/// <example>
/// <![CDATA[
/// // 외부에서 창을 참조했다고 가정
/// hierarchyWindow.OnItemSelected += item => Debug.Log($"Selected: {item.Name}");
/// hierarchyWindow.AddItem(new TreeListItemData("Root A"));
/// hierarchyWindow.AddItemAt(new TreeListItemData("Root B"),0);
/// accordionWindow.OnItemSelected += item => Debug.Log($"Selected: {item.Name}");
/// accordionWindow.AddItem(new TreeListItemData("Root A"));
/// accordionWindow.AddItemAt(new TreeListItemData("Root B"),0);
/// ]]>
/// </example>
/// </summary>