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 class AbstractToolbarDrawer
{ {
public abstract bool Visible { get; }
public abstract bool Enabled { get; } public abstract bool Enabled { get; }
public abstract EToolbarPlacement Placement { get; } public abstract EToolbarPlacement Placement { get; }
public abstract int Priority { get; }
private Rect rect; private Rect rect;
protected Styles styles; protected Styles styles;
@ -18,7 +19,6 @@ namespace Module.NavigationTool.Editor
public virtual void Update() public virtual void Update()
{ {
} }
public void OnGUI() public void OnGUI()

View file

@ -1,4 +1,4 @@
namespace Module.NavigationTool.Editor namespace Module.NavigationTool.Editor.Toolbar
{ {
public enum EToolbarPlacement : byte 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; using UnityEngine;
#if UNITY_2021_1_OR_NEWER #if UNITY_2021_1_OR_NEWER
using System.Collections.Generic;
using UnityEngine.UIElements; using UnityEngine.UIElements;
#endif #endif
namespace Module.NavigationTool.Editor namespace Module.NavigationTool.Editor.Toolbar
{ {
[InitializeOnLoad] [InitializeOnLoad]
internal static class ToolbarDrawer internal static class ToolbarDrawer
@ -14,6 +14,10 @@ namespace Module.NavigationTool.Editor
private static bool IS_INITIALIZED; private static bool IS_INITIALIZED;
private static AbstractToolbarDrawer[] DRAWERS; 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() static ToolbarDrawer()
{ {
EditorApplication.update -= OnEditorUpdate; EditorApplication.update -= OnEditorUpdate;
@ -26,40 +30,93 @@ namespace Module.NavigationTool.Editor
{ {
DRAWERS = ToolbarUtility.GetAllDrawers(); DRAWERS = ToolbarUtility.GetAllDrawers();
#if UNITY_2021_1_OR_NEWER #if !UNITY_2021_1_OR_NEWER
ToolbarUtility.OnUpdate(OnCreateElements);
#else
ToolbarUtility.AddGuiListener(OnGUI); ToolbarUtility.AddGuiListener(OnGUI);
#endif #endif
IS_INITIALIZED = true; IS_INITIALIZED = true;
} }
#if UNITY_2021_1_OR_NEWER
ToolbarUtility.OnUpdate(OnUpdateElements);
#endif
for (var i = 0; i < DRAWERS.Length; i++) for (var i = 0; i < DRAWERS.Length; i++)
{ {
if (DRAWERS[i].Visible)
DRAWERS[i].Update(); DRAWERS[i].Update();
} }
} }
#if UNITY_2021_1_OR_NEWER #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; const float HEIGHT = 22.0f;
var added = false;
for (int i = DRAWERS.Length - 1; i >= 0; i--) for (int i = DRAWERS.Length - 1; i >= 0; i--)
{ {
AbstractToolbarDrawer drawer = DRAWERS[i]; AbstractToolbarDrawer drawer = DRAWERS[i];
bool valid = CheckValidityOfContainer(drawer, leftAlign, rightAlign);
if (drawer.Visible && !valid)
{
var rect = new Rect(0.0f, 0.0f, drawer.CalculateWidth(), HEIGHT); var rect = new Rect(0.0f, 0.0f, drawer.CalculateWidth(), HEIGHT);
drawer.Setup(rect); drawer.Setup(rect);
var container = new IMGUIContainer(drawer.OnGUI); var container = new ToolbarIMGUIContainer(drawer.OnGUI, drawer.Priority);
container.style.width = rect.width; container.style.width = rect.width;
DICT_MAPPING.Add(drawer, container);
added = true;
if (drawer.Placement == EToolbarPlacement.Left) if (drawer.Placement == EToolbarPlacement.Left)
leftAlign.Add(container); leftAlign.Add(container);
else else
rightAlign.Add(container); 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 #else
private static void OnGUI() private static void OnGUI()
@ -80,6 +137,9 @@ namespace Module.NavigationTool.Editor
{ {
AbstractToolbarDrawer drawer = DRAWERS[i]; AbstractToolbarDrawer drawer = DRAWERS[i];
if (!drawer.Visible)
continue;
GUI.enabled = drawer.Enabled; GUI.enabled = drawer.Enabled;
float width = drawer.CalculateWidth(); float width = drawer.CalculateWidth();

View file

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

View file

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

View file

@ -11,13 +11,15 @@ using UnityEditor.SceneManagement;
using UnityEditor.Experimental.SceneManagement; using UnityEditor.Experimental.SceneManagement;
#endif #endif
namespace Module.NavigationTool.Editor.Tools namespace Module.NavigationTool.Editor.Toolbar
{ {
[UsedImplicitly] [UsedImplicitly]
internal sealed class ToolUICanvasPicker : AbstractToolbarDrawer internal sealed class ToolUICanvasPicker : AbstractToolbarDrawer
{ {
public override bool Visible => ToolbarSettings.IsUiEnabled;
public override bool Enabled => (UTools.visibleLayers & (1 << LayerMask.NameToLayer("UI"))) != 0; public override bool Enabled => (UTools.visibleLayers & (1 << LayerMask.NameToLayer("UI"))) != 0;
public override EToolbarPlacement Placement => EToolbarPlacement.Left; public override EToolbarPlacement Placement => EToolbarPlacement.Left;
public override int Priority => (int)EToolbarPriority.Medium;
private static bool IS_DIRTY = true; private static bool IS_DIRTY = true;
private static string[] OPTIONS = new string[0]; private static string[] OPTIONS = new string[0];
@ -62,7 +64,8 @@ namespace Module.NavigationTool.Editor.Tools
protected override void Draw(Rect rect) 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) if (Event.current.type == EventType.MouseDown)
{ {
IS_DIRTY = true; IS_DIRTY = true;

View file

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

View file

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

View file

@ -9,7 +9,7 @@ namespace Module.NavigationTool.Editor.Toolbar
public GUIStyle slider; public GUIStyle slider;
public GUIStyle label; public GUIStyle label;
public GUIStyle labelCenter; public GUIStyle labelCenter;
public GUIStyle settingsGroup;
private GUISkin skin; private GUISkin skin;
public void Initialize(GUISkin skin) public void Initialize(GUISkin skin)
@ -24,6 +24,10 @@ namespace Module.NavigationTool.Editor.Toolbar
label = skin.FindStyle("ToolbarLabel"); label = skin.FindStyle("ToolbarLabel");
labelCenter = skin.FindStyle("ToolbarLabel"); labelCenter = skin.FindStyle("ToolbarLabel");
labelCenter.alignment = TextAnchor.MiddleCenter; labelCenter.alignment = TextAnchor.MiddleCenter;
settingsGroup = new GUIStyle
{
margin = new RectOffset(8, 0, 8, 0)
};
// Available: ToolbarBoldLabel, ToolbarBottom, ToolbarButtonLeft, ToolbarButtonRight, ToolbarDropDown, // Available: ToolbarBoldLabel, ToolbarBottom, ToolbarButtonLeft, ToolbarButtonRight, ToolbarDropDown,
// ToolbarLabel, ToolbarTextField, ... // 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,9 +41,11 @@ namespace Module.NavigationTool.Editor.Toolbar
CURRENT_INSTANCE_ID = CURRENT_TOOLBAR.GetInstanceID(); CURRENT_INSTANCE_ID = CURRENT_TOOLBAR.GetInstanceID();
} }
if (CURRENT_TOOLBAR == null || CURRENT_PARENT_LEFT != null) if (CURRENT_TOOLBAR == null)
return; return;
if (CURRENT_PARENT_LEFT == null)
{
CURRENT_PARENT_LEFT?.RemoveFromHierarchy(); CURRENT_PARENT_LEFT?.RemoveFromHierarchy();
CURRENT_PARENT_RIGHT?.RemoveFromHierarchy(); CURRENT_PARENT_RIGHT?.RemoveFromHierarchy();
@ -53,6 +55,9 @@ namespace Module.NavigationTool.Editor.Toolbar
CURRENT_PARENT_LEFT = CreateParent(mRoot, "ToolbarZoneLeftAlign", true); CURRENT_PARENT_LEFT = CreateParent(mRoot, "ToolbarZoneLeftAlign", true);
CURRENT_PARENT_RIGHT = CreateParent(mRoot, "ToolbarZoneRightAlign", false); CURRENT_PARENT_RIGHT = CreateParent(mRoot, "ToolbarZoneRightAlign", false);
}
if (CURRENT_PARENT_LEFT != null)
callback?.Invoke(CURRENT_PARENT_LEFT, CURRENT_PARENT_RIGHT); callback?.Invoke(CURRENT_PARENT_LEFT, CURRENT_PARENT_RIGHT);
} }

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", "name": "com.module.navigationtool",
"version": "1.0.2", "version": "1.1.0",
"displayName": "Module.NavigationTool", "displayName": "Module.NavigationTool",
"description": "Support for navigation tools, like favorites, history and toolbars", "description": "Support for navigation tools, like favorites, history and toolbars",
"unity": "2019.2", "unity": "2019.2",