112 lines
3.7 KiB
C#
112 lines
3.7 KiB
C#
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using FluidExplorer.Navigation;
|
|
using FluidExplorer.Services;
|
|
using FluidExplorer.Services.FileSystem;
|
|
using FluidExplorer.Services.ItemVisuals;
|
|
using FluidExplorer.Services.Operations;
|
|
using FluidExplorer.Services.Search;
|
|
using Microsoft.UI.Dispatching;
|
|
using PathHelper = FluidExplorer.Services.FileSystem.PathHelper;
|
|
|
|
namespace FluidExplorer.ViewModels;
|
|
|
|
/// <summary>一个标签页:包含主窗格,可选第二窗格(双窗格模式,搬文件不用来回切)。</summary>
|
|
public sealed partial class ExplorerTabViewModel : ObservableObject
|
|
{
|
|
private readonly IFileSystemService _fs;
|
|
private readonly SearchService _search;
|
|
private readonly IFileOperationService _operations;
|
|
private readonly ItemVisualService _visuals;
|
|
private readonly IFileClipboard _clipboard;
|
|
private readonly AppSettings _settings;
|
|
private readonly DispatcherQueue _ui;
|
|
|
|
[ObservableProperty] private bool _isDualPane;
|
|
[ObservableProperty] private bool _isActivePaneSecondary;
|
|
[ObservableProperty] private string _header = "新标签页";
|
|
[ObservableProperty] private string _glyph = "\uE8B7";
|
|
|
|
public ExplorerTabViewModel(
|
|
IFileSystemService fs,
|
|
SearchService search,
|
|
IFileOperationService operations,
|
|
ItemVisualService visuals,
|
|
IFileClipboard clipboard,
|
|
AppSettings settings,
|
|
DispatcherQueue ui,
|
|
NavigationLocation start)
|
|
{
|
|
_fs = fs;
|
|
_search = search;
|
|
_operations = operations;
|
|
_visuals = visuals;
|
|
_clipboard = clipboard;
|
|
_settings = settings;
|
|
_ui = ui;
|
|
|
|
Primary = new ExplorerPaneViewModel(fs, search, operations, visuals, clipboard, settings, ui);
|
|
Primary.PropertyChanged += (_, e) =>
|
|
{
|
|
if (e.PropertyName == nameof(ExplorerPaneViewModel.Title)) UpdateHeader();
|
|
};
|
|
Primary.SettingsChanged += (_, _) => UpdateHeader();
|
|
_ = Primary.NavigateAsync(start);
|
|
UpdateHeader();
|
|
}
|
|
|
|
public ExplorerPaneViewModel Primary { get; }
|
|
|
|
[ObservableProperty] private ExplorerPaneViewModel? _secondary;
|
|
|
|
public ExplorerPaneViewModel ActivePane => IsDualPane && IsActivePaneSecondary && Secondary is not null ? Secondary : Primary;
|
|
|
|
public ExplorerPaneViewModel EnsureSecondary()
|
|
{
|
|
if (Secondary is not null) return Secondary;
|
|
var pane = new ExplorerPaneViewModel(_fs, _search, _operations, _visuals, _clipboard, _settings, _ui)
|
|
{
|
|
ShowSidebar = false
|
|
};
|
|
pane.PropertyChanged += (_, e) =>
|
|
{
|
|
if (e.PropertyName == nameof(ExplorerPaneViewModel.Title)) UpdateHeader();
|
|
};
|
|
Secondary = pane;
|
|
return pane;
|
|
}
|
|
|
|
public void ToggleDualPane()
|
|
{
|
|
if (IsDualPane)
|
|
{
|
|
IsDualPane = false;
|
|
IsActivePaneSecondary = false;
|
|
return;
|
|
}
|
|
|
|
var secondary = EnsureSecondary();
|
|
if (string.IsNullOrEmpty(secondary.CurrentPath) || secondary.CurrentPath.StartsWith("::", StringComparison.Ordinal))
|
|
{
|
|
// 第二个窗格默认停在与主窗格同级的目录,便于对拖
|
|
var parent = PathHelper.GetParent(Primary.CurrentPath);
|
|
_ = secondary.NavigateAsync(NavigationLocation.FromPath(
|
|
Directory.Exists(parent) ? parent : Primary.CurrentPath));
|
|
}
|
|
IsDualPane = true;
|
|
}
|
|
|
|
private void UpdateHeader()
|
|
{
|
|
Header = Primary.IsSearchActive && !string.IsNullOrWhiteSpace(Primary.SearchText)
|
|
? $"搜索:{Primary.SearchText}"
|
|
: Primary.Title;
|
|
Glyph = Primary.Glyph;
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Primary.Dispose();
|
|
Secondary?.Dispose();
|
|
}
|
|
}
|