update editors

This commit is contained in:
Mikhail 2024-09-16 19:31:01 +08:00
parent 1aa51c2a3c
commit 25251f044f
10 changed files with 376 additions and 194 deletions

View File

@ -137,7 +137,8 @@ namespace DCFApixels.DragonECS
{
[SerializeReference]
[ReferenceButton(true, typeof(IEcsModule), typeof(IEcsProcess))]
public object target;
[ArrayElement]
public object target;// нельзя менять поярдок полей, иначе это поломает отрисовку в инспекторе изза применения property.Next(bool);
public AddParams parameters;
public Record(object target, AddParams parameters)
{

View File

@ -8,7 +8,6 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
[CustomPropertyDrawer(typeof(EcsPipelineTemplateSO.Record))]
//[CustomPropertyDrawer(typeof(EcsPipelineTemplate.Record))]
internal class EcsPipelineTemplateSORecordDrawer : ExtendedPropertyDrawer
{
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
@ -28,8 +27,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
Rect subPosition = position;
int depth = -1;
property.Next(true);
float height = 0f;
property.Next(true);
do
{
subPosition.y += height;
@ -71,7 +71,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private SerializedProperty _recordsProp;
private ReorderableList _reorderableLayersList;
private ReorderableList _reorderableRecordsList;
private SystemsDropDown _systemsDropDown;
protected override bool IsInit
{
@ -94,14 +94,29 @@ namespace DCFApixels.DragonECS.Unity.Editors
_reorderableLayersList.drawElementCallback += OnReorderableLayersListDrawElement;
_reorderableLayersList.onReorderCallback += OnReorderableListReorder;
_reorderableRecordsList = new ReorderableList(serializedObject, _recordsProp, true, false, true, true);
_reorderableRecordsList = new ReorderableList(serializedObject, _recordsProp, true, false, false, false);
_reorderableRecordsList.onAddCallback += OnReorderableRecordsListAdd;
_reorderableRecordsList.onRemoveCallback += OnReorderableListRemove;
_reorderableRecordsList.drawElementCallback += OnReorderableRecordsListDrawElement;
_reorderableRecordsList.drawElementCallback += OnReorderableListDrawEmptyElement;
_reorderableRecordsList.drawElementBackgroundCallback += OnReorderableRecordsListDrawElement;
_reorderableRecordsList.drawNoneElementCallback += OnReorderableRecordsListDrawNoneElement;
_reorderableRecordsList.elementHeightCallback += OnReorderableRecordsListElementHeight;
_reorderableRecordsList.onReorderCallback += OnReorderableListReorder;
_reorderableRecordsList.showDefaultBackground = false;
_reorderableRecordsList.footerHeight = 0f;
_reorderableRecordsList.headerHeight = 0f;
_reorderableRecordsList.elementHeight = 0f;
_systemsDropDown = new SystemsDropDown();
}
private void OnReorderableRecordsListDrawNoneElement(Rect rect)
{
}
private void OnReorderableListDrawEmptyElement(Rect rect, int index, bool isActive, bool isFocused) { }
private void OnReorderableListReorder(ReorderableList list)
{
EcsGUI.Changed = true;
@ -148,17 +163,22 @@ namespace DCFApixels.DragonECS.Unity.Editors
#region _reorderableRecordsList
private void OnReorderableRecordsListDrawElement(Rect rect, int index, bool isActive, bool isFocused)
{
if (index < 0) { return; }
rect = rect.AddPadding(OneLineHeight + Spacing, Spacing * 2f, Spacing, Spacing);
using (EcsGUI.CheckChanged())
{
var prop = _recordsProp.GetArrayElementAtIndex(index);
if (Event.current.type == EventType.Used)
{
return;
}
//EcsDebug.PrintPass(index);
SerializedProperty prop = _recordsProp.GetArrayElementAtIndex(index);
var targetProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.target));
var paramsProp = prop.FindPropertyRelative(nameof(EcsPipelineTemplateSO.Record.parameters));
bool isNull = targetProp.managedReferenceValue == null;
ITypeMeta meta = isNull ? null : targetProp.managedReferenceValue.GetMeta();
if (EcsGUI.DrawTypeMetaBlock(ref rect, prop, meta))
if (EcsGUI.DrawTypeMetaElementBlock(ref rect, _recordsProp, index, prop, meta))
{
return;
}
@ -169,7 +189,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
float result;
result = EditorGUI.GetPropertyHeight(_recordsProp.GetArrayElementAtIndex(index));
return EcsGUI.GetTypeMetaBlockHeight(result);
return EcsGUI.GetTypeMetaBlockHeight(result) + Spacing * 2f;
}
private void OnReorderableRecordsListAdd(ReorderableList list)
@ -183,20 +203,16 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void DrawCustom()
{
using (EcsGUI.CheckChanged())
EcsGUI.Changed = GUILayout.Button("Validate");
DrawLayoutNameList(_layersProp);
DrawRecordList(_recordsProp);
if (EcsGUI.Changed)
{
EditorGUI.BeginChangeCheck();
DrawLayoutNameList(_layersProp);
DrawRecordList(_recordsProp);
EcsGUI.Changed = GUILayout.Button("Validate");
if (EcsGUI.Changed)
{
serializedObject.ApplyModifiedProperties();
Validate();
Repaint();
}
serializedObject.ApplyModifiedProperties();
Validate();
Repaint();
}
}
@ -220,9 +236,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
private void DrawRecordList(SerializedProperty recordsProp)
{
using (EcsGUI.Layout.BeginVertical())
GUILayout.Label(UnityEditorUtility.GetLabel(recordsProp.displayName), EditorStyles.boldLabel);
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
GUILayout.Label(UnityEditorUtility.GetLabel(recordsProp.displayName), EditorStyles.boldLabel);
switch (EcsGUI.Layout.AddClearSystemButtons(out Rect dropDownRect))
{
case EcsGUI.AddClearButton.Add:
_systemsDropDown.OpenForArray(dropDownRect, recordsProp);
break;
case EcsGUI.AddClearButton.Clear:
recordsProp.ClearArray();
recordsProp.serializedObject.ApplyModifiedProperties();
break;
}
_reorderableRecordsList.DoLayoutList();
//EditorGUILayout.PropertyField(recordsProp, UnityEditorUtility.GetLabel(recordsProp.displayName));
}

View File

@ -28,8 +28,34 @@ namespace DCFApixels.DragonECS.Unity.Editors
[CustomPropertyDrawer(typeof(ReferenceButtonAttribute))]
internal sealed class ReferenceButtonAttributeDrawer : ExtendedPropertyDrawer<ReferenceButtonAttribute>
{
protected override void OnInit()
{
Type referenceBaseType = typeof(Reference<>);
Type fieldType = fieldInfo.FieldType;
if (fieldType.IsGenericType)
{
if (fieldType.IsGenericTypeDefinition == false)
{
fieldType = fieldType.GetGenericTypeDefinition();
}
if (fieldType == referenceBaseType)
{
_isReferenceWrapper = true;
return;
}
}
_isReferenceWrapper = false;
}
private bool _isReferenceWrapper = false;
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
{
if (_isReferenceWrapper)
{
property.Next(true);
}
if (property.managedReferenceValue != null)
{
return EditorGUI.GetPropertyHeight(property, label, true);
@ -42,9 +68,19 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void DrawCustom(Rect position, SerializedProperty property, GUIContent label)
{
if (_isReferenceWrapper)
{
property.Next(true);
label.text = property.displayName;
}
if (IsArrayElement)
{
label = UnityEditorUtility.GetLabelTemp();
}
Rect selButtnoRect = position;
selButtnoRect.height = OneLineHeight;
DrawSelectionPopup(selButtnoRect, property, label);
DrawSelectionPopupButton(selButtnoRect, property, label);
if (property.managedReferenceValue != null)
{
@ -58,9 +94,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
private void DrawSelectionPopup(Rect position, SerializedProperty property, GUIContent label)
private void DrawSelectionPopupButton(Rect position, SerializedProperty property, GUIContent label)
{
Rect buttonRect = position.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f);
Rect buttonRect = IsArrayElement ? position : position.AddPadding(EditorGUIUtility.labelWidth, 0f, 0f, 0f); ;
EcsGUI.DrawSelectReferenceButton(buttonRect, property, Attribute.PredicateTypes.Length == 0 ? new Type[1] { fieldInfo.FieldType } : Attribute.PredicateTypes, Attribute.IsHideButtonIfNotNull);
}
}

View File

@ -163,7 +163,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * Padding * 1f;
//Canceling isExpanded
if (EcsGUI.HitTest(optionButton) && Event.current.type == EventType.MouseUp)
if (EcsGUI.ClickTest(optionButton))
{
componentProperty.isExpanded = !componentProperty.isExpanded;
}

View File

@ -24,37 +24,10 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void OnInit()
{
_componentDropDown = new ComponentDropDown();
_componentDropDown.OnSelected += OnAddComponent;
}
#endregion
#region Add/Remove
private void OnAddComponent(ComponentDropDown.Item item)
{
Type componentType = item.Obj.GetType();
IComponentTemplate cmptmp = item.Obj;
if (this.target is ITemplateInternal target)
{
SerializedProperty componentsProp = serializedObject.FindProperty(target.ComponentsPropertyName);
if (cmptmp.IsUnique)
{
for (int i = 0, iMax = componentsProp.arraySize; i < iMax; i++)
{
if (componentsProp.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
{
return;
}
}
}
int index = componentsProp.arraySize;
componentsProp.InsertArrayElementAtIndex(index);
componentsProp.GetArrayElementAtIndex(index).managedReferenceValue = cmptmp.Clone();
serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(this.target);
}
}
private void OnRemoveComponentAt(int index)
{
if (this.target is ITemplateInternal target)
@ -76,24 +49,25 @@ namespace DCFApixels.DragonECS.Unity.Editors
return;
}
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f));
DrawTop(target);
GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true));
for (int i = componentsProp.arraySize - 1; i >= 0; i--)
using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(Color.black, 0.2f)))
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), componentsProp.arraySize, i);
DrawTop(target, componentsProp);
GUILayout.Label("", GUILayout.Height(0), GUILayout.ExpandWidth(true));
for (int i = componentsProp.arraySize - 1; i >= 0; i--)
{
DrawComponentData(componentsProp.GetArrayElementAtIndex(i), componentsProp.arraySize, i);
}
}
GUILayout.EndVertical();
}
private void DrawTop(ITemplateInternal target)
private void DrawTop(ITemplateInternal target, SerializedProperty componentsProp)
{
switch (EcsGUI.Layout.AddClearComponentButtons(out Rect rect))
{
case EcsGUI.AddClearComponentButton.AddComponent:
case EcsGUI.AddClearButton.Add:
Init();
_componentDropDown.Show(rect);
_componentDropDown.OpenForArray(rect, componentsProp, true);
break;
case EcsGUI.AddClearComponentButton.Clear:
case EcsGUI.AddClearButton.Clear:
Init();
serializedObject.FindProperty(target.ComponentsPropertyName).ClearArray();
serializedObject.ApplyModifiedProperties();
@ -159,15 +133,11 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f;
bool cancelExpanded = EcsGUI.HitTest(optionButton) && Event.current.type == EventType.MouseUp;
bool cancelExpanded = EcsGUI.ClickTest(optionButton);
using (EcsGUI.CheckChanged())
#region Draw Component Block
using (EcsGUI.CheckChanged()) using (EcsGUI.Layout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor)))
{
//EditorGUI.BeginChangeCheck();
GUILayout.BeginVertical(UnityEditorUtility.GetStyle(alphaPanelColor));
#region Draw Component Block
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (EcsGUI.CloseButton(optionButton))
@ -210,17 +180,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
EditorGUI.PropertyField(r, componentProperty, label, true);
}
}
#endregion
GUILayout.EndVertical();
//if (EditorGUI.EndChangeCheck())
if (EcsGUI.Changed)
{
componentProperty.serializedObject.ApplyModifiedProperties();
EditorUtility.SetDirty(componentProperty.serializedObject.targetObject);
}
}
#endregion
}
private void DrawDamagedComponent_Replaced(SerializedProperty componentRefProp, int index)
{

View File

@ -1,4 +1,5 @@
#if UNITY_EDITOR
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
@ -8,6 +9,72 @@ using UnityEngine;
namespace DCFApixels.DragonECS.Unity.Editors
{
internal class SystemsDropDown : MetaObjectsDropDown<Type>
{
public SystemsDropDown()
{
Type[] predicateTypes = new Type[] { typeof(IEcsModule), typeof(IEcsProcess) };
IEnumerable<(Type, ITypeMeta)> itemMetaPairs = UnityEditorUtility._serializableTypes.Where(o =>
{
foreach (Type predicateTypes in predicateTypes)
{
if (predicateTypes.IsAssignableFrom(o))
{
return true;
}
}
return false;
}).Select(o => (o, (ITypeMeta)o.ToMeta()));
Setup(itemMetaPairs);
}
private SerializedProperty _arrayProperty;
private SerializedProperty _fieldProperty;
public void OpenForArray(Rect position, SerializedProperty arrayProperty)
{
_arrayProperty = arrayProperty;
_fieldProperty = null;
Show(position);
}
public void OpenForField(Rect position, SerializedProperty fieldProperty)
{
_arrayProperty = null;
_fieldProperty = fieldProperty;
Show(position);
}
protected override void ItemSelected(Item item)
{
base.ItemSelected(item);
Type type = item.Obj;
if (_arrayProperty != null)
{
int index = _arrayProperty.arraySize;
_arrayProperty.arraySize += 1;
_fieldProperty = _arrayProperty.GetArrayElementAtIndex(index);
_fieldProperty.Next(true);//Смещение чтобы перейти к полю Traget внутри рекорда
}
if (_fieldProperty != null)
{
if (type == null)
{
_fieldProperty.managedReferenceValue = null;
}
else
{
_fieldProperty.managedReferenceValue = Activator.CreateInstance(type);
_fieldProperty.isExpanded = true;
}
_fieldProperty.serializedObject.ApplyModifiedProperties();
EcsGUI.DelayedChanged = true;
}
}
}
internal class ComponentDropDown : MetaObjectsDropDown<IComponentTemplate>
{
public ComponentDropDown()
@ -27,6 +94,59 @@ namespace DCFApixels.DragonECS.Unity.Editors
});
Setup(itemMetaPairs);
}
private bool _isCheckUnique;
private SerializedProperty _arrayProperty;
private SerializedProperty _fieldProperty;
public void OpenForArray(Rect position, SerializedProperty arrayProperty, bool isCheckUnique)
{
_isCheckUnique = isCheckUnique;
_arrayProperty = arrayProperty;
_fieldProperty = null;
Show(position);
}
public void OpenForField(Rect position, SerializedProperty fieldProperty)
{
_isCheckUnique = false;
_arrayProperty = null;
_fieldProperty = fieldProperty;
Show(position);
}
protected override void ItemSelected(Item item)
{
base.ItemSelected(item);
Type componentType = item.Obj.GetType();
IComponentTemplate cmptmp = item.Obj;
if (_arrayProperty != null)
{
int index = _arrayProperty.arraySize;
if (_isCheckUnique)
{
if (cmptmp.IsUnique)
{
for (int i = 0, iMax = _arrayProperty.arraySize; i < iMax; i++)
{
if (_arrayProperty.GetArrayElementAtIndex(i).managedReferenceValue.GetType() == componentType)
{
return;
}
}
}
}
_arrayProperty.arraySize += 1;
_fieldProperty = _arrayProperty.GetArrayElementAtIndex(index);
}
if (_fieldProperty != null)
{
_fieldProperty.managedReferenceValue = cmptmp.Clone();
_fieldProperty.serializedObject.ApplyModifiedProperties();
}
}
}
internal class RuntimeComponentDropDown : MetaObjectsDropDown<IEcsPool>
{
@ -38,6 +158,31 @@ namespace DCFApixels.DragonECS.Unity.Editors
});
Setup(itemMetaPairs);
}
private int _entityID;
public void Open(Rect position, int entityID)
{
_entityID = entityID;
Show(position);
}
protected override void ItemSelected(Item item)
{
IEcsPool pool = item.Obj;
if (pool.World.IsUsed(_entityID) == false)
{
return;
}
if (pool.Has(_entityID) == false)
{
pool.AddRaw(_entityID, Activator.CreateInstance(pool.ComponentType));
}
else
{
Debug.LogWarning($"Entity({_entityID}) already has component {EcsDebugUtility.GetGenericTypeName(pool.ComponentType)}.");
}
}
}
internal class MetaObjectsDropDown<T> : AdvancedDropdown
{
@ -49,7 +194,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
minimumSize = new Vector2(minimumSize.x, EditorGUIUtility.singleLineHeight * 30);
}
protected void Setup(IEnumerable<(T, ITypeMeta)> itemMetaPairs, string name = "Select Type", bool isContainsNull = true)
protected void Setup(IEnumerable<(T, ITypeMeta)> itemMetaPairs, string name = "Select Type...", bool isContainsNull = true)
{
_name = name;
_isContainsNull = isContainsNull;
@ -103,8 +248,12 @@ namespace DCFApixels.DragonECS.Unity.Editors
protected override void ItemSelected(AdvancedDropdownItem item)
{
base.ItemSelected(item);
OnSelected((Item)item);
var tType = (Item)item;
ItemSelected(tType);
OnSelected(tType);
}
protected virtual void ItemSelected(Item item) { }
public event Action<Item> OnSelected = delegate { };

View File

@ -2,7 +2,6 @@
using DCFApixels.DragonECS.Unity.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEditor.IMGUI.Controls;
@ -265,28 +264,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f;
private static Type[] _serializableTypes;
static EcsGUI()
{
InitSerializableTypes();
}
private static void InitSerializableTypes()
{
List<Type> types = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type =>
(type.IsGenericType || type.IsAbstract || type.IsInterface) == false &&
type.IsSubclassOf(typeof(UnityObject)) == false &&
type.GetCustomAttribute<SerializableAttribute>() != null);
types.AddRange(targetTypes);
}
_serializableTypes = types.ToArray();
}
#region Properties
private static ComponentColorMode AutoColorMode
{
@ -314,14 +291,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
#endregion
#region enums
public enum AddClearComponentButton : byte
public enum AddClearButton : byte
{
None = 0,
AddComponent,
Clear,
Add = 1,
Clear = 2,
}
[Flags]
public enum EntityStatus
public enum EntityStatus : byte
{
NotAlive = 0,
Alive = 1 << 0,
@ -329,7 +306,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
#endregion
#region HitTest
#region HitTest/ClickTest
internal static bool HitTest(Rect rect)
{
return HitTest(rect, Event.current.mousePosition);
@ -347,6 +324,15 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return point.x >= rect.xMin - (float)offset && point.x < rect.xMax + (float)offset && point.y >= rect.yMin - (float)offset && point.y < rect.yMax + (float)offset;
}
internal static bool ClickTest(Rect rect)
{
Event evt = Event.current;
return ClickTest(rect, evt);
}
internal static bool ClickTest(Rect rect, Event evt)
{
return HitTest(rect, evt.mousePosition) && evt.type == EventType.MouseUp;
}
#endregion
#region small elems
@ -538,14 +524,42 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return DrawTypeMetaBlockPadding * 2 + contentHeight;
}
public static bool DrawTypeMetaElementBlock(ref Rect position, SerializedProperty arrayProperty, int elementIndex, SerializedProperty elementProperty, ITypeMeta meta)
{
var result = DrawTypeMetaBlock_Internal(ref position, elementProperty, meta);
if (result.HasFlag(DrawTypeMetaBlockResult.CloseButtonClicked))
{
arrayProperty.DeleteArrayElementAtIndex(elementIndex);
}
return result != DrawTypeMetaBlockResult.None;
}
public static bool DrawTypeMetaBlock(ref Rect position, SerializedProperty property, ITypeMeta meta)
{
var result = DrawTypeMetaBlock_Internal(ref position, property, meta);
if (result.HasFlag(DrawTypeMetaBlockResult.CloseButtonClicked))
{
property.ResetValues();
}
return result.HasFlag(DrawTypeMetaBlockResult.Drop);
}
private enum DrawTypeMetaBlockResult
{
None = 0,
Drop = 1 << 0,
CloseButtonClicked = 1 << 1,
}
private static DrawTypeMetaBlockResult DrawTypeMetaBlock_Internal(ref Rect position, SerializedProperty property, ITypeMeta meta)
{
Color alphaPanelColor;
if (meta == null)
{
return false;
alphaPanelColor = Color.black;
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
EditorGUI.DrawRect(position, alphaPanelColor);
position = position.AddPadding(DrawTypeMetaBlockPadding * 2f);
return DrawTypeMetaBlockResult.None;
}
GUIContent label = UnityEditorUtility.GetLabel(property.displayName);
var counter = property.Copy();
int positionCountr = int.MaxValue;
@ -555,45 +569,40 @@ namespace DCFApixels.DragonECS.Unity.Editors
positionCountr--;
}
//var counter = property.Copy();
//int positionCountr = int.MaxValue;
//while (counter.NextVisible(false))
//{
// positionCountr--;
//}
string name = meta.Name;
string description = meta.Description.Text;
Color panelColor = EcsGUI.SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
Color alphaPanelColor = panelColor;
alphaPanelColor = SelectPanelColor(meta, positionCountr, -1).Desaturate(EscEditorConsts.COMPONENT_DRAWER_DESATURATE);
alphaPanelColor.a = EscEditorConsts.COMPONENT_DRAWER_ALPHA;
DrawTypeMetaBlockResult result = DrawTypeMetaBlockResult.None;
using (CheckChanged())
{
EditorGUI.DrawRect(position, alphaPanelColor);
Rect paddingPosition = RectUtility.AddPadding(position, DrawTypeMetaBlockPadding * 2f);
Rect optionButton = position;
position = position.AddPadding(DrawTypeMetaBlockPadding * 2f);
optionButton.center -= new Vector2(0, optionButton.height);
optionButton.yMin = optionButton.yMax;
optionButton.yMax += HeadIconsRect.height;
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * DrawTypeMetaBlockPadding * 1f;
//Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp)
bool oldIsExpanded = property.isExpanded;
if (ClickTest(optionButton))
{
property.isExpanded = !property.isExpanded;
property.isExpanded = oldIsExpanded;
result |= DrawTypeMetaBlockResult.Drop;
}
//Close button
optionButton.xMin = optionButton.xMax - HeadIconsRect.width;
if (CloseButton(optionButton))
{
property.ResetValues();
return true;
result |= DrawTypeMetaBlockResult.CloseButtonClicked;
return result;
}
//Edit script button
if (UnityEditorUtility.TryGetScriptAsset(meta.Type, out MonoScript script))
@ -607,21 +616,8 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton = HeadIconsRect.MoveTo(optionButton.center - (Vector2.right * optionButton.width));
DescriptionIcon(optionButton, description);
}
//if (string.IsNullOrEmpty(label.text))
//{
// EditorGUI.indentLevel++;
// EditorGUI.PrefixLabel(position.AddPadding(0, 0, 0, position.height - SingleLineWithPadding), UnityEditorUtility.GetLabel(name));
// EditorGUI.indentLevel--;
//}
//else
//{
// GUI.Label(position.AddPadding(EditorGUIUtility.labelWidth, 0, 0, position.height - SingleLineWithPadding), name);
//}
position = paddingPosition;
}
return false;
return result;
}
#endregion
@ -699,22 +695,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
dropDownRect = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
return GUI.Button(dropDownRect, "Add Component");
}
public static AddClearComponentButton AddClearComponentButtons(Rect position, out Rect dropDownRect)
public static AddClearButton AddClearComponentButtons(Rect position, out Rect dropDownRect)
{
return AddClearButtons(position, "Add Component", "Clear", out dropDownRect);
}
public static AddClearButton AddClearSystemButtons(Rect position, out Rect dropDownRect)
{
return AddClearButtons(position, "Add Record", "Clear", out dropDownRect);
}
public static AddClearButton AddClearButtons(Rect position, string addText, string clearText, out Rect dropDownRect)
{
position = RectUtility.AddPadding(position, 20f, 20f, 12f, 2f);
var (left, right) = RectUtility.HorizontalSliceLerp(position, 0.75f);
dropDownRect = left;
if (GUI.Button(left, "Add Component"))
if (GUI.Button(left, addText))
{
return AddClearComponentButton.AddComponent;
return AddClearButton.Add;
}
if (GUI.Button(right, "Clear"))
if (GUI.Button(right, clearText))
{
return AddClearComponentButton.Clear;
return AddClearButton.Clear;
}
return AddClearComponentButton.None;
return AddClearButton.None;
}
public static void DrawEmptyComponentProperty(Rect position, SerializedProperty property, string name, bool isDisplayEmpty)
@ -822,7 +826,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
Dictionary<Key, Item> dict = new Dictionary<Key, Item>();
foreach (var type in _serializableTypes)
foreach (var type in UnityEditorUtility._serializableTypes)
{
bool isAssignable = false;
foreach (Type predicateTypes in PredicateTypes)
@ -937,20 +941,24 @@ namespace DCFApixels.DragonECS.Unity.Editors
public static void DrawSelectReferenceButton(Rect position, SerializedProperty property, Type[] sortedPredicateTypes, bool isHideButtonIfNotNull)
{
object obj = property.hasMultipleDifferentValues ? null : property.managedReferenceValue;
string text = obj == null ? "Select..." : obj.GetMeta().Name;
if (!isHideButtonIfNotNull || obj == null)
{
if (GUI.Button(position, obj == null ? "Select..." : obj.GetMeta().Name, EditorStyles.layerMaskField))
if (GUI.Button(position, text, EditorStyles.layerMaskField))
{
_currentProperty = property;
GetReferenceDropDown(sortedPredicateTypes).Show(position);
DrawSelectReferenceMenu(position, property, sortedPredicateTypes);
}
}
else
{
GUI.Label(position, obj == null ? "Select..." : obj.GetMeta().Name);
GUI.Label(position, text);
}
}
public static void DrawSelectReferenceMenu(Rect position, SerializedProperty property, Type[] sortedPredicateTypes)
{
_currentProperty = property;
GetReferenceDropDown(sortedPredicateTypes).Show(position);
}
#endregion
@ -1045,10 +1053,14 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
return EcsGUI.AddComponentButton(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect);
}
public static AddClearComponentButton AddClearComponentButtons(out Rect dropDownRect)
public static AddClearButton AddClearComponentButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearComponentButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect);
}
public static AddClearButton AddClearSystemButtons(out Rect dropDownRect)
{
return EcsGUI.AddClearSystemButtons(GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, 36f), out dropDownRect);
}
public static void DrawRuntimeComponents(entlong entity, bool isWithFoldout = true)
{
if (entity.TryUnpackForUnityEditor(out int entityID, out _, out _, out EcsWorld world))
@ -1071,9 +1083,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
if (AddComponentButtons(out Rect dropDownRect))
{
RuntimeComponentDropDown genericMenu = RuntimeComponentsUtility.GetAddComponentGenericMenu(world);
RuntimeComponentsUtility.CurrentEntityID = entityID;
genericMenu.Show(dropDownRect);
RuntimeComponentsUtility.GetAddComponentGenericMenu(world).Open(dropDownRect, entityID);
}
GUILayout.Box("", UnityEditorUtility.GetStyle(GUI.color, 0.16f), GUILayout.ExpandWidth(true));
@ -1109,7 +1119,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
optionButton.xMin = optionButton.xMax - 64;
optionButton.center += Vector2.up * padding * 2f;
//Canceling isExpanded
if (HitTest(optionButton) && Event.current.type == EventType.MouseUp)
if (ClickTest(optionButton))
{
ref bool isExpanded = ref expandMatrix.Down();
isExpanded = !isExpanded;

View File

@ -86,7 +86,6 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
internal abstract class ExtendedEditor<T> : ExtendedEditor
{
public T Target
{
get
@ -124,7 +123,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
}
}
private IEnumerable<Attribute> Attributes
protected IEnumerable<Attribute> Attributes
{
get
{

View File

@ -2,10 +2,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using UnityEditor;
using UnityEngine;
using UnityObject = UnityEngine.Object;
namespace DCFApixels.DragonECS.Unity.Editors
{
@ -108,7 +110,30 @@ namespace DCFApixels.DragonECS.Unity.Editors
static UnityEditorUtility()
{
colorBoxeStyles = new SparseArray<GUIStyle>();
#region InitSerializableTypes
List<Type> types = new List<Type>();
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var targetTypes = assembly.GetTypes().Where(type =>
(type.IsGenericType || type.IsAbstract || type.IsInterface) == false &&
type.IsSubclassOf(typeof(UnityObject)) == false &&
type.GetCustomAttribute<SerializableAttribute>() != null);
types.AddRange(targetTypes);
}
_serializableTypes = types.ToArray();
//Array.Sort(_serializableTypes, (a, b) => string.Compare(a.AssemblyQualifiedName, b.AssemblyQualifiedName, StringComparison.Ordinal));
//_noHiddenSerializableTypes = _serializableTypes.Where(o => {
// var atr = o.GetCustomAttribute<MetaTagsAttribute>();
// return atr != null && atr.Tags.Contains(MetaTags.HIDDEN);
//}).ToArray();
#endregion
}
internal static readonly Type[] _serializableTypes;
//private static Type[] _noHiddenSerializableTypes;
private static SparseArray<GUIStyle> colorBoxeStyles = new SparseArray<GUIStyle>();
private static GUIContent _singletonIconContent = null;
private static GUIContent _singletonContent = null;
@ -116,6 +141,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
private static Dictionary<Type, MonoScript> scriptsAssets = new Dictionary<Type, MonoScript>(256);
internal static void ResetValues(this SerializedProperty property, bool isExpand = false)
{
ResetValues_Internal(property.Copy(), isExpand, property.depth);
@ -156,7 +182,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
property.colorValue = default;
break;
case SerializedPropertyType.ObjectReference:
property.objectReferenceValue = null;
property.objectReferenceValue = default;
break;
case SerializedPropertyType.LayerMask:
property.intValue = default;
@ -200,7 +226,7 @@ namespace DCFApixels.DragonECS.Unity.Editors
property.quaternionValue = Quaternion.identity;
break;
case SerializedPropertyType.ExposedReference:
property.objectReferenceValue = null;
property.objectReferenceValue = default;
break;
case SerializedPropertyType.FixedBufferSize:
for (int i = 0, iMax = property.fixedBufferSize; i < iMax; i++)
@ -423,41 +449,9 @@ namespace DCFApixels.DragonECS.Unity.Editors
{
IEnumerable<IEcsPool> pools = world.AllPools.ToArray().Where(o => o.IsNullOrDummy() == false);
RuntimeComponentDropDown genericMenu = new RuntimeComponentDropDown(pools);
//var pools = world.AllPools;
//for (int i = 0; i < pools.Length; i++)
//{
// var pool = pools[i];
// if (pool.IsNullOrDummy())
// {
// continue;
// }
// var meta = pool.ComponentType.ToMeta();
// string name = meta.Group.Name + meta.Name;
// genericMenu.AddItem(new GUIContent(name, meta.Description.Text), false, OnAddComponent, pool);
//}
return new WorldData(genericMenu, world.PoolsCount);
}
public static int CurrentEntityID = 0;
private static void OnAddComponent(object userData)
{
IEcsPool pool = (IEcsPool)userData;
if (pool.World.IsUsed(CurrentEntityID) == false)
{
return;
}
if (pool.Has(CurrentEntityID) == false)
{
pool.AddRaw(CurrentEntityID, Activator.CreateInstance(pool.ComponentType));
}
else
{
Debug.LogWarning($"Entity({CurrentEntityID}) already has component {EcsDebugUtility.GetGenericTypeName(pool.ComponentType)}.");
}
}
private class Listener : IEcsWorldEventListener
{
private EcsWorld _world;