Browse Source

Bugfix: Focus-on-field in inspector now works properly

BearishSun 6 years ago
parent
commit
ee0b67129a

+ 1 - 1
Source/EditorManaged/Windows/Inspector/GenericInspector.cs

@@ -109,7 +109,7 @@ namespace bs.Editor
         /// <param name="path">Path to the field on the object being inspected.</param>
         public void FocusOnField(string path)
         {
-            InspectableField field = InspectableField.FindPath(path, Fields);
+            InspectableField field = InspectableField.FindPath(path, 0, Fields);
             field?.SetHasFocus();
         }
     }

+ 21 - 14
Source/EditorManaged/Windows/Inspector/InspectableArray.cs

@@ -70,32 +70,39 @@ namespace bs.Editor
         /// <inheritdoc />
         public override InspectableField FindPath(string path)
         {
-            string subPath = GetSubPath(path);
+            string subPath = GetSubPath(path, depth + 1);
 
-            if (string.IsNullOrEmpty(subPath) || subPath.Length < 3 || subPath[0] != '[')
+            if (string.IsNullOrEmpty(subPath))
                 return null;
 
-            StringBuilder sb = new StringBuilder();
-            for (int i = 1; i < subPath.Length; i++)
-            {
-                if (path[i] == ']')
-                    break;
+            int lastLeftIdx = subPath.LastIndexOf('[');
+            int lastRightIdx = subPath.LastIndexOf(']', lastLeftIdx);
 
-                if (!char.IsNumber(path[i]))
-                    return null;
+            if (lastLeftIdx == -1 || lastRightIdx == -1)
+                return null;
 
-                sb.Append(path[i]);
-            }
+            int count = lastRightIdx - 1 - lastLeftIdx;
+            if (count <= 0)
+                return null;
+
+            string arrayIdxStr = subPath.Substring(lastLeftIdx, count);
 
-            if (!int.TryParse(sb.ToString(), out int idx))
+            if (!int.TryParse(arrayIdxStr, out int idx))
                 return null;
 
             if (idx >= arrayGUIField.NumRows)
                 return null;
 
             InspectableArrayGUIRow row = arrayGUIField.GetRow(idx);
-            if (row != null)
-                return row.Field;
+            InspectableField field = row?.Field;
+
+            if (field != null)
+            {
+                if (field.Path == path)
+                    return field;
+
+                return field.FindPath(path);
+            }
 
             return null;
         }

+ 1 - 1
Source/EditorManaged/Windows/Inspector/InspectableCategory.cs

@@ -69,7 +69,7 @@ namespace bs.Editor
         /// <inheritdoc />
         public override InspectableField FindPath(string path)
         {
-            return FindPath(path, children);
+            return FindPath(path, depth, children);
         }
 
         /// <inheritdoc/>

+ 34 - 19
Source/EditorManaged/Windows/Inspector/InspectableDictionary.cs

@@ -63,43 +63,58 @@ namespace bs.Editor
         /// <inheritdoc />
         public override InspectableField FindPath(string path)
         {
-            string subPath = GetSubPath(path);
+            string subPath = GetSubPath(path, depth + 1);
 
             if (string.IsNullOrEmpty(subPath))
                 return null;
 
-            bool isKey = false;
-            if (subPath.StartsWith("Key["))
+            int lastLeftIdx = subPath.LastIndexOf("Key[");
+            int lastRightIdx = -1;
+            bool isKey;
+            if (lastLeftIdx != -1)
+            {
+                lastRightIdx = subPath.LastIndexOf(']', lastLeftIdx);
                 isKey = true;
-            else if (subPath.StartsWith("Value["))
-                isKey = false;
+            }
             else
-                return null;
-
-            StringBuilder sb = new StringBuilder();
-            for (int i = 1; i < subPath.Length; i++)
             {
-                if (path[i] == ']')
-                    break;
+                lastLeftIdx = subPath.LastIndexOf("Value[");
+                lastRightIdx = subPath.LastIndexOf(']', lastLeftIdx);
 
-                if (!char.IsNumber(path[i]))
-                    return null;
-
-                sb.Append(path[i]);
+                isKey = false;
             }
 
-            if (!int.TryParse(sb.ToString(), out int idx))
+            if (lastLeftIdx == -1 || lastRightIdx == -1)
+                return null;
+
+            int count = lastRightIdx - 1 - lastLeftIdx;
+            if (count <= 0)
                 return null;
 
+            string arrayIdxStr = subPath.Substring(lastLeftIdx, count);
+
+            if (!int.TryParse(arrayIdxStr, out int idx))
+                return null;;
+
             if (idx >= dictionaryGUIField.NumRows)
                 return null;
 
             InspectableDictionaryGUIRow row = dictionaryGUIField.GetRow(idx);
-
+            InspectableField field = null;
             if (isKey)
-                return row.FieldKey;
+                field = row?.FieldKey;
+            else
+                field = row?.FieldValue;
+
+            if (field != null)
+            {
+                if (field.Path == path)
+                    return field;
+
+                return field.FindPath(path);
+            }
 
-            return row.FieldValue;
+            return null;
         }
 
         /// <summary>

+ 31 - 13
Source/EditorManaged/Windows/Inspector/InspectableField.cs

@@ -46,6 +46,11 @@ namespace bs.Editor
             }
         }
 
+        /// <summary>
+        /// Returns the path to the field.
+        /// </summary>
+        public string Path => path;
+
         /// <summary>
         /// Creates a new inspectable field GUI for the specified property.
         /// </summary>
@@ -128,7 +133,7 @@ namespace bs.Editor
         /// Searches for a child field with the specified path.
         /// </summary>
         /// <param name="path">
-        /// Path relative to the current field. Path entries are readable field names separated with "/". Fields within
+        /// Path relative to the current field. Path entries are field names separated with "/". Fields within
         /// categories are placed within a special category group, surrounded by "[]". Some examples:
         /// - myField
         /// - myObject/myField
@@ -150,19 +155,20 @@ namespace bs.Editor
         /// - myObject/myField
         /// - myObject/[myCategory]/myField
         /// </param>
+        /// <param name="depth">Path depth at which the provided set of fields is at.</param>
         /// <param name="fields">List of fields to search. Children will be searched recursively.</param>
         /// <returns>Matching field if one is found, null otherwise.</returns>
-        public static InspectableField FindPath(string path, IEnumerable<InspectableField> fields)
+        public static InspectableField FindPath(string path, int depth, IEnumerable<InspectableField> fields)
         {
-            string subPath = GetSubPath(path);
+            string subPath = GetSubPath(path, depth + 1);
             foreach (var field in fields)
             {
                 InspectableField foundField = null;
 
-                if (field.path == subPath)
+                if (field.path == path)
                     foundField = field;
-                else
-                    foundField = field.FindPath(subPath);
+                else if (field.path == subPath)
+                    foundField = field.FindPath(path);
 
                 if (foundField != null)
                     return foundField;
@@ -173,13 +179,18 @@ namespace bs.Editor
 
         /// <summary>
         /// Returns the top-most part of the provided field path.
-        /// See <see cref="FindPath(string, IEnumerable{InspectableField})"/> for more information about paths.
+        /// See <see cref="FindPath(string, int, IEnumerable{InspectableField})"/> for more information about paths.
         /// </summary>
         /// <param name="path">Path to return the sub-path of.</param>
-        /// <returns>Top-most part of the path (section before the first "/")</returns>
-        public static string GetSubPath(string path)
+        /// <param name="count">Number of path elements to retrieve.</param>
+        /// <returns>First <paramref name="count"/> elements of the path.</returns>
+        public static string GetSubPath(string path, int count)
         {
+            if (count <= 0)
+                return null;
+
             StringBuilder sb = new StringBuilder();
+            int foundSections = 0;
             bool gotFirstChar = false;
             for (int i = 0; i < path.Length; i++)
             {
@@ -191,7 +202,10 @@ namespace bs.Editor
                         continue;
                     }
 
-                    break;
+                    foundSections++;
+
+                    if (foundSections == count)
+                        break;
                 }
 
                 sb.Append(path[i]);
@@ -329,19 +343,23 @@ namespace bs.Editor
                 }
 
                 int currentIndex;
+                int childDepth;
                 GUILayoutY parentLayout;
                 if (category != null)
                 {
                     currentIndex = categoryIndex;
                     parentLayout = category.ChildLayout;
+                    childDepth = depth + 1;
                 }
                 else
                 {
                     currentIndex = rootIndex;
                     parentLayout = layout;
+                    childDepth = depth;
                 }
 
-                string fieldName = GetReadableIdentifierName(field.Name);
+                string fieldName = field.Name;
+                string readableName = GetReadableIdentifierName(fieldName);
                 string childPath = string.IsNullOrEmpty(path) ? fieldName : $"{path}/{fieldName}";
 
                 InspectableField inspectableField = null;
@@ -352,8 +370,8 @@ namespace bs.Editor
 
                 if (inspectableField == null)
                 {
-                    inspectableField = CreateField(context, fieldName, childPath,
-                        currentIndex, depth, new InspectableFieldLayout(parentLayout), field.GetProperty(), 
+                    inspectableField = CreateField(context, readableName, childPath,
+                        currentIndex, childDepth, new InspectableFieldLayout(parentLayout), field.GetProperty(), 
                         InspectableFieldStyle.Create(field));
                 }
 

+ 21 - 14
Source/EditorManaged/Windows/Inspector/InspectableList.cs

@@ -62,32 +62,39 @@ namespace bs.Editor
         /// <inheritdoc />
         public override InspectableField FindPath(string path)
         {
-            string subPath = GetSubPath(path);
+            string subPath = GetSubPath(path, depth + 1);
 
-            if (string.IsNullOrEmpty(subPath) || subPath.Length < 3 || subPath[0] != '[')
+            if (string.IsNullOrEmpty(subPath))
                 return null;
 
-            StringBuilder sb = new StringBuilder();
-            for (int i = 1; i < subPath.Length; i++)
-            {
-                if (path[i] == ']')
-                    break;
+            int lastLeftIdx = subPath.LastIndexOf('[');
+            int lastRightIdx = subPath.LastIndexOf(']', lastLeftIdx);
 
-                if (!char.IsNumber(path[i]))
-                    return null;
+            if (lastLeftIdx == -1 || lastRightIdx == -1)
+                return null;
 
-                sb.Append(path[i]);
-            }
+            int count = lastRightIdx - 1 - lastLeftIdx;
+            if (count <= 0)
+                return null;
+
+            string arrayIdxStr = subPath.Substring(lastLeftIdx, count);
 
-            if (!int.TryParse(sb.ToString(), out int idx))
+            if (!int.TryParse(arrayIdxStr, out int idx))
                 return null;
 
             if (idx >= listGUIField.NumRows)
                 return null;
 
             InspectableListGUIRow row = listGUIField.GetRow(idx);
-            if (row != null)
-                return row.Field;
+            InspectableField field = row?.Field;
+
+            if (field != null)
+            {
+                if (field.Path == path)
+                    return field;
+
+                return field.FindPath(path);
+            }
 
             return null;
         }

+ 1 - 1
Source/EditorManaged/Windows/Inspector/InspectableObject.cs

@@ -137,7 +137,7 @@ namespace bs.Editor
         /// <inheritdoc />
         public override InspectableField FindPath(string path)
         {
-            return FindPath(path, children);
+            return FindPath(path, depth, children);
         }
 
         /// <summary>

+ 0 - 1
Source/EditorManaged/Windows/Inspector/InspectorWindow.cs

@@ -684,7 +684,6 @@ namespace bs.Editor
             if (activeSO == null)
                 return;
 
-            Debug.Log("FOCUS ON " + uuid + " " + activeSO.UUID + " " + path);
             if (activeSO.UUID == uuid)
             {
                 if(path == "Position.X")