Esempio n. 1
0
        /// <summary>
        /// Handle caching of recursive editors and returns a previously
        /// created editor of given target if it exists. This prevents
        /// escalating creations of CustomTargetTool instances (and more).
        /// </summary>
        /// <param name="target">Target object.</param>
        /// <returns>Cached editor or newly created one if it exists. Otherwise null.</returns>
        public static Editor TryGetOrCreateRecursiveEditor(Object target)
        {
            if (target == null)
            {
                return(null);
            }

            Editor editor = null;

            if (m_recursiveEditors.TryGetValue(target, out editor))
            {
                // Old editor with destroyed target, e.g., when entering
                // edit coming from play mode.
                if (editor.target == null)
                {
                    ReleaseRecursiveEditor(target);
                }
                else
                {
                    return(editor);
                }
            }

            editor = InspectorEditor.CreateRecursive(target);
            if (editor != null)
            {
                m_recursiveEditors.Add(target, editor);
            }
            return(editor);
        }
Esempio n. 2
0
        public static object GenericListDrawer(object obj, InvokeWrapper wrapper, GUISkin skin)
        {
            System.Collections.IList list = wrapper.Get <System.Collections.IList>(obj);
            var target = obj as Object;

            if (GUI.Foldout(EditorData.Instance.GetData(target, wrapper.Member.Name),
                            MakeLabel(wrapper.Member),
                            skin))
            {
                object insertElementBefore = null;
                object insertElementAfter  = null;
                object eraseElement        = null;
                var    buttonLayout        = new GUILayoutOption[] { GUILayout.Width(26), GUILayout.Height(18) };
                using (new GUI.Indent(12)) {
                    foreach (var listObject in list)
                    {
                        GUI.Separator();
                        using (new GUI.Indent(12)) {
                            GUILayout.BeginHorizontal();
                            {
                                GUILayout.BeginVertical();
                                {
                                    // Using target to render listObject since it normally (CollisionGroupEntry) isn't an Object.
                                    InspectorEditor.DrawMembersGUI(new Object[] { target }, ignored => listObject);
                                }
                                GUILayout.EndVertical();

                                using (GUI.NodeListButtonColor) {
                                    if (GUILayout.Button(GUI.MakeLabel(GUI.Symbols.ListInsertElementBefore.ToString(),
                                                                       false,
                                                                       "Insert new element before this"),
                                                         skin.button,
                                                         buttonLayout))
                                    {
                                        insertElementBefore = listObject;
                                    }
                                    if (GUILayout.Button(GUI.MakeLabel(GUI.Symbols.ListInsertElementAfter.ToString(),
                                                                       false,
                                                                       "Insert new element after this"),
                                                         skin.button,
                                                         buttonLayout))
                                    {
                                        insertElementAfter = listObject;
                                    }
                                    if (GUILayout.Button(GUI.MakeLabel(GUI.Symbols.ListEraseElement.ToString(),
                                                                       false,
                                                                       "Erase this element"),
                                                         skin.button,
                                                         buttonLayout))
                                    {
                                        eraseElement = listObject;
                                    }
                                }
                            }
                            GUILayout.EndHorizontal();
                        }
                    }

                    if (list.Count == 0)
                    {
                        GUILayout.Label(GUI.MakeLabel("Empty", true), skin.label);
                    }
                    else
                    {
                        GUI.Separator();
                    }
                }

                bool addElementToList = false;
                GUILayout.BeginHorizontal();
                {
                    GUILayout.FlexibleSpace();
                    using (GUI.NodeListButtonColor)
                        addElementToList = GUILayout.Button(GUI.MakeLabel(GUI.Symbols.ListInsertElementAfter.ToString(),
                                                                          false,
                                                                          "Add new element to list"),
                                                            skin.button,
                                                            buttonLayout);
                }
                GUILayout.EndHorizontal();

                object newObject = null;
                if (addElementToList || insertElementBefore != null || insertElementAfter != null)
                {
                    newObject = Activator.CreateInstance(list.GetType().GetGenericArguments()[0], new object[] { });
                }

                if (eraseElement != null)
                {
                    list.Remove(eraseElement);
                }
                else if (newObject != null)
                {
                    if (addElementToList || (list.Count > 0 && insertElementAfter != null && insertElementAfter == list[list.Count - 1]))
                    {
                        list.Add(newObject);
                    }
                    else if (insertElementAfter != null)
                    {
                        list.Insert(list.IndexOf(insertElementAfter) + 1, newObject);
                    }
                    else if (insertElementBefore != null)
                    {
                        list.Insert(list.IndexOf(insertElementBefore), newObject);
                    }
                }

                if (eraseElement != null || newObject != null)
                {
                    EditorUtility.SetDirty(target);
                }
            }

            // A bit of a hack until I figure out how to handle multi-selection
            // of lists, if that should be possible at all. We're handling the
            // list from inside this drawer and by returning null the return
            // value isn't propagated to any targets.
            return(null);
        }
Esempio n. 3
0
        public static void DrawUrdfElement(AGXUnity.IO.URDF.Element element,
                                           int elementArrayIndex = -1)
        {
            if (element == null)
            {
                return;
            }

            var dropDownName = string.IsNullOrEmpty(element.Name) ?
                               elementArrayIndex >= 0 ?
                               $"{element.GetType().Name}[{elementArrayIndex}]" :
                               element.GetType().Name :
                               element.Name;

            if (!InspectorGUI.Foldout(GetEditorData(element, dropDownName),
                                      GUI.MakeLabel(InspectorGUISkin.Instance.TagTypename($"Urdf.{element.GetType().Name}") +
                                                    ' ' +
                                                    dropDownName)))
            {
                return;
            }

            using (InspectorGUI.IndentScope.Single) {
                var ignoreName = element is AGXUnity.IO.URDF.Inertial;
                if (!ignoreName)
                {
                    var nameRect = EditorGUILayout.GetControlRect();
                    EditorGUI.PrefixLabel(nameRect, GUI.MakeLabel("Name"), InspectorEditor.Skin.Label);
                    var orgXMax = nameRect.xMax;
                    nameRect.x   += EditorGUIUtility.labelWidth - 14.0f * InspectorGUI.IndentScope.Level;
                    nameRect.xMax = orgXMax;
                    EditorGUI.SelectableLabel(nameRect, element.Name, InspectorEditor.Skin.TextField);
                }

                if (element is AGXUnity.IO.URDF.Pose)
                {
                    DrawUrdfPose(element as AGXUnity.IO.URDF.Pose);
                }
                else if (element is AGXUnity.IO.URDF.Material)
                {
                    DrawUrdfMaterial(element as AGXUnity.IO.URDF.Material);
                    return;
                }

                var properties = GetOrFindProperties(element.GetType());
                var elementArg = new object[] { element };
                var geometry   = element as AGXUnity.IO.URDF.Geometry;
                foreach (var property in properties)
                {
                    // Ignoring Unity specific properties such as "name" and "hideFlags".
                    if (!char.IsUpper(property.Member.Name[0]))
                    {
                        continue;
                    }
                    if (!InspectorEditor.ShouldBeShownInInspector(property.Member))
                    {
                        continue;
                    }

                    var containingType = property.GetContainingType();
                    if (containingType.IsArray)
                    {
                        if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType.GetElementType()))
                        {
                            var array = property.Get <System.Collections.ICollection>(element);
                            if (!InspectorGUI.Foldout(GetEditorData(element, property.Member.Name),
                                                      InspectorGUI.MakeLabel(property.Member,
                                                                             $" [{array.Count}]")))
                            {
                                continue;
                            }

                            using (InspectorGUI.IndentScope.Single) {
                                var arrayIndex = 0;
                                foreach (var arrayItem in array)
                                {
                                    DrawUrdfElement(arrayItem as AGXUnity.IO.URDF.Element, arrayIndex++);
                                }
                            }
                        }
                    }
                    else if (typeof(AGXUnity.IO.URDF.Element).IsAssignableFrom(containingType))
                    {
                        DrawUrdfElement(property.Get <AGXUnity.IO.URDF.Element>(element), -1);
                    }
                    else if (geometry == null || IsValidGeometryProperty(geometry, property))
                    {
                        var drawerMethod = GetDrawerMethod(containingType);
                        drawerMethod.Drawer?.Invoke(null, new object[] { elementArg, property });
                    }
                }
            }
        }
Esempio n. 4
0
        public static object GenericListDrawer(object[] objects, InvokeWrapper wrapper)
        {
            var list   = wrapper.Get <System.Collections.IList>(objects[0]);
            var target = objects[0] as Object;

            if (InspectorGUI.Foldout(EditorData.Instance.GetData(target, wrapper.Member.Name),
                                     InspectorGUI.MakeLabel(wrapper.Member)))
            {
                object insertElementBefore = null;
                object insertElementAfter  = null;
                object eraseElement        = null;
                var    skin         = InspectorEditor.Skin;
                var    buttonLayout = new GUILayoutOption[]
                {
                    GUILayout.Width(1.0f * EditorGUIUtility.singleLineHeight),
                    GUILayout.Height(1.0f * EditorGUIUtility.singleLineHeight)
                };
                foreach (var listObject in list)
                {
                    using (InspectorGUI.IndentScope.Single) {
                        GUILayout.BeginHorizontal();
                        {
                            InspectorGUI.Separator(1.0f, EditorGUIUtility.singleLineHeight);

                            if (InspectorGUI.Button(MiscIcon.EntryInsertBefore,
                                                    true,
                                                    "Insert new element before this.",
                                                    buttonLayout))
                            {
                                insertElementBefore = listObject;
                            }
                            if (InspectorGUI.Button(MiscIcon.EntryInsertAfter,
                                                    true,
                                                    "Insert new element after this.",
                                                    buttonLayout))
                            {
                                insertElementAfter = listObject;
                            }
                            if (InspectorGUI.Button(MiscIcon.EntryRemove,
                                                    true,
                                                    "Remove this element.",
                                                    buttonLayout))
                            {
                                eraseElement = listObject;
                            }
                        }
                        GUILayout.EndHorizontal();

                        InspectorEditor.DrawMembersGUI(new Object[] { target }, ignored => listObject);
                    }
                }

                InspectorGUI.Separator(1.0f, 0.5f * EditorGUIUtility.singleLineHeight);

                if (list.Count == 0)
                {
                    GUILayout.Label(GUI.MakeLabel("Empty", true), skin.Label);
                }

                bool addElementToList = false;
                GUILayout.BeginHorizontal();
                {
                    GUILayout.FlexibleSpace();
                    addElementToList = InspectorGUI.Button(MiscIcon.EntryInsertAfter,
                                                           true,
                                                           "Add new element.",
                                                           buttonLayout);
                }
                GUILayout.EndHorizontal();

                object newObject = null;
                if (addElementToList || insertElementBefore != null || insertElementAfter != null)
                {
                    newObject = Activator.CreateInstance(list.GetType().GetGenericArguments()[0], new object[] { });
                }

                if (eraseElement != null)
                {
                    list.Remove(eraseElement);
                }
                else if (newObject != null)
                {
                    if (addElementToList || (list.Count > 0 && insertElementAfter != null && insertElementAfter == list[list.Count - 1]))
                    {
                        list.Add(newObject);
                    }
                    else if (insertElementAfter != null)
                    {
                        list.Insert(list.IndexOf(insertElementAfter) + 1, newObject);
                    }
                    else if (insertElementBefore != null)
                    {
                        list.Insert(list.IndexOf(insertElementBefore), newObject);
                    }
                }

                if (eraseElement != null || newObject != null)
                {
                    EditorUtility.SetDirty(target);
                }
            }

            // A bit of a hack until I figure out how to handle multi-selection
            // of lists, if that should be possible at all. We're handling the
            // list from inside this drawer and by returning null the return
            // value isn't propagated to any targets.
            return(null);
        }