Public Access
64 lines
2.7 KiB
C#
64 lines
2.7 KiB
C#
using System.Windows.Input;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Input;
|
|
using DodoSSH.Client.Shell.ViewModels;
|
|
|
|
namespace DodoSSH.Client.App.Views;
|
|
|
|
/// <summary>
|
|
/// The v5b in-screen tab row: one pill per open terminal, and the "+" that opens another — parameterised by
|
|
/// <see cref="TabCommand"/> so the terminal surface and the SFTP surface can each wire a click to a different
|
|
/// meaning over the same list. See the remark at the top of SessionTabRow.axaml.
|
|
/// </summary>
|
|
internal sealed partial class SessionTabRow : UserControl
|
|
{
|
|
/// <summary>What a left click on a tab runs, with the tab itself as the command parameter.</summary>
|
|
/// <remarks>
|
|
/// A plain <see cref="ICommand"/> rather than a bound property read off the shell, because which command
|
|
/// that is is the one thing this control cannot decide for itself — the terminal surface wants
|
|
/// <c>SelectTabCommand</c> and the SFTP surface wants <c>SelectFilesHostCommand</c>, and only the caller
|
|
/// in <c>MainWindow.axaml</c> knows which screen this instance is on.
|
|
/// </remarks>
|
|
internal static readonly StyledProperty<ICommand?> TabCommandProperty =
|
|
AvaloniaProperty.Register<SessionTabRow, ICommand?>(nameof(TabCommand));
|
|
|
|
public SessionTabRow() => InitializeComponent();
|
|
|
|
internal ICommand? TabCommand
|
|
{
|
|
get => GetValue(TabCommandProperty);
|
|
set => SetValue(TabCommandProperty, value);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Closes a tab on a middle click. See the identical remark on the strip this control replaced,
|
|
/// <c>TerminalTabs.axaml.cs</c>, for why this is <c>PointerUpdateKind</c> rather than
|
|
/// <c>IsMiddleButtonPressed</c>, why it fires on press rather than release, and why it is wired on the
|
|
/// tab's own template root rather than on the row.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Not parameterised like <see cref="TabCommand"/>: closing a tab ends its shell regardless of which
|
|
/// screen the middle click landed on, so both rows want the same answer — <c>CloseTabCommand</c>, read
|
|
/// directly off this control's own <see cref="StyledElement.DataContext"/>, which is the shell on both.
|
|
/// </remarks>
|
|
private void OnTabPointerPressed(object? sender, PointerPressedEventArgs e)
|
|
{
|
|
if (sender is not Visual { DataContext: TerminalTabViewModel tab }
|
|
|| DataContext is not MainWindowViewModel shell)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (e.GetCurrentPoint((Visual)sender).Properties.PointerUpdateKind
|
|
is not PointerUpdateKind.MiddleButtonPressed)
|
|
{
|
|
return;
|
|
}
|
|
|
|
e.Handled = true;
|
|
|
|
shell.CloseTabCommand.Execute(tab);
|
|
}
|
|
}
|