Esempio n. 1
0
        public static void DrawArrayField(ArrayFieldField field)
        {
            IList arr = (IList)field.GetValue();

            field.editor_showContent = EditorGUILayout.Foldout(field.editor_showContent, field.GetName() + System.String.Format(": ({0} Elements)", arr != null ? arr.Count : 0));

            if (field.editor_showContent)
            {
                EditorGUI.indentLevel = 1 + field.IndentLevel;

                if (arr != null)
                {
                    if (field.IsReadOnly())
                    {
                        if (arr.Count == 0)
                        {
                            EditorGUILayout.LabelField("The array is empty");
                        }

                        for (int i = 0; i < arr.Count; ++i)
                        {
                            System.Object v = arr[i];
                            if (v != null)
                            {
                                EditorGUILayout.LabelField(string.Format("[{0}]", i), arr[i].ToString());
                            }
                            else
                            {
                                EditorGUILayout.LabelField(string.Format("[{0}]", i), "(null)");
                            }
                        }
                    }
                    else
                    {
                        System.Type type = field.GetFieldType();
                        if (field.CompactArrayLayout && type.IsPrimitive)
                        {
                            EditorGUILayout.BeginHorizontal();

                            if (field.Type == SerializedPropertyType.Boolean)
                            {
                                // for some reason, editor gui layout doesn't work here
                                GUILayout.Space(EditorGUI.indentLevel * 24);
                            }
                            for (int i = 0; i < arr.Count; ++i)
                            {
                                arr[i] = DrawFieldElementCompact(field.Type, arr[i], type, field.ValueRange, field.Style);
                            }

                            EditorGUILayout.EndHorizontal();
                        }
                        else
                        {
                            int indexToRemove = -1;
                            for (int i = 0; i < arr.Count; ++i)
                            {
                                EditorGUILayout.BeginHorizontal();
                                if (field.CanModifyArrayLength)
                                {
                                    if (GUILayout.Button("-", new GUILayoutOption[] { GUILayout.Width(24) }))
                                    {
                                        indexToRemove = i;
                                    }
                                }
                                arr[i] = DrawFieldElement(field.Type, string.Format("[{0}]", i), arr[i], type, field.ValueRange, field.Style);

                                EditorGUILayout.EndHorizontal();
                            }

                            if (indexToRemove != -1)
                            {
                                field.RemoveAt(indexToRemove);
                            }

                            EditorGUILayout.BeginHorizontal();

                            GUILayout.FlexibleSpace();

                            if (GUILayout.Button("Add", new GUILayoutOption[] { GUILayout.Width(80) }))
                            {
                                field.Add(System.Activator.CreateInstance(type));
                            }

                            EditorGUILayout.EndHorizontal();
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        public static MemberField[] GetFieldsFromType(System.Type type, System.Object obj, int level = 0)
        {
            List <MemberField> fields = new List <MemberField>();
            Dictionary <int, List <MethodField> > buttonFields = new Dictionary <int, List <MethodField> >();

            BindingFlags bindingFlags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static;

            foreach (MemberInfo member in type.GetMembers(bindingFlags))
            {
                ShowInEditor attribute = member.GetCustomAttributes(false).OfType <ShowInEditor>().FirstOrDefault();

                if (level > 0 &&
                    attribute == null &&
                    (member is FieldInfo) &&
                    ((FieldInfo)member).IsPublic)
                {
                    attribute = new ShowInEditor();
                }

                if (attribute != null)
                {
                    if (member is PropertyInfo)
                    {
                        PropertyInfo property = member as PropertyInfo;
                        if (!property.CanRead)
                        {
                            continue;
                        }

                        // skip array property, to do (or is it neccessary?)
                        if (property.PropertyType.IsArray)
                        {
                            continue;
                        }

                        if (attribute != null)
                        {
                            SerializedPropertyType serializedType = SerializedPropertyType.Integer;
                            bool isKnownType = PropertyField.GetSerializedType(property, out serializedType);

                            if (!isKnownType)
                            {
                                attribute.Flags = ShowInEditorFlags.ReadOnly;
                            }

                            fields.Add(new PropertyField(obj, attribute, serializedType, property));
                        }
                    }
                    else if (member is FieldInfo)
                    {
                        FieldInfo field = member as FieldInfo;

                        System.Type realType = field.FieldType;
                        if (realType.IsArray)
                        {
                            realType = field.FieldType.GetElementType();
                        }

                        bool isObjectRef = !FieldField.IsReadOnly(attribute, field);

                        isObjectRef &= (realType.IsClass ||
                                        (realType.IsValueType && !realType.IsEnum && !realType.IsPrimitive));

                        if (isObjectRef)
                        {
                            ShowInEditor showInEditor = realType.GetCustomAttributes(false).OfType <ShowInEditor>().FirstOrDefault();

                            isObjectRef &= (showInEditor != null);
                        }

                        MemberField mf;
                        if (isObjectRef)
                        {
                            MemberField[] memberFields = GetFieldsFromType(realType, null, level + 2);

                            if (!field.FieldType.IsArray)
                            {
                                mf = (new ObjectReferenceField(obj, attribute, SerializedPropertyType.ObjectReference, field, memberFields));
                            }
                            else
                            {
                                mf = (new ArrayObjectReferenceField(obj, attribute, SerializedPropertyType.ObjectReference, field, memberFields));
                            }
                        }
                        else
                        {
                            SerializedPropertyType serializedType = SerializedPropertyType.Integer;
                            bool isKnownType = FieldField.GetSerializedType(field, out serializedType);

                            if (!isKnownType)
                            {
                                attribute.Flags = ShowInEditorFlags.ReadOnly;
                            }

                            if (!field.FieldType.IsArray)
                            {
                                mf = new FieldField(obj, attribute, serializedType, field);
                            }
                            else
                            {
                                mf = new ArrayFieldField(obj, attribute, serializedType, field);
                            }
                        }

                        if (field.IsPublic)
                        {
                            attribute.CanModifyArrayLength = true;
                        }

                        if (mf != null)
                        {
                            if (mf.IndentLevel == 0)
                            {
                                mf.IndentLevel = level;
                            }

                            fields.Add(mf);
                        }
                    }
                    else if (member is MethodInfo)
                    {
                        MethodInfo method = member as MethodInfo;

                        if (method.GetParameters().Length == 0)
                        {
                            if (method.ReturnType != typeof(void))
                            {
                                fields.Add(new MethodField(obj, attribute, SerializedPropertyType.Generic, method));
                            }
                            else if (attribute.Style == ShowInEditorStyle.Button)
                            {
                                if (attribute.Group == -1)
                                {
                                    fields.Add(new MethodField(obj, attribute, SerializedPropertyType.Generic, method));
                                }
                                else
                                {
                                    List <MethodField> group;
                                    if (!buttonFields.TryGetValue(attribute.Group, out group))
                                    {
                                        group = new List <MethodField>();
                                        buttonFields.Add(attribute.Group, group);
                                    }
                                    group.Add(new MethodField(obj, attribute, SerializedPropertyType.Generic, method));
                                }
                            }
                            else
                            {
                                Debug.LogError("[ShowInEditor] Method that returns nothing cannot be shown in the editor");
                            }
                        }
                        else
                        {
                            Debug.LogError("[ShowInEditor] Method with arguments cannot be shown in the editor");
                        }
                    }
                }
            }

            foreach (List <MethodField> buttonGroup in buttonFields.Values)
            {
                fields.Add(new ButtonGroupField(buttonGroup.ToArray()));
            }
            return(fields.ToArray());
        }