public static void Resize(ref IList list, Type elementType, int newSize)
        {
            int oldSize = list.Count;

            // Unity's default behaviour when expanding a collection is to use the last element as the new element value
            object objectToAdd = null;

            if (newSize > oldSize)
            {
                if (oldSize >= 1)
                {
                    objectToAdd = list[oldSize - 1];
                }
                else
                {
                    objectToAdd = TypeUtility.GetDefaultValue(elementType);
                }
            }

            if (list.IsFixedSize)
            {
                Array newArray = Array.CreateInstance(elementType, newSize);
                Array.Copy((Array)list, newArray, Math.Min(oldSize, newArray.Length));

                if (newSize > oldSize)
                {
                    int toAdd = newSize - oldSize;
                    for (int i = 0; i < toAdd; i++)
                    {
                        newArray.SetValue(objectToAdd, oldSize + i);
                    }
                }

                list = newArray;
            }
            else
            {
                if (newSize > oldSize)
                {
                    int toAdd = newSize - oldSize;
                    for (int i = 0; i < toAdd; i++)
                    {
                        list.Add(objectToAdd);
                    }
                }
                else if (newSize < oldSize)
                {
                    int toRemove = oldSize - newSize;
                    for (int i = 0; i < toRemove; i++)
                    {
                        list.RemoveAt(oldSize - i - 1);
                    }
                }
            }
        }
Beispiel #2
0
        public void DrawMethods(Type componentType, object component, MethodInfo[] methods)
        {
            OldSettings settings = OldInspectorSidekick.Current.Settings;             // Grab the active window's settings

            GUIStyle labelStyle = new GUIStyle(GUI.skin.label);

            labelStyle.alignment = TextAnchor.MiddleRight;
            GUIStyle normalButtonStyle = new GUIStyle(GUI.skin.button);

            normalButtonStyle.padding   = normalButtonStyle.padding.SetLeft(100);
            normalButtonStyle.alignment = TextAnchor.MiddleLeft;

            List <MethodSetup> expandedMethods = OldInspectorSidekick.Current.PersistentData.ExpandedMethods;

            GUIStyle   expandButtonStyle = new GUIStyle(GUI.skin.button);
            RectOffset padding           = expandButtonStyle.padding;

            padding.left              = 0;
            padding.right             = 1;
            expandButtonStyle.padding = padding;

            for (int j = 0; j < methods.Length; j++)
            {
                MethodInfo method = methods[j];

                if (!string.IsNullOrEmpty(settings.SearchTerm) && !method.Name.Contains(settings.SearchTerm, StringComparison.InvariantCultureIgnoreCase))
                {
                    // Does not match search term, skip it
                    continue;
                }

                //				object[] customAttributes = method.GetCustomAttributes(false);
                EditorGUILayout.BeginHorizontal();
                ParameterInfo[] parameters = method.GetParameters();


                if (method.ReturnType == typeof(void))
                {
                    labelStyle.normal.textColor = Color.grey;
                }
                else if (method.ReturnType.IsValueType)
                {
                    labelStyle.normal.textColor = new Color(0, 0, 1);
                }
                else
                {
                    labelStyle.normal.textColor = new Color32(255, 130, 0, 255);
                }


                bool buttonClicked = GUILayout.Button(method.Name + " " + parameters.Length, normalButtonStyle);
                Rect lastRect      = GUILayoutUtility.GetLastRect();
                lastRect.xMax = normalButtonStyle.padding.left;
                GUI.Label(lastRect, TypeUtility.NameForType(method.ReturnType), labelStyle);

                if (buttonClicked)
                {
                    object[] arguments = null;
                    if (parameters.Length > 0)
                    {
                        arguments = new object[parameters.Length];
                        for (int i = 0; i < parameters.Length; i++)
                        {
                            arguments[i] = TypeUtility.GetDefaultValue(parameters[i].ParameterType);
                        }
                    }

                    methodOutput = FireMethod(method, component, arguments);
                    opacity      = 1f;
                }

                if (parameters.Length > 0)
                {
                    string methodIdentifier = componentType.FullName + "." + method.Name;

                    bool wasExpanded = expandedMethods.Any(item => item.MethodName == methodIdentifier);
                    bool expanded    = GUILayout.Toggle(wasExpanded, "▼", expandButtonStyle, GUILayout.Width(20));
                    if (expanded != wasExpanded)
                    {
                        if (expanded)
                        {
                            MethodSetup methodSetup = new MethodSetup()
                            {
                                MethodName = methodIdentifier,
                                Values     = new object[parameters.Length],
                            };
                            expandedMethods.Add(methodSetup);
                        }
                        else
                        {
                            expandedMethods.RemoveAll(item => item.MethodName == methodIdentifier);
                        }
                    }

                    EditorGUILayout.EndHorizontal();
                    if (expanded)
                    {
                        MethodSetup methodSetup = expandedMethods.FirstOrDefault(item => item.MethodName == methodIdentifier);

                        if (methodSetup.Values.Length != parameters.Length)
                        {
                            methodSetup.Values = new object[parameters.Length];
                        }

                        EditorGUI.indentLevel++;
                        for (int i = 0; i < parameters.Length; i++)
                        {
//							VariablePane.DrawVariable(parameters[i].ParameterType, parameters[i].Name, GetDefaultValue(parameters[i].ParameterType), "", false);
                            EditorGUI.BeginChangeCheck();
                            object newValue = VariablePane.DrawVariable(parameters[i].ParameterType, parameters[i].Name, methodSetup.Values[i], "", false, null);
                            if (EditorGUI.EndChangeCheck())
                            {
                                methodSetup.Values[i] = newValue;
                            }
                        }
                        EditorGUI.indentLevel--;

                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(30);

                        if (GUILayout.Button("Fire"))
                        {
                            methodOutput = FireMethod(method, component, methodSetup.Values);
                            opacity      = 1f;
                        }
                        EditorGUILayout.EndHorizontal();

                        GUILayout.Space(20);
                    }
                }
                else
                {
                    EditorGUILayout.EndHorizontal();
                }
            }
        }
Beispiel #3
0
        public static object DrawVariable(Type fieldType, string fieldName, object fieldValue, string metaSuffix, bool allowExtensions, Type contextType)
        {
            GUIStyle   expandButtonStyle = new GUIStyle(GUI.skin.button);
            RectOffset padding           = expandButtonStyle.padding;

            padding.left              = 0;
            padding.right             = 1;
            expandButtonStyle.padding = padding;

            if (fieldValue == null)
            {
                fieldValue = TypeUtility.GetDefaultValue(fieldType);
            }

            fieldName = SidekickUtility.ParseDisplayString(fieldName);

            if (!string.IsNullOrEmpty(metaSuffix))
            {
                fieldName += " " + metaSuffix;
            }

            object newValue = fieldValue;

            bool isArray       = fieldType.IsArray;
            bool isGenericList = TypeUtility.IsGenericList(fieldType);

            if (isArray || isGenericList)
            {
                Type elementType = TypeUtility.GetElementType(fieldType);

                string elementTypeName = TypeUtility.NameForType(elementType);
                if (isGenericList)
                {
                    GUILayout.Label("List<" + elementTypeName + "> " + fieldName);
                }
                else
                {
                    GUILayout.Label(elementTypeName + "[] " + fieldName);
                }

                IList list         = null;
                int   previousSize = 0;

                if (fieldValue != null)
                {
                    list = (IList)fieldValue;

                    previousSize = list.Count;
                }


                int newSize = Mathf.Max(0, EditorGUILayout.IntField("Size", previousSize));
                if (newSize != previousSize)
                {
                    if (list == null)
                    {
                        list = (IList)Activator.CreateInstance(fieldType);
                    }
                    CollectionUtility.Resize(ref list, elementType, newSize);
                }

                if (list != null)
                {
                    for (int i = 0; i < list.Count; i++)
                    {
                        list[i] = DrawIndividualVariable("Element " + i, elementType, list[i]);
                    }
                }
            }
            else
            {
                // Not a collection
                EditorGUILayout.BeginHorizontal();

                newValue = DrawIndividualVariable(fieldName, fieldType, fieldValue);

                if (allowExtensions)
                {
                    GUI.enabled = true;
                    //			GUI.SetNextControlName(
                    if (GUILayout.Button("->", expandButtonStyle, GUILayout.Width(20)))
                    {
                        OldInspectorSidekick.Current.SetSelection(fieldValue, true);
                    }
                    bool expanded = GUILayout.Button("...", expandButtonStyle, GUILayout.Width(20));
                    if (Event.current.type == EventType.Repaint)
                    {
                        string methodIdentifier = contextType.FullName + "." + fieldType.FullName;

                        guiRects[methodIdentifier] = GUILayoutUtility.GetLastRect();
                    }


                    //			if (GUIUtility.hot
                    {
                        //				GUILayoutUtility
                        //				gridRect = GUILayoutUtility.GetLastRect();
                        //				gridRect.width = 100;
                    }

                    if (expanded)
                    {
                        string methodIdentifier = contextType.FullName + "." + fieldType.FullName;

                        Rect        gridRect = guiRects[methodIdentifier];
                        GenericMenu menu     = new GenericMenu();
                        menu.AddItem(new GUIContent("Placeholder"), false, null);
                        //					if(fieldType == typeof(Texture))
                        {
                            menu.AddItem(new GUIContent("Export PNG"), false, ExportTexture, fieldValue);
                        }
                        menu.DropDown(gridRect);
                    }
                }

                EditorGUILayout.EndHorizontal();
            }


            return(newValue);
        }
Beispiel #4
0
        public static void DrawVariable(Type fieldType, string fieldName, object fieldValue, string tooltip, VariableAttributes variableAttributes, IEnumerable <Attribute> customAttributes, bool allowExtensions, Type contextType, Action <object> changeCallback)
        {
            if ((variableAttributes & VariableAttributes.Static) != 0)
            {
                var style = new GUIStyle {
                    normal = { background = SidekickEditorGUI.StaticBackground }
                };
                EditorGUILayout.BeginVertical(style);
            }

            GUIStyle   expandButtonStyle = new GUIStyle(GUI.skin.button);
            RectOffset padding           = expandButtonStyle.padding;

            padding.left              = 0;
            padding.right             = 1;
            expandButtonStyle.padding = padding;

            fieldValue ??= TypeUtility.GetDefaultValue(fieldType);

            string displayName = SidekickUtility.NicifyIdentifier(fieldName);

            GUIContent label = new GUIContent(displayName, tooltip);

            bool isArray             = fieldType.IsArray;
            bool isGenericList       = TypeUtility.IsGenericList(fieldType);
            bool isGenericDictionary = TypeUtility.IsGenericDictionary(fieldType);

            if (isGenericDictionary)
            {
                EditorGUILayout.BeginHorizontal();

                string expandedID = fieldType.FullName + fieldName;
                bool   expanded   = DrawHeader(expandedID, label, (variableAttributes & VariableAttributes.Static) != 0);

                int count = 0;
                if (fieldValue != null)
                {
                    EditorGUI.BeginDisabledGroup(true);

                    count = (int)fieldType.GetProperty("Count").GetValue(fieldValue);

                    EditorGUILayout.IntField(count, GUILayout.Width(80));
                    EditorGUI.EndDisabledGroup();
                }

                if (allowExtensions)
                {
                    DrawExtensions(fieldValue, expandButtonStyle);
                }

                EditorGUILayout.EndHorizontal();

                if (expanded)
                {
                    EditorGUI.indentLevel++;

                    if (fieldValue != null)
                    {
                        FieldInfo entriesArrayField     = fieldType.GetField("entries", BindingFlags.NonPublic | BindingFlags.Instance);
                        IList     entriesArray          = (IList)entriesArrayField.GetValue(fieldValue);
                        Type      elementType           = TypeUtility.GetFirstElementType(entriesArrayField.FieldType);
                        FieldInfo elementKeyFieldInfo   = elementType.GetField("key", BindingFlags.Public | BindingFlags.Instance);
                        FieldInfo elementValueFieldInfo = elementType.GetField("value", BindingFlags.Public | BindingFlags.Instance);
                        int       oldIndent             = EditorGUI.indentLevel;
                        EditorGUI.indentLevel = 0;
                        for (int i = 0; i < count; i++)
                        {
                            object entry = entriesArray[i];

                            EditorGUILayout.BeginHorizontal();

                            object key   = elementKeyFieldInfo.GetValue(entry);
                            object value = elementValueFieldInfo.GetValue(entry);

                            using (new EditorGUI.DisabledScope(true))
                            {
                                DrawIndividualVariable(GUIContent.none, key.GetType(), key, null, out _, newValue =>
                                {
                                    /*list[index] = newValue;*/
                                });
                            }

                            DrawIndividualVariable(GUIContent.none, value.GetType(), value, null, out var handled, newValue =>
                            {
                                PropertyInfo indexer = fieldType.GetProperties().First(x => x.GetIndexParameters().Length > 0);
                                indexer.SetValue(fieldValue, newValue, new[] { key });
                            });

                            EditorGUILayout.EndHorizontal();
                        }

                        EditorGUI.indentLevel = oldIndent;
                    }

                    EditorGUI.indentLevel--;
                }

                EditorGUILayout.EndFoldoutHeaderGroup();
            }
            else if (isArray || isGenericList)
            {
                Type elementType = TypeUtility.GetFirstElementType(fieldType);

                EditorGUILayout.BeginHorizontal();

                string expandedID = fieldType.FullName + fieldName;
                bool   expanded   = DrawHeader(expandedID, label, (variableAttributes & VariableAttributes.Static) != 0);

                EditorGUI.BeginDisabledGroup((variableAttributes & VariableAttributes.ReadOnly) != 0);

                IList list         = null;
                int   previousSize = 0;

                if (fieldValue != null)
                {
                    list = (IList)fieldValue;

                    previousSize = list.Count;
                }

                int newSize = Mathf.Max(0, EditorGUILayout.IntField(previousSize, GUILayout.Width(80)));
                if (newSize != previousSize)
                {
                    var newValue = CollectionUtility.Resize(list, isArray, fieldType, elementType, newSize);
                    changeCallback(newValue);
                }

                if (allowExtensions)
                {
                    DrawExtensions(fieldValue, expandButtonStyle);
                }

                EditorGUILayout.EndHorizontal();

                if (expanded)
                {
                    EditorGUI.indentLevel++;

                    if (list != null)
                    {
                        for (int i = 0; i < list.Count; i++)
                        {
                            EditorGUILayout.BeginHorizontal();

                            int index = i;
                            DrawIndividualVariable(new GUIContent("Element " + i), elementType, list[i], null, out var handled, newValue => { list[index] = newValue; });

                            if (allowExtensions)
                            {
                                DrawExtensions(list[i], expandButtonStyle);
                            }

                            EditorGUILayout.EndHorizontal();
                        }
                    }

                    EditorGUI.indentLevel--;
                }

                EditorGUILayout.EndFoldoutHeaderGroup();
            }
            else
            {
                EditorGUI.BeginDisabledGroup((variableAttributes & VariableAttributes.ReadOnly) != 0);

                // Not a collection
                EditorGUILayout.BeginHorizontal();

                DrawIndividualVariable(label, fieldType, fieldValue, customAttributes, out var handled, changeCallback);

                if (handled && allowExtensions)
                {
                    DrawExtensions(fieldValue, expandButtonStyle);
                }

                EditorGUILayout.EndHorizontal();

                if (!handled)
                {
                    EditorGUI.EndDisabledGroup();

                    string expandedID = fieldType.FullName + fieldName;
                    EditorGUILayout.BeginHorizontal();
                    bool expanded = DrawHeader(expandedID, label, (variableAttributes & VariableAttributes.Static) != 0);

                    if (allowExtensions)
                    {
                        DrawExtensions(fieldValue, expandButtonStyle);
                    }

                    EditorGUILayout.EndHorizontal();

                    EditorGUI.BeginDisabledGroup((variableAttributes & VariableAttributes.ReadOnly) != 0);

                    if (expanded)
                    {
                        EditorGUI.indentLevel++;
                        if (fieldValue != null)
                        {
                            var fields = fieldType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);

                            foreach (var fieldInfo in fields)
                            {
                                GUIContent subLabel = new GUIContent(fieldInfo.Name);
                                DrawIndividualVariable(subLabel, fieldInfo.FieldType, fieldInfo.GetValue(fieldValue), null, out _, newValue => { fieldInfo.SetValue(fieldValue, newValue); });
                            }
                        }
                        else
                        {
                            GUILayout.Label("Null");
                        }

                        EditorGUI.indentLevel--;
                    }

                    EditorGUILayout.EndFoldoutHeaderGroup();
                }
            }

            EditorGUI.EndDisabledGroup();

            if ((variableAttributes & VariableAttributes.Static) != 0)
            {
                EditorGUILayout.EndVertical();
            }
        }
Beispiel #5
0
        public void DrawMethods(Type componentType, object component, string searchTerm, MethodInfo[] methods)
        {
            GUIStyle labelStyle = new GUIStyle(GUI.skin.label)
            {
                alignment = TextAnchor.MiddleRight
            };
            GUIStyle normalButtonStyle = new GUIStyle(GUI.skin.button)
            {
                alignment = TextAnchor.MiddleLeft
            };

            normalButtonStyle.padding = normalButtonStyle.padding.SetLeft(100);

            List <MethodSetup> expandedMethods = SidekickWindow.Current.PersistentData.ExpandedMethods;

            GUIStyle   expandButtonStyle = new GUIStyle(GUI.skin.button);
            RectOffset padding           = expandButtonStyle.padding;

            padding.left              = 0;
            padding.right             = 1;
            expandButtonStyle.padding = padding;

            foreach (MethodInfo method in methods)
            {
                if (!SearchMatches(searchTerm, method.Name))
                {
                    // Does not match search term, skip it
                    continue;
                }

                //				object[] customAttributes = method.GetCustomAttributes(false);
                EditorGUILayout.BeginHorizontal();
                ParameterInfo[] parameters = method.GetParameters();

                if (method.ReturnType == typeof(void))
                {
                    labelStyle.normal.textColor = Color.grey;
                }
                else if (method.ReturnType.IsValueType)
                {
                    labelStyle.normal.textColor = new Color(0, 0, 1);
                }
                else
                {
                    labelStyle.normal.textColor = new Color32(255, 130, 0, 255);
                }

                labelStyle.fontSize = 10;

                var genericArguments = method.GetGenericArguments();

                GUIContent buttonLabel = new GUIContent("", "Click to fire with defaults");
                if (genericArguments.Length != 0)
                {
                    string genericArgumentsDisplay = string.Join(", ", genericArguments.Select(item => item.Name));
                    buttonLabel.text = $"{method.Name} <{genericArgumentsDisplay}> {parameters.Length}";
                }
                else
                {
                    buttonLabel.text = $"{method.Name} {parameters.Length}";
                }

                using (new EditorGUI.DisabledScope(method.IsGenericMethod))
                {
                    bool buttonClicked = GUILayout.Button(buttonLabel, normalButtonStyle);
                    Rect lastRect      = GUILayoutUtility.GetLastRect();
                    lastRect.xMax = normalButtonStyle.padding.left;
                    GUI.Label(lastRect, TypeUtility.NameForType(method.ReturnType), labelStyle);

                    if (buttonClicked)
                    {
                        object[] arguments = null;
                        if (parameters.Length > 0)
                        {
                            arguments = new object[parameters.Length];
                            for (int i = 0; i < parameters.Length; i++)
                            {
                                arguments[i] = TypeUtility.GetDefaultValue(parameters[i].ParameterType);
                            }
                        }
                        var output = FireMethod(method, component, arguments, null);
                        outputObjects.AddRange(output);
                        opacity = 1f;
                    }
                }

                if (parameters.Length > 0 || genericArguments.Length > 0)
                {
                    string methodIdentifier = TypeUtility.GetMethodIdentifier(method);

                    bool   wasExpanded = expandedMethods.Any(item => item.MethodIdentifier == methodIdentifier);
                    string label       = wasExpanded ? "▲" : "▼";
                    bool   expanded    = GUILayout.Toggle(wasExpanded, label, expandButtonStyle, GUILayout.Width(20));
                    if (expanded != wasExpanded)
                    {
                        if (expanded)
                        {
                            MethodSetup methodSetup = new MethodSetup()
                            {
                                MethodIdentifier = methodIdentifier,
                                Values           = new object[parameters.Length],
                                GenericArguments = new Type[genericArguments.Length],
                            };
                            expandedMethods.Add(methodSetup);
                        }
                        else
                        {
                            expandedMethods.RemoveAll(item => item.MethodIdentifier == methodIdentifier);
                        }
                    }

                    EditorGUILayout.EndHorizontal();
                    if (expanded)
                    {
                        MethodSetup methodSetup = expandedMethods.FirstOrDefault(item => item.MethodIdentifier == methodIdentifier);

                        if (methodSetup.Values.Length != parameters.Length)
                        {
                            methodSetup.Values = new object[parameters.Length];
                        }

                        EditorGUI.indentLevel++;

                        for (var i = 0; i < genericArguments.Length; i++)
                        {
                            Type   genericArgument = genericArguments[i];
                            string displayLabel    = genericArgument.Name;

                            Type[] constraints = genericArgument.GetGenericParameterConstraints();
                            if (constraints.Length != 0)
                            {
                                displayLabel += $" ({string.Join(", ", constraints.Select(item => item.Name))})";
                            }

                            EditorGUILayout.BeginHorizontal();
                            EditorGUILayout.LabelField(displayLabel, TypeUtility.NameForType(methodSetup.GenericArguments[i]));
                            var popupRect = GUILayoutUtility.GetLastRect();
                            popupRect.width = EditorGUIUtility.currentViewWidth;

                            var selectTypeButtonLabel = new GUIContent("Select");
                            if (GUILayout.Button(selectTypeButtonLabel, EditorStyles.miniButton))
                            {
                                int index = i;
                                TypeSelectDropdown dropdown = new TypeSelectDropdown(new AdvancedDropdownState(), type => methodSetup.GenericArguments[index] = type, constraints);
                                dropdown.Show(popupRect);
                            }

                            EditorGUILayout.EndHorizontal();
                        }

                        for (int i = 0; i < parameters.Length; i++)
                        {
                            int index = i;
                            VariablePane.DrawVariable(parameters[i].ParameterType, parameters[i].Name, methodSetup.Values[i], "", VariablePane.VariableAttributes.None, null, false, null, newValue =>
                            {
                                methodSetup.Values[index] = newValue;
                            });
                        }

                        EditorGUI.indentLevel--;

                        EditorGUILayout.BeginHorizontal();
                        GUILayout.Space(30);

                        bool anyGenericArgumentsMissing = methodSetup.GenericArguments.Any(item => item == null);

                        using (new EditorGUI.DisabledScope(anyGenericArgumentsMissing))
                        {
                            if (GUILayout.Button("Fire"))
                            {
                                var output = FireMethod(method, component, methodSetup.Values, methodSetup.GenericArguments);
                                outputObjects.AddRange(output);
                                opacity = 1f;
                            }
                        }

                        EditorGUILayout.EndHorizontal();

                        GUILayout.Space(20);
                    }
                }
                else
                {
                    EditorGUILayout.EndHorizontal();
                }
            }
        }