Files
Fishing2/Assets/Plugins/vFavorites/VFavorites.cs
2025-05-10 12:49:47 +08:00

1977 lines
65 KiB
C#

#if UNITY_EDITOR
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using UnityEngine.SceneManagement;
using UnityEditor.SceneManagement;
using UnityEditor.ShortcutManagement;
using System.Reflection;
using System.Linq;
using UnityEngine.UIElements;
using Type = System.Type;
using static VFavorites.Libs.VUtils;
using static VFavorites.Libs.VGUI;
using static VFavorites.VFavoritesData;
namespace VFavorites
{
public static class VFavorites
{
static void WrappedOnGUI(object _)
{
if (wrappedBrowser?.GetType() != t_BrowserWindow) { originalBrowserGUI(); return; }
void createData()
{
if (data) return;
data = ScriptableObject.CreateInstance<VFavoritesData>();
AssetDatabase.CreateAsset(data, GetScriptPath("VFavorites").GetParentPath().CombinePath("vFavorites Data.asset"));
// // migrateDataFromV1
// if (!EditorPrefsCached.HasKey("vFavorites-guids-" + GetProjectId())) return;
// if (EditorPrefsCached.HasKey("vHierarchy-dataMigrationFromV1Attempted-" + GetProjectId())) return;
// EditorPrefsCached.SetBool("vHierarchy-dataMigrationFromV1Attempted-" + GetProjectId(), true);
// if (!data.pages.Any())
// data.pages.Add(new Page("Page 1"));
// var guidsFromV1 = EditorPrefsCached.GetString("vFavorites-guids-" + GetProjectId()).Split('-').Where(r => r != "").ToList();
// foreach (var guid in guidsFromV1)
// if (AssetDatabase.LoadAssetAtPath<Object>(guid.ToPath()) is Object obj)
// data.pages.First().items.Add(new Item(obj));
// data.Dirty();
// data.Save();
}
void closeNavbarSearch()
{
if (!curEvent.isLayout) return;
if (t_VFolders == null) return;
if (GUI.GetNameOfFocusedControl() == "navbar search field")
GUI.FocusControl(null);
if (!wrappedBrowser.GetMemberValue<string>("m_SearchFieldText").IsNullOrEmpty())
{
wrappedBrowser.SetMemberValue("m_SearchFieldText", "");
wrappedBrowser.GetMemberValue("m_SearchFilter").SetMemberValue("m_NameFilter", "");
wrappedBrowser.InvokeMethod("UpdateSearchDelayed");
GUIUtility.keyboardControl = 0;
}
// mouse input on vFavorites throws exceptions if search is active on vFolders navbar
// here we close search to avoid this
}
void pageScroll()
{
if (!curEvent.isScroll) return;
if (!VFavoritesMenu.pageScrollEnabled) return;
var scrollDelta = curEvent.mouseDelta.y;
if (scrollDelta == 0 && curEvent.holdingShift)
scrollDelta = curEvent.mouseDelta.x;
if (scrollDelta < 0 && data.curPageIndex == 0) return;
if (scrollDelta < 0)
{
data.curPageIndex--;
prevPageButtonBrightness = 2;
}
if (scrollDelta > 0)
{
data.curPageIndex++;
nextPageButtonBrightness = 2;
}
CancelDragging();
CancelRowAnimations();
curEvent.Use();
}
void background()
{
var color = isDarkTheme ? Greyscale(.2f) : Greyscale(.78f);
totalRect_groupSpace.Draw(color);
}
void pages()
{
void page(Rect pageRect, Page page)
{
void findSelectedItem()
{
if (!curEvent.isLayout) return;
foreach (var item in page.items)
item.isSelected = false;
if (draggingItem) return;
if (mousePresesdOnItem) return;
if (page.lastItemDragTime_ticks > page.lastItemSelectTime_ticks) return;
Item lastSelectedItem = null;
foreach (var item in page.items)
{
if (!item.isLoadable) continue;
if (lastSelectedItem?.lastSelectTime_ticks > item.lastSelectTime_ticks) continue;
var isSelected = false;
if (item.isFolder)
{
var targetBrowser = isWrappedBrowserLocked && isOneColumn ? allBrowsers.FirstOrDefault(r => !r.GetMemberValue<bool>("isLocked")) ?? wrappedBrowser
: wrappedBrowser;
if (targetBrowser.GetFieldValue<int>("m_ViewMode") == 1)
isSelected = targetBrowser.InvokeMethod<string>("GetActiveFolderPath") == item.assetPath;
else
isSelected = Selection.activeObject == item.obj;
}
if (!item.isFolder)
isSelected = Selection.activeObject == item.obj;
if (isSelected)
lastSelectedItem = item;
}
if (lastSelectedItem != null)
lastSelectedItem.isSelected = true;
}
void rows()
{
void row(float y, Item item)
{
var rowRect = pageRect.SetHeight(rowHeight).SetY(y).SetX(0);
var iconOffset = 6;
var iconSize = 25 * Mathf.Min(1, data.rowScale);
var nameOffset = 3;
var deletedOrNotLoadedLabelOffset = 1;
float highlightAmount = 0f;
void set_highlightAmount()
{
if (animatingDroppedItem && item == droppedItem)
highlightAmount = droppedItemHighlightAmount;
if (item.isSelected)
highlightAmount = 1;
if (draggingItem && item == draggedItem)
highlightAmount = 1;
if (mousePresesdOnItem && item == pressedItem)
highlightAmount = 1;
}
void shadow()
{
if (item != draggedItem && item != droppedItem) return;
var amount = item == droppedItem ? droppedItemShadowAmount : 1;
if (amount.Approx(0)) return;
rowRect.AddWidthFromMid(30).DrawBlurred(Greyscale(0, .55f * amount), 22);
}
void background()
{
var evenColor = isDarkTheme ? Greyscale(.249f) : Greyscale(.82f);
var oddColor = isDarkTheme ? Greyscale(.228f) : Greyscale(.85f);
var highlightedColor = isDarkTheme ? Greyscale(.335f) : Greyscale(.9f);
var rowColor = Lerp(evenColor, oddColor, rowRect.y.PingPong(rowHeight) / rowHeight);
Lerp(ref rowColor, highlightedColor, highlightAmount);
rowRect.Draw(rowColor);
}
void icon()
{
var iconRect = rowRect.MoveX(iconOffset).SetWidth(iconSize).SetHeightFromMid(iconSize);
if (item.isSceneGameObject)
iconRect = iconRect.MoveX(1).Resize(.5f);
void asset()
{
if (!item.isAsset) return;
var iconTexture = item.isLoadable ? AssetPreview.GetAssetPreview(item.obj) ?? AssetPreview.GetMiniThumbnail(item.obj) : AssetPreview.GetMiniTypeThumbnail(item.type);
GUI.DrawTexture(iconRect, iconTexture);
}
void sceneGameObject()
{
if (!item.isSceneGameObject) return;
void getIconNameFromAssetPreview()
{
if (!item.isLoadable) return;
item.sceneGameObjectIconName = AssetPreview.GetMiniThumbnail(item.obj).name;
}
void getIconNameFromVHierarchy()
{
if (!item.isLoadable) return;
if (!(item.obj is GameObject gameObject)) return;
if (mi_VHierarchy_GetIconName == null) return;
var iconNameFromVHierarchy = (string)mi_VHierarchy_GetIconName.Invoke(null, new object[] { gameObject });
if (!iconNameFromVHierarchy.IsNullOrEmpty())
item.sceneGameObjectIconName = iconNameFromVHierarchy;
}
getIconNameFromAssetPreview();
getIconNameFromVHierarchy();
var iconTexture = EditorGUIUtility.IconContent(item.sceneGameObjectIconName.IsNullOrEmpty() ? "GameObject icon" : item.sceneGameObjectIconName).image;
GUI.DrawTexture(iconRect, iconTexture);
}
void folder()
{
if (!item.isFolder) return;
iconRect = iconRect.Resize(-1.5f);
void drawNormal()
{
if (isDarkTheme)
if (highlightAmount == 1) return;
GUI.DrawTexture(iconRect, EditorGUIUtility.IconContent("Folder icon").image);
}
void drawHighlighted()
{
if (!isDarkTheme) return;
if (highlightAmount != 1) return;
SetGUIColor(Greyscale(.84f));
GUI.DrawTexture(iconRect, EditorGUIUtility.IconContent("Folder On icon").image);
ResetGUIColor();
}
void drawViaVFolders()
{
mi_VFolders_DrawBigFolderIcon?.Invoke(null, new object[] { iconRect, item.globalId.guid });
}
drawNormal();
drawHighlighted();
drawViaVFolders();
}
asset();
sceneGameObject();
folder();
}
void name()
{
var nameRect = rowRect.MoveX(iconOffset + iconSize + nameOffset).MoveY(-.5f).SetHeightFromMid(16);
void normal()
{
if (isDarkTheme)
if (highlightAmount == 1) return;
GUI.Label(nameRect, item.name);
}
void highlighted()
{
if (!isDarkTheme) return;
if (highlightAmount != 1) return;
if (!curEvent.isRepaint) return;
SetGUIColor(Greyscale(.91f));
GUI.skin.GetStyle("WhiteLabel").Draw(nameRect, item.name, false, false, false, false);
ResetGUIColor();
}
normal();
highlighted();
}
void deletedOrNotLoaded()
{
var labelRect = rowRect.MoveX(iconOffset + iconSize + nameOffset + item.name.GetLabelWidth() + deletedOrNotLoadedLabelOffset).MoveY(.5f);
SetGUIEnabled(false);
SetLabelFontSize(10);
if (item.isDeleted)
GUI.Label(labelRect, "Deleted");
else if (!item.isLoadable)
GUI.Label(labelRect, "Not loaded");
ResetLabelStyle();
ResetGUIEnabled();
}
void crossButton()
{
if (!rowRect.IsHovered()) return;
if (draggingItem) return;
// if (mousePresesdOnItem) return; // idk
var buttonRect = rowRect.SetWidthFromRight(0).MoveX(-crossButtonOffsetFromRight).SetWidthFromMid(crossButtonSize);
var iconRect = buttonRect.SetSizeFromMid(16);
var normalColor = Greyscale(item.isSelected ? .48f : .4f);
var hoveredColor = isDarkTheme ? Greyscale(.8f) : normalColor;
var pressedColor = Greyscale(.6f);
SetGUIColor(buttonRect.IsHovered() ? (mousePressed ? pressedColor : hoveredColor) : normalColor);
GUI.Label(iconRect, EditorGUIUtility.IconContent("CrossIcon"));
ResetGUIColor();
buttonRect.MarkInteractive();
if (!mousePressedOnCrossButtonArea) return;
if (!curEvent.isMouseUp) return;
if (!buttonRect.IsHovered()) return;
CancelRowAnimations();
data.curPage.rowGaps[data.curPage.items.IndexOf(item)] = rowHeight;
data.curPage.items.Remove(item);
data.Dirty();
data.Save();
curEvent.Use();
}
void click()
{
if (!rowRect.IsHovered()) return;
if (!curEvent.isMouseUp) return;
curEvent.Use();
if (draggingItem) return;
if (mouseDragDistance > 2) return;
if (!item.isLoadable) return;
SelectItem(item);
}
void doubleclick()
{
if (!rowRect.IsHovered()) return;
if (!doubleclickUnhandled) return;
OpenItem(item);
doubleclickUnhandled = false;
}
rowRect.MarkInteractive();
set_highlightAmount();
shadow();
background();
icon();
name();
deletedOrNotLoaded();
crossButton();
click();
doubleclick();
}
void normalRow(int i)
{
Space(page.rowGaps[i]);
Space(rowHeight);
if (page.items[i] == droppedItem && animatingDroppedItem && page == data.curPage) return;
row(lastRect.y, page.items[i]);
}
void draggedRow()
{
if (!draggingItem) return;
if (page != data.curPage) return;
row(draggedItemY_rowsSpace, draggedItem);
}
void droppedRow()
{
if (!animatingDroppedItem) return;
if (page != data.curPage) return;
row(droppedItemY_rowsSpace, droppedItem);
}
if (curEvent.isRepaint && skipNextRepaint) { skipNextRepaint = false; return; }
GUILayout.BeginArea(pageRect);
page.scrollPos = EditorGUILayout.BeginScrollView(new Vector2(0, page.scrollPos), GUIStyle.none, GUIStyle.none).y;
for (int i = 0; i < page.items.Count; i++)
normalRow(i);
Space(page.rowGaps.Last());
Space(60);
draggedRow();
droppedRow();
EditorGUILayout.EndScrollView();
GUILayout.EndArea();
}
void curtains()
{
var height = 25;
var color = isDarkTheme ? Greyscale(.2f) : Greyscale(.78f);
pageRect.SetHeight(height).DrawCurtainDown(color.SetAlpha((page.scrollPos / 20).Smoothstep()));
pageRect.SetHeightFromBottom(height).DrawCurtainUp(color);
}
void tutor()
{
if (page.items.Any() || draggingItem) return;
SetGUIEnabled(false);
SetLabelFontSize(11);
SetLabelAlignmentCenter();
GUI.Label(pageRect.MoveY(-13), "Drop folders, assets");
GUI.Label(pageRect.MoveY(5), "or GameObjects");
ResetGUIEnabled();
ResetLabelStyle();
}
findSelectedItem();
rows();
curtains();
tutor();
}
var spaceBetweenPages = 10;
if (pagesScrollPos == -1)
pagesScrollPos = data.curPageIndex;
while (data.pages.Count <= pagesScrollPos.CeilToInt())
data.pages.Add(new Page("Page " + (data.pages.Count + 1)));
for (int i = pagesScrollPos.FloorToInt(); i <= pagesScrollPos.CeilToInt(); i++)
page(totalRect_groupSpace.SetX((totalRect_groupSpace.width + spaceBetweenPages) * (i - pagesScrollPos)), data.pages[i]);
}
void widget()
{
var widthToAdd = 48;
var height = 24;
var distToBottom = 13;
var color = isDarkTheme ? Greyscale(.1f) : Greyscale(.85f);
var shadowSize = 10;
var shadowAlpha = .23f;
var chevronSize = 15;
var chevronOffset = 12;
var chevronBrightness = .5f;
var textSize = 11;
var textBrightness = .65f;
widgetRect_groupSpace = totalRect_groupSpace.SetWidthFromMid(data.curPage.name.GetLabelWidth(textSize) + widthToAdd).SetHeightFromBottom(height).MoveY(-distToBottom);
void shadow()
{
widgetRect_groupSpace.Resize(1).DrawBlurred(Greyscale(0f, shadowAlpha), shadowSize);
}
void background()
{
widgetRect_groupSpace.DrawWithRoundedCorners(color, 1223);
}
void nameLabel()
{
if (renamingPage) return;
var buttonRect = widgetRect_groupSpace.SetWidthFromMid(data.curPage.name.GetLabelWidth(textSize) - 2);
buttonRect.MarkInteractive();
var activated = curEvent.isMouseUp && buttonRect.IsHovered();
var brightness = !buttonRect.IsHovered() ? textBrightness : (mousePressed ? .75f : 1);
SetGUIColor(Greyscale(brightness));
SetLabelAlignmentCenter();
SetLabelFontSize(textSize);
SetLabelBold();
GUI.Label(widgetRect_groupSpace, data.curPage.name);
ResetGUIColor();
ResetLabelStyle();
if (!activated) return;
renamingPage = true;
prevPageName = data.curPage.name;
curEvent.Use();
}
void leftButton()
{
if (renamingPage) return;
var iconRect = widgetRect_groupSpace.SetWidth(chevronOffset * 2).SetSizeFromMid(chevronSize, chevronSize);
var buttonRect = Rect.zero.SetX(0).SetY(widgetRect_groupSpace.y).SetXMax(iconRect.xMax + 4).SetYMax(totalRect_groupSpace.yMax);
buttonRect.MarkInteractive();
var active = data.curPageIndex > 0;
var activated = curEvent.isMouseUp && buttonRect.IsHovered();
var brightness = prevPageButtonBrightness * (!buttonRect.IsHovered() || !active ? chevronBrightness : (mousePressed ? .75f : 1));
SetGUIColor(Greyscale(brightness));
GUI.DrawTexture(iconRect, EditorGUIUtility.IconContent("NodeChevronLeft@2x").image);
ResetGUIColor();
if (!activated) return;
curEvent.Use();
if (!active) return;
CancelDragging();
CancelRowAnimations();
data.curPageIndex--;
}
void rightButton()
{
if (renamingPage) return;
var iconRect = widgetRect_groupSpace.SetWidthFromRight(chevronOffset * 2).SetSizeFromMid(chevronSize, chevronSize);
var buttonRect = Rect.zero.SetX(iconRect.x - 6).SetY(widgetRect_groupSpace.y).SetXMax(totalRect_groupSpace.xMax).SetYMax(totalRect_groupSpace.yMax);
buttonRect.MarkInteractive();
var active = true;// data.curPageIndex < data.pages.Count - 1 && data.curPage.items.Any();
var activated = curEvent.isMouseUp && buttonRect.IsHovered();
var brightness = nextPageButtonBrightness * (!buttonRect.IsHovered() || !active ? chevronBrightness : (mousePressed ? .75f : 1));
SetGUIColor(Greyscale(brightness));
GUI.DrawTexture(iconRect, EditorGUIUtility.IconContent("NodeChevronRight@2x").image);
ResetGUIColor();
if (!activated) return;
curEvent.Use();
if (!active) return;
CancelDragging();
CancelRowAnimations();
data.curPageIndex++;
}
void nameTextField()
{
if (!renamingPage) return;
var textFieldRect = widgetRect_groupSpace.AddHeightFromMid(-2).SetWidthFromMid(data.curPage.name.GetLabelWidth(textSize) + 4);
var s = new GUIStyle(GUI.skin.textField);
s.alignment = TextAnchor.MiddleCenter;
s.fontSize = 11;
EditorGUIUtility.AddCursorRect(textFieldRect, MouseCursor.CustomCursor);
GUI.SetNextControlName("asdasdasd");
EditorGUI.FocusTextInControl("asdasdasd");
data.curPage.name = EditorGUI.TextField(textFieldRect, data.curPage.name, s);
if (data.curPage.name.IsNullOrEmpty())
data.curPage.name = "Page " + (data.curPageIndex + 1);
EditorGUIUtility.AddCursorRect(textFieldRect, MouseCursor.CustomCursor);
}
void cancelRename_button()
{
if (!renamingPage) return;
var iconRect = widgetRect_groupSpace.SetWidth(chevronOffset * 2).SetSizeFromMid(chevronSize - 2);
var buttonRect = iconRect.SetSizeFromMid(25, 25);
buttonRect.MarkInteractive();
var brightness = !buttonRect.IsHovered() ? chevronBrightness : (mousePressed ? .75f : 1);
SetGUIColor(Greyscale(brightness));
GUI.DrawTexture(iconRect, EditorGUIUtility.IconContent("CrossIcon").image);
ResetGUIColor();
if (!curEvent.isMouseUp) return;
if (!buttonRect.IsHovered()) return;
curEvent.Use();
data.curPage.name = prevPageName;
renamingPage = false;
}
void acceptRename_button()
{
if (!renamingPage) return;
var iconRect = widgetRect_groupSpace.SetWidthFromRight(chevronOffset * 2).SetSizeFromMid(chevronSize - 0);
var buttonRect = iconRect.SetSizeFromMid(25, 25);
buttonRect.MarkInteractive();
var brightness = !buttonRect.IsHovered() ? chevronBrightness : (mousePressed ? .75f : 1);
SetGUIColor(Greyscale(brightness));
GUI.DrawTexture(iconRect, EditorGUIUtility.IconContent("check").image);
ResetGUIColor();
if (!curEvent.isMouseUp) return;
if (!buttonRect.IsHovered()) return;
curEvent.Use();
renamingPage = false;
data.Dirty();
data.Save();
}
void acceptRename_enterKey()
{
if (!renamingPage) return;
if (curEvent.keyCode != KeyCode.Return) return;
renamingPage = false;
data.Dirty();
data.Save();
}
void cancelRename_escapeKey()
{
if (!renamingPage) return;
if (curEvent.keyCode != KeyCode.Escape) return;
data.curPage.name = prevPageName;
renamingPage = false;
}
shadow();
background();
leftButton();
rightButton();
nameLabel();
nameTextField();
cancelRename_button();
acceptRename_button();
acceptRename_enterKey();
cancelRename_escapeKey();
}
void keys()
{
if (isWrappedBrowserLocked && !totalRect_browserSpace.IsHovered()) return;
void prevPage()
{
if (!curEvent.isKeyDown) return;
if (curEvent.keyCode != KeyCode.LeftArrow) return;
if (!VFavoritesMenu.arrowKeysEnabled) return;
if (data.curPageIndex == 0) return;
CancelDragging();
CancelRowAnimations();
data.curPageIndex--;
prevPageButtonBrightness = 2;
curEvent.Use();
}
void nextPage()
{
if (curEvent.keyCode != KeyCode.RightArrow) return;
if (!curEvent.isKeyDown) return;
if (!VFavoritesMenu.arrowKeysEnabled) return;
CancelDragging();
CancelRowAnimations();
data.curPageIndex++;
nextPageButtonBrightness = 2;
curEvent.Use();
}
void selectPrev()
{
if (!curEvent.isKeyDown) return;
if (curEvent.keyCode != KeyCode.UpArrow) return;
if (!VFavoritesMenu.arrowKeysEnabled) return;
var iToSelect = data.curPage.items.IndexOfFirst(r => r.isSelected) - 1;
if (iToSelect < 0)
iToSelect = data.curPage.items.LastIndex();
if (iToSelect.IsInRangeOf(data.curPage.items))
SelectItem(data.curPage.items[iToSelect]);
curEvent.Use();
}
void selectNext()
{
if (!curEvent.isKeyDown) return;
if (curEvent.keyCode != KeyCode.DownArrow) return;
if (!VFavoritesMenu.arrowKeysEnabled) return;
var iToSelect = data.curPage.items.IndexOfFirst(r => r.isSelected) + 1;
if (iToSelect >= data.curPage.items.Count)
iToSelect = 0;
if (iToSelect.IsInRangeOf(data.curPage.items))
SelectItem(data.curPage.items[iToSelect]);
curEvent.Use();
}
void numberKeys()
{
if (!curEvent.isKeyDown) return;
if (!VFavoritesMenu.numberKeysEnabled) return;
if (EditorGUIUtility.editingTextField) return;
var i = ((int)curEvent.keyCode - 48);
if (i == 0) i = 10;
if (!i.IsInRange(1, 10)) return;
data.curPageIndex = i - 1;
curEvent.Use();
}
prevPage();
nextPage();
selectPrev();
selectNext();
numberKeys();
}
void doOriginalGUIFirst_()
{
originalBrowserGUI();
GUI.BeginGroup(totalRect_browserSpace);
GUI.color = GUI.color.SetAlpha(currentOpacity);
background();
pages();
widget();
GUI.color = GUI.color.SetAlpha(1);
GUI.EndGroup();
}
void doVFavoritesGUIFirst_()
{
keys();
pageScroll();
GUI.BeginGroup(totalRect_browserSpace);
widget();
pages();
GUI.EndGroup();
if (totalRect_browserSpace.IsHovered())
if (curEvent.isMouseUp || curEvent.isMouseDrag || curEvent.isScroll) // prevents these events from reaching original gui
curEvent.Use();
originalBrowserGUI();
}
void originalBrowserGUI()
{
if (origBrowserOnGUIDelegate.GetMethodInfo().DeclaringType.Name.Contains("VTabs")) return;
if (isOneColumn && currentOpacity.Approx(1)) // to optimize locked one-column browser functioning as a dedicated favorites window
if (originalGUICalledOnce) // needs to be called once to init stuff so pinging object won't throw exceptions
return;
if (origBrowserOnGUIDelegate.GetMethodInfo().IsStatic) // wrapped by vFolders
origBrowserOnGUIDelegate.GetMethodInfo().Invoke(null, new[] { wrappedBrowser });
else
origBrowserOnGUIDelegate.GetMethodInfo().Invoke(wrappedBrowser, null);
originalGUICalledOnce = true;
}
createData();
closeNavbarSearch();
UpdateMouseState();
UpdateDragging();
var doOriginalGUIFirst = VFavoritesMenu.pageScrollEnabled ? curEvent.isRepaint || curEvent.isLayout
: curEvent.isRepaint;
if (renamingPage)
doOriginalGUIFirst = !curEvent.isMouseDown && !curEvent.isMouseUp;
if (renamingPage && curEvent.isMouseDown)
curEvent.Use();
if (doOriginalGUIFirst)
doOriginalGUIFirst_();
else
doVFavoritesGUIFirst_();
if (isWrappedBrowserLocked)
if (!totalRect_browserSpace.IsHovered() && !animatingDroppedItem && !animatingPageScroll) return;
if (animatingOpacity || animatingDroppedItem || animatingPageScroll || animatingRowGaps)
wrappedBrowser.Repaint();
}
static void SelectItem(Item item)
{
void openFolder(EditorWindow browser, string path)
{
var folderAsset = AssetDatabase.LoadAssetAtPath<Object>(path);
if (browser.GetFieldValue<int>("m_ViewMode") == 1)
browser.InvokeMethod("SetFolderSelection", new[] { folderAsset.GetInstanceID() }, false);
else
{
Selection.activeObject = folderAsset;
browser.GetMemberValue("m_AssetTree")?.GetPropertyValue("data")?.InvokeMethod("SetExpanded", folderAsset.GetInstanceID(), true);
}
}
void selectSceneObject()
{
if (!item.isSceneGameObject) return;
Selection.activeObject = item.obj;
}
void selectAsset_twoColumns()
{
if (!item.isAsset) return;
if (wrappedBrowser.GetFieldValue<int>("m_ViewMode") != 1) return;
openFolder(wrappedBrowser, item.assetPath.GetParentPath());
Selection.activeObject = item.obj;
}
void selectAsset_oneColumn()
{
if (!item.isAsset) return;
if (wrappedBrowser.GetFieldValue<int>("m_ViewMode") != 0) return;
Selection.activeObject = item.obj;
}
void openFolder_unlocked()
{
if (!item.isFolder) return;
if (isWrappedBrowserLocked) return;
openFolder(wrappedBrowser, item.assetPath);
}
void openFolder_locked()
{
if (!item.isFolder) return;
if (!isWrappedBrowserLocked) return;
var unlockedBrowser = allBrowsers.FirstOrDefault(r => !r.GetMemberValue<bool>("isLocked"));
var browserToUse = isOneColumn ? unlockedBrowser : lockedBrowser;
if (!browserToUse) return;
openFolder(browserToUse, item.assetPath);
}
selectSceneObject();
selectAsset_twoColumns();
selectAsset_oneColumn();
openFolder_unlocked();
openFolder_locked();
item.lastSelectTime_ticks = data.curPage.lastItemSelectTime_ticks = System.DateTime.UtcNow.Ticks;
}
static void OpenItem(Item item)
{
void openText()
{
if (item.assetPath.GetExtension() != ".cs"
&& item.assetPath.GetExtension() != ".shader"
&& item.assetPath.GetExtension() != ".compute"
&& item.assetPath.GetExtension() != ".cginc"
&& item.assetPath.GetExtension() != ".json") return;
AssetDatabase.OpenAsset(item.globalId.guid.LoadGuid());
}
void openPrefab()
{
if (item.type != typeof(GameObject)) return;
if (!item.isLoadable) return;
if ((item.obj as GameObject).scene.rootCount != 0) return;
AssetDatabase.OpenAsset(item.obj);
}
void openScene()
{
if (item.type != typeof(SceneAsset)) return;
EditorSceneManager.SaveOpenScenes();
EditorSceneManager.OpenScene(item.assetPath);
}
void openSceneForNotLoadedGameObject()
{
if (!item.isSceneGameObject) return;
if (item.isLoadable) return;
if (item.isDeleted) return;
EditorSceneManager.SaveOpenScenes();
EditorSceneManager.OpenScene(item.assetPath);
Selection.activeObject = item.obj;
}
openText();
openPrefab();
openScene();
openSceneForNotLoadedGameObject();
}
static float rowHeight => 44 * data.rowScale;
static float crossButtonOffsetFromRight = 23;
static float crossButtonSize = 16;
static Rect totalRect_browserSpace
{
get
{
if (isOneColumn)
return wrappedBrowser.position.SetPos(0, 0);
var treeViewRect = wrappedBrowser.GetFieldValue<Rect>("m_TreeViewRect");
return wrappedBrowser.position.SetPos(0, 0).SetWidth(treeViewRect.width).SetHeightFromBottom(treeViewRect.height);
}
}
static Rect totalRect_groupSpace => totalRect_browserSpace.SetPos(0, 0);
static Rect widgetRect_browserSpace => widgetRect_groupSpace.MoveY(totalRect_browserSpace.y);
static Rect widgetRect_groupSpace;
static bool renamingPage;
static string prevPageName;
static int lastNumberKeyPressedIndex;
static long lastNumberKeyPressedTime_ticks;
static bool isOneColumn => wrappedBrowser?.GetFieldValue<int>("m_ViewMode") == 0;
static bool skipNextRepaint;
static bool originalGUICalledOnce;
static void UpdateMouseState() // called from WrappedOnGUI
{
if (!shortcutPressed && !isWrappedBrowserLocked) { setDefaultState(); return; }
if (!totalRect_browserSpace.IsHovered()) { setDefaultState(); return; }
void setDefaultState()
{
mousePressed = false;
mousePressedOnCrossButtonArea = false;
mousePressedOnWidget = false;
pressedItem = null;
doubleclickUnhandled = false;
}
void position()
{
mousePosiion_browserSpace = curEvent.mousePosition;
}
void down()
{
if (!curEvent.isMouseDown) return;
mousePressed = true;
mousePressedOnCrossButtonArea = totalRect_browserSpace.SetWidthFromRight(0).MoveX(-crossButtonOffsetFromRight).SetWidthFromMid(crossButtonSize).IsHovered();
mousePressedOnWidget = curEvent.mousePosition.y >= widgetRect_browserSpace.y;
mouseDownPosiion_browserSpace = curEvent.mousePosition;
var pressedItemIndex = (mouseDownPosition_rowsSpace.y / rowHeight).FloorToInt();
if (pressedItemIndex.IsInRangeOf(data.curPage.items) && !mousePressedOnCrossButtonArea && !mousePressedOnWidget)
pressedItem = data.curPage.items[pressedItemIndex];
doubleclickUnhandled = !mousePressedOnCrossButtonArea && curEvent.clickCount == 2;
curEvent.Use();
}
void up()
{
if (!curEvent.isMouseUp) return;
mousePressed = false;
doubleclickUnhandled = false;
pressedItem = null;
}
position();
down();
up();
}
static bool mousePressed;
static bool mousePresesdOnItem => pressedItem != null;
static bool mousePressedOnCrossButtonArea;
static bool mousePressedOnWidget;
static bool doubleclickUnhandled;
static float groupRectOffsetY => isOneColumn ? 0 : -20;
static Vector2 mousePosiion_browserSpace;
static Vector2 mousePosition_groupSpace => mousePosiion_browserSpace.AddY(groupRectOffsetY);
static Vector2 mousePosition_rowsSpace => mousePosiion_browserSpace.AddY(groupRectOffsetY + data.curPage.scrollPos);
static Vector2 mouseDownPosiion_browserSpace;
static Vector2 mouseDownPosition_groupSpace => mouseDownPosiion_browserSpace.AddY(groupRectOffsetY);
static Vector2 mouseDownPosition_rowsSpace => mouseDownPosiion_browserSpace.AddY(groupRectOffsetY + data.curPage.scrollPos);
static float mouseDragDistance => (mousePosiion_browserSpace - mouseDownPosiion_browserSpace).magnitude;
static Item pressedItem;
static void UpdateAnimations() // Update
{
void calcDeltaTime()
{
deltaTime = (float)(EditorApplication.timeSinceStartup - lastLayoutTime);
if (deltaTime > .05f)
deltaTime = .0166f;
lastLayoutTime = EditorApplication.timeSinceStartup;
}
void opacity()
{
if (!VFavoritesMenu.fadeAnimationsEnabled) { currentOpacity = targetOpacity; return; }
if (!UnityEditorInternal.InternalEditorUtility.isApplicationActive) { currentOpacity = targetOpacity; return; }
SmoothDamp(ref currentOpacity, targetOpacity, 11, ref currentOpacityDerivative, deltaTime);
if (targetOpacity == 0 && currentOpacity < .04f)
currentOpacity = 0;
}
void pagesScroll()
{
if (!data) return;
if (!VFavoritesMenu.pageScrollAnimationEnabled) { pagesScrollPos = data.curPageIndex; return; }
if (pagesScrollPos == -1)
pagesScrollPos = data.curPageIndex;
SmoothDamp(ref pagesScrollPos, data.curPageIndex, 5, ref pagesScrollDerivative, deltaTime);
if (pagesScrollPos.DistanceTo(data.curPageIndex) < .001f)
pagesScrollPos = data.curPageIndex;
}
void rowGaps()
{
if (!data) return;
var lerpSpeed = 10;
for (int i = 0; i < data.curPage.rowGaps.Count; i++)
data.curPage.rowGaps[i] = Lerp(data.curPage.rowGaps[i], draggingItem && i == insertDraggedItemAtIndex ? rowHeight : 0, lerpSpeed, deltaTime);
}
void droppedItem()
{
if (!animatingDroppedItem) return;
var yLerpSpeed = 8;
var shadowLerpSpeed = 8;
var highlightLerpSpeed = 10;
SmoothDamp(ref droppedItemY_rowsSpace, data.curPage.items.IndexOf(VFavorites.droppedItem) * rowHeight, yLerpSpeed, ref droppedItemYDerivative, deltaTime);
Lerp(ref droppedItemShadowAmount, 0, shadowLerpSpeed, deltaTime);
Lerp(ref droppedItemHighlightAmount, 0, highlightLerpSpeed, deltaTime);
if (droppedItemShadowAmount < .01f)
animatingDroppedItem = false;
}
void pageButtons()
{
if (!VFavoritesMenu.pageScrollAnimationEnabled) { prevPageButtonBrightness = nextPageButtonBrightness = 1; return; }
var lerpSpeed = 7;
Lerp(ref prevPageButtonBrightness, 1, lerpSpeed, deltaTime);
Lerp(ref nextPageButtonBrightness, 1, lerpSpeed, deltaTime);
}
calcDeltaTime();
opacity();
pagesScroll();
rowGaps();
droppedItem();
pageButtons();
}
static void CancelRowAnimations()
{
for (int i = 0; i < data.curPage.rowGaps.Count; i++)
data.curPage.rowGaps[i] = 0;
animatingDroppedItem = false;
droppedItem = null;
}
static float deltaTime;
static double lastLayoutTime;
static bool animatingRowGaps => data.curPage.rowGaps.Any(r => r > .1f && r < rowHeight - .1f);
static float pagesScrollPos = -1;
static float pagesScrollDerivative;
static bool animatingPageScroll => !pagesScrollPos.Approx(data ? data.curPageIndex : 0);
static float droppedItemY_rowsSpace;
static float droppedItemYDerivative;
static float droppedItemShadowAmount;
static float droppedItemHighlightAmount;
static bool animatingDroppedItem;
static float prevPageButtonBrightness = 1;
static float nextPageButtonBrightness = 1;
static float currentOpacity;
static float currentOpacityDerivative;
static float targetOpacity => curEvent.holdingAlt || renamingPage || draggingItemFromPageToOutside || isWrappedBrowserLocked ? 1 : 0; // holdingAlt instead of shortcutPressed to prevent unwrapping due to incorrect event modifiers on key down on mac
static bool animatingOpacity => currentOpacity.DistanceTo(targetOpacity) > .01f;
static void UpdateDragging() // called from WrappedOnGUI
{
void initFromOutside()
{
if (draggingItem) return;
if (!totalRect_browserSpace.IsHovered()) return;
if (!curEvent.isDragUpdate) return;
if (!DragAndDrop.objectReferences.FirstOrDefault()) return;
if (draggingItemFromPageToOutside) return; // to avoid duplication when dragging item from page to outside and back
animatingDroppedItem = false;
draggingItem = true;
draggingItemFromPage = false;
draggedItem = new Item(DragAndDrop.objectReferences.FirstOrDefault());
draggedItemHoldOffset = 0;
data.curPage.lastItemDragTime_ticks = System.DateTime.UtcNow.Ticks;
}
void initFromPage()
{
if (draggingItem) return;
if (!totalRect_browserSpace.IsHovered()) return;
if (!curEvent.isMouseDrag) return;
if (mouseDragDistance < 2) return;
var i = (mouseDownPosition_rowsSpace.y / rowHeight).FloorToInt();
if (i >= data.curPage.items.Count) return;
if (i < 0) return; // somehow i = -1 with mouseDownPosition_rowsSpace.y = -20 when dragging in from outside quickly
animatingDroppedItem = false;
draggingItem = true;
draggingItemFromPage = true;
draggingItemFromPageAtIndex = i;
draggedItem = data.curPage.items[i];
draggedItemHoldOffset = (i * rowHeight + rowHeight / 2) - mouseDownPosition_rowsSpace.y;
data.curPage.lastItemDragTime_ticks = System.DateTime.UtcNow.Ticks;
data.curPage.items.Remove(draggedItem);
data.curPage.rowGaps[draggingItemFromPageAtIndex] = rowHeight;
data.Dirty();
data.Save();
}
void acceptFromOutside()
{
if (!draggingItem) return;
if (!curEvent.isDragPerform) return;
DragAndDrop.AcceptDrag();
curEvent.Use();
AcceptDragging();
}
void acceptFromPage()
{
if (!draggingItem) return;
if (!curEvent.isMouseUp) return;
curEvent.Use();
AcceptDragging();
}
void cancelFromOutside()
{
if (!draggingItemFromOutside) return;
if (totalRect_browserSpace.IsHovered()) return;
CancelDragging();
}
void cancelFromPageAndInitToOutside()
{
if (!curEvent.isMouseDrag) return;
if (!draggingItemFromPage) return;
if (totalRect_browserSpace.IsHovered()) return;
if (DragAndDrop.objectReferences.Any()) return;
DragAndDrop.PrepareStartDrag();
DragAndDrop.objectReferences = new[] { draggedItem.obj };
DragAndDrop.StartDrag(draggedItem.name);
CancelDragging();
draggingItemFromPageToOutside = true;
}
void setVisualMode()
{
if (!draggingItem) return;
DragAndDrop.visualMode = DragAndDropVisualMode.Generic;
}
void setHotControl()
{
if (!draggingItem) return;
EditorGUIUtility.hotControl = EditorGUIUtility.GetControlID(FocusType.Passive);
}
void resetDraggingItemFromPageToOutside() // delayCall loop
{
if (!DragAndDrop.objectReferences.Any())
draggingItemFromPageToOutside = false;
EditorApplication.delayCall -= resetDraggingItemFromPageToOutside;
EditorApplication.delayCall += resetDraggingItemFromPageToOutside;
// DragAndDrop.objectReferences is unreliable outside of delayCall
}
initFromOutside();
initFromPage();
acceptFromOutside();
acceptFromPage();
cancelFromOutside();
cancelFromPageAndInitToOutside();
setVisualMode();
setHotControl();
EditorApplication.delayCall -= resetDraggingItemFromPageToOutside;
EditorApplication.delayCall += resetDraggingItemFromPageToOutside;
}
static void AcceptDragging()
{
draggingItem = false;
draggingItemFromPage = false;
mousePressed = false;
data.curPage.items.AddAt(draggedItem, insertDraggedItemAtIndex);
data.curPage.rowGaps[insertDraggedItemAtIndex] -= rowHeight;
data.curPage.rowGaps.AddAt(0, insertDraggedItemAtIndex);
droppedItem = draggedItem;
droppedItemY_rowsSpace = draggedItemY_groupSpace + data.curPage.scrollPos;
droppedItemYDerivative = 0;
droppedItemShadowAmount = droppedItemHighlightAmount = 1;
animatingDroppedItem = true;
draggedItem = null;
EditorGUIUtility.hotControl = 0;
data.Dirty();
data.Save();
}
static void CancelDragging()
{
if (!draggingItem) return;
draggingItem = false;
mousePressed = false;
if (!draggingItemFromPage) { draggedItem = null; return; }
data.curPage.items.AddAt(draggedItem, draggingItemFromPageAtIndex);
data.curPage.rowGaps[draggingItemFromPageAtIndex] -= rowHeight;
droppedItem = draggedItem;
droppedItemY_rowsSpace = draggedItemY_groupSpace - data.curPage.scrollPos;
droppedItemShadowAmount = droppedItemHighlightAmount = 1;
animatingDroppedItem = true;
draggingItemFromPage = false;
draggedItem = null;
EditorGUIUtility.hotControl = 0;
data.Dirty();
data.Save();
}
static bool draggingItem;
static bool draggingItemFromPage;
static bool draggingItemFromPageToOutside;
static bool draggingItemFromOutside => draggingItem && !draggingItemFromPage;
static int draggingItemFromPageAtIndex;
static Item draggedItem;
static float draggedItemHoldOffset;
static float draggedItemY_groupSpace => (mousePosition_groupSpace.y - rowHeight / 2 + draggedItemHoldOffset).Clamp(0, 12321);
static float draggedItemY_rowsSpace => draggedItemY_groupSpace + data.curPage.scrollPos;
static int insertDraggedItemAtIndex => ((mousePosition_rowsSpace.y + draggedItemHoldOffset) / rowHeight).FloorToInt().Clamp(0, data.curPage.items.Count);
static Item droppedItem;
static void UpdateGUIWrapping() // called from EditorApplicaton.update
{
void wrap()
{
if (wrappedBrowser) return;
if (!UnityEditorInternal.InternalEditorUtility.isApplicationActive) return;
if (!shortcutPressed) return;
if (EditorWindow.mouseOverWindow?.GetType() != t_BrowserWindow) return;
if (t_VTabs != null && !EditorPrefsCached.GetBool("vTabs-pluginDisabled", false) && EditorWindow.mouseOverWindow.GetMemberValue<bool>("isLocked")) return;
WrapBrowserGUI(EditorWindow.mouseOverWindow);
wrappedBrowser = EditorWindow.mouseOverWindow;
wrappedBrowser.Focus();
wrappedBrowser.Repaint();
t_BrowserWindow.SetFieldValue("s_LastInteractedProjectBrowser", wrappedBrowser); // so vTabs can copy its layout setting
}
void unwrap()
{
if (!wrappedBrowser) return;
if (shortcutPressed && wrappedBrowser.hasFocus) return;
if (currentOpacity > 0 && wrappedBrowser.hasFocus) return;
CancelDragging();
CancelRowAnimations();
UnwrapBrowserGUI();
wrappedBrowser.Repaint();
wrappedBrowser = null;
}
unwrap();
wrap();
}
static void WrapBrowserGUI(EditorWindow browser)
{
var hostView = fi_m_Parent.GetValue(browser);
var newDelegate = mi_WrappedOnGUI.CreateDelegate(t_EditorWindowDelegate, hostView);
origBrowserOnGUIDelegate = fi_m_OnGUI.GetValue(hostView) as System.Delegate;
fi_m_OnGUI.SetValue(hostView, newDelegate);
}
static void UnwrapBrowserGUI()
{
if (wrappedBrowser.GetFieldValue("m_Parent").GetFieldValue<System.Delegate>("m_OnGUI").Method != mi_WrappedOnGUI) return;
wrappedBrowser.GetFieldValue("m_Parent").SetFieldValue("m_OnGUI", origBrowserOnGUIDelegate);
}
static EditorWindow wrappedBrowser;
static System.Delegate origBrowserOnGUIDelegate;
static bool shortcutPressed
{
get
{
if (VFavoritesMenu.activeOnAltEnabled)
return curEvent.holdingAlt;
if (VFavoritesMenu.activeOnAltShiftEnabled)
return curEvent.modifiers == (EventModifiers.Alt | EventModifiers.Shift);
if (VFavoritesMenu.activeOnCtrlAltEnabled)
if (Application.platform == RuntimePlatform.OSXEditor)
return curEvent.modifiers == (EventModifiers.Command | EventModifiers.Alt);
else
return curEvent.modifiers == (EventModifiers.Control | EventModifiers.Alt);
return false;
}
}
static void UpdateLocking() // called from EditorApplicaton.update
{
void unsetWrappedBrowser()
{
if (!isWrappedBrowserLocked) return;
if (wrappedBrowser.GetFieldValue("m_Parent").GetFieldValue<System.Delegate>("m_OnGUI").Method == mi_WrappedOnGUI) return;
wrappedBrowser = null;
// nulls wrappedBrowser if it was unwrapped externally
// ie when locked browser gets moved or maximized
}
void markLockedBrowser()
{
if (!lockedBrowser) return;
MarkAsLocked(lockedBrowser);
// fixes marking getting reset on scene load
}
void setMinWidthOnLockedBrowser()
{
if (!lockedBrowser) return;
if (lockedBrowser.minSize.x == 100) return;
lockedBrowser.minSize = Vector2.one * 100;
}
void lock_()
{
if (lockedBrowser) return;
if (!wrappedBrowser) return;
if (!wrappedBrowser.GetMemberValue<bool>("isLocked")) return;
lockedBrowser = wrappedBrowser;
EditorPrefsCached.SetInt("vFavorites-lockedBrowserHash", lockedBrowser.GetHashCode());
EditorPrefsCached.SetInt("vFavorites-lockedBrowserDockAreaInstanceId", lockedBrowser.GetMemberValue<Object>("m_Parent").GetInstanceID());
curEvent.Use();
}
void unlock()
{
if (!lockedBrowser) return;
if (lockedBrowser.GetMemberValue<bool>("isLocked")) return;
lockedBrowser = null;
EditorPrefsCached.SetInt("vFavorites-lockedBrowserHash", 0);
EditorPrefsCached.SetInt("vFavorites-lockedBrowserDockAreaInstanceId", 0);
curEvent.Use();
}
void wrap()
{
if (!lockedBrowser) return;
if (!lockedBrowser.hasFocus) return;
if (isWrappedBrowserLocked) return;
WrapBrowserGUI(lockedBrowser);
currentOpacity = 1;
wrappedBrowser = lockedBrowser;
}
unsetWrappedBrowser();
markLockedBrowser();
setMinWidthOnLockedBrowser();
lock_();
unlock();
wrap();
}
static EditorWindow lockedBrowser
{
get
{
if (_lockedBrowser) return _lockedBrowser;
var lockedBrowserInstanceId = EditorPrefsCached.GetInt("vFavorites-lockedBrowserInstanceId", 0);
if (lockedBrowserInstanceId == 0) return null;
var window = Resources.InstanceIDToObject(lockedBrowserInstanceId) as EditorWindow;
if (window && window.GetType() == t_BrowserWindow) // prevents iid collisions
_lockedBrowser = window;
if (_lockedBrowser) return _lockedBrowser;
_lockedBrowser = allBrowsers.FirstOrDefault(r => IsMarkedAsLocked(r));
if (_lockedBrowser) return _lockedBrowser; // todo set instanceid
// EditorPrefsCached.SetInt("vFavorites-lockedBrowserInstanceId", 0); // one attempt to find the locked browser isn't enough after unmaximize
return null;
}
set
{
if (_lockedBrowser)
MarkAsUnlocked(_lockedBrowser);
if (value == null)
{
EditorPrefsCached.SetInt("vFavorites-lockedBrowserInstanceId", 0);
_lockedBrowser = null;
}
else
{
EditorPrefsCached.SetInt("vFavorites-lockedBrowserInstanceId", value.GetInstanceID());
MarkAsLocked(value);
_lockedBrowser = value;
}
}
}
static EditorWindow _lockedBrowser;
static bool IsMarkedAsLocked(EditorWindow browser) => browser.GetMemberValue("m_SearchFilter")?.GetMemberValue<string>("m_OriginalText") == "asd";
static void MarkAsLocked(EditorWindow browser) => browser.GetMemberValue("m_SearchFilter")?.SetMemberValue("m_OriginalText", "asd");
static void MarkAsUnlocked(EditorWindow browser) => browser.GetMemberValue("m_SearchFilter")?.SetMemberValue("m_OriginalText", "");
static bool isWrappedBrowserLocked => wrappedBrowser && wrappedBrowser == lockedBrowser;
static bool CanBrowserBeWrapped_byVTabs(EditorWindow browser) => !IsMarkedAsLocked(browser);
static void RepaintOnAltUp() // Update
{
var lastEvent = typeof(Event).GetFieldValue<Event>("s_Current");
if (wasAlt && !lastEvent.alt)
if (EditorWindow.mouseOverWindow?.GetType() == t_BrowserWindow)
EditorApplication.RepaintProjectWindow();
wasAlt = lastEvent.alt;
}
static bool wasAlt;
[InitializeOnLoadMethod]
static void Init()
{
if (VFavoritesMenu.pluginDisabled) return;
void subscribe()
{
EditorApplication.update -= UpdateGUIWrapping;
EditorApplication.update += UpdateGUIWrapping;
EditorApplication.update -= UpdateLocking;
EditorApplication.update += UpdateLocking;
EditorApplication.update -= UpdateAnimations;
EditorApplication.update += UpdateAnimations;
EditorApplication.update -= RepaintOnAltUp;
EditorApplication.update += RepaintOnAltUp;
EditorApplication.quitting -= VFavoritesState.Save;
EditorApplication.quitting += VFavoritesState.Save;
}
void loadData()
{
data = AssetDatabase.LoadAssetAtPath<VFavoritesData>(EditorPrefsCached.GetString("vFavorites-lastKnownDataPath-" + GetProjectId()));
if (data) return;
data = AssetDatabase.FindAssets("t:VFavoritesData").Select(guid => AssetDatabase.LoadAssetAtPath<VFavoritesData>(guid.ToPath())).FirstOrDefault();
if (!data) return;
EditorPrefsCached.SetString("vFavorites-lastKnownDataPath-" + GetProjectId(), data.GetPath());
}
void loadDataDelayed()
{
if (data) return;
EditorApplication.delayCall += () => EditorApplication.delayCall += loadData;
// AssetDatabase isn't up to date at this point (it gets updated after InitializeOnLoadMethod)
// and if current AssetDatabase state doesn't contain the data - it won't be loaded during Init()
// so here we schedule an additional, delayed attempt to load the data
// this addresses reports of data loss when trying to load it on a new machine
}
subscribe();
loadData();
loadDataDelayed();
}
public static VFavoritesData data;
static void BeforeWindowCreated_byVTabs(object dockArea)
{
if (!wrappedBrowser) return;
if (wrappedBrowser.GetFieldValue("m_Parent") != dockArea) return;
CancelDragging();
CancelRowAnimations();
UnwrapBrowserGUI();
draggingItemFromPageToOutside = false;
}
static IEnumerable<EditorWindow> allBrowsers => _allBrowsers ??= t_BrowserWindow.GetFieldValue<IList>("s_ProjectBrowsers").Cast<EditorWindow>();
static IEnumerable<EditorWindow> _allBrowsers;
static Type t_BrowserWindow = typeof(Editor).Assembly.GetType("UnityEditor.ProjectBrowser");
static Type t_HostView = typeof(Editor).Assembly.GetType("UnityEditor.HostView");
static Type t_EditorWindowDelegate = t_HostView.GetNestedType("EditorWindowDelegate", maxBindingFlags);
static FieldInfo fi_m_Parent = typeof(EditorWindow).GetField("m_Parent", maxBindingFlags);
static FieldInfo fi_m_OnGUI = t_HostView.GetField("m_OnGUI", maxBindingFlags);
static MethodInfo mi_WrappedOnGUI = typeof(VFavorites).GetMethod(nameof(WrappedOnGUI), maxBindingFlags);
static Type t_VHierarchy = Type.GetType("VHierarchy.VHierarchy") ?? Type.GetType("VHierarchy.VHierarchy, VHierarchy, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
static Type t_VFolders = Type.GetType("VFolders.VFolders") ?? Type.GetType("VFolders.VFolders, VFolders, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
static Type t_VTabs = Type.GetType("VTabs.VTabs") ?? Type.GetType("VTabs.VTabs, VTabs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
static MethodInfo mi_VHierarchy_GetIconName = t_VHierarchy?.GetMethod("GetIconName_forVFavorites", maxBindingFlags);
static MethodInfo mi_VFolders_DrawBigFolderIcon = t_VFolders?.GetMethod("DrawBigFolderIcon_forVFavorites", maxBindingFlags);
const string version = "2.0.9";
}
}
#endif