예제 #1
0
        /// <summary>
        /// Makes a deep copy of this object.
        /// </summary>
        public InspectableFieldStyleInfo Clone()
        {
            InspectableFieldStyleInfo style = new InspectableFieldStyleInfo();

            style.StyleFlags = StyleFlags;

            if (RangeStyle != null)
            {
                style.RangeStyle = new InspectableFieldRangeStyle(RangeStyle.Min, RangeStyle.Max, RangeStyle.Slider);
            }

            if (StepStyle != null)
            {
                style.StepStyle = new InspectableFieldStepStyle(StepStyle.Step);
            }

            if (CategoryStyle != null)
            {
                style.CategoryStyle = new InspectableFieldCategoryStyle(CategoryStyle.Category);
            }

            if (OrderStyle != null)
            {
                style.OrderStyle = new InspectableFieldOrderStyle(OrderStyle.Index);
            }

            return(style);
        }
예제 #2
0
        /// <summary>
        /// Creates a new field accessing the provided property.
        /// </summary>
        /// <param name="title">Title to display on the field.</param>
        /// <param name="name">Name of the field.</param>
        /// <param name="property">Property used to access the field contents.</param>
        /// <param name="style">Optional style used to customize the look of the field.</param>
        /// <param name="fieldCreateCallback">
        /// Optional callback allowing the caller to override how is the field created.
        /// </param>
        private void AddFieldInternal(string title, string name, SerializableProperty property,
                                      InspectableFieldStyleInfo style,
                                      Func <string, InspectableFieldLayout, int, int, InspectableField> fieldCreateCallback)
        {
            int        currentIndex;
            int        childDepth;
            GUILayoutY parentLayout;

            if (category != null)
            {
                currentIndex = categoryIndex;
                parentLayout = category.ChildLayout;
                childDepth   = depth + 1;
            }
            else
            {
                currentIndex = rootIndex;
                parentLayout = layout;
                childDepth   = depth;
            }

            string childPath = string.IsNullOrEmpty(path) ? name : $"{path}/{name}";

            InspectableField inspectableField = null;

            if (fieldCreateCallback != null)
            {
                inspectableField = fieldCreateCallback(path, new InspectableFieldLayout(parentLayout), currentIndex, depth);
            }

            if (inspectableField == null)
            {
                inspectableField = InspectableField.CreateField(context, title, childPath,
                                                                currentIndex, childDepth, new InspectableFieldLayout(parentLayout), property, style);
            }

            if (category != null)
            {
                category.AddChild(inspectableField);
            }
            else
            {
                Fields.Add(inspectableField);
            }

            currentIndex += inspectableField.GetNumLayoutElements();

            if (category != null)
            {
                categoryIndex = currentIndex;
            }
            else
            {
                rootIndex = currentIndex;
            }
        }
예제 #3
0
        /// <summary>
        /// Creates all the relevant style information for a SerializableField.
        /// </summary>
        /// <param name="field">Field to create the style info structure for.</param>
        /// <returns>Style information retrieved from the field.</returns>
        public static InspectableFieldStyleInfo Create(SerializableField field)
        {
            SerializableFieldStyle      style = field.Style;
            SerializableFieldAttributes flags = field.Flags;

            var styleInfo = new InspectableFieldStyleInfo();

            styleInfo.RangeStyle = flags.HasFlag(SerializableFieldAttributes.Ranged)
                ? new InspectableFieldRangeStyle(style.RangeMin, style.RangeMax, style.DisplayAsSlider) : null;
            styleInfo.StepStyle = flags.HasFlag(SerializableFieldAttributes.Stepped)
                ? new InspectableFieldStepStyle(style.StepIncrement) : null;
            styleInfo.CategoryStyle = flags.HasFlag(SerializableFieldAttributes.Category)
                ? new InspectableFieldCategoryStyle(style.CategoryName) : null;
            styleInfo.OrderStyle = flags.HasFlag(SerializableFieldAttributes.Order)
                ? new InspectableFieldOrderStyle(style.Order) : null;
            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.AsLayerMask)
                ? InspectableFieldStyleFlags.AsLayerMask : 0;
            styleInfo.StyleFlags |= style.DisplayAsSlider ? InspectableFieldStyleFlags.AsSlider : 0;
            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.PassByCopy)
                ? InspectableFieldStyleFlags.CopiedAsValue
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.NotNull)
                ? InspectableFieldStyleFlags.NotNull
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.NativeWrapper)
                ? InspectableFieldStyleFlags.NativeWrapper
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.ApplyOnDirty)
                ? InspectableFieldStyleFlags.ApplyOnDirty
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.AsQuaternion)
                ? InspectableFieldStyleFlags.AsQuaternion
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.Inline)
                ? InspectableFieldStyleFlags.Inline
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.LoadOnAssign)
                ? InspectableFieldStyleFlags.LoadOnAssign
                : 0;

            styleInfo.StyleFlags |= flags.HasFlag(SerializableFieldAttributes.HDR)
                ? InspectableFieldStyleFlags.HDR
                : 0;

            return(styleInfo);
        }
예제 #4
0
        /// <summary>
        /// Creates a new inspectable object GUI for the specified property.
        /// </summary>
        /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
        /// <param name="title">Name of the property, or some other value to set as the title.</param>
        /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
        /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
        ///                     contain other fields, in which case you should increase this value by one.</param>
        /// <param name="layout">Parent layout that all the field elements will be added to.</param>
        /// <param name="property">Serializable property referencing the object whose contents to display.</param>
        /// <param name="style">Information that can be used for customizing field rendering and behaviour.</param>
        public InspectableObject(InspectableContext context, string title, string path, int depth, InspectableFieldLayout layout,
                                 SerializableProperty property, InspectableFieldStyleInfo style)
            : base(context, title, path, SerializableProperty.FieldType.Object, depth, layout, property)
        {
            this.style = style;
            isExpanded = context.Persistent.GetBool(path + "_Expanded");
            isInline   = style != null && style.StyleFlags.HasFlag(InspectableFieldStyleFlags.Inline);

            // Builds a context menu that lets the user create objects to assign to this field.
            bool hasCreateButton = !property.IsValueType && !isInline;

            if (hasCreateButton)
            {
                instantiableTypes = GetInstantiableTypes(property.InternalType);
                if (instantiableTypes.Length > 1)
                {
                    createContextMenu = new ContextMenu();

                    Array.Sort(instantiableTypes, (x, y) => string.Compare(x.Name, y.Name, StringComparison.Ordinal));

                    bool   showNamespace = false;
                    string ns            = instantiableTypes[0].Namespace;
                    for (int i = 1; i < instantiableTypes.Length; i++)
                    {
                        if (instantiableTypes[i].Namespace != ns)
                        {
                            showNamespace = true;
                            break;
                        }
                    }

                    foreach (var type in instantiableTypes)
                    {
                        string prefix = "";
                        if (showNamespace)
                        {
                            prefix = type.Namespace + ".";
                        }

                        createContextMenu.AddItem(prefix + type.Name,
                                                  () =>
                        {
                            StartUndo();
                            property.SetValue(Activator.CreateInstance(type));
                            EndUndo();
                        });
                    }
                }
            }
        }
예제 #5
0
            /// <summary>
            /// Constructs a new inspectable array GUI.
            /// </summary>
            /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
            /// <param name="title">Label to display on the list GUI title.</param>
            /// <param name="path">Full path to this property (includes name of this property and all parent properties).
            /// </param>
            /// <param name="property">Serializable property referencing a single-dimensional array.</param>
            /// <param name="layout">Layout to which to append the list GUI elements to.</param>
            /// <param name="depth">Determines at which depth to render the background. Useful when you have multiple
            ///                     nested containers whose backgrounds are overlaping. Also determines background style,
            ///                     depths divisible by two will use an alternate style.</param>
            /// <param name="style">Information that can be used for customizing field rendering and behaviour.</param>
            public InspectableArrayGUI(InspectableContext context, LocString title, string path, SerializableProperty property,
                                       GUILayout layout, int depth, InspectableFieldStyleInfo style)
                : base(title, layout, depth)
            {
                this.property = property;
                this.context  = context;
                this.path     = path;
                this.style    = style;

                array = property.GetValue <Array>();
                if (array != null)
                {
                    numElements = array.Length;
                }
            }
예제 #6
0
            /// <inheritdoc/>
            protected override GUILayoutX CreateGUI(GUILayoutY layout)
            {
                InspectableArrayGUI  arrayParent = (InspectableArrayGUI)parent;
                SerializableProperty property    = GetValue <SerializableProperty>();

                InspectableFieldStyleInfo styleInfo = arrayParent.Style.Clone();

                styleInfo.StyleFlags &= ~InspectableFieldStyleFlags.NativeWrapper;

                string entryPath = arrayParent.Path + "[" + SeqIndex + "]";

                Field = CreateField(arrayParent.Context, SeqIndex + ".", entryPath, 0, Depth + 1,
                                    new InspectableFieldLayout(layout), property, styleInfo);

                return(Field.GetTitleLayout());
            }
 /// <summary>
 /// Creates a new inspectable ranged field GUI for the specified property.
 /// </summary>
 /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
 /// <param name="title">Name of the property, or some other value to set as the title.</param>
 /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
 /// <param name="type">Type of property this field will be used for displaying.</param>
 /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
 ///                     contain other fields, in which case you should increase this value by one.</param>
 /// <param name="layout">Parent layout that all the field elements will be added to.</param>
 /// <param name="property">Serializable property referencing the field whose contents to display.</param>
 /// <param name="style">Contains information about the field style</param>
 public InspectableRangedField(InspectableContext context, string title, string path, SerializableProperty.FieldType type,
                               int depth, InspectableFieldLayout layout, SerializableProperty property, InspectableFieldStyleInfo style)
     : base(context, title, path, type, depth, layout, property)
 {
     this.style = style;
 }
 /// <summary>
 /// Creates a new inspectable color GUI for the specified property.
 /// </summary>
 /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
 /// <param name="title">Name of the property, or some other value to set as the title.</param>
 /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
 /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
 ///                     contain other fields, in which case you should increase this value by one.</param>
 /// <param name="layout">Parent layout that all the field elements will be added to.</param>
 /// <param name="property">Serializable property referencing the field whose contents to display.</param>
 /// <param name="style">Contains information about the field style.</param>
 public InspectableColor(InspectableContext context, string title, string path, int depth, InspectableFieldLayout layout,
                         SerializableProperty property, InspectableFieldStyleInfo style)
     : base(context, title, path, SerializableProperty.FieldType.Color, depth, layout, property)
 {
     hdr = style?.StyleFlags.HasFlag(InspectableFieldStyleFlags.HDR) ?? false;
 }
예제 #9
0
 /// <summary>
 /// Creates a new inspectable AABox GUI for the specified property.
 /// </summary>
 /// <param name="parent">Parent Inspector this field belongs to.</param>
 /// <param name="title">Name of the property, or some other value to set as the title.</param>
 /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
 /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
 ///                     contain other fields, in which case you should increase this value by one.</param>
 /// <param name="layout">Parent layout that all the field elements will be added to.</param>
 /// <param name="property">Serializable property referencing the field whose contents to display.</param>
 /// <param name="style">Information that can be used for customizing field rendering and behaviour.</param>
 public InspectableAABox(Inspector parent, string title, string path, int depth, InspectableFieldLayout layout,
                         SerializableProperty property, InspectableFieldStyleInfo style)
     : base(parent, title, path, SerializableProperty.FieldType.Object, depth, layout, property)
 {
 }
예제 #10
0
        /// <summary>
        /// Creates a new inspectable field, automatically detecting the most appropriate implementation for the type
        /// contained in the provided serializable property. This may be one of the built-in inspectable field implemetations
        /// (like ones for primitives like int or bool), or a user defined implementation defined with a
        /// <see cref="CustomInspector"/> attribute.
        /// </summary>
        /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
        /// <param name="title">Name of the property, or some other value to set as the title.</param>
        /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
        /// <param name="layoutIndex">Index into the parent layout at which to insert the GUI elements for the field .</param>
        /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
        ///                     contain other fields, in which case you should increase this value by one.</param>
        /// <param name="layout">Parent layout that all the field elements will be added to.</param>
        /// <param name="property">Serializable property referencing the array whose contents to display.</param>
        /// <param name="style">Information that can be used for customizing field rendering and behaviour.</param>
        /// <returns>Inspectable field implementation that can be used for displaying the GUI for a serializable property
        ///          of the provided type.</returns>
        public static InspectableField CreateField(InspectableContext context, string title, string path, int layoutIndex,
                                                   int depth, InspectableFieldLayout layout, SerializableProperty property, InspectableFieldStyleInfo style = null)
        {
            InspectableField field = null;

            Type type = property.InternalType;

            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(RRef <>))
            {
                type = type.GenericTypeArguments[0];
            }

            Type customInspectable = InspectorUtility.GetCustomInspectable(type);

            if (customInspectable != null)
            {
                field = (InspectableField)Activator.CreateInstance(customInspectable, context, title, path, depth, layout,
                                                                   property, style);
            }
            else
            {
                switch (property.Type)
                {
                case SerializableProperty.FieldType.Int:
                    if (style != null && style.StyleFlags.HasFlag(InspectableFieldStyleFlags.AsLayerMask))
                    {
                        field = new InspectableLayerMask(context, title, path, depth, layout, property);
                    }
                    else
                    {
                        if (style?.RangeStyle == null || !style.RangeStyle.Slider)
                        {
                            field = new InspectableInt(context, title, path, depth, layout, property, style);
                        }
                        else
                        {
                            field = new InspectableRangedInt(context, title, path, depth, layout, property, style);
                        }
                    }

                    break;

                case SerializableProperty.FieldType.Float:
                    if (style?.RangeStyle == null || !style.RangeStyle.Slider)
                    {
                        field = new InspectableFloat(context, title, path, depth, layout, property, style);
                    }
                    else
                    {
                        field = new InspectableRangedFloat(context, title, path, depth, layout, property, style);
                    }
                    break;

                case SerializableProperty.FieldType.Bool:
                    field = new InspectableBool(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Color:
                    field = new InspectableColor(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.ColorGradient:
                    field = new InspectableColorGradient(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Curve:
                    field = new InspectableCurve(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.FloatDistribution:
                    field = new InspectableFloatDistribution(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Vector2Distribution:
                    field = new InspectableVector2Distribution(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Vector3Distribution:
                    field = new InspectableVector3Distribution(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.ColorDistribution:
                    field = new InspectableColorDistribution(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.String:
                    field = new InspectableString(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Vector2:
                    field = new InspectableVector2(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Vector3:
                    field = new InspectableVector3(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Vector4:
                    field = new InspectableVector4(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Quaternion:
                    if (style != null && style.StyleFlags.HasFlag(InspectableFieldStyleFlags.AsQuaternion))
                    {
                        field = new InspectableQuaternion(context, title, path, depth, layout, property);
                    }
                    else
                    {
                        field = new InspectableEuler(context, title, path, depth, layout, property);
                    }
                    break;

                case SerializableProperty.FieldType.Resource:
                    field = new InspectableResource(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.RRef:
                    field = new InspectableRRef(context, title, path, depth, layout, property, style);
                    break;

                case SerializableProperty.FieldType.GameObjectRef:
                    field = new InspectableGameObjectRef(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Object:
                    field = new InspectableObject(context, title, path, depth, layout, property, style);
                    break;

                case SerializableProperty.FieldType.Array:
                    field = new InspectableArray(context, title, path, depth, layout, property, style);
                    break;

                case SerializableProperty.FieldType.List:
                    field = new InspectableList(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Dictionary:
                    field = new InspectableDictionary(context, title, path, depth, layout, property);
                    break;

                case SerializableProperty.FieldType.Enum:
                    field = new InspectableEnum(context, title, path, depth, layout, property);
                    break;
                }
            }

            if (field == null)
            {
                throw new Exception("No inspector exists for the provided field type.");
            }

            field.Initialize(layoutIndex);
            field.Refresh(layoutIndex);

            return(field);
        }
예제 #11
0
            /// <summary>
            /// Creates a new inspectable array GUI object that displays the contents of the provided serializable property.
            /// </summary>
            /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
            /// <param name="title">Label to display on the list GUI title.</param>
            /// <param name="path">Full path to this property (includes name of this property and all parent properties).
            /// </param>
            /// <param name="property">Serializable property referencing a single-dimensional array.</param>
            /// <param name="layout">Layout to which to append the list GUI elements to.</param>
            /// <param name="depth">Determines at which depth to render the background. Useful when you have multiple
            ///                     nested containers whose backgrounds are overlaping. Also determines background style,
            ///                     depths divisible by two will use an alternate style.</param>
            /// <param name="style">Information that can be used for customizing field rendering and behaviour.</param>
            public static InspectableArrayGUI Create(InspectableContext context, LocString title, string path,
                                                     SerializableProperty property, GUILayout layout, int depth, InspectableFieldStyleInfo style)
            {
                InspectableArrayGUI guiArray = new InspectableArrayGUI(context, title, path, property, layout, depth, style);

                guiArray.BuildGUI();

                return(guiArray);
            }
예제 #12
0
 /// <summary>
 /// Creates a new inspectable float GUI for the specified property.
 /// </summary>
 /// <param name="parent">Parent Inspector this field belongs to.</param>
 /// <param name="title">Name of the property, or some other value to set as the title.</param>
 /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
 /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
 ///                     contain other fields, in which case you should increase this value by one.</param>
 /// <param name="layout">Parent layout that all the field elements will be added to.</param>
 /// <param name="property">Serializable property referencing the field whose contents to display.</param>
 /// <param name="style">Information that can be used for customizing field rendering and behaviour.</param>
 public InspectableFloat(Inspector parent, string title, string path, int depth, InspectableFieldLayout layout,
                         SerializableProperty property, InspectableFieldStyleInfo style)
     : base(parent, title, path, SerializableProperty.FieldType.Float, depth, layout, property)
 {
     this.style = style;
 }
 /// <summary>
 /// Creates a new inspectable float GUI for the specified property with a range.
 /// </summary>
 /// <param name="context">Context shared by all inspectable fields created by the same parent.</param>
 /// <param name="title">Name of the property, or some other value to set as the title.</param>
 /// <param name="path">Full path to this property (includes name of this property and all parent properties).</param>
 /// <param name="depth">Determines how deep within the inspector nesting hierarchy is this field. Some fields may
 ///                     contain other fields, in which case you should increase this value by one.</param>
 /// <param name="layout">Parent layout that all the field elements will be added to.</param>
 /// <param name="property">Serializable property referencing the field whose contents to display.</param>
 /// <param name="style">Information about the range of the field.</param>
 public InspectableRangedInt(InspectableContext context, string title, string path, int depth, InspectableFieldLayout layout,
                             SerializableProperty property, InspectableFieldStyleInfo style)
     : base(context, title, path, SerializableProperty.FieldType.Int, depth, layout, property, style)
 {
 }