286 lines
13 KiB
C#
286 lines
13 KiB
C#
#nullable enable
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace UVC.UIToolkit
|
|
{
|
|
/// <summary>
|
|
/// PropertyItem 데이터에 해당하는 View를 생성하는 팩토리 클래스입니다.
|
|
///
|
|
/// <para><b>주요 기능:</b></para>
|
|
/// <list type="bullet">
|
|
/// <item>PropertyType에 따라 적절한 View 인스턴스 생성</item>
|
|
/// <item>Data 클래스와 View 자동 바인딩</item>
|
|
/// <item>커스텀 View 등록 지원</item>
|
|
/// </list>
|
|
///
|
|
/// <para><b>사용법:</b></para>
|
|
/// <code>
|
|
/// var data = new UTKFloatPropertyItem("speed", "속도", 1.5f);
|
|
/// var view = UTKPropertyItemViewFactory.CreateView(data);
|
|
/// parent.Add(view);
|
|
/// </code>
|
|
/// </summary>
|
|
public static class UTKPropertyItemViewFactory
|
|
{
|
|
#region Fields
|
|
private static readonly Dictionary<UTKPropertyType, Func<IUTKPropertyItemView>> _customViewFactories = new();
|
|
#endregion
|
|
|
|
#region Public Methods
|
|
/// <summary>
|
|
/// PropertyItem 데이터에 해당하는 View를 생성하고 바인딩합니다.
|
|
/// </summary>
|
|
/// <param name="data">PropertyItem 데이터</param>
|
|
/// <returns>바인딩된 View (VisualElement)</returns>
|
|
public static VisualElement CreateView(IUTKPropertyItem data)
|
|
{
|
|
var view = CreateViewInstance(data);
|
|
view.Bind(data);
|
|
|
|
if (view is VisualElement element)
|
|
{
|
|
return element;
|
|
}
|
|
|
|
Debug.LogError($"[UTKPropertyItemViewFactory] View is not a VisualElement: {view.GetType().Name}");
|
|
return new VisualElement();
|
|
}
|
|
|
|
/// <summary>
|
|
/// PropertyItem 데이터에 해당하는 View를 생성합니다 (바인딩 없음).
|
|
/// </summary>
|
|
/// <param name="data">PropertyItem 데이터 (View 설정에 필요한 정보 제공)</param>
|
|
/// <returns>View 인스턴스</returns>
|
|
public static IUTKPropertyItemView CreateViewInstance(IUTKPropertyItem data)
|
|
{
|
|
// 커스텀 팩토리 우선
|
|
if (_customViewFactories.TryGetValue(data.PropertyType, out var customFactory))
|
|
{
|
|
return customFactory();
|
|
}
|
|
|
|
// 기본 View 생성 - View의 Bind 메서드에서 데이터 속성 동기화 처리
|
|
return data.PropertyType switch
|
|
{
|
|
UTKPropertyType.String => CreateStringView(data),
|
|
UTKPropertyType.Int => CreateIntView(data),
|
|
UTKPropertyType.Float => CreateFloatView(data),
|
|
UTKPropertyType.Bool => new UTKBoolPropertyItemView(),
|
|
UTKPropertyType.Vector2 => new UTKVector2PropertyItemView(),
|
|
UTKPropertyType.Vector3 => new UTKVector3PropertyItemView(),
|
|
UTKPropertyType.Color => new UTKColorPropertyItemView(),
|
|
UTKPropertyType.Date => new UTKDatePropertyItemView(),
|
|
UTKPropertyType.DateTime => new UTKDateTimePropertyItemView(),
|
|
UTKPropertyType.Enum => CreateEnumView(data),
|
|
UTKPropertyType.DropdownList => CreateDropdownView(data),
|
|
UTKPropertyType.MultiSelectDropdownList => CreateMultiSelectDropdownView(data),
|
|
UTKPropertyType.RadioGroup => CreateRadioView(data),
|
|
UTKPropertyType.IntRange => new UTKIntRangePropertyItemView(),
|
|
UTKPropertyType.FloatRange => new UTKFloatRangePropertyItemView(),
|
|
UTKPropertyType.DateRange => new UTKDateRangePropertyItemView(),
|
|
UTKPropertyType.DateTimeRange => new UTKDateTimeRangePropertyItemView(),
|
|
UTKPropertyType.ColorState => new UTKColorStatePropertyItemView(),
|
|
UTKPropertyType.FloatDropdown => CreateFloatDropdownView(data),
|
|
UTKPropertyType.Button => CreateButtonView(data),
|
|
_ => throw new ArgumentException($"Unknown property type: {data.PropertyType}")
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// PropertyType에 해당하는 빈 View 인스턴스를 생성합니다.
|
|
/// </summary>
|
|
/// <param name="propertyType">속성 타입</param>
|
|
/// <returns>View 인스턴스</returns>
|
|
public static IUTKPropertyItemView CreateViewInstance(UTKPropertyType propertyType)
|
|
{
|
|
// 커스텀 팩토리 우선
|
|
if (_customViewFactories.TryGetValue(propertyType, out var customFactory))
|
|
{
|
|
return customFactory();
|
|
}
|
|
|
|
return propertyType switch
|
|
{
|
|
UTKPropertyType.String => new UTKStringPropertyItemView(),
|
|
UTKPropertyType.Int => new UTKIntPropertyItemView(),
|
|
UTKPropertyType.Float => new UTKFloatPropertyItemView(),
|
|
UTKPropertyType.Bool => new UTKBoolPropertyItemView(),
|
|
UTKPropertyType.Vector2 => new UTKVector2PropertyItemView(),
|
|
UTKPropertyType.Vector3 => new UTKVector3PropertyItemView(),
|
|
UTKPropertyType.Color => new UTKColorPropertyItemView(),
|
|
UTKPropertyType.Date => new UTKDatePropertyItemView(),
|
|
UTKPropertyType.DateTime => new UTKDateTimePropertyItemView(),
|
|
UTKPropertyType.Enum => new UTKEnumPropertyItemView(),
|
|
UTKPropertyType.DropdownList => new UTKDropdownPropertyItemView(),
|
|
UTKPropertyType.MultiSelectDropdownList => new UTKMultiSelectDropdownPropertyItemView(),
|
|
UTKPropertyType.RadioGroup => new UTKRadioPropertyItemView(),
|
|
UTKPropertyType.IntRange => new UTKIntRangePropertyItemView(),
|
|
UTKPropertyType.FloatRange => new UTKFloatRangePropertyItemView(),
|
|
UTKPropertyType.DateRange => new UTKDateRangePropertyItemView(),
|
|
UTKPropertyType.DateTimeRange => new UTKDateTimeRangePropertyItemView(),
|
|
UTKPropertyType.ColorState => new UTKColorStatePropertyItemView(),
|
|
UTKPropertyType.FloatDropdown => new UTKFloatDropdownPropertyItemView(),
|
|
UTKPropertyType.Button => new UTKButtonItemView(),
|
|
_ => throw new ArgumentException($"Unknown property type: {propertyType}")
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// PropertyItem 데이터에 해당하는 View의 Type을 반환합니다.
|
|
/// View 재사용 시 기존 View와 타입 호환 여부 확인에 사용합니다.
|
|
/// </summary>
|
|
/// <param name="data">PropertyItem 데이터</param>
|
|
/// <returns>View Type</returns>
|
|
public static Type GetViewType(IUTKPropertyItem data)
|
|
{
|
|
return data.PropertyType switch
|
|
{
|
|
UTKPropertyType.String => typeof(UTKStringPropertyItemView),
|
|
UTKPropertyType.Int => typeof(UTKIntPropertyItemView),
|
|
UTKPropertyType.Float => typeof(UTKFloatPropertyItemView),
|
|
UTKPropertyType.Bool => typeof(UTKBoolPropertyItemView),
|
|
UTKPropertyType.Vector2 => typeof(UTKVector2PropertyItemView),
|
|
UTKPropertyType.Vector3 => typeof(UTKVector3PropertyItemView),
|
|
UTKPropertyType.Color => typeof(UTKColorPropertyItemView),
|
|
UTKPropertyType.Date => typeof(UTKDatePropertyItemView),
|
|
UTKPropertyType.DateTime => typeof(UTKDateTimePropertyItemView),
|
|
UTKPropertyType.Enum => typeof(UTKEnumPropertyItemView),
|
|
UTKPropertyType.DropdownList => typeof(UTKDropdownPropertyItemView),
|
|
UTKPropertyType.MultiSelectDropdownList => typeof(UTKMultiSelectDropdownPropertyItemView),
|
|
UTKPropertyType.RadioGroup => typeof(UTKRadioPropertyItemView),
|
|
UTKPropertyType.IntRange => typeof(UTKIntRangePropertyItemView),
|
|
UTKPropertyType.FloatRange => typeof(UTKFloatRangePropertyItemView),
|
|
UTKPropertyType.DateRange => typeof(UTKDateRangePropertyItemView),
|
|
UTKPropertyType.DateTimeRange => typeof(UTKDateTimeRangePropertyItemView),
|
|
UTKPropertyType.ColorState => typeof(UTKColorStatePropertyItemView),
|
|
UTKPropertyType.FloatDropdown => typeof(UTKFloatDropdownPropertyItemView),
|
|
UTKPropertyType.Button => typeof(UTKButtonItemView),
|
|
_ => typeof(VisualElement)
|
|
};
|
|
}
|
|
|
|
/// <summary>
|
|
/// 커스텀 View 팩토리를 등록합니다.
|
|
/// </summary>
|
|
/// <param name="propertyType">속성 타입</param>
|
|
/// <param name="factory">View 생성 팩토리 함수</param>
|
|
public static void RegisterCustomView(UTKPropertyType propertyType, Func<IUTKPropertyItemView> factory)
|
|
{
|
|
_customViewFactories[propertyType] = factory;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 커스텀 View 팩토리를 제거합니다.
|
|
/// </summary>
|
|
/// <param name="propertyType">속성 타입</param>
|
|
public static void UnregisterCustomView(UTKPropertyType propertyType)
|
|
{
|
|
_customViewFactories.Remove(propertyType);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 모든 커스텀 View 팩토리를 제거합니다.
|
|
/// </summary>
|
|
public static void ClearCustomViews()
|
|
{
|
|
_customViewFactories.Clear();
|
|
}
|
|
#endregion
|
|
|
|
#region Private Methods
|
|
private static IUTKPropertyItemView CreateStringView(IUTKPropertyItem data)
|
|
{
|
|
// UTKStringPropertyItem의 Multiline 속성에 따라 View 생성
|
|
if (data is UTKStringPropertyItem stringItem)
|
|
{
|
|
return new UTKStringPropertyItemView(stringItem.Id, stringItem.Value ?? "", stringItem.IsMultiline, stringItem.MaxLength, stringItem.IsReadOnly);
|
|
}
|
|
return new UTKStringPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateIntView(IUTKPropertyItem data)
|
|
{
|
|
// UTKIntPropertyItem의 UseSlider 속성에 따라 View 생성
|
|
if (data is UTKIntPropertyItem intItem && intItem.UseSlider)
|
|
{
|
|
return new UTKIntPropertyItemView("", intItem.Value, intItem.MinValue, intItem.MaxValue, true);
|
|
}
|
|
return new UTKIntPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateFloatView(IUTKPropertyItem data)
|
|
{
|
|
// UTKFloatPropertyItem의 UseSlider 속성에 따라 View 생성
|
|
if (data is UTKFloatPropertyItem floatItem && floatItem.UseSlider)
|
|
{
|
|
return new UTKFloatPropertyItemView("", floatItem.Value, floatItem.MinValue, floatItem.MaxValue, true);
|
|
}
|
|
return new UTKFloatPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateEnumView(IUTKPropertyItem data)
|
|
{
|
|
// UTKEnumPropertyItem의 Value로 EnumDropDown 초기화
|
|
if (data is UTKEnumPropertyItem enumItem && enumItem.Value != null)
|
|
{
|
|
return new UTKEnumPropertyItemView("", enumItem.Value);
|
|
}
|
|
return new UTKEnumPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateDropdownView(IUTKPropertyItem data)
|
|
{
|
|
// UTKDropdownPropertyItem의 Choices로 Dropdown 초기화
|
|
if (data is UTKDropdownPropertyItem dropdownItem)
|
|
{
|
|
return new UTKDropdownPropertyItemView("", dropdownItem.Choices);
|
|
}
|
|
return new UTKDropdownPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateRadioView(IUTKPropertyItem data)
|
|
{
|
|
// UTKRadioPropertyItem의 Choices로 RadioGroup 초기화
|
|
if (data is UTKRadioPropertyItem radioItem)
|
|
{
|
|
return new UTKRadioPropertyItemView("", radioItem.Choices);
|
|
}
|
|
return new UTKRadioPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateMultiSelectDropdownView(IUTKPropertyItem data)
|
|
{
|
|
// UTKMultiSelectDropdownPropertyItem의 Choices로 MultiSelectDropdown 초기화
|
|
if (data is UTKMultiSelectDropdownPropertyItem multiSelectItem)
|
|
{
|
|
return new UTKMultiSelectDropdownPropertyItemView("", multiSelectItem.Choices);
|
|
}
|
|
return new UTKMultiSelectDropdownPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateFloatDropdownView(IUTKPropertyItem data)
|
|
{
|
|
// UTKFloatDropdownPropertyItem의 Choices로 View 초기화
|
|
if (data is UTKFloatDropdownPropertyItem floatDropdownItem)
|
|
{
|
|
return new UTKFloatDropdownPropertyItemView(floatDropdownItem);
|
|
}
|
|
return new UTKFloatDropdownPropertyItemView();
|
|
}
|
|
|
|
private static IUTKPropertyItemView CreateButtonView(IUTKPropertyItem data)
|
|
{
|
|
// UTKButtonItem으로 ButtonView 초기화
|
|
if (data is UTKButtonItem buttonItem)
|
|
{
|
|
return new UTKButtonItemView(buttonItem);
|
|
}
|
|
return new UTKButtonItemView();
|
|
}
|
|
#endregion
|
|
}
|
|
}
|