//...
        void OnGUI()
        {
            if (targetType == null)
            {
                return;
            }

            var e = Event.current;

            if (e.type == EventType.ValidateCommand && e.commandName == "UndoRedoPerformed")
            {
                GUIUtility.hotControl      = 0;
                GUIUtility.keyboardControl = 0;
                e.Use();
                return;
            }

            GUILayout.Space(10);
            GUILayout.Label(string.Format("<size=14><b>{0}</b></size>", targetType.FriendlyName()), Styles.centerLabel);
            EditorUtils.Separator();
            GUILayout.Space(10);
            scrollPos = GUILayout.BeginScrollView(scrollPos);
            var serializationInfo = new InspectedFieldInfo(unityObjectContext, null, null, null);
            var oldValue          = read();
            var newValue          = EditorUtils.ReflectedFieldInspector(friendlyTitle, oldValue, targetType, serializationInfo);

            if (!Equals(oldValue, newValue) || GUI.changed)
            {
                write(newValue);
            }
            GUILayout.EndScrollView();

            willRepaint = true;
        }
예제 #2
0
        ///<summary>Show an automatic editor GUI inspector for target object, taking into account drawer attributes</summary>
        public static void ReflectedObjectInspector(object target, UnityObject unityObjectContext)
        {
            if (target == null)
            {
                return;
            }

            var fields = target.GetType().RTGetFields();

            for (var i = 0; i < fields.Length; i++)
            {
                var field = fields[i];

                //no statics
                if (field.IsStatic)
                {
                    continue;
                }

                //hide type altogether?
                if (field.FieldType.RTIsDefined(typeof(HideInInspector), true))
                {
                    continue;
                }

                //inspect only public fields or private fields with the [ExposeField] attribute
                if (field.IsPublic || field.RTIsDefined(typeof(ExposeFieldAttribute), true))
                {
                    var attributes = field.RTGetAllAttributes();
                    //Hide field?
                    if (attributes.Any(a => a is HideInInspector))
                    {
                        continue;
                    }
                    var serializationInfo = new InspectedFieldInfo(unityObjectContext, field, target, attributes);
                    var currentValue      = field.GetValue(target);
                    var newValue          = ReflectedFieldInspector(field.Name, currentValue, field.FieldType, serializationInfo);

                    var changed = !object.Equals(newValue, currentValue);
                    if (changed)
                    {
                        UndoUtility.RecordObject(unityObjectContext, field.Name);
                    }
                    if (changed || field.FieldType.IsValueType)
                    {
                        field.SetValue(target, newValue);
                    }
                    if (changed)
                    {
                        UndoUtility.SetDirty(unityObjectContext);
                    }
                }
            }
        }
예제 #3
0
        ///Begin GUI
        object IObjectDrawer.DrawGUI(GUIContent content, object instance, InspectedFieldInfo info)
        {
            this.content  = content;
            this.instance = (T)instance;
            this.info     = info;

            this.attributes = info.attributes != null?info.attributes.OfType <DrawerAttribute>().OrderBy(a => a.priority).ToArray() : null;

            this.attributeIndex = -1;
            var result = (this as IObjectDrawer).MoveNextDrawer();

            // //flush references
            this.info       = default(InspectedFieldInfo);
            this.content    = null;
            this.instance   = default(T);
            this.attributes = null;

            return(result);
        }
예제 #4
0
        ///A IDictionary editor
        public static IDictionary DictionaryEditor(GUIContent content, IDictionary dict, Type dictType, InspectedFieldInfo info)
        {
            var keyType   = dictType.RTGetGenericArguments()[0];
            var valueType = dictType.RTGetGenericArguments()[1];

            if (object.Equals(dict, null))
            {
                GUILayout.Label("Null Dictionary");
                return(dict);
            }

            if (!CachedFoldout(dictType, content))
            {
                return(dict);
            }

            GUILayout.BeginVertical();

            var keys   = dict.Keys.Cast <object>().ToList();
            var values = dict.Values.Cast <object>().ToList();

            if (GUILayout.Button("Add Element"))
            {
                if (!typeof(UnityObject).IsAssignableFrom(keyType))
                {
                    object newKey = null;
                    if (keyType == typeof(string))
                    {
                        newKey = string.Empty;
                    }
                    else
                    {
                        newKey = Activator.CreateInstance(keyType);
                    }

                    if (dict.Contains(newKey))
                    {
                        Logger.LogWarning(string.Format("Key '{0}' already exists in Dictionary", newKey.ToString()), "Editor");
                        return(dict);
                    }

                    keys.Add(newKey);
                }
                else
                {
                    Logger.LogWarning("Can't add a 'null' Dictionary Key", "Editor");
                    return(dict);
                }

                values.Add(valueType.IsValueType ? Activator.CreateInstance(valueType) : null);
            }

            //clear before reconstruct
            dict.Clear();

            for (var i = 0; i < keys.Count; i++)
            {
                GUILayout.BeginHorizontal("box");
                GUILayout.Box("", GUILayout.Width(6), GUILayout.Height(35));

                GUILayout.BeginVertical();
                keys[i]   = ReflectedFieldInspector("K:", keys[i], keyType, info);
                values[i] = ReflectedFieldInspector("V:", values[i], valueType, info);
                GUILayout.EndVertical();

                if (GUILayout.Button("X", GUILayout.Width(18), GUILayout.Height(34)))
                {
                    keys.RemoveAt(i);
                    values.RemoveAt(i);
                }

                GUILayout.EndHorizontal();

                try { dict.Add(keys[i], values[i]); }
                catch { Logger.Log("Dictionary Key removed due to duplicate found", "Editor"); }
            }

            Separator();

            GUILayout.EndVertical();
            return(dict);
        }
예제 #5
0
        ///An IList editor (List<T> and Arrays)
        public static IList ListEditor(GUIContent content, IList list, Type listType, InspectedFieldInfo info)
        {
            var argType = listType.GetEnumerableElementType();

            if (argType == null)
            {
                return(list);
            }

            if (object.Equals(list, null))
            {
                GUILayout.Label("Null List");
                return(list);
            }

            if (!CachedFoldout(listType, content))
            {
                return(list);
            }

            GUILayout.BeginVertical();
            EditorGUI.indentLevel++;

            var options = new ReorderableListOptions();

            options.allowAdd           = true;
            options.allowRemove        = true;
            options.unityObjectContext = info.unityObjectContext;
            list = EditorUtils.ReorderableList(list, options, (i, r) =>
            {
                list[i] = ReflectedFieldInspector("Element " + i, list[i], argType, info);
            });

            EditorGUI.indentLevel--;
            Separator();
            GUILayout.EndVertical();
            return(list);
        }
예제 #6
0
        ///Begin GUI
        object IAttributeDrawer.DrawGUI(IObjectDrawer objectDrawer, GUIContent content, object instance, DrawerAttribute attribute, InspectedFieldInfo info)
        {
            this.objectDrawer = objectDrawer;
            this.content      = content;
            this.instance     = instance;
            this.attribute    = (T)attribute;

            this.info = info;
            var result = OnGUI(content, instance);

            //flush references
            this.info         = default(InspectedFieldInfo);
            this.content      = null;
            this.instance     = null;
            this.attribute    = null;
            this.objectDrawer = null;

            return(result);
        }
예제 #7
0
        ///<summary>Draws an Editor field for object of type directly WITH taking into acount object drawers and drawer attributes</summary>
        public static object ReflectedFieldInspector(string name, object value, Type t, InspectedFieldInfo info)
        {
            var content = GetTempContent(name.SplitCamelCase());

            if (info.attributes != null)
            {
                //Create proper GUIContent
                var nameAtt = info.attributes.FirstOrDefault(a => a is NameAttribute) as NameAttribute;
                if (nameAtt != null)
                {
                    content.text = nameAtt.name;
                }

                var tooltipAtt = info.attributes.FirstOrDefault(a => a is TooltipAttribute) as TooltipAttribute;
                if (tooltipAtt != null)
                {
                    content.tooltip = tooltipAtt.tooltip;
                }
            }

            return(ReflectedFieldInspector(content, value, t, info));
        }
예제 #8
0
        ///<summary>Draws an Editor field for object of type directly WITHOUT taking into acount object drawers and drawer attributes unless provided</summary>
        public static object DrawEditorFieldDirect(GUIContent content, object value, Type t, InspectedFieldInfo info)
        {
            ///----------------------------------------------------------------------------------------------
            bool handled;
            var  newValue = DirectFieldControl(content, value, t, info.unityObjectContext, info.attributes, out handled);
            var  changed  = !object.Equals(newValue, value);

            if (changed)
            {
                UndoUtility.RecordObjectComplete(info.unityObjectContext, content.text + "Field Change");
            }
            value = newValue;
            if (changed)
            {
                UndoUtility.SetDirty(info.unityObjectContext);
            }
            if (handled)
            {
                return(value);
            }
            ///----------------------------------------------------------------------------------------------


            if (typeof(IList).IsAssignableFrom(t))
            {
                return(ListEditor(content, (IList)value, t, info));
            }

            if (typeof(IDictionary).IsAssignableFrom(t))
            {
                return(DictionaryEditor(content, (IDictionary)value, t, info));
            }

            //show nested class members recursively, avoid all collections not handles above manually
            if (value != null && (t.IsClass || t.IsValueType) && !typeof(ICollection).IsAssignableFrom(t))
            {
                if (EditorGUI.indentLevel <= 8)
                {
                    if (!CachedFoldout(t, content))
                    {
                        return(value);
                    }

                    EditorGUI.indentLevel++;
                    ReflectedObjectInspector(value, info.unityObjectContext);
                    EditorGUI.indentLevel--;
                }
            }
            else
            {
                EditorGUILayout.LabelField(content, GetTempContent(string.Format("NonInspectable ({0})", t.FriendlyName())));
            }

            return(value);
        }
예제 #9
0
        ///<summary>Draws an Editor field for object of type directly WITH taking into acount object drawers and drawer attributes</summary>
        public static object ReflectedFieldInspector(GUIContent content, object value, Type t, InspectedFieldInfo info)
        {
            if (t == null)
            {
                GUILayout.Label("NO TYPE PROVIDED!");
                return(value);
            }

            //Use drawers
            var objectDrawer = PropertyDrawerFactory.GetObjectDrawer(t);
            var newValue     = objectDrawer.DrawGUI(content, value, info);
            var changed      = !object.Equals(newValue, value);

            if (changed)
            {
                UndoUtility.RecordObjectComplete(info.unityObjectContext, content.text + "Field Change");
            }
            value = newValue;
            if (changed)
            {
                UndoUtility.SetDirty(info.unityObjectContext);
            }
            return(value);
        }
예제 #10
0
        ///<summary>An IList editor (List<T> and Arrays)</summary>
        public static IList ListEditor(GUIContent content, IList list, Type listType, InspectedFieldInfo info)
        {
            var optionsAtt = info.attributes?.FirstOrDefault(x => x is ListInspectorOptionAttribute) as ListInspectorOptionAttribute;

            var argType = listType.GetEnumerableElementType();

            if (argType == null)
            {
                return(list);
            }

            if (object.Equals(list, null))
            {
                GUILayout.Label("Null List");
                return(list);
            }

            if (optionsAtt == null || optionsAtt.showFoldout)
            {
                if (!CachedFoldout(listType, content))
                {
                    return(list);
                }
            }
            else
            {
                GUILayout.Label(content.text);
            }

            GUILayout.BeginVertical();
            EditorGUI.indentLevel++;

            var options = new ReorderableListOptions();

            options.allowAdd           = optionsAtt == null || optionsAtt.allowAdd;
            options.allowRemove        = optionsAtt == null || optionsAtt.allowRemove;
            options.unityObjectContext = info.unityObjectContext;
            list = EditorUtils.ReorderableList(list, options, (i, r) =>
            {
                list[i] = ReflectedFieldInspector("Element " + i, list[i], argType, info);
            });

            EditorGUI.indentLevel--;
            Separator();
            GUILayout.EndVertical();
            return(list);
        }