Browse Source

Much better header display for arrays and list containing objects

Marko Pintera 10 years ago
parent
commit
59f8c29bf0

+ 44 - 11
MBansheeEditor/Inspector/InspectableArray.cs

@@ -13,12 +13,30 @@ namespace BansheeEditor
         {
             public GUILayoutY contentLayout;
             private GUILayoutX rowLayout;
+            private GUILayoutX titleLayout;
+            private bool ownsTitleLayout;
 
-            public EntryRow(GUILayout parentLayout, int seqIndex, InspectableArray parent)
+            public EntryRow(GUILayout parentLayout)
             {
                 rowLayout = parentLayout.AddLayoutX();
                 contentLayout = rowLayout.AddLayoutY();
-                GUILayoutY buttonLayout = rowLayout.AddLayoutY();
+            }
+
+            public void Refresh(InspectableObjectBase child, int seqIndex, InspectableArray parent)
+            {
+                if (ownsTitleLayout)
+                    return;
+
+                titleLayout = child.GetTitleLayout();
+                if (titleLayout == null)
+                {
+                    GUILayoutY buttonCenter = rowLayout.AddLayoutY();
+                    buttonCenter.AddFlexibleSpace();
+                    titleLayout = buttonCenter.AddLayoutX();
+                    buttonCenter.AddFlexibleSpace();
+
+                    ownsTitleLayout = true;
+                }
 
                 GUIButton cloneBtn = new GUIButton("C");
                 GUIButton deleteBtn = new GUIButton("X");
@@ -30,11 +48,10 @@ namespace BansheeEditor
                 moveUpBtn.OnClick += () => parent.OnMoveUpButtonClicked(seqIndex);
                 moveDownBtn.OnClick += () => parent.OnMoveDownButtonClicked(seqIndex);
 
-                buttonLayout.AddElement(cloneBtn);
-                buttonLayout.AddElement(deleteBtn);
-                buttonLayout.AddElement(moveUpBtn);
-                buttonLayout.AddElement(moveDownBtn);
-                buttonLayout.AddFlexibleSpace();
+                titleLayout.AddElement(cloneBtn);
+                titleLayout.AddElement(deleteBtn);
+                titleLayout.AddElement(moveUpBtn);
+                titleLayout.AddElement(moveDownBtn);
             }
 
             public void Destroy()
@@ -51,6 +68,7 @@ namespace BansheeEditor
         private List<EntryRow> rows = new List<EntryRow>();
         private GUIIntField guiSizeField;
         private GUILayoutX guiChildLayout;
+        private GUILayoutX guiTitleLayout;
         private bool isExpanded;
 
         private bool forceUpdate = true;
@@ -61,6 +79,11 @@ namespace BansheeEditor
 
         }
 
+        public override GUILayoutX GetTitleLayout()
+        {
+            return guiTitleLayout;
+        }
+
         protected override bool IsModified()
         {
             if (forceUpdate)
@@ -94,7 +117,15 @@ namespace BansheeEditor
             }
 
             for (int i = 0; i < GetChildCount(); i++)
-                anythingModified |= GetChild(i).Refresh(0);
+            {
+                InspectableObjectBase child = GetChild(i);
+                bool childModified = child.Refresh(0);
+
+                if (childModified)
+                    rows[i].Refresh(child, i, this);
+
+                anythingModified |= childModified;
+            }
 
             return anythingModified;
         }
@@ -103,6 +134,7 @@ namespace BansheeEditor
         {
             base.Update(layoutIndex);
             forceUpdate = false;
+            guiTitleLayout = null;
 
             if (property.Type != SerializableProperty.FieldType.Array || property.InternalType.GetArrayRank() != 1) // We don't support multirank arrays
                 return;
@@ -117,7 +149,7 @@ namespace BansheeEditor
             if (propertyValue == null)
             {
                 guiChildLayout = null;
-                GUILayoutX guiTitleLayout = layout.AddLayoutX(layoutIndex);
+                guiTitleLayout = layout.AddLayoutX(layoutIndex);
 
                 guiTitleLayout.AddElement(new GUILabel(title));
                 guiTitleLayout.AddElement(new GUILabel("Empty"));
@@ -143,7 +175,7 @@ namespace BansheeEditor
                 GUIButton guiClearBtn = new GUIButton("Clear");
                 guiClearBtn.OnClick += OnClearButtonClicked;
 
-                GUILayoutX guiTitleLayout = layout.AddLayoutX(layoutIndex);
+                guiTitleLayout = layout.AddLayoutX(layoutIndex);
                 guiTitleLayout.AddElement(guiFoldout);
                 guiTitleLayout.AddElement(guiSizeField);
                 guiTitleLayout.AddElement(guiResizeBtn);
@@ -162,13 +194,14 @@ namespace BansheeEditor
 
                     for (int i = 0; i < numArrayElements; i++)
                     {
-                        EntryRow newRow = new EntryRow(guiContentLayout, i, this);
+                        EntryRow newRow = new EntryRow(guiContentLayout);
                         rows.Add(newRow);
 
                         InspectableObjectBase childObj = CreateDefaultInspectable(i + ".", new InspectableFieldLayout(newRow.contentLayout), array.GetProperty(i));
                         AddChild(childObj);
 
                         childObj.Refresh(0);
+                        rows[i].Refresh(childObj, i, this);
                     }
                 }
                 else

+ 50 - 23
MBansheeEditor/Inspector/InspectableList.cs

@@ -11,41 +11,52 @@ namespace BansheeEditor
     {
         private class EntryRow
         {
-            public GUILayoutX rowLayout;
             public GUILayoutY contentLayout;
-            public GUIButton cloneBtn;
-            public GUIButton deleteBtn;
-            public GUIButton moveUpBtn;
-            public GUIButton moveDownBtn;
+            private GUILayoutX rowLayout;
+            private GUILayoutX titleLayout;
+            private bool ownsTitleLayout;
 
-            public EntryRow(GUILayout parentLayout, int seqIndex, InspectableList parent)
+            public EntryRow(GUILayout parentLayout)
             {
                 rowLayout = parentLayout.AddLayoutX();
                 contentLayout = rowLayout.AddLayoutY();
-                cloneBtn = new GUIButton("C");
-                deleteBtn = new GUIButton("X");
-                moveUpBtn = new GUIButton("Up");
-                moveDownBtn = new GUIButton("Down");
+            }
+
+            public void Refresh(InspectableObjectBase child, int seqIndex, InspectableList parent)
+            {
+                if (ownsTitleLayout)
+                    return;
+
+                titleLayout = child.GetTitleLayout();
+                if (titleLayout == null)
+                {
+                    GUILayoutY buttonCenter = rowLayout.AddLayoutY();
+                    buttonCenter.AddFlexibleSpace();
+                    titleLayout = buttonCenter.AddLayoutX();
+                    buttonCenter.AddFlexibleSpace();
+
+                    ownsTitleLayout = true;
+                }
+
+                GUIButton cloneBtn = new GUIButton("C");
+                GUIButton deleteBtn = new GUIButton("X");
+                GUIButton moveUpBtn = new GUIButton("Up");
+                GUIButton moveDownBtn = new GUIButton("Down");
 
                 cloneBtn.OnClick += () => parent.OnCloneButtonClicked(seqIndex);
                 deleteBtn.OnClick += () => parent.OnDeleteButtonClicked(seqIndex);
                 moveUpBtn.OnClick += () => parent.OnMoveUpButtonClicked(seqIndex);
                 moveDownBtn.OnClick += () => parent.OnMoveDownButtonClicked(seqIndex);
 
-                rowLayout.AddElement(cloneBtn);
-                rowLayout.AddElement(deleteBtn);
-                rowLayout.AddElement(moveUpBtn);
-                rowLayout.AddElement(moveDownBtn);
+                titleLayout.AddElement(cloneBtn);
+                titleLayout.AddElement(deleteBtn);
+                titleLayout.AddElement(moveUpBtn);
+                titleLayout.AddElement(moveDownBtn);
             }
 
             public void Destroy()
             {
                 rowLayout.Destroy();
-                contentLayout.Destroy();
-                cloneBtn.Destroy();
-                deleteBtn.Destroy();
-                moveUpBtn.Destroy();
-                moveDownBtn.Destroy();
             }
         }
 
@@ -56,6 +67,7 @@ namespace BansheeEditor
 
         private GUIIntField guiSizeField;
         private GUILayoutX guiChildLayout;
+        private GUILayoutX guiTitleLayout;
         private List<EntryRow> rows = new List<EntryRow>();
 
         private bool forceUpdate = true;
@@ -67,6 +79,11 @@ namespace BansheeEditor
 
         }
 
+        public override GUILayoutX GetTitleLayout()
+        {
+            return guiTitleLayout;
+        }
+
         protected override bool IsModified()
         {
             if (forceUpdate)
@@ -100,7 +117,15 @@ namespace BansheeEditor
             }
 
             for (int i = 0; i < GetChildCount(); i++)
-                anythingModified |= GetChild(i).Refresh(0);
+            {
+                InspectableObjectBase child = GetChild(i);
+                bool childModified = child.Refresh(0);
+
+                if (childModified)
+                    rows[i].Refresh(child, i, this);
+
+                anythingModified |= childModified;
+            }
 
             return anythingModified;
         }
@@ -109,6 +134,7 @@ namespace BansheeEditor
         {
             base.Update(layoutIndex);
             forceUpdate = false;
+            guiTitleLayout = null;
 
             if (property.Type != SerializableProperty.FieldType.List)
                 return;
@@ -123,7 +149,7 @@ namespace BansheeEditor
             if (propertyValue == null)
             {
                 guiChildLayout = null;
-                GUILayoutX guiTitleLayout = layout.AddLayoutX(layoutIndex);
+                guiTitleLayout = layout.AddLayoutX(layoutIndex);
 
                 guiTitleLayout.AddElement(new GUILabel(title));
                 guiTitleLayout.AddElement(new GUILabel("Empty"));
@@ -149,7 +175,7 @@ namespace BansheeEditor
                 GUIButton guiClearBtn = new GUIButton("Clear");
                 guiClearBtn.OnClick += OnClearButtonClicked;
 
-                GUILayoutX guiTitleLayout = layout.AddLayoutX(layoutIndex);
+                guiTitleLayout = layout.AddLayoutX(layoutIndex);
                 guiTitleLayout.AddElement(guiFoldout);
                 guiTitleLayout.AddElement(guiSizeField);
                 guiTitleLayout.AddElement(guiResizeBtn);
@@ -168,13 +194,14 @@ namespace BansheeEditor
 
                     for (int i = 0; i < numArrayElements; i++)
                     {
-                        EntryRow newRow = new EntryRow(guiContentLayout, i, this);
+                        EntryRow newRow = new EntryRow(guiContentLayout);
                         rows.Add(newRow);
 
                         InspectableObjectBase childObj = CreateDefaultInspectable(i + ".", new InspectableFieldLayout(newRow.contentLayout), list.GetProperty(i));
                         AddChild(childObj);
 
                         childObj.Refresh(0);
+                        rows[i].Refresh(childObj, i, this);
                     }
                 }
                 else

+ 9 - 2
MBansheeEditor/Inspector/InspectableObject.cs

@@ -14,6 +14,7 @@ namespace BansheeEditor
         private object propertyValue;
 
         private GUILayoutX guiChildLayout;
+        private GUILayoutX guiTitleLayout;
         private bool isExpanded;
         private bool forceUpdate = true;
 
@@ -23,6 +24,11 @@ namespace BansheeEditor
             
         }
 
+        public override GUILayoutX GetTitleLayout()
+        {
+            return guiTitleLayout;
+        }
+
         protected override bool IsModified()
         {
             if (forceUpdate)
@@ -45,6 +51,7 @@ namespace BansheeEditor
         {
             base.Update(index);
             forceUpdate = false;
+            guiTitleLayout = null;
 
             if (property.Type != SerializableProperty.FieldType.Object)
                 return;
@@ -55,7 +62,7 @@ namespace BansheeEditor
             if (propertyValue == null)
             {
                 guiChildLayout = null;
-                GUILayoutX guiTitleLayout = layout.AddLayoutX(index);
+                guiTitleLayout = layout.AddLayoutX(index);
 
                 guiTitleLayout.AddElement(new GUILabel(title));
                 guiTitleLayout.AddElement(new GUILabel("Empty"));
@@ -69,7 +76,7 @@ namespace BansheeEditor
             }
             else
             {
-                GUILayoutX guiTitleLayout = layout.AddLayoutX(index);
+                guiTitleLayout = layout.AddLayoutX(index);
 
                 GUIFoldout guiFoldout = new GUIFoldout(title);
                 guiFoldout.SetExpanded(isExpanded);

+ 5 - 0
MBansheeEditor/Inspector/InspectableObjectBase.cs

@@ -66,6 +66,11 @@ namespace BansheeEditor
             return layout.GetNumElements();
         }
 
+        public virtual GUILayoutX GetTitleLayout()
+        {
+            return null;
+        }
+
         protected virtual bool IsModified()
         {
             return false;

+ 1 - 1
TODO.txt

@@ -73,7 +73,6 @@ Ribek use:
    - Will need C# wrapper for GUISkin (and a way to assign the current skin to a window)
 
 First screenshot:
- - Inspectors for array & list don't display headers for objects neatly
  - Additional menu bar items: 
   - File: Exit, Save Project, New Project, Open Project, Save Scene As
   - Edit: Undo/Redo, Cut/Copy/Paste/Duplicate/Delete(need to make sure it works in Hierarchy, with shortcuts), Frame Selected, Preferences, Play/Pause/Step
@@ -107,6 +106,7 @@ Other polish:
  - Replace "minimize" button in tabbed title bar with maximize and make sure it works
  - When I expand inspector elements and them come back to that object it should remember the previous state
    - Add a chaching mechanism to inspector (likely based on instance ID & property names)
+   - This has to work not only when I come back to the object, but whenever inspector rebuilds (e.g. after removing element from array)
  - Make sure to persist EditorSettings
  - Import option inspectors for Texture, Mesh, Font
  - DOck manager maximize doesn't work'