Public Access
Give the window its v5b chrome and each session surface its own shell
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user