1.1.0: Added README and ToolbarSettings, so visibility of tools can be set in Preferences -> Module -> Toolbar

This commit is contained in:
Anders Ejlersen 2021-12-19 20:49:15 +01:00
parent e1d2deb4c5
commit 9802f8aaa3
23 changed files with 297 additions and 43 deletions

View file

@ -1,12 +1,13 @@
using Module.NavigationTool.Editor.Toolbar;
using UnityEngine;
using UnityEngine;
namespace Module.NavigationTool.Editor
namespace Module.NavigationTool.Editor.Toolbar
{
public abstract class AbstractToolbarDrawer
{
public abstract bool Visible { get; }
public abstract bool Enabled { get; }
public abstract EToolbarPlacement Placement { get; }
public abstract int Priority { get; }
private Rect rect;
protected Styles styles;
@ -18,7 +19,6 @@ namespace Module.NavigationTool.Editor
public virtual void Update()
{
}
public void OnGUI()

View file

@ -1,4 +1,4 @@
namespace Module.NavigationTool.Editor
namespace Module.NavigationTool.Editor.Toolbar
{
public enum EToolbarPlacement : byte
{

View file

@ -0,0 +1,9 @@
namespace Module.NavigationTool.Editor.Toolbar
{
public enum EToolbarPriority
{
Low,
Medium = 1000,
High = 2000
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 5ae525e780674292add7f50aef822261
timeCreated: 1639929153

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7718853c1abb499a9fd06d686c3624ed
timeCreated: 1639924155

View file

@ -0,0 +1,29 @@
using UnityEditor;
namespace Module.NavigationTool.Editor.Toolbar
{
internal static class ToolbarSettings
{
private const string PREF_IS_UI_ENABLED = "ToolbarSettings_IsUiEnabled";
private const string PREF_IS_UI_LAYER_ENABLED = "ToolbarSettings_IsUiLayerEnabled";
private const string PREF_IS_SCENE_ENABLED = "ToolbarSettings_IsSceneEnabled";
public static bool IsUiEnabled
{
get => EditorPrefs.GetBool(PREF_IS_UI_ENABLED, true);
set => EditorPrefs.SetBool(PREF_IS_UI_ENABLED, value);
}
public static bool IsUiLayerEnabled
{
get => EditorPrefs.GetBool(PREF_IS_UI_LAYER_ENABLED, true);
set => EditorPrefs.SetBool(PREF_IS_UI_LAYER_ENABLED, value);
}
public static bool IsSceneEnabled
{
get => EditorPrefs.GetBool(PREF_IS_SCENE_ENABLED, true);
set => EditorPrefs.SetBool(PREF_IS_SCENE_ENABLED, value);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ee57c1a04c9448e585e7e524886bdeda
timeCreated: 1639924440

View file

@ -0,0 +1,41 @@
using UnityEditor;
using UnityEngine;
namespace Module.NavigationTool.Editor.Toolbar
{
internal static class ToolbarSettingsProvider
{
private static Styles STYLES;
[SettingsProvider]
public static SettingsProvider GetProvider()
{
return new SettingsProvider("Module/Toolbar", SettingsScope.User)
{
label = "Toolbar",
keywords = new[] { "Scene", "UI", "Toolbar" },
guiHandler = OnGui
};
}
private static void OnGui(string searchContext)
{
if (STYLES == null)
STYLES = new Styles();
STYLES.Initialize((GUI.skin));
EditorGUILayout.BeginVertical(STYLES.settingsGroup);
{
EditorGUILayout.LabelField("UI", EditorStyles.boldLabel);
ToolbarSettings.IsUiEnabled = EditorGUILayout.Toggle("Enable Canvas picker", ToolbarSettings.IsUiEnabled);
ToolbarSettings.IsUiLayerEnabled = EditorGUILayout.Toggle("Enable Layer toggle", ToolbarSettings.IsUiLayerEnabled);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Scene", EditorStyles.boldLabel);
ToolbarSettings.IsSceneEnabled = EditorGUILayout.Toggle("Enable Scene picker", ToolbarSettings.IsSceneEnabled);
}
EditorGUILayout.EndVertical();
}
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7254a01fd35a8c5499c07751fbd7d6fb
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -1,12 +1,12 @@
using Module.NavigationTool.Editor.Toolbar;
using UnityEditor;
using UnityEditor;
using UnityEngine;
#if UNITY_2021_1_OR_NEWER
using System.Collections.Generic;
using UnityEngine.UIElements;
#endif
namespace Module.NavigationTool.Editor
namespace Module.NavigationTool.Editor.Toolbar
{
[InitializeOnLoad]
internal static class ToolbarDrawer
@ -14,6 +14,10 @@ namespace Module.NavigationTool.Editor
private static bool IS_INITIALIZED;
private static AbstractToolbarDrawer[] DRAWERS;
#if UNITY_2021_1_OR_NEWER
private static readonly Dictionary<AbstractToolbarDrawer, IMGUIContainer> DICT_MAPPING = new Dictionary<AbstractToolbarDrawer, IMGUIContainer>();
#endif
static ToolbarDrawer()
{
EditorApplication.update -= OnEditorUpdate;
@ -26,40 +30,93 @@ namespace Module.NavigationTool.Editor
{
DRAWERS = ToolbarUtility.GetAllDrawers();
#if UNITY_2021_1_OR_NEWER
ToolbarUtility.OnUpdate(OnCreateElements);
#else
#if !UNITY_2021_1_OR_NEWER
ToolbarUtility.AddGuiListener(OnGUI);
#endif
IS_INITIALIZED = true;
}
#if UNITY_2021_1_OR_NEWER
ToolbarUtility.OnUpdate(OnUpdateElements);
#endif
for (var i = 0; i < DRAWERS.Length; i++)
{
DRAWERS[i].Update();
if (DRAWERS[i].Visible)
DRAWERS[i].Update();
}
}
#if UNITY_2021_1_OR_NEWER
private static void OnCreateElements(VisualElement leftAlign, VisualElement rightAlign)
private static void OnUpdateElements(VisualElement leftAlign, VisualElement rightAlign)
{
const float HEIGHT = 22.0f;
var added = false;
for (int i = DRAWERS.Length - 1; i >= 0; i--)
{
AbstractToolbarDrawer drawer = DRAWERS[i];
var rect = new Rect(0.0f, 0.0f, drawer.CalculateWidth(), HEIGHT);
drawer.Setup(rect);
bool valid = CheckValidityOfContainer(drawer, leftAlign, rightAlign);
var container = new IMGUIContainer(drawer.OnGUI);
container.style.width = rect.width;
if (drawer.Visible && !valid)
{
var rect = new Rect(0.0f, 0.0f, drawer.CalculateWidth(), HEIGHT);
drawer.Setup(rect);
if (drawer.Placement == EToolbarPlacement.Left)
leftAlign.Add(container);
else
rightAlign.Add(container);
var container = new ToolbarIMGUIContainer(drawer.OnGUI, drawer.Priority);
container.style.width = rect.width;
DICT_MAPPING.Add(drawer, container);
added = true;
if (drawer.Placement == EToolbarPlacement.Left)
leftAlign.Add(container);
else
rightAlign.Add(container);
}
else if (!drawer.Visible && valid)
{
IMGUIContainer container = DICT_MAPPING[drawer];
DICT_MAPPING.Remove(drawer);
container.RemoveFromHierarchy();
}
}
if (added)
{
leftAlign.Sort(SortVisualElements);
rightAlign.Sort(SortVisualElements);
}
}
private static bool CheckValidityOfContainer(AbstractToolbarDrawer drawer, VisualElement leftAlign, VisualElement rightAlign)
{
if (!DICT_MAPPING.TryGetValue(drawer, out IMGUIContainer container))
return false;
bool valid = drawer.Placement == EToolbarPlacement.Left
? leftAlign.Contains(container)
: rightAlign.Contains(container);
if (!valid)
DICT_MAPPING.Remove(drawer);
return valid;
}
private static int SortVisualElements(VisualElement ve0, VisualElement ve1)
{
var c0 = ve0 as ToolbarIMGUIContainer;
var c1 = ve1 as ToolbarIMGUIContainer;
if (c0 == null && c1 == null)
return 0;
if (c0 == null)
return -1;
if (c1 == null)
return 1;
return c0.Priority.CompareTo(c1.Priority);
}
#else
private static void OnGUI()
@ -80,6 +137,9 @@ namespace Module.NavigationTool.Editor
{
AbstractToolbarDrawer drawer = DRAWERS[i];
if (!drawer.Visible)
continue;
GUI.enabled = drawer.Enabled;
float width = drawer.CalculateWidth();

View file

@ -6,13 +6,15 @@ using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace Module.NavigationTool.Editor.Tools
namespace Module.NavigationTool.Editor.Toolbar
{
[UsedImplicitly]
internal sealed class ToolScenePicker : AbstractToolbarDrawer
{
public override bool Visible => ToolbarSettings.IsSceneEnabled;
public override bool Enabled => !EditorApplication.isPlaying && !EditorApplication.isPlayingOrWillChangePlaymode;
public override EToolbarPlacement Placement => EToolbarPlacement.Right;
public override int Priority => (int)EToolbarPriority.Medium;
private static bool IS_DIRTY = true;
private static int SELECTED_INDEX = -1;

View file

@ -1,5 +1,4 @@
using Module.NavigationTool.Editor.Tools;
using UnityEditor;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;

View file

@ -1,5 +1,4 @@
using System.Linq;
using Module.NavigationTool.Editor.Tools;
using UnityEditor;
namespace Module.NavigationTool.Editor.Toolbar

View file

@ -11,13 +11,15 @@ using UnityEditor.SceneManagement;
using UnityEditor.Experimental.SceneManagement;
#endif
namespace Module.NavigationTool.Editor.Tools
namespace Module.NavigationTool.Editor.Toolbar
{
[UsedImplicitly]
internal sealed class ToolUICanvasPicker : AbstractToolbarDrawer
{
public override bool Visible => ToolbarSettings.IsUiEnabled;
public override bool Enabled => (UTools.visibleLayers & (1 << LayerMask.NameToLayer("UI"))) != 0;
public override EToolbarPlacement Placement => EToolbarPlacement.Left;
public override int Priority => (int)EToolbarPriority.Medium;
private static bool IS_DIRTY = true;
private static string[] OPTIONS = new string[0];
@ -62,7 +64,8 @@ namespace Module.NavigationTool.Editor.Tools
protected override void Draw(Rect rect)
{
// Note: To fix an issue, where instantiated canvases wouldn't be detected, due to no events for canvas additions/removals exist in Unity API (at the moment)
// Note: To fix an issue, where instantiated canvases wouldn't be detected, due to no events for canvas
// additions/removals exist in Unity API (at the moment)
if (Event.current.type == EventType.MouseDown)
{
IS_DIRTY = true;

View file

@ -1,5 +1,4 @@
using Module.NavigationTool.Editor.Tools;
using UnityEditor;
using UnityEditor;
using UnityEditor.Experimental.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEngine.SceneManagement;

View file

@ -3,13 +3,15 @@ using UnityEditor;
using UnityEngine;
using UTools = UnityEditor.Tools;
namespace Module.NavigationTool.Editor.Tools
namespace Module.NavigationTool.Editor.Toolbar
{
[UsedImplicitly]
internal sealed class ToolUILayerToggle : AbstractToolbarDrawer
{
public override bool Visible => ToolbarSettings.IsUiLayerEnabled;
public override bool Enabled => true;
public override EToolbarPlacement Placement => EToolbarPlacement.Left;
public override int Priority => (int)EToolbarPriority.Medium - 1;
protected override void Draw(Rect rect)
{

View file

@ -9,7 +9,7 @@ namespace Module.NavigationTool.Editor.Toolbar
public GUIStyle slider;
public GUIStyle label;
public GUIStyle labelCenter;
public GUIStyle settingsGroup;
private GUISkin skin;
public void Initialize(GUISkin skin)
@ -24,6 +24,10 @@ namespace Module.NavigationTool.Editor.Toolbar
label = skin.FindStyle("ToolbarLabel");
labelCenter = skin.FindStyle("ToolbarLabel");
labelCenter.alignment = TextAnchor.MiddleCenter;
settingsGroup = new GUIStyle
{
margin = new RectOffset(8, 0, 8, 0)
};
// Available: ToolbarBoldLabel, ToolbarBottom, ToolbarButtonLeft, ToolbarButtonRight, ToolbarDropDown,
// ToolbarLabel, ToolbarTextField, ...

View file

@ -0,0 +1,16 @@
using System;
using UnityEngine.UIElements;
namespace Module.NavigationTool.Editor.Toolbar
{
internal sealed class ToolbarIMGUIContainer : IMGUIContainer
{
public int Priority { get; }
public ToolbarIMGUIContainer(Action onGuiHandler, int priority)
: base(onGuiHandler)
{
Priority = priority;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 33569aa7bb974bd19b2208063bd64e95
timeCreated: 1639929711

View file

@ -41,19 +41,24 @@ namespace Module.NavigationTool.Editor.Toolbar
CURRENT_INSTANCE_ID = CURRENT_TOOLBAR.GetInstanceID();
}
if (CURRENT_TOOLBAR == null || CURRENT_PARENT_LEFT != null)
if (CURRENT_TOOLBAR == null)
return;
CURRENT_PARENT_LEFT?.RemoveFromHierarchy();
CURRENT_PARENT_RIGHT?.RemoveFromHierarchy();
if (CURRENT_PARENT_LEFT == null)
{
CURRENT_PARENT_LEFT?.RemoveFromHierarchy();
CURRENT_PARENT_RIGHT?.RemoveFromHierarchy();
FieldInfo root = CURRENT_TOOLBAR.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
object rawRoot = root?.GetValue(CURRENT_TOOLBAR);
var mRoot = rawRoot as VisualElement;
FieldInfo root = CURRENT_TOOLBAR.GetType().GetField("m_Root", BindingFlags.NonPublic | BindingFlags.Instance);
object rawRoot = root?.GetValue(CURRENT_TOOLBAR);
var mRoot = rawRoot as VisualElement;
CURRENT_PARENT_LEFT = CreateParent(mRoot, "ToolbarZoneLeftAlign", true);
CURRENT_PARENT_RIGHT = CreateParent(mRoot, "ToolbarZoneRightAlign", false);
callback?.Invoke(CURRENT_PARENT_LEFT, CURRENT_PARENT_RIGHT);
CURRENT_PARENT_LEFT = CreateParent(mRoot, "ToolbarZoneLeftAlign", true);
CURRENT_PARENT_RIGHT = CreateParent(mRoot, "ToolbarZoneRightAlign", false);
}
if (CURRENT_PARENT_LEFT != null)
callback?.Invoke(CURRENT_PARENT_LEFT, CURRENT_PARENT_RIGHT);
}
private static VisualElement CreateParent(VisualElement root, string query, bool isLeft)

60
README.md Normal file
View file

@ -0,0 +1,60 @@
# Description
This module contains a few helpful editor tools, like favorites, history and some handy toolbar tools.
## Favorites
An editor window, where you can pin folders and assets, so you can easily find the most used assets in your project.
## History
An editor window, where the history of all selected assets are shown. An asset in the window can be selected to easy get back to previous selections.
## Toolbar
Toolbars to the left and right of the play-buttons. Anything can be added, as long as it is supported by IMGUI.
### Default tools
Three tools are available from start:
* UI Layer: Toggle the UI layer on/off
* UI Canvas: Select and center the camera on any Canvases in the scene
* Scene: Load any scene in the project easily by using the dropdown
### Customization
You can create your own toolbar extensions by extending `AbstractToolbarDrawer`.
```
internal sealed class MyCustomTool : AbstractToolbarDrawer
{
public override bool Visible => true;
public override bool Enabled => true;
public override EToolbarPlacement Placement => EToolbarPlacement.Left;
public override int Priority => (int)EToolbarPriority.Medium;
protected override void Draw(Rect rect)
{
// Use IMGUI methods for drawing
}
public override float CalculateWidth()
{
// Default height for toolbar buttons is 30
return 30.0f;
}
}
```
The four properties help define draw and enable state:
* `Visible`: If it is visible in the toolbar
* `Enabled`: If it is enabled in the toolbar (`GUI.enabled`)
* `Placement`: If it is placed to the left or right of the play-buttons
* `Priority`: Sort order/priority, when drawing the tool

3
README.md.meta Normal file
View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: ada1af04766a4dcbaba125af58ec4c71
timeCreated: 1639942319

View file

@ -1,6 +1,6 @@
{
"name": "com.module.navigationtool",
"version": "1.0.2",
"version": "1.1.0",
"displayName": "Module.NavigationTool",
"description": "Support for navigation tools, like favorites, history and toolbars",
"unity": "2019.2",