Example #1
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();
            }
        }