protected override void OnGuiSafe(SerializedProperty property, GUIContent label, T attribute)
        {
            var minValueSource = attribute.MinValueSource;
            var maxValueSource = attribute.MaxValueSource;

            if (!ValueExtractionHelper.TryGetValue(minValueSource, property, out var minValueCandidate, out _) ||
                !ValueExtractionHelper.TryGetValue(maxValueSource, property, out var maxValueCandidate, out _))
            {
                ToolboxEditorLog.MemberNotFoundWarning(attribute, property,
                                                       string.Format("{0} or {1}", minValueSource, maxValueSource));
                base.OnGuiSafe(property, label, attribute);
                return;
            }

            float minValue;
            float maxValue;

            try
            {
                minValue = Convert.ToSingle(minValueCandidate);
                maxValue = Convert.ToSingle(maxValueCandidate);
            }
            catch (Exception e) when(e is InvalidCastException || e is FormatException)
            {
                ToolboxEditorLog.AttributeUsageWarning(attribute, property,
                                                       string.Format("Invalid source types, cannot convert them to {0}", typeof(float)));
                base.OnGuiSafe(property, label, attribute);
                return;
            }

            OnGuiSafe(property, label, minValue, maxValue);
        }
        protected override void OnGuiBeginSafe(DynamicHelpAttribute attribute)
        {
            var sourceHandle  = attribute.SourceHandle;
            var targetObjects = InspectorUtility.CurrentTargetObjects;

            if (ValueExtractionHelper.TryGetValue(sourceHandle, targetObjects, out var value, out var hasMixedValues))
            {
                var messageText = hasMixedValues ? "-" : value?.ToString();
                var messageType = (MessageType)attribute.Type;
                EditorGUILayout.HelpBox(messageText, messageType);
                return;
            }

            var targetType = targetObjects[0].GetType();

            ToolboxEditorLog.MemberNotFoundWarning(attribute, targetType, sourceHandle);
        }
Exemple #3
0
        protected override PropertyCondition OnGuiValidateSafe(SerializedProperty property, T attribute)
        {
            var sourceHandle = attribute.SourceHandle;

            if (!ValueExtractionHelper.TryGetValue(sourceHandle, property, out var value, out var hasMixedValues))
            {
                ToolboxEditorLog.MemberNotFoundWarning(attribute, property, sourceHandle);
                return(PropertyCondition.Valid);
            }

            var comparison  = (ValueComparisonMethod)attribute.Comparison;
            var targetValue = attribute.ValueToMatch;

            if (!ValueComparisonHelper.TryCompare(value, targetValue, comparison, out var result))
            {
                ToolboxEditorLog.AttributeUsageWarning(attribute, property,
                                                       string.Format("Invalid comparison input: source:{0}, target:{1}, method:{2}.",
                                                                     value?.GetType(), targetValue?.GetType(), comparison));
                return(PropertyCondition.Valid);
            }

            return(OnComparisonResult(hasMixedValues ? false : result));
        }
Exemple #4
0
        protected override void OnGUISafe(Rect position, SerializedProperty property, GUIContent label)
        {
            //NOTE: this implementation does not support multiple different sources
            var sourceHandle    = Attribute.SourceHandle;
            var declaringObject = property.GetDeclaringObject();

            //extract (if available) the real preset value
            if (!ValueExtractionHelper.TryGetValue(sourceHandle, declaringObject, out var sourceValue))
            {
                ToolboxEditorLog.MemberNotFoundWarning(attribute, property, sourceHandle);
                EditorGUI.PropertyField(position, property, label);
                return;
            }

            if (!(sourceValue is IList presetList))
            {
                ToolboxEditorLog.AttributeUsageWarning(attribute, property,
                                                       string.Format("Preset ({0}) has to be a one-dimensional collection (array or list).", sourceHandle));
                EditorGUI.PropertyField(position, property, label);
                return;
            }

            var sourceType = sourceValue.GetType();
            var targetType = property.GetProperType(fieldInfo);

            //check if types match between property and provided preset
            if (targetType != (sourceType.IsGenericType
                             ? sourceType.GetGenericArguments()[0]
                             : sourceType.GetElementType()))
            {
                ToolboxEditorLog.AttributeUsageWarning(attribute, property,
                                                       "Type mismatch between serialized property and given Preset.");
                EditorGUI.PropertyField(position, property, label);
                return;
            }

            var itemsCount = presetList.Count;
            var objects    = new object[itemsCount];
            var options    = new string[itemsCount];

            for (var i = 0; i < itemsCount; i++)
            {
                objects[i] = presetList[i];
                options[i] = presetList[i]?.ToString();
            }

            var value = property.GetProperValue(fieldInfo, declaringObject);
            var index = Array.IndexOf(objects, value);

            //begin the true property
            label = EditorGUI.BeginProperty(position, label, property);
            EditorGUI.BeginChangeCheck();
            //get selected preset value
            index = EditorGUI.Popup(position, label, index, EditorGUIUtility.TrTempContent(options));
            index = Mathf.Clamp(index, 0, itemsCount - 1);
            if (EditorGUI.EndChangeCheck())
            {
                //udpate property value using previously cached FieldInfo and picked value
                //there is no cleaner way to do it, since we don't really know what kind of
                //serialized property we are updating

                property.serializedObject.Update();
                property.SetProperValue(fieldInfo, objects[index]);
                property.serializedObject.ApplyModifiedProperties();
                //handle situation when updating multiple different targets
                property.serializedObject.SetIsDifferentCacheDirty();
            }

            EditorGUI.EndProperty();
        }