Files
fluid-explorer/Views/ExplorerTabView.xaml.cs
T

99 lines
3.4 KiB
C#

using System.ComponentModel;
using FluidExplorer.ViewModels;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Input;
namespace FluidExplorer.Views;
/// <summary>一个标签页的宿主:负责单/双窗格布局与中间分隔条。</summary>
public sealed partial class ExplorerTabView : UserControl
{
private bool _dragging;
private double _startX;
private double _startFirstWidth;
private double _startSecondWidth;
public ExplorerTabView()
{
InitializeComponent();
Loaded += (_, _) => UpdatePaneLayout();
}
public static readonly DependencyProperty TabViewModelProperty = DependencyProperty.Register(
nameof(TabViewModel),
typeof(ExplorerTabViewModel),
typeof(ExplorerTabView),
new PropertyMetadata(null, OnTabChanged));
public ExplorerTabViewModel? TabViewModel
{
get => (ExplorerTabViewModel?)GetValue(TabViewModelProperty);
set => SetValue(TabViewModelProperty, value);
}
private static void OnTabChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var view = (ExplorerTabView)d;
if (e.OldValue is ExplorerTabViewModel old) old.PropertyChanged -= view.OnTabPropertyChanged;
if (e.NewValue is ExplorerTabViewModel tab) tab.PropertyChanged += view.OnTabPropertyChanged;
view.UpdatePaneLayout();
}
private void OnTabPropertyChanged(object? sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(ExplorerTabViewModel.IsDualPane)) UpdatePaneLayout();
}
private void UpdatePaneLayout()
{
var dual = TabViewModel?.IsDualPane == true;
if (dual)
{
Splitter.Visibility = Visibility.Visible;
SecondaryPaneView.Visibility = Visibility.Visible;
SplitterColumn.Width = new GridLength(4);
if (FirstColumn.Width.IsAbsolute && SecondColumn.Width.IsAbsolute) return;
FirstColumn.Width = new GridLength(1, GridUnitType.Star);
SecondColumn.Width = new GridLength(1, GridUnitType.Star);
}
else
{
Splitter.Visibility = Visibility.Collapsed;
SecondaryPaneView.Visibility = Visibility.Collapsed;
SplitterColumn.Width = new GridLength(0);
FirstColumn.Width = new GridLength(1, GridUnitType.Star);
SecondColumn.Width = new GridLength(0);
}
}
private void OnSplitterPointerPressed(object sender, PointerRoutedEventArgs e)
{
_dragging = true;
_startX = e.GetCurrentPoint(LayoutRoot).Position.X;
_startFirstWidth = FirstColumn.ActualWidth;
_startSecondWidth = SecondColumn.ActualWidth;
Splitter.CapturePointer(e.Pointer);
}
private void OnSplitterPointerMoved(object sender, PointerRoutedEventArgs e)
{
if (!_dragging) return;
var delta = e.GetCurrentPoint(LayoutRoot).Position.X - _startX;
var total = _startFirstWidth + _startSecondWidth;
const double min = 240;
var first = Math.Clamp(_startFirstWidth + delta, min, total - min);
FirstColumn.Width = new GridLength(first, GridUnitType.Pixel);
SecondColumn.Width = new GridLength(total - first, GridUnitType.Pixel);
}
private void OnSplitterPointerReleased(object sender, PointerRoutedEventArgs e)
{
if (!_dragging) return;
_dragging = false;
Splitter.ReleasePointerCapture(e.Pointer);
}
}