diff --git a/Editor.meta b/Editor.meta new file mode 100644 index 0000000..26a7ffc --- /dev/null +++ b/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ff0dcc3c0bdb6f34cb6fdeeca979933f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/BetterAttributes.Editor.asmdef b/Editor/BetterAttributes.Editor.asmdef new file mode 100644 index 0000000..d981188 --- /dev/null +++ b/Editor/BetterAttributes.Editor.asmdef @@ -0,0 +1,21 @@ +{ + "name": "BetterAttributes.Editor", + "rootNamespace": "Better.Attributes.EditorAddons", + "references": [ + "GUID:35101f455c979e94c9a0a4793484b7fd", + "GUID:01df13aca8d01e24a911bcc3e8277031", + "GUID:8bd4b41f8da90144d9006c4d926c9679", + "GUID:55fbe2a01ca11514f94a66e7102c8895" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Editor/BetterAttributes.Editor.asmdef.meta b/Editor/BetterAttributes.Editor.asmdef.meta new file mode 100644 index 0000000..ffbf4f4 --- /dev/null +++ b/Editor/BetterAttributes.Editor.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b6053aaf850e1f44ebbe8a655121831f +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/EditorAddons.meta b/Editor/EditorAddons.meta new file mode 100644 index 0000000..e535a52 --- /dev/null +++ b/Editor/EditorAddons.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2723479bb55b0c147952fbbce94104cb +timeCreated: 1660519157 \ No newline at end of file diff --git a/Editor/EditorAddons/Comparers.meta b/Editor/EditorAddons/Comparers.meta new file mode 100644 index 0000000..662de5d --- /dev/null +++ b/Editor/EditorAddons/Comparers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 40cad780ba9c4d0ea211a433afc6ba6d +timeCreated: 1712746562 \ No newline at end of file diff --git a/Editor/EditorAddons/Comparers/AnyTypeComparer.cs b/Editor/EditorAddons/Comparers/AnyTypeComparer.cs new file mode 100644 index 0000000..d2bde4b --- /dev/null +++ b/Editor/EditorAddons/Comparers/AnyTypeComparer.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using Better.Commons.Runtime.Comparers; + +namespace Better.Attributes.EditorAddons.Comparers +{ + public class AnyTypeComparer : BaseComparer, IEqualityComparer + { + public bool Equals(Type x, Type y) + { + if (ReferenceEquals(x, y)) return true; + if (ReferenceEquals(x, null)) return false; + if (ReferenceEquals(y, null)) return false; + if (x.IsAssignableFrom(y) || x == y) return true; + return x == typeof(Type); + } + + public int GetHashCode(Type obj) + { + return 0; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Comparers/AnyTypeComparer.cs.meta b/Editor/EditorAddons/Comparers/AnyTypeComparer.cs.meta new file mode 100644 index 0000000..4fe7f74 --- /dev/null +++ b/Editor/EditorAddons/Comparers/AnyTypeComparer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 10f26e1cb5a34f2f87ecfbe79cad1cd2 +timeCreated: 1690411633 \ No newline at end of file diff --git a/Editor/EditorAddons/CustomEditors.meta b/Editor/EditorAddons/CustomEditors.meta new file mode 100644 index 0000000..6098b09 --- /dev/null +++ b/Editor/EditorAddons/CustomEditors.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c11fea05982447bb840a231134b6b14f +timeCreated: 1682216202 \ No newline at end of file diff --git a/Editor/EditorAddons/CustomEditors/ButtonsEditor.cs b/Editor/EditorAddons/CustomEditors/ButtonsEditor.cs new file mode 100644 index 0000000..2bebc90 --- /dev/null +++ b/Editor/EditorAddons/CustomEditors/ButtonsEditor.cs @@ -0,0 +1,108 @@ +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Better.Attributes.Runtime; +using Better.Commons.EditorAddons.CustomEditors.Attributes; +using Better.Commons.EditorAddons.CustomEditors.Base; +using Better.Commons.EditorAddons.Extensions; +using Better.Commons.EditorAddons.Utility; +using Better.Commons.Runtime.Extensions; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; +using Object = UnityEngine.Object; + +namespace Better.Attributes.EditorAddons.CustomEditors +{ + [MultiEditor(typeof(Object), true, Order = 999)] + public class ButtonsEditor : ExtendedEditor + { + private Dictionary>> _methodButtonsAttributes = + new Dictionary>>(); + + public ButtonsEditor(Object target, SerializedObject serializedObject) : base(target, serializedObject) + { + } + + public override void OnDisable() + { + } + + public override void OnEnable() + { + var type = _target.GetType(); + _methodButtonsAttributes = EditorButtonUtility.GetSortedMethodAttributes(type); + } + + private Button DrawButton(MethodInfo methodInfo, EditorButtonAttribute attribute) + { + var button = new Button + { + text = attribute.GetDisplayName(methodInfo.PrettyMemberName()), + name = methodInfo.PrettyMemberName() + }; + button.style.FlexGrow(StyleDefinition.OneStyleFloat); + button.RegisterCallback(OnClick, (methodInfo, attribute)); + return button; + } + + private void OnClick(ClickEvent clickEvent, (MethodInfo methodInfo, EditorButtonAttribute attribute) data) + { + _serializedObject.Update(); + data.methodInfo.Invoke(_target, data.attribute.InvokeParams); + EditorUtility.SetDirty(_target); + _serializedObject.ApplyModifiedProperties(); + } + + + private VisualElement DrawButtons(Dictionary>> buttons) + { + var container = new VisualElement(); + + foreach (var button in buttons) + { + if (button.Key == -1) + { + var grouped = button.Value.GroupBy(key => key.Key, pair => pair.Value, + (info, attributes) => new KeyValuePair>(info, attributes)); + var verticalElement = VisualElementUtility.CreateVerticalGroup(); + container.Add(verticalElement); + + foreach (var group in grouped) + { + var horizontalElement = VisualElementUtility.CreateHorizontalGroup(); + verticalElement.Add(horizontalElement); + + foreach (var attribute in group.Value) + { + var buttonElement = DrawButton(group.Key, attribute); + horizontalElement.Add(buttonElement); + } + } + } + else + { + var horizontalElement = VisualElementUtility.CreateHorizontalGroup(); + container.Add(horizontalElement); + foreach (var (key, value) in button.Value) + { + var element = DrawButton(key, value); + horizontalElement.Add(element); + } + } + } + + return container; + } + + public override VisualElement CreateInspectorGUI() + { + var buttons = DrawButtons(_methodButtonsAttributes); + return buttons; + } + + public override void OnChanged(SerializedObject serializedObject) + { + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/CustomEditors/ButtonsEditor.cs.meta b/Editor/EditorAddons/CustomEditors/ButtonsEditor.cs.meta new file mode 100644 index 0000000..c24b446 --- /dev/null +++ b/Editor/EditorAddons/CustomEditors/ButtonsEditor.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 20f290ac9e7e12c47bbd79e0db963b19 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/EditorAddons/CustomEditors/GizmosEditor.cs b/Editor/EditorAddons/CustomEditors/GizmosEditor.cs new file mode 100644 index 0000000..08a6e7c --- /dev/null +++ b/Editor/EditorAddons/CustomEditors/GizmosEditor.cs @@ -0,0 +1,76 @@ +using System.Reflection; +using Better.Attributes.EditorAddons.Drawers.Gizmo; +using Better.Attributes.Runtime.Gizmo; +using Better.Commons.EditorAddons.CustomEditors.Attributes; +using Better.Commons.EditorAddons.CustomEditors.Base; +using Better.Commons.EditorAddons.Extensions; +using UnityEditor; +using UnityEngine; +using UnityEngine.UIElements; + +namespace Better.Attributes.EditorAddons.CustomEditors +{ + [MultiEditor(typeof(Object), true, Order = -999)] + public class GizmosEditor : ExtendedEditor + { + private HideTransformButtonHelper _hideTransformHelper; + + public GizmosEditor(Object target, SerializedObject serializedObject) : base(target, serializedObject) + { + } + + public override void OnDisable() + { + } + + public override void OnEnable() + { + CheckAttribute(); + } + + private void CheckAttribute() + { + var attributeFound = IsAttributeFound(); + + if (attributeFound && !(_serializedObject.targetObject is ScriptableObject)) + { + _hideTransformHelper = new HideTransformButtonHelper(); + } + } + + private bool IsAttributeFound() + { + var iterator = _serializedObject.GetIterator().Copy(); + var attributeFound = false; + while (iterator.Next(true)) + { + var data = iterator.GetFieldInfoAndStaticTypeFromProperty(); + if (data == null) + { + continue; + } + + if (data.FieldInfo.GetCustomAttribute() == null && data.FieldInfo.GetCustomAttribute() == null) continue; + attributeFound = true; + break; + } + + return attributeFound; + } + + public override VisualElement CreateInspectorGUI() + { + if (_hideTransformHelper != null) + { + return _hideTransformHelper.DrawHideTransformButton(); + } + + return null; + } + + public override void OnChanged(SerializedObject serializedObject) + { + CheckAttribute(); + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/CustomEditors/GizmosEditor.cs.meta b/Editor/EditorAddons/CustomEditors/GizmosEditor.cs.meta new file mode 100644 index 0000000..d1bb368 --- /dev/null +++ b/Editor/EditorAddons/CustomEditors/GizmosEditor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 60771ff3ebf349c2b83d7c4ec8066d93 +timeCreated: 1682216447 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers.meta b/Editor/EditorAddons/Drawers.meta new file mode 100644 index 0000000..917593d --- /dev/null +++ b/Editor/EditorAddons/Drawers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c7b3ee0692f058e44ae1b3acaa3db300 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/EditorAddons/Drawers/Decorators.meta b/Editor/EditorAddons/Drawers/Decorators.meta new file mode 100644 index 0000000..5a5b5d7 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 04e4655c8a5c8d24eaabe0e30685e4bf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Editor/EditorAddons/Drawers/Decorators/IconHeaderDrawer.cs b/Editor/EditorAddons/Drawers/Decorators/IconHeaderDrawer.cs new file mode 100644 index 0000000..e573524 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/IconHeaderDrawer.cs @@ -0,0 +1,40 @@ +using Better.Attributes.Runtime.Headers; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Decorators +{ + [CustomPropertyDrawer(typeof(IconHeaderAttribute))] + internal sealed class IconHeaderDrawer : DecoratorDrawer + { + private Texture _loadedTexture; + private float _height; + + public override void OnGUI(Rect position) + { + position.yMin += EditorGUIUtility.singleLineHeight * 0.5f; + position = EditorGUI.IndentedRect(position); + if (!(attribute is IconHeaderAttribute iconHeaderAttribute)) return; + if (_loadedTexture == null) + { + var path = AssetDatabase.GUIDToAssetPath(iconHeaderAttribute.Guid); + _loadedTexture = AssetDatabase.LoadAssetAtPath(path); + } + + var texture = (Texture)Texture2D.whiteTexture; + if (_loadedTexture != null) + { + texture = _loadedTexture; + } + + var imageAspect = texture.width / (float)texture.height; + _height = EditorGUIUtility.currentViewWidth / imageAspect; + GUI.DrawTexture(position, texture, ScaleMode.ScaleToFit, iconHeaderAttribute.UseTransparency, imageAspect); + } + + public override float GetHeight() + { + return _height; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/IconHeaderDrawer.cs.meta b/Editor/EditorAddons/Drawers/Decorators/IconHeaderDrawer.cs.meta new file mode 100644 index 0000000..4f29576 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/IconHeaderDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cb4b39f0ce6741e7b52f95bf84b29927 +timeCreated: 1667430858 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/PrefabHeaderDrawer.cs b/Editor/EditorAddons/Drawers/Decorators/PrefabHeaderDrawer.cs new file mode 100644 index 0000000..d9995bc --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/PrefabHeaderDrawer.cs @@ -0,0 +1,22 @@ +using Better.Attributes.Runtime.Headers; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Decorators +{ + [CustomPropertyDrawer(typeof(PrefabHeaderAttribute))] + internal sealed class PrefabHeaderDrawer : DecoratorDrawer + { + public override void OnGUI(Rect position) + { + position.yMin += EditorGUIUtility.singleLineHeight * 0.5f; + position = EditorGUI.IndentedRect(position); + GUI.Label(position, (attribute as HeaderAttribute)?.header, EditorStyles.boldLabel); + } + + public override float GetHeight() + { + return EditorGUIUtility.singleLineHeight * 1.5f; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/PrefabHeaderDrawer.cs.meta b/Editor/EditorAddons/Drawers/Decorators/PrefabHeaderDrawer.cs.meta new file mode 100644 index 0000000..d1078e1 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/PrefabHeaderDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 64a67f7a51654ce42a6d03f440f9b2de +timeCreated: 1615412215 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/ReferencesHeaderDrawer.cs b/Editor/EditorAddons/Drawers/Decorators/ReferencesHeaderDrawer.cs new file mode 100644 index 0000000..4ef5af1 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/ReferencesHeaderDrawer.cs @@ -0,0 +1,22 @@ +using Better.Attributes.Runtime.Headers; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Decorators +{ + [CustomPropertyDrawer(typeof(ReferencesHeaderAttribute))] + internal sealed class ReferencesHeaderDrawer : DecoratorDrawer + { + public override void OnGUI(Rect position) + { + position.yMin += EditorGUIUtility.singleLineHeight * 0.5f; + position = EditorGUI.IndentedRect(position); + GUI.Label(position, (attribute as HeaderAttribute)?.header, EditorStyles.boldLabel); + } + + public override float GetHeight() + { + return EditorGUIUtility.singleLineHeight * 1.5f; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/ReferencesHeaderDrawer.cs.meta b/Editor/EditorAddons/Drawers/Decorators/ReferencesHeaderDrawer.cs.meta new file mode 100644 index 0000000..3fc760d --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/ReferencesHeaderDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 32123521c290f43408c8ea980800d659 +timeCreated: 1615208046 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/SettingsHeaderDrawer.cs b/Editor/EditorAddons/Drawers/Decorators/SettingsHeaderDrawer.cs new file mode 100644 index 0000000..8077e3e --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/SettingsHeaderDrawer.cs @@ -0,0 +1,22 @@ +using Better.Attributes.Runtime.Headers; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Decorators +{ + [CustomPropertyDrawer(typeof(SettingsHeaderAttribute))] + internal sealed class SettingsHeaderDrawer : DecoratorDrawer + { + public override void OnGUI(Rect position) + { + position.yMin += EditorGUIUtility.singleLineHeight * 0.5f; + position = EditorGUI.IndentedRect(position); + GUI.Label(position, (attribute as HeaderAttribute)?.header, EditorStyles.boldLabel); + } + + public override float GetHeight() + { + return EditorGUIUtility.singleLineHeight * 1.5f; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/SettingsHeaderDrawer.cs.meta b/Editor/EditorAddons/Drawers/Decorators/SettingsHeaderDrawer.cs.meta new file mode 100644 index 0000000..1209be3 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/SettingsHeaderDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7e3f9c32c859a894d9bf81a83f5ce400 +timeCreated: 1615208046 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/StateHeaderDrawer.cs b/Editor/EditorAddons/Drawers/Decorators/StateHeaderDrawer.cs new file mode 100644 index 0000000..7cc7bc0 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/StateHeaderDrawer.cs @@ -0,0 +1,22 @@ +using Better.Attributes.Runtime.Headers; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Decorators +{ + [CustomPropertyDrawer(typeof(StateHeaderAttribute))] + internal sealed class StateHeaderDrawer : DecoratorDrawer + { + public override void OnGUI(Rect position) + { + position.yMin += EditorGUIUtility.singleLineHeight * 0.5f; + position = EditorGUI.IndentedRect(position); + GUI.Label(position, (attribute as HeaderAttribute)?.header, EditorStyles.boldLabel); + } + + public override float GetHeight() + { + return EditorGUIUtility.singleLineHeight * 1.5f; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Decorators/StateHeaderDrawer.cs.meta b/Editor/EditorAddons/Drawers/Decorators/StateHeaderDrawer.cs.meta new file mode 100644 index 0000000..864084a --- /dev/null +++ b/Editor/EditorAddons/Drawers/Decorators/StateHeaderDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 05948c980b372404aa9324e4da1f4d04 +timeCreated: 1615208046 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/DrawInspector.meta b/Editor/EditorAddons/Drawers/DrawInspector.meta new file mode 100644 index 0000000..fd4b896 --- /dev/null +++ b/Editor/EditorAddons/Drawers/DrawInspector.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9dceb237d6e34604985064ad89d91bc6 +timeCreated: 1667575991 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorDrawer.cs b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorDrawer.cs new file mode 100644 index 0000000..9482685 --- /dev/null +++ b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorDrawer.cs @@ -0,0 +1,60 @@ +using Better.Attributes.Runtime.DrawInspector; +using Better.Commons.EditorAddons.Drawers; +using Better.Commons.EditorAddons.Drawers.Container; +using Better.Commons.EditorAddons.Enums; +using Better.Commons.EditorAddons.Extensions; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine.UIElements; + +namespace Better.Attributes.EditorAddons.Drawers.DrawInspector +{ + [CustomPropertyDrawer(typeof(DrawInspectorAttribute), true)] + public class DrawInspectorDrawer : BasePropertyDrawer + { + protected override void PopulateContainer(ElementsContainer container) + { + var fieldType = GetFieldOrElementType(); + var property = container.SerializedProperty; + if (!TypeHandlersBinder.IsSupported(fieldType)) + { + container.AddNotSupportedBox(fieldType, Attribute.GetType()); + return; + } + + container.SerializedPropertyChanged += OnPropertyChanged; + var handler = GetHandler(property); + + var inspectorElement = handler.GetInspectorContainer(property); + container.CreateElementFrom(inspectorElement); + handler.SetupInspector(); + + var isOpen = handler.IsOpen(); + handler.SetOpen(isOpen); + var iconType = isOpen ? IconType.Minus : IconType.PlusMore; + container.AddClickableIcon(iconType, property, OnIconClickEvent); + } + + private void OnPropertyChanged(ElementsContainer elementsContainer) + { + var handler = GetHandler(elementsContainer.SerializedProperty); + handler.SetupInspector(); + } + + private void OnIconClickEvent(ClickEvent clickEvent, (SerializedProperty property, Image icon) data) + { + UpdateState(data.property, data.icon); + } + + private void UpdateState(SerializedProperty property, Image icon) + { + var handler = GetHandler(property); + if (!handler.CanOpen()) return; + var isOpen = !handler.IsOpen(); + + var iconType = isOpen ? IconType.Minus : IconType.PlusMore; + icon.image = iconType.GetIcon(); + handler.SetOpen(isOpen); + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorDrawer.cs.meta b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorDrawer.cs.meta new file mode 100644 index 0000000..2740eb4 --- /dev/null +++ b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorDrawer.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fbe272ec2b9d4fd5a507d2dee1b84d09 +timeCreated: 1667575999 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorHandler.cs b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorHandler.cs new file mode 100644 index 0000000..13a206e --- /dev/null +++ b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorHandler.cs @@ -0,0 +1,98 @@ +using System; +using Better.Commons.EditorAddons.Drawers.Handlers; +using Better.Commons.EditorAddons.Extensions; +using Better.Commons.EditorAddons.Utility; +using Better.Commons.Runtime.Extensions; +using Better.Commons.Runtime.Utility; +using UnityEditor; +using UnityEditor.UIElements; +using UnityEngine.UIElements; + +namespace Better.Attributes.EditorAddons.Drawers.DrawInspector +{ + [Serializable] + public class DrawInspectorHandler : SerializedPropertyHandler + { + private SerializedProperty _property; + private bool _isOpen = false; + private VisualElement _rootElement; + + public DrawInspectorHandler() + { + _rootElement = new VisualElement(); + } + + private void UpdateVisible(VisualElement editorElement) + { + editorElement.style.SetVisible(_isOpen); + } + + public void SetOpen(bool value) + { + _isOpen = value; + UpdateVisible(_rootElement); + ReorderableListUtility.RepaintAllInspectors(_property); + } + + public bool IsOpen() + { + return _isOpen; + } + + public VisualElement GetInspectorContainer(SerializedProperty property) + { + if (property == null) + { + DebugUtility.LogException(nameof(property)); + return null; + } + + _property = property; + return _rootElement; + } + + public void SetupInspector() + { + _rootElement.Clear(); + + if (_property == null || _property.IsDisposed()) + { + DebugUtility.LogException(new ObjectDisposedException(nameof(_property))); + return; + } + + var referenceValue = _property.objectReferenceValue; + if (referenceValue == null) + { + return; + } + + var inspectorElement = new InspectorElement(_property.objectReferenceValue); + UpdateVisible(_rootElement); + _rootElement.Add(inspectorElement); + _rootElement.style.PaddingLeft(StyleDefinition.IndentLevelPadding); + } + + public bool CanOpen() + { + if (_property == null || _property.IsDisposed()) + { + DebugUtility.LogException(new ObjectDisposedException(nameof(_property))); + return false; + } + + var referenceValue = _property.objectReferenceValue; + if (referenceValue == null) + { + return false; + } + + return true; + } + + public override void Deconstruct() + { + _property = null; + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorHandler.cs.meta b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorHandler.cs.meta new file mode 100644 index 0000000..b1fae42 --- /dev/null +++ b/Editor/EditorAddons/Drawers/DrawInspector/DrawInspectorHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 48969434f0bb46f696016b5ba2b0dfac +timeCreated: 1667588521 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo.meta b/Editor/EditorAddons/Drawers/Gizmo.meta new file mode 100644 index 0000000..c514f7a --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8890807caef9ccb40a280c75a5ca62fc +timeCreated: 1658860908 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers.meta b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers.meta new file mode 100644 index 0000000..49fe016 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f3c4803dca2d276438110209d7242797 +timeCreated: 1658880022 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/BoundsBaseHandler.cs b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/BoundsBaseHandler.cs new file mode 100644 index 0000000..a66bc11 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/BoundsBaseHandler.cs @@ -0,0 +1,42 @@ +using System; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Gizmo +{ + public abstract class BoundsBaseHandler : GizmoHandler + { + private protected Bounds _previousValue; + + private protected Vector3 DrawSize(Vector3 position) + { + return Handles.ScaleHandle(_previousValue.size, position, Quaternion.identity, + HandleUtility.GetHandleSize(position) * 0.7f); + } + + private protected void ValidateSize(Vector3 size) + { + for (int i = 0; i < 3; i++) + { + if (size[i] <= 0) + { + var boundsSize = size; + boundsSize[i] = 0.01f; + size = boundsSize; + } + } + } + + public override void SetProperty(SerializedProperty property, Type fieldType) + { + _previousValue = property.boundsValue; + base.SetProperty(property, fieldType); + + if (_previousValue.size == Vector3.zero) + { + _previousValue.size = Vector3.one / 10f; + SetValueAndApply(_previousValue); + } + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/BoundsBaseHandler.cs.meta b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/BoundsBaseHandler.cs.meta new file mode 100644 index 0000000..775e4dc --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/BoundsBaseHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cf1af38cb749f054eb8c583c25b645c6 +timeCreated: 1658879902 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/GizmoHandler.cs b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/GizmoHandler.cs new file mode 100644 index 0000000..d758855 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/GizmoHandler.cs @@ -0,0 +1,132 @@ +using System; +using Better.Commons.EditorAddons.Drawers.Handlers; +using Better.Commons.EditorAddons.Extensions; +using Better.Commons.Runtime.Utility; +using UnityEditor; +using UnityEngine; + +namespace Better.Attributes.EditorAddons.Drawers.Gizmo +{ + public abstract class GizmoHandler : SerializedPropertyHandler + { + private protected SerializedProperty _serializedProperty; + + private protected readonly Quaternion _defaultRotation = Quaternion.identity; + private protected readonly Vector3 _defaultPosition = Vector3.zero; + private Type _fieldType; + + private string _compiledName; + + public bool ShowInSceneView { get; private set; } + + public virtual void SetProperty(SerializedProperty property, Type fieldType) + { + _serializedProperty = property; + _fieldType = fieldType; + _compiledName = GetCompiledName(); + ShowInSceneView = true; + } + + private string GetCompiledName() + { + if (Validate()) + { + if (_serializedProperty.IsArrayElement()) + { + return $"{ObjectNames.NicifyVariableName(_serializedProperty.GetArrayPath())}"; + } + + return _serializedProperty.displayName; + } + + return string.Empty; + } + + public void SetMode(bool value) + { + ShowInSceneView = value; + } + + public abstract void Apply(SceneView sceneView); + + private protected virtual string GetName() + { + return _compiledName; + } + + public override void Deconstruct() + { + _serializedProperty = null; + } + + public virtual bool Validate() + { + try + { + if (_serializedProperty == null) + { + return false; + } + + if (!_serializedProperty.Verify()) + { + return false; + } + + if (_serializedProperty.IsDisposed()) + { + return false; + } + + return _serializedProperty.serializedObject.targetObject != null; + } + catch + { + return false; + } + } + + private protected void SetValueAndApply(object value) + { + if (!Validate()) + { + return; + } + + if (_fieldType.IsEquivalentTo(typeof(Vector2))) + _serializedProperty.vector2Value = (Vector2)value; + else if (_fieldType.IsEquivalentTo(typeof(Vector3))) + _serializedProperty.vector3Value = (Vector3)value; + else if (_fieldType.IsEquivalentTo(typeof(Bounds))) + _serializedProperty.boundsValue = (Bounds)value; + else if (_fieldType.IsEquivalentTo(typeof(Quaternion))) + _serializedProperty.quaternionValue = (Quaternion)value; + else + DebugUtility.LogException(); + + _serializedProperty.serializedObject.ApplyModifiedProperties(); + } + + private protected virtual void DrawLabel(string value, Vector3 position, Quaternion rotation, SceneView sceneView) + { + var style = new GUIStyle + { + normal = + { + textColor = Color.green + } + }; + + + var vector3 = GetPosition(position, rotation, sceneView); + + Handles.Label(vector3, value, style); + } + + private protected virtual Vector3 GetPosition(Vector3 position, Quaternion rotation, SceneView sceneView) + { + return rotation * (position + Vector3.up * HandleUtility.GetHandleSize(position) + + sceneView.camera.transform.right * 0.2f * HandleUtility.GetHandleSize(position)); + } + } +} \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/GizmoHandler.cs.meta b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/GizmoHandler.cs.meta new file mode 100644 index 0000000..592aee4 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo/BaseHandlers/GizmoHandler.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: db61636d913e6bc4ab6a4ce56dfcd915 +timeCreated: 1658865058 \ No newline at end of file diff --git a/Editor/EditorAddons/Drawers/Gizmo/GizmoDrawer.cs b/Editor/EditorAddons/Drawers/Gizmo/GizmoDrawer.cs new file mode 100644 index 0000000..cf13697 --- /dev/null +++ b/Editor/EditorAddons/Drawers/Gizmo/GizmoDrawer.cs @@ -0,0 +1,128 @@ +using System.Collections.Generic; +using Better.Attributes.Runtime.Gizmo; +using Better.Commons.EditorAddons.Comparers; +using Better.Commons.EditorAddons.Drawers; +using Better.Commons.EditorAddons.Drawers.BehavioredElements; +using Better.Commons.EditorAddons.Drawers.Container; +using Better.Commons.EditorAddons.Extensions; +using Better.Commons.EditorAddons.Utility; +using UnityEditor; +using UnityEngine.UIElements; + +namespace Better.Attributes.EditorAddons.Drawers.Gizmo +{ + [CustomPropertyDrawer(typeof(BaseGizmoAttribute), true)] + public class GizmoDrawer : BasePropertyDrawer + { + public const string Hide = "Hide"; + public const string Show = "Show"; + + private Dictionary> _behavioredElements; + + public GizmoDrawer() + { + EditorApplication.delayCall += DelayCall; + _behavioredElements = new Dictionary>(SerializedPropertyComparer.Instance); + } + + private void DelayCall() + { + EditorApplication.delayCall -= DelayCall; + SceneView.duringSceneGui += OnSceneGUIDelegate; + SceneView.RepaintAll(); + } + + private void OnSceneGUIDelegate(SceneView sceneView) + { + if (sceneView.drawGizmos) + { + ValidationUtility.ValidateCachedProperties(Handlers); + Apply(sceneView); + } + } + + private void Apply(SceneView sceneView) + { + List keysToRemove = null; + foreach (var gizmo in Handlers) + { + var valueWrapper = gizmo.Value.Handler; + if (valueWrapper.Validate()) + { + valueWrapper.Apply(sceneView); + } + else + { + if (keysToRemove == null) + { + keysToRemove = new List(); + } + + keysToRemove.Add(gizmo.Key); + } + } + + if (keysToRemove != null) + { + foreach (var property in keysToRemove) + { + Handlers.Remove(property); + } + } + } + + protected override void Deconstruct() + { + base.Deconstruct(); + SceneView.duringSceneGui -= OnSceneGUIDelegate; + } + + protected override void PopulateContainer(ElementsContainer container) + { + var fieldType = GetFieldOrElementType(); + var serializedProperty = container.SerializedProperty; + + if (!TypeHandlersBinder.IsSupported(fieldType)) + { + container.AddNotSupportedBox(fieldType, Attribute.GetType()); + return; + } + + var handler = GetHandler(serializedProperty); + handler.SetProperty(serializedProperty, fieldType); + + + if (!_behavioredElements.TryGetValue(serializedProperty, out var element)) + { + element = CreateBehavioredElement(serializedProperty); + _behavioredElements.Add(serializedProperty, element); + } + + var text = handler.ShowInSceneView ? Hide : Show; + element.SubElement.text = text; + element.Attach(container.RootElement); + } + + private void OnClicked(ClickEvent clickEvent, SerializedProperty property) + { + var handler = GetHandler(property); + handler.SetMode(!handler.ShowInSceneView); + if (!_behavioredElements.TryGetValue(property, out var element)) + { + element = CreateBehavioredElement(property); + _behavioredElements.Add(property, element); + } + + var text = handler.ShowInSceneView ? Hide : Show; + element.SubElement.text = text; + SceneView.RepaintAll(); + } + + private BehavioredElement