86 lines
3.4 KiB
C#
86 lines
3.4 KiB
C#
namespace FluidExplorer.Navigation;
|
|
|
|
public enum LocationKind
|
|
{
|
|
Home,
|
|
Gallery,
|
|
QuickAccess,
|
|
ThisPc,
|
|
RecycleBin,
|
|
Network,
|
|
Drive,
|
|
Folder,
|
|
Search
|
|
}
|
|
|
|
/// <summary>一个可导航的位置(侧边栏节点、面包屑、标签页都基于它)。</summary>
|
|
public sealed record NavigationLocation(LocationKind Kind, string Path, string DisplayName, string Glyph)
|
|
{
|
|
public static NavigationLocation Home { get; } = new(LocationKind.Home, Services.Shell.KnownFolders.HomeParsingName, "主页", "\uE80F");
|
|
public static NavigationLocation Gallery { get; } = new(LocationKind.Gallery, Services.Shell.KnownFolders.GalleryParsingName, "图库", "\uE91B");
|
|
public static NavigationLocation ThisPc { get; } = new(LocationKind.ThisPc, Services.Shell.KnownFolders.ThisPcParsingName, "此电脑", "\uE977");
|
|
public static NavigationLocation RecycleBin { get; } = new(LocationKind.RecycleBin, Services.Shell.KnownFolders.RecycleBinParsingName, "回收站", "\uE74D");
|
|
public static NavigationLocation Network { get; } = new(LocationKind.Network, Services.Shell.KnownFolders.NetworkParsingName, "网络", "\uE968");
|
|
|
|
public static NavigationLocation FromPath(string path, LocationKind kind = LocationKind.Folder)
|
|
{
|
|
var normalized = Services.FileSystem.PathHelper.NormalizeDisplay(path);
|
|
return new NavigationLocation(kind, normalized, Services.FileSystem.PathHelper.GetName(normalized), "\uE8B7");
|
|
}
|
|
|
|
public static NavigationLocation FromDrive(DriveItemInfo drive)
|
|
=> new(LocationKind.Drive, drive.RootPath, drive.DisplayName, drive.Glyph);
|
|
|
|
/// <summary>是否是外壳虚拟位置(不能用 System.IO 直接枚举,需要走 shell: 视图)。</summary>
|
|
public bool IsVirtual => Kind is LocationKind.Home or LocationKind.Gallery or LocationKind.ThisPc
|
|
or LocationKind.RecycleBin or LocationKind.Network or LocationKind.Search
|
|
|| Path.StartsWith("::", StringComparison.Ordinal) || Path.StartsWith("shell:", StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
public readonly record struct DriveItemInfo(string RootPath, string DisplayName, string Glyph);
|
|
|
|
/// <summary>前进/后退历史(资源管理器行为:新导航截断前进栈)。</summary>
|
|
public sealed class NavigationHistory
|
|
{
|
|
private readonly List<NavigationLocation> _back = [];
|
|
private readonly List<NavigationLocation> _forward = [];
|
|
private const int Capacity = 64;
|
|
|
|
public bool CanGoBack => _back.Count > 1;
|
|
public bool CanGoForward => _forward.Count > 0;
|
|
public NavigationLocation? Current => _back.Count > 0 ? _back[^1] : null;
|
|
|
|
public void Push(NavigationLocation location)
|
|
{
|
|
if (_back.Count > 0 && _back[^1] == location) return;
|
|
_back.Add(location);
|
|
if (_back.Count > Capacity) _back.RemoveAt(0);
|
|
_forward.Clear();
|
|
}
|
|
|
|
public NavigationLocation? Back()
|
|
{
|
|
if (!CanGoBack) return null;
|
|
var current = _back[^1];
|
|
_back.RemoveAt(_back.Count - 1);
|
|
_forward.Add(current);
|
|
return _back[^1];
|
|
}
|
|
|
|
public NavigationLocation? Forward()
|
|
{
|
|
if (_forward.Count == 0) return null;
|
|
var next = _forward[^1];
|
|
_forward.RemoveAt(_forward.Count - 1);
|
|
_back.Add(next);
|
|
return next;
|
|
}
|
|
|
|
public void Reset(NavigationLocation location)
|
|
{
|
|
_back.Clear();
|
|
_forward.Clear();
|
|
_back.Add(location);
|
|
}
|
|
}
|