Example #1
0
        private void DrawSerializedProperties()
        {
            serializedObject.Update();

            // Draw non-grouped serialized properties
            foreach (var property in GetNonGroupedProperties(_serializedProperties))
            {
                if (property.name.Equals("m_Script", System.StringComparison.Ordinal))
                {
                    GUI.enabled = false;
                    EditorGUILayout.PropertyField(property);
                    GUI.enabled = true;
                }
                else
                {
                    NaughtyEditorGUI.PropertyField_Layout(property, true);
                }
            }

            // Draw grouped serialized properties
            foreach (var group in GetGroupedProperties(_serializedProperties))
            {
                NaughtyEditorGUI.BeginBoxGroup_Layout(group.Key);
                foreach (var property in group)
                {
                    NaughtyEditorGUI.PropertyField_Layout(property, true);
                }

                NaughtyEditorGUI.EndBoxGroup_Layout();
            }

            serializedObject.ApplyModifiedProperties();
        }
Example #2
0
        public override void ValidateProperty(SerializedProperty property)
        {
            if (_cachedRequiredAttribute == null)
            {
                _cachedRequiredAttribute = PropertyUtility.GetAttribute <RequiredAttribute>(property);
            }

            RequiredAttribute requiredAttribute = _cachedRequiredAttribute;

            if (property.propertyType == SerializedPropertyType.ObjectReference)
            {
                if (property.objectReferenceValue == null)
                {
                    string errorMessage = property.name + " is required";
                    if (!string.IsNullOrEmpty(requiredAttribute.Message))
                    {
                        errorMessage = requiredAttribute.Message;
                    }

                    NaughtyEditorGUI.HelpBox_Layout(errorMessage, MessageType.Error, context: property.serializedObject.targetObject);
                }
            }
            else
            {
                string warning = requiredAttribute.GetType().Name + " works only on reference types";
                NaughtyEditorGUI.HelpBox_Layout(warning, MessageType.Warning, context: property.serializedObject.targetObject);
            }
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            if (!IsNumber(property))
            {
                string message = string.Format("Field {0} is not a number", property.name);
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
                return;
            }

            ProgressBarAttribute progressBarAttribute = PropertyUtility.GetAttribute <ProgressBarAttribute>(property);
            var value          = property.propertyType == SerializedPropertyType.Integer ? property.intValue : property.floatValue;
            var valueFormatted = property.propertyType == SerializedPropertyType.Integer ? value.ToString() : string.Format("{0:0.00}", value);
            var fillPercentage = value / progressBarAttribute.MaxValue;
            var barLabel       = (!string.IsNullOrEmpty(progressBarAttribute.Name) ? "[" + progressBarAttribute.Name + "] " : "") + valueFormatted + "/" + progressBarAttribute.MaxValue;
            var barColor       = progressBarAttribute.Color.GetColor();
            var labelColor     = Color.white;

            var  indentLength = NaughtyEditorGUI.GetIndentLength(rect);
            Rect barRect      = new Rect()
            {
                x      = rect.x + indentLength,
                y      = rect.y,
                width  = rect.width - indentLength,
                height = EditorGUIUtility.singleLineHeight
            };

            DrawBar(barRect, Mathf.Clamp01(fillPercentage), barLabel, barColor, labelColor);
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            System.Type propertyType = PropertyUtility.GetPropertyType(property);
            if (typeof(ScriptableObject).IsAssignableFrom(propertyType))
            {
                ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;
                if (scriptableObject == null)
                {
                    EditorGUI.PropertyField(rect, property, label, false);
                }
                else
                {
                    // Draw a foldout
                    Rect foldoutRect = new Rect()
                    {
                        x      = rect.x,
                        y      = rect.y,
                        width  = EditorGUIUtility.labelWidth,
                        height = EditorGUIUtility.singleLineHeight
                    };

                    property.isExpanded = EditorGUI.Foldout(foldoutRect, property.isExpanded, label, toggleOnLabelClick: true);

                    // Draw the scriptable object field
                    float indentLength = NaughtyEditorGUI.GetIndentLength(rect);
                    float labelWidth   = EditorGUIUtility.labelWidth - indentLength + NaughtyEditorGUI.HorizontalSpacing;
                    Rect  propertyRect = new Rect()
                    {
                        x      = rect.x + labelWidth,
                        y      = rect.y,
                        width  = rect.width - labelWidth,
                        height = EditorGUIUtility.singleLineHeight
                    };

                    EditorGUI.BeginChangeCheck();
                    property.objectReferenceValue = EditorGUI.ObjectField(propertyRect, GUIContent.none, property.objectReferenceValue, propertyType, false);
                    if (EditorGUI.EndChangeCheck())
                    {
                        property.serializedObject.ApplyModifiedProperties();
                    }

                    // Draw the child properties
                    if (property.isExpanded)
                    {
                        DrawChildProperties(rect, property);
                    }
                }
            }
            else
            {
                string message = $"{typeof(ExpandableAttribute).Name} can only be used on scriptable objects";
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
        public override void OnGUI(Rect position)
        {
            Rect rect = EditorGUI.IndentedRect(position);

            rect.y += EditorGUIUtility.singleLineHeight / 3.0f;
            HorizontalLineAttribute lineAttr = (HorizontalLineAttribute)attribute;

            NaughtyEditorGUI.HorizontalLine(rect, lineAttr.Height, lineAttr.Color.GetColor());
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            if (property.isArray)
            {
                string key = GetPropertyKeyName(property);

                ReorderableList reorderableList = null;

                if (!_reorderableListsByPropertyName.ContainsKey(key))
                {
                    reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true)
                    {
                        drawHeaderCallback = (Rect r) =>
                        {
                            EditorGUI.LabelField(r, string.Format("{0}: {1}", label.text, property.arraySize), EditorStyles.boldLabel);
                            HandleDragAndDrop(r, reorderableList);
                        },

                        drawElementCallback = (Rect r, int index, bool isActive, bool isFocused) =>
                        {
                            SerializedProperty element = property.GetArrayElementAtIndex(index);
                            r.y     += 1.0f;
                            r.x     += 10.0f;
                            r.width -= 10.0f;

                            EditorGUI.PropertyField(new Rect(r.x, r.y, r.width, 0.0f), element, true);
                        },

                        elementHeightCallback = (int index) =>
                        {
                            return(EditorGUI.GetPropertyHeight(property.GetArrayElementAtIndex(index)) + 4.0f);
                        }
                    };

                    _reorderableListsByPropertyName[key] = reorderableList;
                }

                reorderableList = _reorderableListsByPropertyName[key];

                if (rect == default)
                {
                    reorderableList.DoLayoutList();
                }
                else
                {
                    reorderableList.DoList(rect);
                }
            }
            else
            {
                string message = typeof(ReorderableListAttribute).Name + " can be used only on arrays or lists";
                NaughtyEditorGUI.HelpBox_Layout(message, MessageType.Warning, context: property.serializedObject.targetObject);
                EditorGUILayout.PropertyField(property, true);
            }
        }
        private void DrawButtons()
        {
            if (_methods.Any())
            {
                EditorGUILayout.Space();

                foreach (var method in _methods)
                {
                    NaughtyEditorGUI.Button(serializedObject.targetObject, method);
                }
            }
        }
Example #8
0
        public override void OnGUI(Rect rect)
        {
            InfoBoxAttribute infoBoxAttribute = (InfoBoxAttribute)attribute;

            float indentLength = NaughtyEditorGUI.GetIndentLength(rect);
            Rect  infoBoxRect  = new Rect(
                rect.x + indentLength,
                rect.y,
                rect.width - indentLength,
                GetHelpBoxHeight());

            DrawInfoBox(infoBoxRect, infoBoxAttribute.Text, infoBoxAttribute.Type);
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            if (property.propertyType == SerializedPropertyType.ObjectReference)
            {
                Rect propertyRect = new Rect()
                {
                    x      = rect.x,
                    y      = rect.y,
                    width  = rect.width,
                    height = EditorGUIUtility.singleLineHeight
                };

                EditorGUI.PropertyField(propertyRect, property, label);

                Texture2D previewTexture = GetAssetPreview(property);
                if (previewTexture != null)
                {
                    var previewAttribute = PropertyUtility.GetAttribute <ShowAssetPreviewAttribute>(property);
                    var previewSize      = GetAssetPreviewSize(property, previewAttribute);
                    var previewPosition  = rect.x + NaughtyEditorGUI.GetIndentLength(rect);
                    switch (previewAttribute.Alignment)
                    {
                    case TextAlignment.Center:
                        previewPosition += (rect.width - previewSize.x) / 2;
                        break;

                    case TextAlignment.Right:
                        previewPosition = rect.max.x - previewSize.x;
                        break;
                    }
                    Rect previewRect = new Rect
                    {
                        x      = previewPosition,
                        y      = rect.y + EditorGUIUtility.singleLineHeight,
                        width  = rect.width,
                        height = previewSize.y
                    };

                    GUI.Label(previewRect, previewTexture);
                }
            }
            else
            {
                string message = property.name + " doesn't have an asset preview";
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            DropdownDefinedAttribute dropdownAttribute = (DropdownDefinedAttribute)attribute;
            object target = PropertyUtility.GetTargetObjectWithProperty(property);

            object[]  valuesObject  = dropdownAttribute.ValuesArray;
            FieldInfo dropdownField = ReflectionUtility.GetField(target, property.name);

            if (AreValuesValid(valuesObject, dropdownField))
            {
                if (valuesObject is IList && dropdownField.FieldType == GetElementType(valuesObject))
                {
                    // Selected value
                    object selectedValue = dropdownField.GetValue(target);

                    // Values and display options
                    IList    valuesList     = (IList)valuesObject;
                    object[] values         = new object[valuesList.Count];
                    string[] displayOptions = new string[valuesList.Count];

                    for (int i = 0; i < values.Length; i++)
                    {
                        object value = valuesList[i];
                        values[i]         = value;
                        displayOptions[i] = value == null ? "<null>" : value.ToString();
                    }

                    // Selected value index
                    int selectedValueIndex = Array.IndexOf(values, selectedValue);
                    if (selectedValueIndex < 0)
                    {
                        selectedValueIndex = 0;
                    }

                    NaughtyEditorGUI.Dropdown(
                        rect, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values,
                        displayOptions);
                }
            }
            else
            {
                string message =
                    $"Invalid values provided to '{dropdownAttribute.GetType().Name}'. The types of the target field and the values provided to the attribute don't match";

                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
Example #11
0
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            if (!IsNumber(property))
            {
                string message = string.Format("Field {0} is not a number", property.name);
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
                return;
            }

            if (_cachedProgressBarAttribute == null)
            {
                _cachedProgressBarAttribute = PropertyUtility.GetAttribute <ProgressBarAttribute>(property);
            }

            ProgressBarAttribute progressBarAttribute = _cachedProgressBarAttribute;
            var value          = property.propertyType == SerializedPropertyType.Integer ? property.intValue : property.floatValue;
            var valueFormatted = property.propertyType == SerializedPropertyType.Integer ? value.ToString() : string.Format("{0:0.00}", value);
            var maxValue       = GetMaxValue(property, progressBarAttribute);

            if (maxValue != null && IsNumber(maxValue))
            {
                var fillPercentage = value / CastToFloat(maxValue);
                var barLabel       = (!string.IsNullOrEmpty(progressBarAttribute.Name) ? "[" + progressBarAttribute.Name + "] " : "") + valueFormatted + "/" + maxValue;
                var barColor       = progressBarAttribute.Color.GetColor();
                var labelColor     = Color.white;

                var  indentLength = NaughtyEditorGUI.GetIndentLength(rect);
                Rect barRect      = new Rect()
                {
                    x      = rect.x + indentLength,
                    y      = rect.y,
                    width  = rect.width - indentLength,
                    height = EditorGUIUtility.singleLineHeight
                };

                DrawBar(barRect, Mathf.Clamp01(fillPercentage), barLabel, barColor, labelColor);
            }
            else
            {
                string message = string.Format(
                    "The provided dynamic max value for the progress bar is not correct. Please check if the '{0}' is correct, or the return type is float/int",
                    nameof(progressBarAttribute.MaxValueName));

                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
Example #12
0
        protected void DrawButtons()
        {
            if (_anyMethods)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Buttons", GetHeaderGUIStyle());
                NaughtyEditorGUI.HorizontalLine(
                    EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor());

                foreach (var method in _methods)
                {
                    NaughtyEditorGUI.Button(serializedObject.targetObject, method);
                }
            }
        }
Example #13
0
        protected void DrawNonSerializedFields()
        {
            if (_nonSerializedFields.Any())
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Non-Serialized Fields", GetHeaderGUIStyle());
                NaughtyEditorGUI.HorizontalLine(
                    EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor());

                foreach (var field in _nonSerializedFields)
                {
                    NaughtyEditorGUI.NonSerializedField_Layout(serializedObject.targetObject, field);
                }
            }
        }
Example #14
0
        protected void DrawNativeProperties()
        {
            if (_anyNativeProperties)
            {
                EditorGUILayout.Space();
                EditorGUILayout.LabelField("Native Properties", GetHeaderGUIStyle());
                NaughtyEditorGUI.HorizontalLine(
                    EditorGUILayout.GetControlRect(false), HorizontalLineAttribute.DefaultHeight, HorizontalLineAttribute.DefaultColor.GetColor());

                foreach (var property in _nativeProperties)
                {
                    NaughtyEditorGUI.NativeProperty_Layout(serializedObject.targetObject, property);
                }
            }
        }
Example #15
0
        public override void ValidateProperty(SerializedProperty property)
        {
            ValidateInputAttribute validateInputAttribute = PropertyUtility.GetAttribute <ValidateInputAttribute>(property);
            object target = PropertyUtility.GetTargetObjectWithProperty(property);

            MethodInfo validationCallback = ReflectionUtility.GetMethod(target, validateInputAttribute.CallbackName);

            if (validationCallback != null &&
                validationCallback.ReturnType == typeof(bool) &&
                validationCallback.GetParameters().Length == 1)
            {
                FieldInfo fieldInfo     = ReflectionUtility.GetField(target, property.name);
                Type      fieldType     = fieldInfo.FieldType;
                Type      parameterType = validationCallback.GetParameters()[0].ParameterType;

                if (fieldType == parameterType)
                {
                    if (!(bool)validationCallback.Invoke(target, new object[] { fieldInfo.GetValue(target) }))
                    {
                        if (string.IsNullOrEmpty(validateInputAttribute.Message))
                        {
                            NaughtyEditorGUI.HelpBox_Layout(
                                property.name + " is not valid", MessageType.Error, context: property.serializedObject.targetObject);
                        }
                        else
                        {
                            NaughtyEditorGUI.HelpBox_Layout(
                                validateInputAttribute.Message, MessageType.Error, context: property.serializedObject.targetObject);
                        }
                    }
                }
                else
                {
                    string warning = "The field type is not the same as the callback's parameter type";
                    NaughtyEditorGUI.HelpBox_Layout(warning, MessageType.Warning, context: property.serializedObject.targetObject);
                }
            }
            else
            {
                string warning =
                    validateInputAttribute.GetType().Name +
                    " needs a callback with boolean return type and a single parameter of the same type as the field";

                NaughtyEditorGUI.HelpBox_Layout(warning, MessageType.Warning, context: property.serializedObject.targetObject);
            }
        }
        public void DrawDefaultPropertyAndHelpBox(Rect rect, SerializedProperty property, string message, MessageType messageType)
        {
            float indentLength = NaughtyEditorGUI.GetIndentLength(rect);
            Rect  helpBoxRect  = new Rect(
                rect.x + indentLength,
                rect.y,
                rect.width - indentLength,
                GetHelpBoxHeight());

            NaughtyEditorGUI.HelpBox(helpBoxRect, message, MessageType.Warning, context: property.serializedObject.targetObject);

            Rect propertyRect = new Rect(
                rect.x,
                rect.y + GetHelpBoxHeight(),
                rect.width,
                GetPropertyHeight(property));

            EditorGUI.PropertyField(propertyRect, property, true);
        }
Example #17
0
        private void DrawInfoBox(Rect rect, string infoText, EInfoBoxType infoBoxType)
        {
            MessageType messageType = MessageType.None;

            switch (infoBoxType)
            {
            case EInfoBoxType.Normal:
                messageType = MessageType.Info;
                break;

            case EInfoBoxType.Warning:
                messageType = MessageType.Warning;
                break;

            case EInfoBoxType.Error:
                messageType = MessageType.Error;
                break;
            }

            NaughtyEditorGUI.HelpBox(rect, infoText, messageType);
        }
        protected override void OnGUI_Internal(SerializedProperty property, GUIContent label)
        {
            if (!property.isArray)
            {
                string message = nameof(ReorderableListAttribute) + " can be used only on arrays or lists";
                NaughtyEditorGUI.HelpBox_Layout(message, MessageType.Warning, context: property.serializedObject.targetObject);
                EditorGUILayout.PropertyField(property, true);
                return;
            }

            string key = GetPropertyKeyName(property);

            if (!_reorderableListsByPropertyName.ContainsKey(key))
            {
                var reorderableList = new ReorderableList(property.serializedObject, property, true, true, true, true)
                {
                    drawHeaderCallback = (Rect rect) =>
                    {
                        EditorGUI.LabelField(rect, $"{label.text}: {property.arraySize}", EditorStyles.boldLabel);
                    },

                    drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) =>
                    {
                        var elementProperty = property.GetArrayElementAtIndex(index);
                        rect.y     += 1.0f;
                        rect.x     += 10.0f;
                        rect.width -= 10.0f;

                        EditorGUI.PropertyField(new Rect(rect.x, rect.y, rect.width, 0.0f), elementProperty, true);
                    },

                    elementHeightCallback = index => EditorGUI.GetPropertyHeight(property.GetArrayElementAtIndex(index)) + 4.0f
                };

                _reorderableListsByPropertyName[key] = reorderableList;
            }

            EditorGUILayout.Space();
            _reorderableListsByPropertyName[key].DoLayoutList();
        }
Example #19
0
        protected void DrawSerializedProperties()
        {
            serializedObject.Update();

            // Draw non-grouped serialized properties
            foreach (var property in GetNonGroupedProperties(_serializedProperties))
            {
                if (property.name.Equals("m_Script", System.StringComparison.Ordinal))
                {
                    GUI.enabled = false;
                    EditorGUILayout.PropertyField(property);
                    GUI.enabled = true;
                }
                else
                {
                    NaughtyEditorGUI.PropertyField_Layout(property, true);
                }
            }

            // Draw grouped serialized properties
            foreach (var group in GetGroupedProperties(_serializedProperties))
            {
                IEnumerable <SerializedProperty> visibleProperties = group.Where(p => PropertyUtility.IsVisible(p));
                if (!visibleProperties.Any())
                {
                    continue;
                }

                NaughtyEditorGUI.BeginBoxGroup_Layout(group.Key);
                foreach (var property in visibleProperties)
                {
                    NaughtyEditorGUI.PropertyField_Layout(property, true);
                }

                NaughtyEditorGUI.EndBoxGroup_Layout();
            }

            serializedObject.ApplyModifiedProperties();
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            if (property.propertyType == SerializedPropertyType.ObjectReference)
            {
                Rect propertyRect = new Rect()
                {
                    x      = rect.x,
                    y      = rect.y,
                    width  = rect.width,
                    height = EditorGUIUtility.singleLineHeight
                };

                EditorGUI.PropertyField(propertyRect, property, label);

                Texture2D previewTexture = GetAssetPreview(property);
                if (previewTexture != null)
                {
                    Rect previewRect = new Rect()
                    {
                        x      = rect.x + NaughtyEditorGUI.GetIndentLength(rect),
                        y      = rect.y + EditorGUIUtility.singleLineHeight,
                        width  = rect.width,
                        height = GetAssetPreviewSize(property).y
                    };

                    GUI.Label(previewRect, previewTexture);
                }
            }
            else
            {
                string message = property.name + " doesn't have an asset preview";
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
        private void DrawChildProperties(Rect rect, SerializedProperty property)
        {
            ScriptableObject scriptableObject = property.objectReferenceValue as ScriptableObject;

            if (scriptableObject == null)
            {
                return;
            }

            Rect boxRect = new Rect()
            {
                x      = 0.0f,
                y      = rect.y + EditorGUIUtility.singleLineHeight,
                width  = rect.width * 2.0f,
                height = rect.height - EditorGUIUtility.singleLineHeight
            };

            GUI.Box(boxRect, GUIContent.none);

            using (new EditorGUI.IndentLevelScope())
            {
                SerializedObject serializedObject = new SerializedObject(scriptableObject);

                using (var iterator = serializedObject.GetIterator())
                {
                    float yOffset = EditorGUIUtility.singleLineHeight;

                    if (iterator.NextVisible(true))
                    {
                        do
                        {
                            SerializedProperty childProperty = serializedObject.FindProperty(iterator.name);
                            if (childProperty.name.Equals("m_Script", System.StringComparison.Ordinal))
                            {
                                continue;
                            }

                            bool visible = PropertyUtility.IsVisible(childProperty);
                            if (!visible)
                            {
                                continue;
                            }

                            float childHeight = GetPropertyHeight(childProperty);
                            Rect  childRect   = new Rect()
                            {
                                x      = rect.x,
                                y      = rect.y + yOffset,
                                width  = rect.width,
                                height = childHeight
                            };

                            NaughtyEditorGUI.PropertyField(childRect, childProperty, true);

                            yOffset += childHeight;
                        }while (iterator.NextVisible(false));
                    }
                }

                serializedObject.ApplyModifiedProperties();
            }
        }
Example #22
0
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            MinMaxSliderAttribute minMaxSliderAttribute = (MinMaxSliderAttribute)attribute;

            if (property.propertyType == SerializedPropertyType.Vector2 || property.propertyType == SerializedPropertyType.Vector2Int)
            {
                EditorGUI.BeginProperty(rect, label, property);

                float indentLength    = NaughtyEditorGUI.GetIndentLength(rect);
                float labelWidth      = EditorGUIUtility.labelWidth + NaughtyEditorGUI.HorizontalSpacing;
                float floatFieldWidth = EditorGUIUtility.fieldWidth;
                float sliderWidth     = rect.width - labelWidth - 2.0f * floatFieldWidth;
                float sliderPadding   = 5.0f;

                Rect labelRect = new Rect(
                    rect.x,
                    rect.y,
                    labelWidth,
                    rect.height);

                Rect sliderRect = new Rect(
                    rect.x + labelWidth + floatFieldWidth + sliderPadding - indentLength,
                    rect.y,
                    sliderWidth - 2.0f * sliderPadding + indentLength,
                    rect.height);

                Rect minFloatFieldRect = new Rect(
                    rect.x + labelWidth - indentLength,
                    rect.y,
                    floatFieldWidth + indentLength,
                    rect.height);

                Rect maxFloatFieldRect = new Rect(
                    rect.x + labelWidth + floatFieldWidth + sliderWidth - indentLength,
                    rect.y,
                    floatFieldWidth + indentLength,
                    rect.height);

                // Draw the label
                EditorGUI.LabelField(labelRect, label.text);

                // Draw the slider
                EditorGUI.BeginChangeCheck();

                if (property.propertyType == SerializedPropertyType.Vector2)
                {
                    Vector2 sliderValue = property.vector2Value;
                    EditorGUI.MinMaxSlider(sliderRect, ref sliderValue.x, ref sliderValue.y, minMaxSliderAttribute.MinValue, minMaxSliderAttribute.MaxValue);

                    sliderValue.x = EditorGUI.FloatField(minFloatFieldRect, sliderValue.x);
                    sliderValue.x = Mathf.Clamp(sliderValue.x, minMaxSliderAttribute.MinValue, Mathf.Min(minMaxSliderAttribute.MaxValue, sliderValue.y));

                    sliderValue.y = EditorGUI.FloatField(maxFloatFieldRect, sliderValue.y);
                    sliderValue.y = Mathf.Clamp(sliderValue.y, Mathf.Max(minMaxSliderAttribute.MinValue, sliderValue.x), minMaxSliderAttribute.MaxValue);

                    if (EditorGUI.EndChangeCheck())
                    {
                        property.vector2Value = sliderValue;
                    }
                }
                else if (property.propertyType == SerializedPropertyType.Vector2Int)
                {
                    Vector2Int sliderValue = property.vector2IntValue;
                    float      xValue      = sliderValue.x;
                    float      yValue      = sliderValue.y;
                    EditorGUI.MinMaxSlider(sliderRect, ref xValue, ref yValue, minMaxSliderAttribute.MinValue, minMaxSliderAttribute.MaxValue);

                    sliderValue.x = EditorGUI.IntField(minFloatFieldRect, (int)xValue);
                    sliderValue.x = (int)Mathf.Clamp(sliderValue.x, minMaxSliderAttribute.MinValue, Mathf.Min(minMaxSliderAttribute.MaxValue, sliderValue.y));

                    sliderValue.y = EditorGUI.IntField(maxFloatFieldRect, (int)yValue);
                    sliderValue.y = (int)Mathf.Clamp(sliderValue.y, Mathf.Max(minMaxSliderAttribute.MinValue, sliderValue.x), minMaxSliderAttribute.MaxValue);

                    if (EditorGUI.EndChangeCheck())
                    {
                        property.vector2IntValue = sliderValue;
                    }
                }

                EditorGUI.EndProperty();
            }
            else
            {
                string message = minMaxSliderAttribute.GetType().Name + " can be used only on Vector2 or Vector2Int fields";
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
Example #23
0
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            DropdownConstantsAttribute dropdownAttribute = (DropdownConstantsAttribute)attribute;
            object target = PropertyUtility.GetTargetObjectWithProperty(property);

            Type      selectFromType = dropdownAttribute.SelectFromType;
            FieldInfo dropdownField  = ReflectionUtility.GetField(target, property.name);

            if (AreValuesValid(selectFromType, dropdownField))
            {
                var searchFlags               = BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy;
                var allPublicStaticFields     = dropdownAttribute.SelectFromType.GetFields(searchFlags);
                var allPublicStaticProperties = dropdownAttribute.SelectFromType.GetProperties(searchFlags);

                // IsLiteral determines if its value is written at compile time and not changeable
                // IsInitOnly determines if the field can be set in the body of the constructor
                // for C# a field which is readonly keyword would have both true but a const field would have only IsLiteral equal to true
                foreach (FieldInfo field in allPublicStaticFields)
                {
                    if ((field.IsInitOnly || field.IsLiteral) && field.FieldType == selectFromType)
                    {
                        _constants.Add(field);
                    }
                }
                foreach (var prop in allPublicStaticProperties)
                {
                    if (prop.PropertyType == selectFromType)
                    {
                        _constants.Add(prop);
                    }
                }


                if (IsNullOrEmpty(_constants))
                {
                    return;
                }

                string[] names  = new string[_constants.Count];
                object[] values = new object[_constants.Count];
                for (var i = 0; i < _constants.Count; i++)
                {
                    names[i]  = _constants[i].Name;
                    values[i] = GetValue(i);
                }

                // Selected value
                object selectedValue = dropdownField.GetValue(target);

                int  selectedValueIndex = -1;
                bool valueFound         = false;

                if (selectedValue != null)
                {
                    for (var i = 0; i < values.Length; i++)
                    {
                        if (selectedValue.Equals(values[i]))
                        {
                            valueFound         = true;
                            selectedValueIndex = i;
                        }
                    }
                }

                if (!valueFound)
                {
                    names  = InsertAt(names, 0);
                    values = InsertAt(values, 0);
                    var actualValue = selectedValue;
                    var value       = actualValue != null ? actualValue : "NULL";
                    names[0]  = "NOT FOUND: " + value;
                    values[0] = actualValue;
                }

                NaughtyEditorGUI.Dropdown(
                    rect, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values, names);
            }
            else
            {
                string message =
                    $"Invalid values provided to '{dropdownAttribute.GetType().Name}'. The types of the target field and the type provided to the attribute don't match";

                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
Example #24
0
        protected virtual void DrawSerializedProperties()
        {
            serializedObject.Update();

            if (m_ScriptProperty != null)
            {
                using (new EditorGUI.DisabledScope(disabled: true))
                {
                    EditorGUILayout.PropertyField(m_ScriptProperty);
                }
            }

            // Draw non-grouped serialized properties
            foreach (var naughtyProperty in _nonGroupedSerializedProperty)
            {
                if (!_useCachedMetaAttributes)
                {
                    naughtyProperty.cachedIsVisible = PropertyUtility.IsVisible(naughtyProperty.showIfAttribute,
                                                                                naughtyProperty.serializedProperty);

                    naughtyProperty.cachedIsEnabled = PropertyUtility.IsEnabled(naughtyProperty.readOnlyAttribute, naughtyProperty.enableIfAttribute,
                                                                                naughtyProperty.serializedProperty);
                }

                _changeDetected |= NaughtyEditorGUI.PropertyField_Layout(naughtyProperty, includeChildren: true);
            }

            // Draw grouped serialized properties
            foreach (var group in _groupedSerialzedProperty)
            {
                IEnumerable <NaughtyProperty> visibleProperties =
                    _useCachedMetaAttributes
                                                ? group.Where(p => p.cachedIsVisible)
                                                : group.Where(p =>
                {
                    p.cachedIsEnabled = PropertyUtility.IsEnabled(p.readOnlyAttribute, p.enableIfAttribute,
                                                                  p.serializedProperty);

                    return(p.cachedIsVisible =
                               PropertyUtility.IsVisible(p.showIfAttribute, p.serializedProperty));
                });

                if (!visibleProperties.Any())
                {
                    continue;
                }

                NaughtyEditorGUI.BeginBoxGroup_Layout(group.Key);
                foreach (var naughtyProperty in visibleProperties)
                {
                    _changeDetected |= NaughtyEditorGUI.PropertyField_Layout(naughtyProperty, includeChildren: true);
                }
                NaughtyEditorGUI.EndBoxGroup_Layout();
            }

            // Draw foldout serialized properties
            foreach (var group in _foldoutGroupedSerializedProperty)
            {
                IEnumerable <NaughtyProperty> visibleProperties =
                    _useCachedMetaAttributes
                                                ? group.Where(p => p.cachedIsVisible)
                                                : group.Where(p =>
                {
                    p.cachedIsEnabled = PropertyUtility.IsEnabled(p.readOnlyAttribute, p.enableIfAttribute,
                                                                  p.serializedProperty);

                    return(p.cachedIsVisible =
                               PropertyUtility.IsVisible(p.showIfAttribute, p.serializedProperty));
                });

                if (!visibleProperties.Any())
                {
                    continue;
                }

                if (!_foldouts.ContainsKey(group.Key))
                {
                    _foldouts[group.Key] = new SavedBool($"{target.GetInstanceID()}.{group.Key}", false);
                }

                _foldouts[group.Key].Value = EditorGUILayout.Foldout(_foldouts[group.Key].Value, group.Key, true);
                if (_foldouts[group.Key].Value)
                {
                    foreach (var naughtyProperty in visibleProperties)
                    {
                        _changeDetected |= NaughtyEditorGUI.PropertyField_Layout(naughtyProperty, true);
                    }
                }
            }

            serializedObject.ApplyModifiedProperties();
        }
Example #25
0
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);
            Texture2D            previewTexture = GetAssetPreview(property);
            HeaderImageAttribute headerImageAttribute
                = PropertyUtility.GetAttribute <HeaderImageAttribute>(property);

            if (previewTexture != null)
            {
                float indentLength = NaughtyEditorGUI.GetIndentLength(rect);
                var   previewSize  = GetAssetPreviewSize(property);

                float width = rect.width - indentLength;
                previewSize = RescaleSize(previewSize, width);
                float alignmentLength = 0f;
                if (previewSize.x < width)
                {
                    switch (headerImageAttribute.Alignment)
                    {
                    case EAlignment.Center:
                        alignmentLength = (width - previewSize.x) / 2f;
                        break;

                    case EAlignment.Right:
                        alignmentLength = (width - previewSize.x);
                        break;

                    case EAlignment.Left:
                    default:
                        alignmentLength = 0f;
                        break;
                    }
                }
                Rect propertyRect = new Rect()
                {
                    x      = rect.x,
                    y      = rect.y + previewSize.y,
                    width  = width,
                    height = EditorGUIUtility.singleLineHeight
                };

                EditorGUI.PropertyField(propertyRect, property, label);

                Rect previewRect = new Rect()
                {
                    x = rect.x + indentLength + alignmentLength,
                    y = rect.y,
                    // width = rect.width,
                    width  = previewSize.x,
                    height = previewSize.y
                };

                GUI.Label(previewRect, previewTexture);
            }
            else
            {
                string message = property.name + " has no header image for path: " + headerImageAttribute.Path;
                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
        protected override void OnGUI_Internal(Rect rect, SerializedProperty property, GUIContent label)
        {
            EditorGUI.BeginProperty(rect, label, property);

            DropdownAttribute dropdownAttribute = (DropdownAttribute)attribute;
            object            target            = PropertyUtility.GetTargetObjectWithProperty(property);

            object    valuesObject  = GetValues(property, dropdownAttribute.ValuesName);
            FieldInfo dropdownField = ReflectionUtility.GetField(target, property.name);

            if (AreValuesValid(valuesObject, dropdownField))
            {
                if (valuesObject is IList && dropdownField.FieldType == GetElementType(valuesObject))
                {
                    // Selected value
                    object selectedValue = dropdownField.GetValue(target);

                    // Values and display options
                    IList    valuesList     = (IList)valuesObject;
                    object[] values         = new object[valuesList.Count];
                    string[] displayOptions = new string[valuesList.Count];

                    for (int i = 0; i < values.Length; i++)
                    {
                        object value = valuesList[i];
                        values[i]         = value;
                        displayOptions[i] = value == null ? "<null>" : value.ToString();
                    }

                    // Selected value index
                    int selectedValueIndex = Array.IndexOf(values, selectedValue);
                    if (selectedValueIndex < 0)
                    {
                        selectedValueIndex = 0;
                    }

                    NaughtyEditorGUI.Dropdown(
                        rect, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values, displayOptions);
                }
                else if (valuesObject is IDropdownList)
                {
                    // Current value
                    object selectedValue = dropdownField.GetValue(target);

                    // Current value index, values and display options
                    int           index = -1;
                    int           selectedValueIndex = -1;
                    List <object> values             = new List <object>();
                    List <string> displayOptions     = new List <string>();
                    IDropdownList dropdown           = (IDropdownList)valuesObject;

                    using (IEnumerator <KeyValuePair <string, object> > dropdownEnumerator = dropdown.GetEnumerator())
                    {
                        while (dropdownEnumerator.MoveNext())
                        {
                            index++;

                            KeyValuePair <string, object> current = dropdownEnumerator.Current;
                            if (current.Value?.Equals(selectedValue) == true)
                            {
                                selectedValueIndex = index;
                            }

                            values.Add(current.Value);

                            if (current.Key == null)
                            {
                                displayOptions.Add("<null>");
                            }
                            else if (string.IsNullOrWhiteSpace(current.Key))
                            {
                                displayOptions.Add("<empty>");
                            }
                            else
                            {
                                displayOptions.Add(current.Key);
                            }
                        }
                    }

                    if (selectedValueIndex < 0)
                    {
                        selectedValueIndex = 0;
                    }

                    NaughtyEditorGUI.Dropdown(
                        rect, property.serializedObject, target, dropdownField, label.text, selectedValueIndex, values.ToArray(), displayOptions.ToArray());
                }
            }
            else
            {
                string message = string.Format("Invalid values with name '{0}' provided to '{1}'. Either the values name is incorrect or the types of the target field and the values field/property/method don't match",
                                               dropdownAttribute.ValuesName, dropdownAttribute.GetType().Name);

                DrawDefaultPropertyAndHelpBox(rect, property, message, MessageType.Warning);
            }

            EditorGUI.EndProperty();
        }
Example #27
0
        protected void DrawSerializedProperties()
        {
            serializedObject.Update();

            // Draw non-grouped serialized properties
            foreach (var property in GetNonGroupedProperties(_serializedProperties))
            {
                if (property.name.Equals("m_Script", System.StringComparison.Ordinal))
                {
                    using (new EditorGUI.DisabledScope(disabled: true))
                    {
                        EditorGUILayout.PropertyField(property);
                    }
                }
                else
                {
                    NaughtyEditorGUI.PropertyField_Layout(property, includeChildren: true);
                }
            }

            // Draw grouped serialized properties
            foreach (var group in GetGroupedProperties(_serializedProperties))
            {
                IEnumerable <SerializedProperty> visibleProperties = group.Where(p => PropertyUtility.IsVisible(p));
                if (!visibleProperties.Any())
                {
                    continue;
                }

                NaughtyEditorGUI.BeginBoxGroup_Layout(group.Key);
                foreach (var property in visibleProperties)
                {
                    NaughtyEditorGUI.PropertyField_Layout(property, includeChildren: true);
                }

                NaughtyEditorGUI.EndBoxGroup_Layout();
            }

            // Draw foldout serialized properties
            foreach (var group in GetFoldoutProperties(_serializedProperties))
            {
                IEnumerable <SerializedProperty> visibleProperties = group.Where(p => PropertyUtility.IsVisible(p));
                if (!visibleProperties.Any())
                {
                    continue;
                }

                if (!_foldouts.ContainsKey(group.Key))
                {
                    _foldouts[group.Key] = new SavedBool($"{target.GetInstanceID()}.{group.Key}", false);
                }

                _foldouts[group.Key].Value = EditorGUILayout.Foldout(_foldouts[group.Key].Value, group.Key, true);
                if (_foldouts[group.Key].Value)
                {
                    foreach (var property in visibleProperties)
                    {
                        NaughtyEditorGUI.PropertyField_Layout(property, true);
                    }
                }
            }

            serializedObject.ApplyModifiedProperties();
        }