using UnityEditor; using UnityEditorInternal; using UnityEngine; namespace Game.NavigationTool.Editor.Favorite { internal static class FavoritesGUIUtility { private static readonly int ENTRY_HASH = "DrawFavoriteEntry".GetHashCode(); public static Favorites.Entry manipulatingEntry; public static EManipulatingState manipulatingState; public static Vector2 manipulatingMouseOffset; public static Rect manipulatingRect; private static Favorites.Entry LAST_CLICK_ENTRY; private static double LAST_CLICK_TIME; private static int CLICK_COUNT; 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; switch (Event.current.type) { case EventType.MouseDown: if (intersects) { SetManipulating(rect, entry, Event.current.button == 0 ? EManipulatingState.BeginClick : EManipulatingState.BeginContextClick); manipulatingMouseOffset = Event.current.mousePosition - rect.position; Event.current.Use(); } break; case EventType.MouseUp: if (manipulatingEntry == entry) { if (manipulatingState == EManipulatingState.BeginClick) { if (intersects && Event.current.button == 0) { double dt = EditorApplication.timeSinceStartup - LAST_CLICK_TIME; if (dt < 0.3 && CLICK_COUNT == 1 && LAST_CLICK_ENTRY == entry) CLICK_COUNT++; else CLICK_COUNT = 1; LAST_CLICK_ENTRY = entry; LAST_CLICK_TIME = EditorApplication.timeSinceStartup; SetManipulating(rect, entry, CLICK_COUNT == 1 ? EManipulatingState.PerformedClick : EManipulatingState.PerformedDoubleClick); } else { SetManipulating(rect, entry, EManipulatingState.EndClick); } } else if (manipulatingState == EManipulatingState.BeginContextClick) { if (intersects && Event.current.button == 1) SetManipulating(rect, entry, EManipulatingState.PerformedContextClick); else SetManipulating(rect, entry, EManipulatingState.EndContextClick); } else if (manipulatingState == EManipulatingState.BeginDrag) { if (intersects) SetManipulating(rect, entry, EManipulatingState.EndDrag); else SetManipulating(rect, entry, EManipulatingState.PerformedDrag); } Event.current.Use(); } break; case EventType.MouseDrag: if (manipulatingEntry == entry) { SetManipulating(rect, entry, EManipulatingState.BeginDrag); Event.current.Use(); } 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; Vector2 oldSize = EditorGUIUtility.GetIconSize(); EditorGUIUtility.SetIconSize(new Vector2(rect.height, rect.height)); GUIStyle style = entry.valid ? styles.entry : styles.invalidEntry; style.Draw(rect, entry.content, id, on, intersects); EditorGUIUtility.SetIconSize(oldSize); break; } } public static void DrawShadowEntry(Rect rect, Favorites.Entry entry, Styles styles) { if (Event.current.type != EventType.Repaint) return; if (!entry.isAsset) entry.content.image = entry.expanded ? styles.foldoutOut : styles.foldoutIn; int id = GUIUtility.GetControlID(ENTRY_HASH, FocusType.Passive, rect); GUIStyle style = entry.valid ? styles.entry : styles.invalidEntry; GUI.enabled = false; style.Draw(rect, entry.content, id, false, false); GUI.enabled = true; } public static void EndDraw() { hoverEntry = null; } 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(Rect rect, Favorites.Entry entry, EManipulatingState state) { manipulatingRect = rect; manipulatingEntry = entry; manipulatingState = state; } public static void ClearManipulating() { SetManipulating(Rect.zero, null, EManipulatingState.None); hoverEntry = null; } } }