0.1.0: Added favorites window

This commit is contained in:
Anders Ejlersen 2021-02-14 11:14:16 +01:00
parent 80499f0a7e
commit dea60c6e4a
37 changed files with 1129 additions and 0 deletions

View file

@ -0,0 +1,47 @@
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal sealed class EditorFavoritesPopupWindowAddFolder : PopupWindowContent
{
private readonly Favorites.Entry toParent;
private string inputStr = string.Empty;
public static void Show(Vector2 mousePosition, Favorites.Entry toParent)
{
var rect = new Rect(mousePosition.x - 200.0f, mousePosition.y, 0.0f, 0.0f);
PopupWindow.Show(rect, new EditorFavoritesPopupWindowAddFolder(toParent));
}
private EditorFavoritesPopupWindowAddFolder(Favorites.Entry toParent)
{
this.toParent = toParent;
}
public override void OnGUI(Rect rect)
{
bool isReturn = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return;
bool isEscape = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape;
GUI.SetNextControlName("TextField");
inputStr = GUI.TextField(rect, inputStr);
GUI.FocusControl("TextField");
if (isReturn && !string.IsNullOrEmpty(inputStr))
{
Favorites favorites = FavoritesUtility.GetFavorites();
favorites.AddFolder(inputStr, toParent);
editorWindow.Close();
}
if (isEscape)
editorWindow.Close();
}
public override Vector2 GetWindowSize()
{
return new Vector2(200.0f, EditorGUIUtility.singleLineHeight);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 645cd8d4c1164fc491789d22763f6167
timeCreated: 1613252500

View file

@ -0,0 +1,93 @@
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal sealed class EditorFavoritesPopupWindowContextMenu : PopupWindowContent
{
private readonly Favorites.Entry entry;
private readonly Option[] options;
private readonly Styles styles;
public static void Show(Vector2 mousePosition, Favorites.Entry entry)
{
var rect = new Rect(mousePosition.x, mousePosition.y, 0.0f, 0.0f);
PopupWindow.Show(rect, new EditorFavoritesPopupWindowContextMenu(entry));
}
private EditorFavoritesPopupWindowContextMenu(Favorites.Entry entry)
{
this.entry = entry;
styles = new Styles();
options = new[]
{
new Option("Add Folder", OnAddFolder, () => entry == null || !entry.isAsset),
new Option("Rename Folder", OnRenameFolder, () => entry != null && !entry.isAsset),
new Option("Remove", OnRemove, () => entry != null)
};
}
public override void OnGUI(Rect rect)
{
styles.Initialize(GUI.skin);
var entryRect = new Rect(0.0f, 0.0f, rect.width, EditorGUIUtility.singleLineHeight);
for (var i = 0; i < options.Length; i++)
{
GUI.enabled = options[i].criteria.Invoke();
if (GUI.Button(entryRect, options[i].name, styles.contextOption))
options[i].action.Invoke();
entryRect.y += EditorGUIUtility.singleLineHeight;
}
GUI.enabled = true;
}
public override Vector2 GetWindowSize()
{
return new Vector2(200.0f, options.Length * EditorGUIUtility.singleLineHeight + 6.0f);
}
private void OnAddFolder()
{
editorWindow.Close();
EditorFavoritesPopupWindowAddFolder.Show(new Vector2(0.0f, 0.0f), entry);
}
private void OnRenameFolder()
{
editorWindow.Close();
EditorFavoritesPopupWindowRenameFolder.Show(new Vector2(0.0f, 0.0f), entry);
}
private void OnRemove()
{
Favorites favorites = FavoritesUtility.GetFavorites();
favorites.Remove(entry);
editorWindow.Close();
}
/// <summary>
/// Class: Option in drop down menu
/// </summary>
private sealed class Option
{
public delegate void DoAction();
public delegate bool DoActionCriteria();
public readonly string name;
public readonly DoAction action;
public readonly DoActionCriteria criteria;
public Option(string name, DoAction action, DoActionCriteria criteria = null)
{
this.name = name;
this.action = action;
this.criteria = criteria;
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 476b6add28b14bde9fe51db4ba9497ff
timeCreated: 1613218094

View file

@ -0,0 +1,53 @@
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal sealed class EditorFavoritesPopupWindowRenameFolder : PopupWindowContent
{
private readonly Favorites.Entry entry;
private string inputStr;
public static void Show(Vector2 mousePosition, Favorites.Entry entry)
{
var rect = new Rect(mousePosition.x - 200.0f, mousePosition.y, 0.0f, 0.0f);
PopupWindow.Show(rect, new EditorFavoritesPopupWindowRenameFolder(entry));
}
private EditorFavoritesPopupWindowRenameFolder(Favorites.Entry entry)
{
this.entry = entry;
inputStr = entry.name;
}
public override void OnGUI(Rect rect)
{
bool isReturn = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return;
bool isEscape = Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape;
GUI.SetNextControlName("TextField");
inputStr = GUI.TextField(rect, inputStr);
GUI.FocusControl("TextField");
if (isReturn && !string.IsNullOrEmpty(inputStr))
{
entry.name = inputStr;
entry.lowerName = inputStr.ToLower();
entry.content.text = inputStr;
Favorites favorites = FavoritesUtility.GetFavorites();
favorites.Save();
editorWindow.Close();
}
if (isEscape)
editorWindow.Close();
}
public override Vector2 GetWindowSize()
{
return new Vector2(200.0f, EditorGUIUtility.singleLineHeight);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0c7a514e1c6b4846857dcc980b42485d
timeCreated: 1613291517

View file

@ -0,0 +1,128 @@
using System;
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal sealed class EditorFavoritesWindow : EditorWindow
{
[NonSerialized]
private Styles styles;
[SerializeField]
public EditorFavoritesViewTools viewTools;
[SerializeField]
private EditorFavoritesViewTreeList viewTreeList;
[SerializeField]
private EditorFavoritesViewSearchList viewSearchList;
[MenuItem("Tools/Windows/Favorites")]
public static void Open()
{
var window = GetWindow<EditorFavoritesWindow>();
window.titleContent = new GUIContent("Favorites");
window.Show();
}
private void OnEnable()
{
if (styles == null)
styles = new Styles();
if (viewTools == null)
viewTools = new EditorFavoritesViewTools();
if (viewTreeList == null)
viewTreeList = new EditorFavoritesViewTreeList();
if (viewSearchList == null)
viewSearchList = new EditorFavoritesViewSearchList();
}
private void OnGUI()
{
if (Event.current.type == EventType.Layout)
return;
styles.Initialize(GUI.skin);
var rectTools = new Rect(0.0f, 0.0f, position.width, EditorGUIUtility.singleLineHeight);
var rectList = new Rect(0.0f, rectTools.yMax, position.width, position.height - rectTools.height);
viewTools.Initialize();
viewTools.Draw(this, rectTools, styles);
if (viewTools.IsSearching())
{
viewSearchList.Initialize();
viewSearchList.Draw(this, rectList, styles);
}
else
{
viewTreeList.Initialize();
viewTreeList.Draw(this, rectList, styles);
}
HandleDragAndDropEvents();
HandleManipulatedEntry();
}
private void HandleDragAndDropEvents()
{
Favorites favorites = FavoritesUtility.GetFavorites();
if (Event.current.type == EventType.DragUpdated)
{
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
}
else if (Event.current.type == EventType.DragPerform)
{
Favorites.Entry toParent = null;
if (!viewTools.IsSearching())
toParent = FavoritesGUIUtility.hoverEntry;
favorites.AddRangeByPath(DragAndDrop.paths, toParent);
}
}
private static void HandleManipulatedEntry()
{
Favorites favorites = FavoritesUtility.GetFavorites();
Favorites.Entry entry = FavoritesGUIUtility.manipulatingEntry;
switch (FavoritesGUIUtility.manipulatingState)
{
case EManipulatingState.BeginClick:
break;
case EManipulatingState.PerformedClick:
if (entry.isAsset)
{
Selection.activeObject = favorites.GetObject(entry);
EditorGUIUtility.PingObject(Selection.activeObject);
}
else
{
entry.expanded = !entry.expanded;
favorites.Save();
}
FavoritesGUIUtility.ClearManipulating();
break;
case EManipulatingState.EndClick:
FavoritesGUIUtility.ClearManipulating();
break;
case EManipulatingState.BeginDrag:
break;
case EManipulatingState.PerformedDrag:
FavoritesGUIUtility.ClearManipulating();
break;
case EManipulatingState.EndDrag:
FavoritesGUIUtility.ClearManipulating();
break;
case EManipulatingState.PerformedContextClick:
FavoritesGUIUtility.ClearManipulating();
EditorFavoritesPopupWindowContextMenu.Show(Event.current.mousePosition, entry);
break;
case EManipulatingState.EndContextClick:
FavoritesGUIUtility.ClearManipulating();
break;
}
}
}
}

View file

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

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 15b0d6cd0e064f94bf81f3738a36ff85
timeCreated: 1613211891

View file

@ -0,0 +1,47 @@
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal sealed class Styles
{
public GUIStyle toolbox;
public GUIStyle buttonAddFolder;
public GUIStyle entry;
public Texture2D foldoutIn;
public Texture2D foldoutOut;
public GUIStyle contextOption;
private GUISkin skin;
public void Initialize(GUISkin skin)
{
if (this.skin == skin)
return;
toolbox = new GUIStyle(skin.box);
buttonAddFolder = new GUIStyle(skin.button);
buttonAddFolder.padding = new RectOffset(4, 0, 0, 4);
entry = new GUIStyle(skin.label);
entry.hover.textColor = entry.onHover.textColor = Color.white;
entry.active.textColor = entry.onActive.textColor = Color.yellow;
GUIStyle style = skin.FindStyle("Foldout");
if (style != null)
{
foldoutIn = style.normal.scaledBackgrounds[0];
foldoutOut = style.onNormal.scaledBackgrounds[0];
}
contextOption = new GUIStyle(skin.label);
contextOption.hover.textColor = contextOption.onHover.textColor = Color.white;
contextOption.hover.scaledBackgrounds = contextOption.onHover.scaledBackgrounds = skin.box.normal.scaledBackgrounds;
contextOption.active.textColor = contextOption.onActive.textColor = Color.yellow;
contextOption.active.scaledBackgrounds = contextOption.onActive.scaledBackgrounds = skin.box.normal.scaledBackgrounds;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 6d7dcc40bb3d471d91439071d6157a8f
timeCreated: 1613211898

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 8d38858044174890af932bea10cfbb9d
timeCreated: 1613211112

View file

@ -0,0 +1,10 @@
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal abstract class AbstractEditorFavoritesView
{
public abstract void Initialize();
public abstract void Draw(EditorFavoritesWindow window, Rect rect, Styles styles);
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 1d16482b17fb430fa905dea21ec2fdab
timeCreated: 1613211130

View file

@ -0,0 +1,51 @@
using System;
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
[Serializable]
internal sealed class EditorFavoritesViewSearchList : AbstractEditorFavoritesView
{
[SerializeField]
private Vector2 scrollPosition;
[NonSerialized]
private Favorites favorites;
public override void Initialize()
{
favorites = FavoritesUtility.GetFavorites();
}
public override void Draw(EditorFavoritesWindow window, Rect rect, Styles styles)
{
float entryHeight = EditorGUIUtility.singleLineHeight;
float height = entryHeight * favorites.entries.Count;
string lowerSearchStr = window.viewTools.searchStr.ToLower();
GUI.BeginGroup(rect);
{
var position = new Rect(0.0f, 0.0f, rect.width, rect.height);
var viewRect = new Rect(0.0f, 0.0f, position.height > height ? position.width : position.width - 14.0f, height);
var entryRect = new Rect(0.0f, 0.0f, viewRect.width, entryHeight);
scrollPosition = GUI.BeginScrollView(position, scrollPosition, viewRect);
{
for (var i = 0; i < favorites.entries.Count; i++)
{
Favorites.Entry e = favorites.entries[i];
if (!e.isAsset || !e.lowerName.Contains(lowerSearchStr))
continue;
FavoritesGUIUtility.DrawEntry(entryRect, favorites.entries[i], styles, true);
entryRect.y += entryHeight;
}
}
GUI.EndScrollView();
}
GUI.EndGroup();
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 65d3b26a5050438c8d995b3c383c474f
timeCreated: 1613211189

View file

@ -0,0 +1,38 @@
using System;
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
[Serializable]
internal sealed class EditorFavoritesViewTools : AbstractEditorFavoritesView
{
public string searchStr;
public override void Initialize()
{
}
public override void Draw(EditorFavoritesWindow window, Rect rect, Styles styles)
{
float dim = rect.height;
GUI.BeginGroup(rect, styles.toolbox);
{
var r0 = new Rect(0.0f, 0.0f, rect.width - dim, dim);
var r1 = new Rect(rect.width - r0.height, 0.0f, dim, dim);
searchStr = EditorGUI.TextField(r0, searchStr);
if (GUI.Button(r1, "+", styles.buttonAddFolder))
EditorFavoritesPopupWindowAddFolder.Show(new Vector2(r1.xMax, dim), null);
}
GUI.EndGroup();
}
public bool IsSearching()
{
return !string.IsNullOrEmpty(searchStr);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b597a5bc0de34d96accec02ef9cb80ed
timeCreated: 1613211779

View file

@ -0,0 +1,61 @@
using System;
using UnityEditor;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
[Serializable]
internal sealed class EditorFavoritesViewTreeList : AbstractEditorFavoritesView
{
[SerializeField]
private Vector2 scrollPosition;
[NonSerialized]
private Favorites favorites;
public override void Initialize()
{
favorites = FavoritesUtility.GetFavorites();
}
public override void Draw(EditorFavoritesWindow window, Rect rect, Styles styles)
{
float entryHeight = EditorGUIUtility.singleLineHeight;
float height = entryHeight * favorites.entries.Count;
GUI.BeginGroup(rect);
{
var position = new Rect(0.0f, 0.0f, rect.width, rect.height);
var viewRect = new Rect(0.0f, 0.0f, position.height > height ? position.width : position.width - 14.0f, height);
var entryRect = new Rect(0.0f, 0.0f, viewRect.width, entryHeight);
scrollPosition = GUI.BeginScrollView(position, scrollPosition, viewRect);
{
for (var i = 0; i < favorites.entries.Count; i++)
{
Favorites.Entry e = favorites.entries[i];
if (e.indentLevel == 0)
DrawEntry(e, ref entryRect, entryHeight, styles);
}
}
GUI.EndScrollView();
}
GUI.EndGroup();
}
private void DrawEntry(Favorites.Entry entry, ref Rect entryRect, float entryHeight, Styles styles)
{
FavoritesGUIUtility.DrawEntry(entryRect, entry, styles);
entryRect.y += entryHeight;
if (entry.isAsset || !entry.expanded)
return;
for (var i = 0; i < entry.children.Count; i++)
{
DrawEntry(entry.children[i].entry, ref entryRect, entryHeight, styles);
}
}
}
}

View file

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