public static object ObjectField(object obj, Type objType, GUIContent label, ref bool dataChanged, GUIStyle style, params GUILayoutOption[] options)
            {
                //If object is an array show an editable array field
                if (objType.IsArray)
                {
                    bool  arrayChanged = false;
                    Array arrayObj     = obj as Array;
                    arrayObj = ArrayField(label, arrayObj, objType.GetElementType(), ref arrayChanged, style, options);

                    if (arrayChanged)
                    {
                        dataChanged = true;
                        return(arrayObj as object);
                    }

                    return(obj);
                }

                //If the object is a ICustomEditable then just need to call its render properties function.
                if (typeof(ICustomEditorInspector).IsAssignableFrom(objType))
                {
                    //If obj is null then need to create new instance for editor
                    if (obj == null)
                    {
                        ConstructorInfo constructor = objType.GetConstructor(Type.EmptyTypes);
                        if (constructor != null)
                        {
                            obj = constructor.Invoke(null);
                        }
                        else
                        {
                            throw new Exception("Classes that implement ICustomEditorInspector need a parameterless constructor");
                        }
                    }

                    if (obj != null)
                    {
                        dataChanged |= ((ICustomEditorInspector)obj).RenderObjectProperties(label);
                    }

                    return(obj);
                }

                //Otherwise check the class has a object editor class associated with it.
                SerializedObjectEditorAttribute.RenderPropertiesDelegate renderPropertiesDelegate = GetEditorDelegateForObject(objType);
                if (renderPropertiesDelegate != null)
                {
                    //If it has one then just need to call its render properties function.
                    return(renderPropertiesDelegate(obj, label, ref dataChanged, style, options));
                }

                //Otherwise render all the objects memebers as object fields
                return(RenderObjectMemebers(obj, objType, ref dataChanged, style, options));
            }
            private static void BuildEditorMap()
            {
                if (_editorMap == null)
                {
                    _editorMap = new Dictionary <Type, SerializedObjectEditorAttribute.RenderPropertiesDelegate>();

                    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();

                    foreach (Assembly assembly in assemblies)
                    {
                        Type[] types = assembly.GetTypes();

                        foreach (Type type in types)
                        {
                            SerializedObjectEditorAttribute attribute = SystemUtils.GetAttribute <SerializedObjectEditorAttribute>(type);

                            if (attribute != null)
                            {
                                SerializedObjectEditorAttribute.RenderPropertiesDelegate func = SystemUtils.GetStaticMethodAsDelegate <SerializedObjectEditorAttribute.RenderPropertiesDelegate>(type, attribute.OnRenderPropertiesMethod);

                                _editorMap[attribute.ObjectType] = func;


                                if (attribute.UseForChildTypes)
                                {
                                    Type[] childTypes = SystemUtils.GetAllSubTypes(attribute.ObjectType);

                                    foreach (Type childType in childTypes)
                                    {
                                        if (!_editorMap.ContainsKey(childType))
                                        {
                                            _editorMap[childType] = func;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
Esempio n. 3
0
            //The equivalent of a SerializedPropertyField but for objects serialized using Xml.
            public static T ObjectField <T>(T obj, GUIContent label, out bool dataChanged)
            {
                //If object is an array show an editable array field
                if (typeof(T).IsArray)
                {
                    bool  arrayChanged = false;
                    Array arrayObj     = obj as Array;
                    arrayObj = ArrayField(label, arrayObj, typeof(T).GetElementType(), ref arrayChanged);

                    if (arrayChanged)
                    {
                        dataChanged = true;
                        return((T)(arrayObj as object));
                    }

                    dataChanged = false;
                    return(obj);
                }

                //If the object is a ICustomEditable then just need to call its render properties function.
                if (obj != null && obj is ICustomEditorInspector)
                {
                    dataChanged = ((ICustomEditorInspector)obj).RenderObjectProperties(label);
                    return(obj);
                }

                Type objType = obj == null ? typeof(T) : obj.GetType();

                //Otherwise check the class has a object editor class associated with it.
                SerializedObjectEditorAttribute.RenderPropertiesDelegate renderPropertiesDelegate = GetEditorDelegateForObject(objType);
                if (renderPropertiesDelegate != null)
                {
                    //If it has one then just need to call its render properties function.
                    return((T)renderPropertiesDelegate(obj, label, out dataChanged));
                }

                //Otherwise loop through each xml field in object and render each as a property field
                {
                    dataChanged = false;
                    SerializedFieldInfo[] serializedFields = SerializedFieldInfo.GetSerializedFields(objType);
                    foreach (SerializedFieldInfo serializedField in serializedFields)
                    {
                        if (!serializedField.HideInEditor())
                        {
                            //Create GUIContent for label and optional tooltip
                            string           fieldName       = StringUtils.FromCamelCase(serializedField.GetID());
                            TooltipAttribute fieldToolTipAtt = SystemUtils.GetAttribute <TooltipAttribute>(serializedField);
                            GUIContent       labelContent    = fieldToolTipAtt != null ? new GUIContent(fieldName, fieldToolTipAtt.tooltip) : new GUIContent(fieldName);

                            bool   fieldChanged;
                            object nodeFieldObject = serializedField.GetValue(obj);

                            if (serializedField.GetFieldType().IsArray)
                            {
                                fieldChanged    = false;
                                nodeFieldObject = ArrayField(labelContent, nodeFieldObject as Array, serializedField.GetFieldType().GetElementType(), ref fieldChanged);
                            }
                            else
                            {
                                nodeFieldObject = ObjectField(nodeFieldObject, labelContent, out fieldChanged);
                            }

                            if (fieldChanged)
                            {
                                dataChanged = true;
                                serializedField.SetValue(obj, nodeFieldObject);
                            }
                        }
                    }

                    return(obj);
                }
            }