/// <summary>
        /// Sets a resource whose GUI is to be displayed in the inspector. Clears any previous contents of the window.
        /// </summary>
        /// <param name="resourcePath">Resource path relative to the project of the resource to inspect.</param>
        private void SetObjectToInspect(String resourcePath)
        {
            activeResourcePath = resourcePath;
            if (!ProjectLibrary.Exists(resourcePath))
            {
                return;
            }

            ResourceMeta meta = ProjectLibrary.GetMeta(resourcePath);

            if (meta == null)
            {
                return;
            }

            Type resourceType = meta.Type;

            currentType = InspectorType.Resource;

            inspectorScrollArea = new GUIScrollArea();
            GUI.AddElement(inspectorScrollArea);
            inspectorLayout = inspectorScrollArea.Layout;

            GUIPanel titlePanel = inspectorLayout.AddPanel();

            titlePanel.SetHeight(RESOURCE_TITLE_HEIGHT);

            GUILayoutY titleLayout = titlePanel.AddLayoutY();

            titleLayout.SetPosition(PADDING, PADDING);

            string name = Path.GetFileNameWithoutExtension(resourcePath);
            string type = resourceType.Name;

            LocString title      = new LocEdString(name + " (" + type + ")");
            GUILabel  titleLabel = new GUILabel(title);

            titleLayout.AddFlexibleSpace();
            GUILayoutX titleLabelLayout = titleLayout.AddLayoutX();

            titleLabelLayout.AddElement(titleLabel);
            titleLayout.AddFlexibleSpace();

            GUIPanel titleBgPanel = titlePanel.AddPanel(1);

            GUITexture titleBg = new GUITexture(null, EditorStylesInternal.InspectorTitleBg);

            titleBgPanel.AddElement(titleBg);

            inspectorLayout.AddSpace(COMPONENT_SPACING);

            inspectorResource       = new InspectorResource();
            inspectorResource.panel = inspectorLayout.AddPanel();

            var persistentProperties = persistentData.GetProperties(meta.UUID.ToString());

            inspectorResource.inspector = InspectorUtility.GetInspector(resourceType);
            inspectorResource.inspector.Initialize(inspectorResource.panel, activeResourcePath, persistentProperties);

            inspectorLayout.AddFlexibleSpace();
        }
        /// <summary>
        /// Sets a scene object whose GUI is to be displayed in the inspector. Clears any previous contents of the window.
        /// </summary>
        /// <param name="so">Scene object to inspect.</param>
        private void SetObjectToInspect(SceneObject so)
        {
            if (so == null)
            {
                return;
            }

            currentType = InspectorType.SceneObject;
            activeSO    = so;

            inspectorScrollArea = new GUIScrollArea();
            scrollAreaHighlight = new GUITexture(Builtin.WhiteTexture);
            scrollAreaHighlight.SetTint(HIGHLIGHT_COLOR);
            scrollAreaHighlight.Active = false;

            GUI.AddElement(inspectorScrollArea);
            GUIPanel inspectorPanel = inspectorScrollArea.Layout.AddPanel();

            inspectorLayout = inspectorPanel.AddLayoutY();
            highlightPanel  = inspectorPanel.AddPanel(-1);
            highlightPanel.AddElement(scrollAreaHighlight);

            // SceneObject fields
            CreateSceneObjectFields();
            RefreshSceneObjectFields(true);

            // Components
            Component[] allComponents = so.GetComponents();
            for (int i = 0; i < allComponents.Length; i++)
            {
                inspectorLayout.AddSpace(COMPONENT_SPACING);

                InspectorComponent data = new InspectorComponent();
                data.instanceId = allComponents[i].InstanceId;
                data.folded     = false;

                data.foldout = new GUIToggle(allComponents[i].GetType().Name, EditorStyles.Foldout);
                data.foldout.AcceptsKeyFocus = false;

                SpriteTexture xBtnIcon = EditorBuiltin.GetEditorIcon(EditorIcon.X);
                data.removeBtn = new GUIButton(new GUIContent(xBtnIcon), GUIOption.FixedWidth(30));

                data.title = inspectorLayout.AddLayoutX();
                data.title.AddElement(data.foldout);
                data.title.AddElement(data.removeBtn);
                data.panel = inspectorLayout.AddPanel();

                var persistentProperties = persistentData.GetProperties(allComponents[i].InstanceId);

                data.inspector = InspectorUtility.GetInspector(allComponents[i].GetType());
                data.inspector.Initialize(data.panel, allComponents[i], persistentProperties);

                bool isExpanded = data.inspector.Persistent.GetBool(data.instanceId + "_Expanded", true);
                data.foldout.Value = isExpanded;

                if (!isExpanded)
                {
                    data.inspector.SetVisible(false);
                }

                Type curComponentType = allComponents[i].GetType();
                data.foldout.OnToggled += (bool expanded) => OnComponentFoldoutToggled(data, expanded);
                data.removeBtn.OnClick += () => OnComponentRemoveClicked(curComponentType);

                inspectorComponents.Add(data);
            }

            inspectorLayout.AddFlexibleSpace();

            UpdateDropAreas();
        }
Example #3
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="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="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 CreateInspectable(Inspector parent, 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, parent, title, path, depth, layout,
                                                                   property);
            }
            else
            {
                switch (property.Type)
                {
                case SerializableProperty.FieldType.Int:
                    if (style != null && style.StyleFlags.HasFlag(InspectableFieldStyleFlags.UseLayerMask))
                    {
                        field = new InspectableLayerMask(parent, title, path, depth, layout, property);
                    }
                    else
                    {
                        if (style?.RangeStyle == null || !style.RangeStyle.Slider)
                        {
                            field = new InspectableInt(parent, title, path, depth, layout, property, style);
                        }
                        else
                        {
                            field = new InspectableRangedInt(parent, title, path, depth, layout, property, style);
                        }
                    }

                    break;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                case SerializableProperty.FieldType.Enum:
                    field = new InspectableEnum(parent, 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);
        }