using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.InputSystem; namespace UVC.UI.Window.PropertyWindow { /// /// 속성의 값 타입을 정의하는 열거형입니다. /// View에서 이 타입을 보고 적절한 UI 컨트롤을 생성합니다. /// public enum PropertyType { String, Int, Float, Bool, Vector2, Vector3, Color, Date, DateTime, Enum, DropdownList, RadioGroup, IntRange, FloatRange, DateRange, DateTimeRange, } /// /// 속성 값이 변경되었을 때 전달될 이벤트 데이터 클래스입니다. /// public class PropertyValueChangedEventArgs : EventArgs { /// /// 변경된 속성의 고유 ID /// public string PropertyId { get; } /// /// 이 인스턴스가 나타내는 속성의 유형을 가져옵니다. /// public PropertyType PropertyType { get; } /// /// 변경 전의 값 /// public object OldValue { get; } /// /// 변경 후의 새로운 값 /// public object NewValue { get; } public PropertyValueChangedEventArgs(string propertyId, PropertyType propertyType, object oldValue, object newValue) { PropertyId = propertyId; PropertyType = propertyType; OldValue = oldValue; NewValue = newValue; } } /// /// 모든 속성 항목이 구현해야 하는 기본 인터페이스입니다. /// public interface IPropertyItem { /// /// 속성의 고유 식별자 (필수) /// string Id { get; } /// /// UI에 표시될 속성 이름 (필수) /// string Name { get; } /// /// 속성에 대한 간단한 설명 (선택) /// string Description { get; set; } /// /// 마우스를 올렸을 때 표시될 툴팁 (선택) /// string Tooltip { get; set; } /// /// 읽기 전용 여부. true이면 UI에서 값 수정이 비활성화됩니다. /// bool IsReadOnly { get; set; } /// /// 속성의 현재 값 (object 타입) /// object GetValue(); /// /// 속성의 값을 설정합니다. /// /// 새로운 값 void SetValue(object value); /// /// 속성의 데이터 타입 /// PropertyType PropertyType { get; } } /// /// IPropertyItem 인터페이스를 구현하는 제네릭 기반의 추상 클래스입니다. /// 공통적인 기능을 미리 구현하여 코드 중복을 줄입니다. /// /// 속성 값의 실제 타입 public abstract class PropertyItem : IPropertyItem { public string Id { get; set; } public string Name { get; set; } public string Description { get; set; } public string Tooltip { get; set; } public bool IsReadOnly { get; set; } = false; public abstract PropertyType PropertyType { get; } /// /// 실제 데이터가 저장되는 필드 /// protected T _value; /// /// 속성의 현재 값 (제네릭 타입) /// public T Value { get => _value; set => _value = value; } protected PropertyItem(string id, string name, T initialValue) { Id = id; Name = name; _value = initialValue; } // IPropertyItem 인터페이스 구현 public object GetValue() => _value; public void SetValue(object value) { // 타입 안정성을 위해 캐스팅 시도 if (value is T typedValue) { _value = typedValue; } else { Debug.LogError($"[PropertyItem] ID '{Id}'에 잘못된 타입의 값({value.GetType().Name})이 할당되었습니다. 필요한 타입: {typeof(T).Name}"); } } } #region Concrete Property Classes // --- 기본 타입 속성 --- public class StringProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.String; public StringProperty(string id, string name, string initialValue) : base(id, name, initialValue) { } } public class IntProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.Int; public bool IsSlider { get; set; } = false; // 슬라이더로 표시할지 여부 public int MinValue { get; set; } = 0; // 슬라이더 최소값 public int MaxValue { get; set; } = 100; // 슬라이더 최대값 public IntProperty(string id, string name, int initialValue, bool isSlider = false, int minValue = 0, int maxValue = 100) : base(id, name, initialValue) { this.IsSlider = isSlider; this.MinValue = minValue; this.MaxValue = maxValue; } } public class FloatProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.Float; public bool IsSlider { get; set; } = false; // 슬라이더로 표시할지 여부 public float MinValue { get; set; } = 0; // 슬라이더 최소값 public float MaxValue { get; set; } = 1; // 슬라이더 최대값 public FloatProperty(string id, string name, float initialValue, bool isSlider = false, float minValue = 0, float maxValue = 1) : base(id, name, initialValue) { this.IsSlider = isSlider; this.MinValue = minValue; this.MaxValue = maxValue; } } public class BoolProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.Bool; public BoolProperty(string id, string name, bool initialValue) : base(id, name, initialValue) { } } public class ColorProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.Color; public ColorProperty(string id, string name, Color initialValue) : base(id, name, initialValue) { } } public class DateProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.Date; public DateProperty(string id, string name, DateTime initialValue) : base(id, name, initialValue) { } } public class DateTimeProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.DateTime; public DateTimeProperty(string id, string name, DateTime initialValue) : base(id, name, initialValue) { } } // --- 복합 타입 속성 --- public class Vector2Property : PropertyItem { public override PropertyType PropertyType => PropertyType.Vector2; /// /// 자식 필드의 이름 목록 (예: "X", "Y") /// public List ChildNames { get; set; } = new List { "X", "Y" }; public Vector2Property(string id, string name, Vector2 initialValue) : base(id, name, initialValue) { } } public class Vector3Property : PropertyItem { public override PropertyType PropertyType => PropertyType.Vector3; /// /// 자식 필드의 이름 목록 (예: "X", "Y", "Z") /// public List ChildNames { get; set; } = new List { "X", "Y", "Z" }; public Vector3Property(string id, string name, Vector3 initialValue) : base(id, name, initialValue) { } } // --- 범위 타입 속성 --- public class IntRangeProperty : PropertyItem> { public override PropertyType PropertyType => PropertyType.IntRange; public IntRangeProperty(string id, string name, Tuple initialValue) : base(id, name, initialValue) { } } public class FloatRangeProperty : PropertyItem> { public override PropertyType PropertyType => PropertyType.FloatRange; public FloatRangeProperty(string id, string name, Tuple initialValue) : base(id, name, initialValue) { } } public class DateRangeProperty : PropertyItem> { public override PropertyType PropertyType => PropertyType.DateRange; public DateRangeProperty(string id, string name, Tuple initialValue) : base(id, name, initialValue) { } } public class DateTimeRangeProperty : PropertyItem> { public override PropertyType PropertyType => PropertyType.DateTimeRange; public DateTimeRangeProperty(string id, string name, Tuple initialValue) : base(id, name, initialValue) { } } // --- 열거형 및 목록 타입 속성 --- public class EnumProperty : PropertyItem { public override PropertyType PropertyType => PropertyType.Enum; /// /// UI에서 드롭다운 목록을 채우기 위한 열거형의 타입 정보 /// public Type EnumType { get; } public EnumProperty(string id, string name, Enum initialValue) : base(id, name, initialValue) { EnumType = initialValue.GetType(); } } public class ListProperty : PropertyItem // 값은 선택된 항목의 값을 저장 { public override PropertyType PropertyType => PropertyType.DropdownList; /// /// 드롭다운에 표시될 항목 목록 /// public List ItemsSource { get; } public ListProperty(string id, string name, List items, string initialValue) : base(id, name, initialValue) { ItemsSource = items ?? new List(); } } public class RadioGroupProperty : PropertyItem // 값은 선택된 항목의 값을 저장 { public override PropertyType PropertyType => PropertyType.RadioGroup; /// /// 드롭다운에 표시될 항목 목록 /// public List ItemsSource { get; } public RadioGroupProperty(string id, string name, List items, string initialValue) : base(id, name, initialValue) { ItemsSource = items ?? new List(); } } #endregion }