Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .vsconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"version": "1.0",
"components": [
"Microsoft.VisualStudio.Workload.ManagedGame"
]
}
13 changes: 13 additions & 0 deletions Assets/Editor Toolbox/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## 0.9.0 [19.07.2021]

### Added:
- FormattedNumberAttribute
- SceneAsset picker for the SceneNameAttribute
- Optional foldout for the ReorderableList and related attributes
- GuiColorAttribute

### Changed:

- Remove obsolete attributes
- Rename ToolboxCompositionAttribute class to ToolboxArchetypeAttribute

## 0.8.13 [04.07.2021]

### Added:
Expand Down
8 changes: 8 additions & 0 deletions Assets/Editor Toolbox/Editor/Drawers/Internal.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ namespace Toolbox.Editor.Drawers
[CustomPropertyDrawer(typeof(FolderData))]
internal class FolderDataDrawer : PropertyDrawer
{
private const string selectorEventName = "ObjectSelectorUpdated";

private const int largeIconPickedId = 1001;
private const int smallIconPickedId = 1002;

Expand Down Expand Up @@ -81,15 +79,15 @@ public override float GetPropertyHeight(SerializedProperty property, GUIContent
var pathProperty = property.FindPropertyRelative("path");
var tooltipProperty = property.FindPropertyRelative("tooltip");

//check if type is path-based or name-based
height += typeProperty.intValue == 0
? EditorGUI.GetPropertyHeight(pathProperty)
: EditorGUI.GetPropertyHeight(nameProperty);
height += EditorGUI.GetPropertyHeight(tooltipProperty);
height += Style.height;
height += Style.height;
height += Style.largeFolderHeight;
height += Style.spacing * 4;
//check if type is path-based or name-based
height += typeProperty.intValue == 0
? EditorGUI.GetPropertyHeight(pathProperty)
: EditorGUI.GetPropertyHeight(nameProperty);
return height;
}

Expand Down Expand Up @@ -210,7 +208,7 @@ public override void OnGUI(Rect position, SerializedProperty property, GUIConten
}

//catch object selection event and assign it to proper property
if (Event.current.commandName == selectorEventName)
if (Event.current.commandName == "ObjectSelectorUpdated")
{
//get proper action id by removing unique property hash code
var rawPickId = EditorGUIUtility.GetObjectPickerControlID();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,25 @@ protected override void OnGUISafe(Rect position, SerializedProperty property, GU
{
var minValue = Attribute.MinValue;
var maxValue = Attribute.MaxValue;

if (property.propertyType == SerializedPropertyType.Float)
if (property.hasMultipleDifferentValues)
{
property.floatValue = Mathf.Clamp(property.floatValue, minValue, maxValue);
EditorGUI.PropertyField(position, property, label);
return;
}
else

switch (property.propertyType)
{
property.intValue = Mathf.Clamp(property.intValue, (int)minValue, (int)maxValue);
case SerializedPropertyType.Float:
property.floatValue = Mathf.Clamp(property.floatValue, minValue, maxValue);
break;
case SerializedPropertyType.Integer:
property.intValue = (int)Mathf.Clamp(property.intValue, minValue, maxValue);
break;
default:
break;
}

EditorGUI.PropertyField(position, property, label, property.isExpanded);
EditorGUI.PropertyField(position, property, label);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,48 @@ private static bool IsPathValid(string propertyPath, string assetRelativePath)
return Directory.Exists(targetPath);
}

private Rect DrawWarningMessage(Rect position)
{
position = new Rect(position.x,
position.y,
position.width, Style.boxHeight);
EditorGUI.HelpBox(position, "Provided directory does not exist.", MessageType.Warning);
return position;
}

private void UseDirectoryPicker(SerializedProperty property, string relativePath)
{
var baseDataPath = Application.dataPath;
var baseOpenPath = Path.GetFileName(baseDataPath);
if (!string.IsNullOrEmpty(relativePath))
{
baseDataPath = Path.Combine(baseDataPath, relativePath);
baseOpenPath = Path.Combine(baseOpenPath, relativePath);
}

var selectedPath = EditorUtility.OpenFolderPanel("Pick directory", baseOpenPath, "");
if (!string.IsNullOrEmpty(selectedPath))
{
//Unity's API always returns slash
baseDataPath = baseDataPath.Replace('\\', '/');
selectedPath = selectedPath.Replace(baseDataPath, "");
selectedPath = selectedPath.Remove(0, 1);

property.serializedObject.Update();
property.stringValue = selectedPath;
property.serializedObject.ApplyModifiedProperties();
}

//NOTE: we have to exit GUI since the EditorUtility.OpenFolderPanel method will break the layouting system
GUIUtility.ExitGUI();
}


protected override float GetPropertyHeightSafe(SerializedProperty property, GUIContent label)
{
//validate property type and serialized path
return IsPathValid(property.stringValue, Attribute.RelativePath)
? base.GetPropertyHeightSafe(property, label)
return IsPathValid(property.stringValue, Attribute.RelativePath)
? base.GetPropertyHeightSafe(property, label)
: base.GetPropertyHeightSafe(property, label) + Style.boxHeight + Style.spacing * 2;
}

Expand All @@ -31,47 +67,20 @@ protected override void OnGUISafe(Rect position, SerializedProperty property, GU
//validate currently serialized path value
if (!IsPathValid(property.stringValue, Attribute.RelativePath))
{
var helpBoxRect = new Rect(position.x,
position.y,
position.width, Style.boxHeight);
EditorGUI.HelpBox(helpBoxRect, "Provided directory does not exist.", MessageType.Warning);
position.y += Style.boxHeight + Style.spacing + Style.spacing;
position = DrawWarningMessage(position);
position.yMin = position.yMax + Style.spacing;
position.yMax = position.yMin + Style.rowHeight;
}

position.height = Style.rowHeight;
position.width -= Style.directoryButtonWidth + Style.spacing;
//draw the default string property field
position.xMax -= Style.pickerWidth + Style.spacing;
EditorGUI.PropertyField(position, property, label);
position.x = position.xMax + Style.spacing;
position.width = Style.directoryButtonWidth;
position.xMax += Style.pickerWidth + Style.spacing;
position.xMin = position.xMax - Style.pickerWidth;

//create additional pick directory button
if (GUI.Button(position, Style.directoryButtonContent, EditorStyles.miniButton))
if (GUI.Button(position, Style.pickerContent, EditorStyles.miniButton))
{
var relativePath = Attribute.RelativePath;
var baseDataPath = Application.dataPath;
var baseOpenPath = "Assets";
if (!string.IsNullOrEmpty(relativePath))
{
baseDataPath = Path.Combine(baseDataPath, relativePath);
baseOpenPath = Path.Combine(baseOpenPath, relativePath);
}

var selectedPath = EditorUtility.OpenFolderPanel("Pick directory", baseOpenPath, "");
if (!string.IsNullOrEmpty(selectedPath))
{
//Unity's API always returns slash
baseDataPath = baseDataPath.Replace('\\', '/');
selectedPath = selectedPath.Replace(baseDataPath, "");
selectedPath = selectedPath.Remove(0, 1);

property.serializedObject.Update();
property.stringValue = selectedPath;
property.serializedObject.ApplyModifiedProperties();
}

//NOTE: we have to exit GUI since the EditorUtility.OpenFolderPanel method will break the layouting system
GUIUtility.ExitGUI();
UseDirectoryPicker(property, Attribute.RelativePath);
}
}

Expand All @@ -94,13 +103,14 @@ private static class Style
internal static readonly float boxHeight = EditorGUIUtility.singleLineHeight * 2.5f;
#endif
internal static readonly float spacing = EditorGUIUtility.standardVerticalSpacing;
internal static readonly float directoryButtonWidth = 30.0f;
internal static readonly float pickerWidth = 30.0f;

internal static readonly GUIContent directoryButtonContent;
internal static readonly GUIContent pickerContent;

static Style()
{
directoryButtonContent = new GUIContent(EditorGUIUtility.FindTexture("Folder Icon"), "Pick directory");
pickerContent = EditorGUIUtility.IconContent("Folder Icon");
pickerContent.tooltip = "Pick directory";
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Globalization;

using UnityEditor;
using UnityEngine;

namespace Toolbox.Editor.Drawers
{
[CustomPropertyDrawer(typeof(FormattedNumberAttribute))]
public class FormattedNumberAttributeDrawer : ToolboxNativePropertyDrawer
{
private readonly NumberFormatInfo formatInfo = new NumberFormatInfo()
{
NumberGroupSeparator = " ",
CurrencySymbol = "$",
CurrencyDecimalSeparator = "."
};


private void ApplyControlName(string propertyKey)
{
GUI.SetNextControlName(propertyKey);
}

private bool IsControlEditing(string propertyKey)
{
return EditorGUIUtility.editingTextField && GUI.GetNameOfFocusedControl() == propertyKey;
}

private Single GetSingle(SerializedProperty property)
{
return property.propertyType == SerializedPropertyType.Integer
? property.intValue
: property.floatValue;
}

private string GetFormat(SerializedProperty property, FormattedNumberAttribute attribute)
{
var isInt = property.propertyType == SerializedPropertyType.Integer;
return string.Format("{0}{1}", attribute.Format, isInt ? 0 : attribute.DecimalsToShow);
}


protected override void OnGUISafe(Rect position, SerializedProperty property, GUIContent label)
{
var key = property.GetPropertyHashKey();
ApplyControlName(key);
EditorGUI.PropertyField(position, property, label);
if (IsControlEditing(key))
{
position.width = 0;
position.height = 0;
}
else
{
position.xMin += EditorGUIUtility.labelWidth + EditorGUIUtility.standardVerticalSpacing;
}

var targetAttribute = attribute as FormattedNumberAttribute;
var single = GetSingle(property);
var format = GetFormat(property, targetAttribute);

try
{
EditorGUI.TextField(position, single.ToString(format, formatInfo));
}
catch (FormatException)
{
ToolboxEditorLog.AttributeUsageWarning(attribute, property, string.Format("{0} format is not supported.", format));
}
}


public override bool IsPropertyValid(SerializedProperty property)
{
return property.propertyType == SerializedPropertyType.Integer ||
property.propertyType == SerializedPropertyType.Float;
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,12 @@ protected override void OnGUISafe(Rect position, SerializedProperty property, GU
//validate availability of the child property
if (childProperty != null)
{
//set new label if found (unknown values will be ignored)
//set new label if found (unknown types will be ignored)
label = GetLabelByValue(childProperty, label);
}
else
{
ToolboxEditorLog.AttributeUsageWarning(attribute, property, propertyName + " does not exists.");
ToolboxEditorLog.AttributeUsageWarning(attribute, property, string.Format("{0} does not exists.", propertyName));
}

EditorGUI.PropertyField(position, property, label, property.isExpanded);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace Toolbox.Editor.Drawers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@ protected override float GetPropertyHeightSafe(SerializedProperty property, GUIC
protected override void OnGUISafe(Rect position, SerializedProperty property, GUIContent label)
{
var attribute = Attribute;

//determine the real value of the property
var value = property.propertyType == SerializedPropertyType.Integer ? property.intValue : property.floatValue;
var value = property.propertyType == SerializedPropertyType.Integer
? property.intValue
: property.floatValue;

var color = attribute.GetBarColor();
var fillLabel = attribute.Name;
var fillColor = attribute.Color;
var minValue = attribute.MinValue;
var maxValue = attribute.MaxValue;

//set the value text label (add name if needed)
var valueText = property.hasMultipleDifferentValues ? "-" : value.ToString();
var labelText = !string.IsNullOrEmpty(attribute.Name)
? attribute.Name + " " + valueText + "|" + maxValue : valueText + "|" + maxValue;
var labelText = !string.IsNullOrEmpty(fillLabel)
? string.Format("{0} {1}|{2}", fillLabel, valueText, maxValue)
: string.Format("{0}|{1}", valueText, maxValue);

//clamp current value between min and max values
value = Mathf.Clamp(value, minValue, maxValue);
Expand All @@ -39,7 +42,7 @@ protected override void OnGUISafe(Rect position, SerializedProperty property, GU

//draw the background and fill colors
EditorGUI.DrawRect(position, Style.backgroundColor);
EditorGUI.DrawRect(fillRect, color);
EditorGUI.DrawRect(fillRect, fillColor);

//adjust rect for the shadow label
var diff = Style.barHeight - Style.rowHeight;
Expand Down
Loading