403 lines
11 KiB
C#
403 lines
11 KiB
C#
#if UNITY_EDITOR
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using UnityEngine;
|
|
using UnityEditor;
|
|
using UnityEditor.ShortcutManagement;
|
|
using UnityEngine.UIElements;
|
|
using UnityEngine.SceneManagement;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEditor.IMGUI.Controls;
|
|
using Type = System.Type;
|
|
using static VFolders.Libs.VUtils;
|
|
using static VFolders.Libs.VGUI;
|
|
// using static VTools.VDebug;
|
|
using static VFolders.VFolders;
|
|
using static VFolders.VFoldersData;
|
|
using static VFolders.VFoldersCache;
|
|
|
|
|
|
|
|
namespace VFolders
|
|
{
|
|
[System.Serializable]
|
|
public class VFoldersHistory
|
|
{
|
|
|
|
public void CheckTreeStateChange()
|
|
{
|
|
if (!VFoldersMenu.navigationBarEnabled) return;
|
|
if (!isOneColumn) return;
|
|
|
|
if (lastTreeState == null) { lastTreeState = new() { scrollPos = currentScrollPos, expandedIds = expandedIds.ToList() }; return; }
|
|
|
|
|
|
var curTreeState = new TreeState();
|
|
|
|
var targetScrollPosChanged = false;
|
|
var targetExpandedIdsChanged = false;
|
|
|
|
|
|
|
|
void set_curState_scrollPos()
|
|
{
|
|
if (controller.animatingScroll)
|
|
curTreeState.scrollPos = controller.targetScrollPos;
|
|
else
|
|
curTreeState.scrollPos = currentScrollPos;
|
|
|
|
}
|
|
void set_curState_expandedIds()
|
|
{
|
|
var expandedIdsHashset = expandedIds.ToHashSet();
|
|
|
|
|
|
|
|
if (treeViewAnimatesExpansion)
|
|
if (animatingItemTragetExpanded_fromTreeViewExpandAnimator == true)
|
|
expandedIdsHashset.UnionWith(new HashSet<int>() { animatingItemId_fromTreeViewExpandAnimator });
|
|
else
|
|
expandedIdsHashset.ExceptWith(new HashSet<int>() { animatingItemId_fromTreeViewExpandAnimator });
|
|
|
|
|
|
|
|
if (controller.animatingExpansion)
|
|
{
|
|
foreach (var r in controller.expandQueue_toAnimate)
|
|
if (r.expand)
|
|
expandedIdsHashset.UnionWith(new HashSet<int>() { r.id });
|
|
else
|
|
expandedIdsHashset.ExceptWith(new HashSet<int>() { r.id });
|
|
|
|
expandedIdsHashset.ExceptWith(controller.expandQueue_toCollapseAfterAnimation.ToHashSet());
|
|
}
|
|
|
|
|
|
curTreeState.expandedIds = expandedIdsHashset.ToList();
|
|
|
|
}
|
|
|
|
void checkScrollPosChange()
|
|
{
|
|
if (framesSinceLastExpansionAnimation < 2) return;
|
|
if (framesSinceLastScrollAnimation < 2) return;
|
|
|
|
if (curTreeState.scrollPos == lastTreeState.scrollPos) return;
|
|
|
|
|
|
|
|
if (EditorApplication.timeSinceStartup - lastScrollTime > 2 || lastTargetStateChangeWasExpandedIds)
|
|
targetScrollPosChanged = true;
|
|
|
|
lastScrollTime = EditorApplication.timeSinceStartup;
|
|
|
|
}
|
|
void checkExpandedIdsChange()
|
|
{
|
|
if (lastTreeState.expandedIds.ToHashSet().SetEquals(curTreeState.expandedIds.ToHashSet())) return;
|
|
|
|
targetExpandedIdsChanged = true;
|
|
|
|
// lastTargetState.expandedIds.LogAll("lastTargetState");
|
|
// curTargetState.expandedIds.LogAll("curTargetState");
|
|
|
|
}
|
|
|
|
void registerStateChange()
|
|
{
|
|
if (!targetScrollPosChanged && !targetExpandedIdsChanged) return;
|
|
|
|
|
|
prevTreeStates.Add(lastTreeState);
|
|
nextTreeStates.Clear();
|
|
|
|
lastTargetStateChangeWasExpandedIds = targetExpandedIdsChanged;
|
|
|
|
|
|
if (prevTreeStates.Count > 50)
|
|
prevTreeStates.RemoveAt(0);
|
|
|
|
|
|
// if (targetScrollPosChanged && targetExpandedIdsChanged)
|
|
// "expand and scroll".Log();
|
|
// else if (targetScrollPosChanged)
|
|
// "scroll".Log();
|
|
// else if (targetExpandedIdsChanged)
|
|
// "expand".Log();
|
|
|
|
}
|
|
|
|
void updateCountersSinceAnimation()
|
|
{
|
|
if (controller.animatingExpansion || treeViewAnimatesExpansion)
|
|
framesSinceLastExpansionAnimation = 0;
|
|
else
|
|
framesSinceLastExpansionAnimation++;
|
|
|
|
if (controller.animatingScroll || treeViewAnimatesScroll)
|
|
framesSinceLastScrollAnimation = 0;
|
|
else
|
|
framesSinceLastScrollAnimation++;
|
|
|
|
}
|
|
|
|
|
|
|
|
set_curState_scrollPos();
|
|
set_curState_expandedIds();
|
|
|
|
checkScrollPosChange();
|
|
checkExpandedIdsChange();
|
|
|
|
registerStateChange();
|
|
|
|
updateCountersSinceAnimation();
|
|
|
|
|
|
lastTreeState = curTreeState;
|
|
|
|
}
|
|
|
|
int framesSinceLastExpansionAnimation;
|
|
int framesSinceLastScrollAnimation;
|
|
|
|
public double lastScrollTime = 0;
|
|
|
|
bool lastTargetStateChangeWasExpandedIds;
|
|
|
|
[System.NonSerialized] TreeState lastTreeState = null;
|
|
|
|
|
|
|
|
public void CheckFolderPathChange()
|
|
{
|
|
if (!VFoldersMenu.navigationBarEnabled) return;
|
|
if (isOneColumn) return;
|
|
|
|
var curFolderPath = window.GetMemberValue("m_SearchFilter").GetMemberValue<string[]>("folders").FirstOrDefault();
|
|
|
|
if (curFolderPath.IsNullOrEmpty()) return;
|
|
|
|
if (lastFolderPath.IsNullOrEmpty()) lastFolderPath = curFolderPath;
|
|
if (curFolderPath == lastFolderPath) return;
|
|
|
|
|
|
prevFolderPaths.Add(lastFolderPath);
|
|
nextFolderPaths.Clear();
|
|
|
|
if (prevFolderPaths.Count > 50)
|
|
prevFolderPaths.RemoveAt(0);
|
|
|
|
|
|
lastFolderPath = curFolderPath;
|
|
|
|
}
|
|
|
|
string lastFolderPath = "";
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void UpdateState()
|
|
{
|
|
if (!VFoldersMenu.navigationBarEnabled) return;
|
|
|
|
|
|
isOneColumn = window.GetFieldValue<int>("m_ViewMode") == 0;
|
|
|
|
var treeViewController = window.GetFieldValue(isOneColumn ? "m_AssetTree" : "m_FolderTree");
|
|
var treeViewControllerData = treeViewController?.GetPropertyValue("data");
|
|
|
|
|
|
|
|
var treeViewControllerState = treeViewController?.GetPropertyValue<TreeViewState>("state");
|
|
|
|
currentScrollPos = treeViewControllerState?.scrollPos.y ?? 0;
|
|
|
|
expandedIds = treeViewControllerState?.expandedIDs ?? new List<int>();
|
|
|
|
|
|
|
|
var treeViewAnimator = treeViewController?.GetMemberValue("m_ExpansionAnimator");
|
|
var treeViewAnimatorSetup = treeViewAnimator?.GetMemberValue("m_Setup");
|
|
|
|
treeViewAnimatesScroll = treeViewController?.GetMemberValue<UnityEditor.AnimatedValues.AnimFloat>("m_FramingAnimFloat").isAnimating ?? false;
|
|
|
|
treeViewAnimatesExpansion = treeViewAnimator?.GetMemberValue<bool>("isAnimating") ?? false;
|
|
animatingItemTragetExpanded_fromTreeViewExpandAnimator = treeViewAnimatorSetup?.GetMemberValue<bool>("expanding") ?? false;
|
|
animatingItemId_fromTreeViewExpandAnimator = treeViewAnimatorSetup?.GetMemberValue("item").GetMemberValue<int>("id") ?? 0;
|
|
|
|
}
|
|
|
|
public bool isOneColumn;
|
|
public bool isTwoColumns => !isOneColumn;
|
|
|
|
public bool isSearchActive;
|
|
|
|
public float currentScrollPos;
|
|
|
|
public List<int> expandedIds = new();
|
|
|
|
public bool treeViewAnimatesScroll;
|
|
|
|
public bool treeViewAnimatesExpansion;
|
|
public bool animatingItemTragetExpanded_fromTreeViewExpandAnimator;
|
|
public int animatingItemId_fromTreeViewExpandAnimator;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void MoveBack_OneColumn(bool withAnimation = true)
|
|
{
|
|
var prevState = prevTreeStates.Last();
|
|
|
|
prevTreeStates.Remove(prevState);
|
|
nextTreeStates.Add(lastTreeState);
|
|
lastTreeState = prevState;
|
|
|
|
|
|
if (withAnimation)
|
|
{
|
|
controller.StartScrollAnimation(prevState.scrollPos);
|
|
controller.StartExpandAnimation(prevState.expandedIds);
|
|
}
|
|
else
|
|
{
|
|
controller.SetScrollPos(prevState.scrollPos);
|
|
controller.SetExpandedIds(prevState.expandedIds);
|
|
}
|
|
|
|
}
|
|
public void MoveForward_OneColumn(bool withAnimation = true)
|
|
{
|
|
var nextState = nextTreeStates.Last();
|
|
|
|
nextTreeStates.Remove(nextState);
|
|
prevTreeStates.Add(lastTreeState);
|
|
lastTreeState = nextState;
|
|
|
|
|
|
if (withAnimation)
|
|
{
|
|
controller.StartScrollAnimation(nextState.scrollPos);
|
|
controller.StartExpandAnimation(nextState.expandedIds);
|
|
}
|
|
else
|
|
{
|
|
controller.SetScrollPos(nextState.scrollPos);
|
|
controller.SetExpandedIds(nextState.expandedIds);
|
|
}
|
|
|
|
}
|
|
|
|
public List<TreeState> prevTreeStates = new();
|
|
public List<TreeState> nextTreeStates = new();
|
|
|
|
|
|
|
|
public void MoveBack_TwoColumns(bool withAnimation = true)
|
|
{
|
|
var prevPath = prevFolderPaths.Last();
|
|
|
|
prevFolderPaths.RemoveLast();
|
|
nextFolderPaths.Add(lastFolderPath);
|
|
lastFolderPath = prevPath;
|
|
|
|
|
|
if (withAnimation)
|
|
{
|
|
controller.RevealFolder(prevPath, expand: false, highlight: false, snapToTopMargin: false);
|
|
controller.OpenFolder(prevPath);
|
|
}
|
|
else
|
|
{
|
|
window.InvokeMethod("ShowFolderContents", AssetDatabase.LoadAssetAtPath<DefaultAsset>(prevPath).GetInstanceID(), true);
|
|
}
|
|
|
|
}
|
|
public void MoveForward_TwoColumns(bool withAnimation = true)
|
|
{
|
|
var nextPath = nextFolderPaths.Last();
|
|
|
|
nextFolderPaths.RemoveLast();
|
|
prevFolderPaths.Add(lastFolderPath);
|
|
lastFolderPath = nextPath;
|
|
|
|
|
|
if (withAnimation)
|
|
{
|
|
controller.RevealFolder(nextPath, expand: false, highlight: false, snapToTopMargin: false);
|
|
controller.OpenFolder(nextPath);
|
|
}
|
|
else
|
|
{
|
|
window.InvokeMethod("ShowFolderContents", AssetDatabase.LoadAssetAtPath<DefaultAsset>(nextPath).GetInstanceID(), true);
|
|
}
|
|
|
|
}
|
|
|
|
public List<string> prevFolderPaths = new();
|
|
public List<string> nextFolderPaths = new();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[System.Serializable]
|
|
public class TreeState
|
|
{
|
|
public List<int> expandedIds = new();
|
|
|
|
public float scrollPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public VFoldersHistory(EditorWindow window) => this.window = window;
|
|
|
|
EditorWindow window;
|
|
|
|
VFoldersGUI gui => VFolders.guis_byWindow[window];
|
|
VFoldersController controller => VFolders.controllers_byWindow[window];
|
|
|
|
}
|
|
|
|
|
|
public class VFoldersHistorySingleton : ScriptableSingleton<VFoldersHistorySingleton>
|
|
{
|
|
public SerializableDictionary<EditorWindow, VFoldersHistory> histories_byWindow = new();
|
|
}
|
|
|
|
|
|
}
|
|
#endif |