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); }
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)); }
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(); }