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

8
Editor.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 3404f03e41295794998e14f145cc0000
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

8
Editor/Favorites.meta Normal file
View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 22b00eaff1a81a44ea0fcf0c016bd2e2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1b77a50e79274018aac89e7a4f0c185d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View file

@ -0,0 +1,16 @@
namespace Game.NavigationTool.Editor
{
public enum EManipulatingState : byte
{
None,
BeginClick,
PerformedClick,
EndClick,
BeginContextClick,
PerformedContextClick,
EndContextClick,
BeginDrag,
PerformedDrag,
EndDrag
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a166f7a5dc6042dcae04bf352b8144ce
timeCreated: 1613213516

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: feac89e79687422296585bfe2a8a4ebc
timeCreated: 1613162380

View file

@ -0,0 +1,309 @@
using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
namespace Game.NavigationTool.Editor
{
[Serializable]
internal sealed class Favorites : ISerializationCallbackReceiver
{
public static readonly string PREF_ID = "PREF_FAVORITE_LIST";
public List<Entry> entries;
public Favorites()
{
entries = new List<Entry>();
string json = EditorPrefs.GetString(PREF_ID);
if (!string.IsNullOrEmpty(json))
EditorJsonUtility.FromJsonOverwrite(json, this);
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
var guidToEntry = new Dictionary<string, Entry>(entries.Count);
for (var i = 0; i < entries.Count; i++)
{
Entry e = entries[i];
guidToEntry.Add(e.guid, e);
}
for (var i = 0; i < entries.Count; i++)
{
Entry e = entries[i];
if (e.isAsset)
continue;
for (int j = e.children.Count - 1; j >= 0; j--)
{
Entry c = guidToEntry[e.children[j].guid];
if (c != null)
{
e.children[j].entry = c;
c.parent = e;
}
else
{
e.children.RemoveAt(j);
}
}
}
}
public void Add(string guid, Entry toParent = null)
{
if (InternalAddEntry(Entry.CreateAsset(guid), toParent))
Save();
}
public void AddFolder(string name, Entry toParent = null)
{
if (InternalAddEntry(Entry.CreateFolder(name), toParent))
Save();
}
private bool InternalAddEntry(Entry e, Entry toParent)
{
e.Refresh();
if (!e.valid)
return false;
entries.Add(e);
if (toParent != null)
{
e.parent = toParent;
e.indentLevel = toParent.indentLevel + 1;
toParent.AddChild(e);
}
return true;
}
public void AddRange(string[] guids, Entry toParent = null)
{
var isDirty = false;
for (var i = 0; i < guids.Length; i++)
{
if (InternalAddEntry(Entry.CreateAsset(guids[i]), toParent))
isDirty = true;
}
if (isDirty)
Save();
}
public void AddRangeByPath(string[] paths, Entry toParent = null)
{
var isDirty = false;
for (var i = 0; i < paths.Length; i++)
{
string guid = AssetDatabase.AssetPathToGUID(paths[i]);
if (InternalAddEntry(Entry.CreateAsset(guid), toParent))
isDirty = true;
}
if (isDirty)
Save();
}
public void Remove(Entry e)
{
if (InternalRemove(e))
Save();
}
private bool InternalRemove(Entry e)
{
if (!entries.Remove(e))
return false;
e.parent?.RemoveChild(e);
if (!e.isAsset)
{
for (var i = 0; i < e.children.Count; i++)
{
InternalRemove(e.children[i].entry);
}
}
return true;
}
public void Move(Entry e, Entry toParent)
{
InternalMove(e, toParent);
Save();
}
private void InternalMove(Entry e, Entry toParent)
{
if (e.parent != null)
{
e.parent.RemoveChild(e);
e.parent = null;
e.indentLevel = 0;
}
if (toParent != null && toParent.isAsset)
toParent = toParent.parent;
if (toParent != null)
{
toParent.AddChild(e);
e.parent = toParent;
e.indentLevel = e.parent.indentLevel + 1;
}
InternalMoveIndentLevel(e);
}
private void InternalMoveIndentLevel(Entry parent)
{
if (parent.isAsset)
return;
for (var i = 0; i < parent.children.Count; i++)
{
parent.children[i].entry.indentLevel = parent.indentLevel + 1;
InternalMoveIndentLevel(parent.children[i].entry);
}
}
public Object GetObject(Entry entry)
{
string path = AssetDatabase.GUIDToAssetPath(entry.assetGuid);
return AssetDatabase.LoadMainAssetAtPath(path);
}
public void Save()
{
string json = EditorJsonUtility.ToJson(this, false);
EditorPrefs.SetString(PREF_ID, json);
}
/// <summary>
/// Class: Entry
/// </summary>
[Serializable]
public sealed class Entry : ISerializationCallbackReceiver
{
public string guid;
public string assetGuid;
public string name;
public bool isAsset;
public bool expanded;
public int indentLevel;
public List<Child> children;
[NonSerialized]
public bool valid;
[NonSerialized]
public Entry parent;
[NonSerialized]
public GUIContent content;
[NonSerialized]
public string lowerName;
private Entry(string assetGuid, string name, bool isAsset)
{
guid = Guid.NewGuid().ToString();
this.assetGuid = assetGuid;
this.name = name;
this.isAsset = isAsset;
if (!isAsset)
{
expanded = true;
children = new List<Child>();
}
}
void ISerializationCallbackReceiver.OnBeforeSerialize()
{
}
void ISerializationCallbackReceiver.OnAfterDeserialize()
{
if (isAsset)
children = null;
Refresh();
}
public void Refresh()
{
if (isAsset)
{
string path = AssetDatabase.GUIDToAssetPath(assetGuid);
name = Path.GetFileNameWithoutExtension(path);
lowerName = name.ToLower();
valid = !string.IsNullOrEmpty(path);
content = new GUIContent(name, FavoritesGUIUtility.GetIcon(path), path);
}
else
{
valid = true;
content = new GUIContent(name, FavoritesGUIUtility.GetFolderIcon());
}
}
public void AddChild(Entry entry)
{
children.Add(new Child(entry));
}
public void RemoveChild(Entry entry)
{
for (int i = children.Count - 1; i >= 0; i--)
{
if (children[i].entry == entry)
children.RemoveAt(i);
}
}
public static Entry CreateFolder(string name)
{
return new Entry(string.Empty, name, false);
}
public static Entry CreateAsset(string assetGuid)
{
return new Entry(assetGuid, string.Empty, true);
}
/// <summary>
/// Class: Entry child
/// </summary>
[Serializable]
public sealed class Child
{
public string guid;
[NonSerialized]
public Entry entry;
public Child(Entry entry)
{
guid = entry.guid;
this.entry = entry;
}
}
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7ec45414bdf74e81800f8ffaf95f26ec
timeCreated: 1613162445

View file

@ -0,0 +1,112 @@
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
namespace Game.NavigationTool.Editor
{
internal static class FavoritesGUIUtility
{
private static readonly int ENTRY_HASH = "DrawEntry".GetHashCode();
public static Favorites.Entry manipulatingEntry;
public static EManipulatingState manipulatingState;
public static Favorites.Entry hoverEntry;
public static void DrawEntry(Rect rect, Favorites.Entry entry, Styles styles, bool ignoreIndentLevel = false)
{
int id = GUIUtility.GetControlID(ENTRY_HASH, FocusType.Passive, rect);
bool on = manipulatingEntry == entry;
bool intersects = rect.Contains(Event.current.mousePosition);
if (intersects)
hoverEntry = entry;
else if (hoverEntry == entry)
hoverEntry = null;
switch (Event.current.type)
{
case EventType.MouseDown:
if (intersects)
{
SetManipulating(entry, Event.current.button == 0 ? EManipulatingState.BeginClick : EManipulatingState.BeginContextClick);
Event.current.Use();
}
break;
case EventType.MouseUp:
if (manipulatingEntry == entry)
{
if (manipulatingState == EManipulatingState.BeginClick)
{
if (intersects && Event.current.button == 0)
SetManipulating(entry, EManipulatingState.PerformedClick);
else
SetManipulating(entry, EManipulatingState.EndClick);
}
else if (manipulatingState == EManipulatingState.BeginContextClick)
{
if (intersects && Event.current.button == 1)
SetManipulating(entry, EManipulatingState.PerformedContextClick);
else
SetManipulating(entry, EManipulatingState.EndContextClick);
}
Event.current.Use();
}
break;
case EventType.MouseDrag:
if (manipulatingEntry == entry)
Event.current.Use();
break;
case EventType.KeyDown:
break;
case EventType.KeyUp:
break;
case EventType.Repaint:
if (!ignoreIndentLevel)
{
rect.x += entry.indentLevel * 15.0f;
rect.width -= entry.indentLevel * 15.0f;
}
if (!entry.isAsset)
entry.content.image = entry.expanded ? styles.foldoutOut : styles.foldoutIn;
styles.entry.Draw(rect, entry.content, id, on, intersects);
break;
case EventType.DragUpdated:
break;
case EventType.DragPerform:
break;
case EventType.DragExited:
break;
}
}
public static Texture2D GetIcon(string path)
{
var texture = AssetDatabase.GetCachedIcon(path) as Texture2D;
if (texture == null)
texture = InternalEditorUtility.GetIconForFile(path);
return texture;
}
public static Texture2D GetFolderIcon()
{
return AssetDatabase.GetCachedIcon("Assets") as Texture2D;
}
private static void SetManipulating(Favorites.Entry entry, EManipulatingState state)
{
manipulatingEntry = entry;
manipulatingState = state;
}
public static void ClearManipulating()
{
SetManipulating(null, EManipulatingState.None);
hoverEntry = null;
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: a964d9decf5f4d619caccf91a2448661
timeCreated: 1613211223

View file

@ -0,0 +1,26 @@
using UnityEditor;
namespace Game.NavigationTool.Editor
{
internal static class FavoritesUtility
{
private static Favorites FAVORITES;
static FavoritesUtility()
{
FAVORITES = null;
}
public static Favorites GetFavorites()
{
return FAVORITES ?? (FAVORITES = new Favorites());
}
[MenuItem("Tools/Utilities/Favorites/Delete")]
public static void DeleteAll()
{
FAVORITES = null;
EditorPrefs.DeleteKey(Favorites.PREF_ID);
}
}
}

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 892d63101f6a41ecb789405dc0d7576a
timeCreated: 1613210854

View file

@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f365d80e29254040a54189ce0a22f29f
timeCreated: 1613211006

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:

View file

@ -0,0 +1,15 @@
{
"name": "Game.NavigationTool.Editor",
"references": [],
"includePlatforms": [
"Editor"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 8339b3ce77cb32f489776d81010ad36c
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

18
package.json Normal file
View file

@ -0,0 +1,18 @@
{
"name": "com.module.navigationtool",
"version": "0.1.0",
"displayName": "Module.NavigationTool",
"description": "Support for navigation tools",
"unity": "2019.2",
"unityRelease": "17f1",
"dependencies": {
},
"keywords": [
"navigation"
],
"author": {
"name": "Anders Ejlersen",
"email": "anders@ejlersen.info",
"url": "https://www.ejlersen.info"
}
}

7
package.json.meta Normal file
View file

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6896738deb10ff34e8931d5e91ac5f8a
PackageManifestImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant: