0.1.0: Added favorites window
This commit is contained in:
parent
80499f0a7e
commit
dea60c6e4a
37 changed files with 1129 additions and 0 deletions
309
Editor/Favorites/Utilities/Favorites.cs
Normal file
309
Editor/Favorites/Utilities/Favorites.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Editor/Favorites/Utilities/Favorites.cs.meta
Normal file
3
Editor/Favorites/Utilities/Favorites.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7ec45414bdf74e81800f8ffaf95f26ec
|
||||
timeCreated: 1613162445
|
||||
112
Editor/Favorites/Utilities/FavoritesGUIUtility.cs
Normal file
112
Editor/Favorites/Utilities/FavoritesGUIUtility.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Editor/Favorites/Utilities/FavoritesGUIUtility.cs.meta
Normal file
3
Editor/Favorites/Utilities/FavoritesGUIUtility.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a964d9decf5f4d619caccf91a2448661
|
||||
timeCreated: 1613211223
|
||||
26
Editor/Favorites/Utilities/FavoritesUtility.cs
Normal file
26
Editor/Favorites/Utilities/FavoritesUtility.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
3
Editor/Favorites/Utilities/FavoritesUtility.cs.meta
Normal file
3
Editor/Favorites/Utilities/FavoritesUtility.cs.meta
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 892d63101f6a41ecb789405dc0d7576a
|
||||
timeCreated: 1613210854
|
||||
Loading…
Add table
Add a link
Reference in a new issue