using UnityEditor; using UnityEditorInternal; using UnityEngine; namespace Module.NavigationTool.Editor.History { internal static class EditorHistoryGUIUtility { private static readonly int ENTRY_HASH = "DrawHistoryEntry".GetHashCode(); public static bool isClicked; public static bool isDoubleClick; public static bool isPinClicked; public static EditorHistoryList.Entry currentEntry; public static bool isCurrentEntryPinned; private static EditorHistoryList.Entry LAST_CLICK_ENTRY; private static double LAST_CLICK_TIME; private static int CLICK_COUNT; public static void DrawEntry(Rect rect, EditorHistoryList.Entry entry, Styles styles, bool isPinned) { const float PIN_WIDTH = 20.0f; var r0 = new Rect(rect.x, rect.y, PIN_WIDTH, rect.height); var r1 = new Rect(r0.xMax, rect.y, rect.width - PIN_WIDTH, rect.height); int id = GUIUtility.GetControlID(ENTRY_HASH, FocusType.Passive, rect); bool on = currentEntry == entry; bool intersectsPin = r0.Contains(Event.current.mousePosition); bool intersectsEntry = r1.Contains(Event.current.mousePosition); bool intersects = intersectsPin || intersectsEntry; switch (Event.current.type) { case EventType.MouseDown: if (intersects) { isPinClicked = intersectsPin; currentEntry = entry; isCurrentEntryPinned = isPinned; Event.current.Use(); } break; case EventType.MouseMove: Event.current.Use(); break; case EventType.MouseUp: if (currentEntry == entry) { isClicked = intersects; if (isClicked) { if (!isPinClicked) { 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; isDoubleClick = CLICK_COUNT == 2; } } else { currentEntry = null; } if (!isClicked) currentEntry = null; Event.current.Use(); } break; case EventType.Repaint: if (isPinned) { GUI.color = intersectsPin ? styles.colorToggleOff : styles.colorToggleOn; styles.icon.Draw(r0, styles.iconPinned, id, on, intersectsPin); GUI.color = Color.white; } else { GUI.color = intersectsPin ? styles.colorToggleOff : styles.colorNone; styles.icon.Draw(r0, styles.iconUnpinned, id, on, intersectsPin); GUI.color = Color.white; } Vector2 oldSize = EditorGUIUtility.GetIconSize(); EditorGUIUtility.SetIconSize(new Vector2(r1.height, r1.height)); GUIStyle style = entry.valid ? styles.entry : styles.invalidEntry; style.Draw(r1, entry.content, id, on, intersectsEntry); EditorGUIUtility.SetIconSize(oldSize); break; } } public static void Used() { isClicked = false; currentEntry = 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 void Repaint() { if (!EditorWindow.HasOpenInstances()) return; var window = EditorWindow.GetWindow("History", false); window.Repaint(); } } }