using System; using System.Collections.Generic; using UnityEngine.VFX; using UnityEngine.UIElements; namespace UnityEditor.VFX.UI { abstract class ListPropertyRM : PropertyRM> where U : PropertyRM { public ListPropertyRM(IPropertyRMProvider controller, float labelWidth) : base(controller, labelWidth) { AddToClassList("ListPropertyRM"); var label = new Label(ObjectNames.NicifyVariableName(controller.name)); label.AddToClassList("label"); Add(label); m_List = new ReorderableList(this); Add(m_List); } protected class ReorderableList : VFXReorderableList { ListPropertyRM m_List; public ReorderableList(ListPropertyRM list) { m_List = list; } public override void OnAdd() { m_List.OnAdd(); } public override void OnRemove(int index) { m_List.OnRemove(index); } protected override void ElementMoved(int movedIndex, int targetIndex) { base.ElementMoved(movedIndex, targetIndex); m_List.ElementMoved(movedIndex, targetIndex); } } void OnAdd() { T value = CreateItem(); ((List)m_Provider.value).Add(value); NotifyValueChanged(); Update(); } void OnRemove(int index) { ((List)m_Provider.value).RemoveAt(index); NotifyValueChanged(); Update(); } void ElementMoved(int movedIndex, int targetIndex) { var list = ((List)m_Provider.value); T tmp = list[movedIndex]; list.RemoveAt(movedIndex); list.Insert(targetIndex, tmp); NotifyValueChanged(); Update(); } void ItemChanged() { NotifyValueChanged(); } protected ReorderableList m_List; public override float GetPreferredControlWidth() { return 150; } public override void UpdateGUI(bool force) { List list = (List)m_Provider.value; int itemCount = 0; if (list != null) { itemCount = list.Count; } while (m_List.itemCount < itemCount) { m_List.AddItem(CreateNewField(m_List.itemCount)); } while (m_List.itemCount > itemCount) { m_List.RemoveItemAt(m_List.itemCount - 1); } for (int i = 0; i < itemCount; ++i) { var item = (m_List.ItemAt(i) as U); (item.provider as ItemProvider).m_Index = i; item.name = item.provider.name; item.Update(); } } class ItemProvider : IPropertyRMProvider { ListPropertyRM m_List; public int m_Index; public ItemProvider(ListPropertyRM list, int index) { m_List = list; m_Index = index; } bool IPropertyRMProvider.expanded => false; bool IPropertyRMProvider.expandable => false; bool IPropertyRMProvider.expandableIfShowsEverything => false; object IPropertyRMProvider.value { get => ((List)m_List.GetValue())[m_Index]; set { ((List)m_List.GetValue())[m_Index] = (T)value; m_List.ItemChanged(); } } bool IPropertyRMProvider.spaceableAndMasterOfSpace => false; VFXSpace IPropertyRMProvider.space { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } string IPropertyRMProvider.name => m_Index.ToString(); VFXPropertyAttributes IPropertyRMProvider.attributes => new VFXPropertyAttributes(); object[] IPropertyRMProvider.customAttributes => null; Type IPropertyRMProvider.portType => typeof(T); int IPropertyRMProvider.depth => 0; bool IPropertyRMProvider.editable => m_List.provider.editable; void IPropertyRMProvider.ExpandPath() { throw new NotImplementedException(); } bool IPropertyRMProvider.IsSpaceInherited() { return false; } IEnumerable IPropertyRMProvider.filteredOutEnumerators { get { return null; } } void IPropertyRMProvider.RetractPath() { throw new NotImplementedException(); } void IPropertyRMProvider.StartLiveModification() { m_List.provider.StartLiveModification(); } void IPropertyRMProvider.EndLiveModification() { m_List.provider.EndLiveModification(); } } protected abstract U CreateField(IPropertyRMProvider provider); protected abstract T CreateItem(); protected U CreateNewField(int index) { U item = CreateField(new ItemProvider(this, index)); item.isDelayed = true; return item; } protected override void UpdateEnabled() { } protected override void UpdateIndeterminate() { } public override bool showsEverything { get { return true; } } } }