Files
DodoSSH/src/DodoSSH.Client.App/Views/SessionTabRow.axaml
T

129 lines
8.0 KiB
XML

<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="using:DodoSSH.Client.Shell.ViewModels"
x:Class="DodoSSH.Client.App.Views.SessionTabRow"
x:Name="Root"
x:DataType="vm:MainWindowViewModel">
<!--
── v5b's in-screen tab row, the replacement for TerminalTabs ───────────────────────────────────────────
One pill per open terminal and the button that opens another — the same list <c>TerminalTabs</c> drew
above the whole window — now drawn inside each of the two screens the design gives a tab row: the
terminal surface and the SFTP surface. See <c>MainWindow.axaml</c> for where the strip itself went and
<c>Palette.axaml</c>'s v5b remark for why the row is 38 tall rather than the old strip's 42.
One control rather than two copies of the same markup, because the two rows share everything except two
things: which colour marks the active tab, and what a click on a tab actually does. Both are handed in
from the usage site rather than branched on a mode property here.
◆ THE COLOUR is <c>Classes="sftp"</c> on this control's own usage in <c>MainWindow.axaml</c> — unmarked
is the terminal row and reads <c>TerminalTabAccent</c>; <c>.sftp</c> reads <c>Magenta</c>. Both are
<c>App.axaml</c> selectors keyed off that class on this element, which is why the two rows need no
binding of their own for it: <c>Button.sesstab.active</c> and <c>.sftp Button.sesstab.active</c> are
the whole of it.
◆ THE CLICK is <see cref="TabCommand"/>, a plain <c>ICommand</c> this control exposes rather than reads
off the shell — the terminal row binds it to <c>SelectTabCommand</c> and the SFTP row to
<c>SelectFilesHostCommand</c>, and neither of those is a decision this control has any business making.
Every tab button's own <c>CommandParameter</c> is the tab itself, exactly as the strip's was.
The close box, the middle-click gesture and the "+" are not parameterised: closing a tab ends its shell
regardless of which screen it was clicked from, and "+" always opens the same palette. See
<c>MainWindowViewModel.CloseTabCommand</c> and <c>ToggleSearchCommand</c>.
-->
<Border Height="38">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<StackPanel Orientation="Horizontal" Spacing="6">
<ItemsControl ItemsSource="{Binding Tabs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" Spacing="6" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="vm:TerminalTabViewModel">
<!--
Marked on IsSelected rather than IsShowing, unlike the old strip: IsShowing is "the terminal
surface is showing this tab's pane", which the SFTP row's own active tab is never true of. A
selected tab survives navigating away from the terminal surface — that is the whole point of
a selection outliving a screen — so both rows agree on what "active" means without either
one needing a flag scoped to just one surface. See App.axaml's own remark on Button.sesstab.
-->
<Button Classes="sesstab"
Classes.active="{Binding IsSelected}"
Command="{Binding #Root.TabCommand}"
CommandParameter="{Binding}"
PointerPressed="OnTabPointerPressed"
ToolTip.Tip="{Binding Address}">
<StackPanel Orientation="Horizontal" Spacing="9" VerticalAlignment="Center">
<!--
Three states now, where there were two. Green while the shell behind this tab is running
and grey once it has ended, as the strip's dots always were — and amber while it is
connecting, which used to be grey as well.
The design's amber had no meaning here while nothing in this application knew how far a
connection had got; that changed with the step list, and the note this comment used to
carry — that amber is for a host merely reachable, so it is not drawn — is answered
rather than ignored. It is not being reachable that is amber, it is being underway. See
ConnectingCard.axaml, whose track and running step are the same colour for the same
reason, and design-notes/v5b-fidelity-notes.md for the state this is not.
Worth the third colour because the two it replaces were the same one: a tab still
dialling and a tab whose shell has exited both drew grey, which are the two states in
this strip with the least in common — one is worth waiting for and the other is over.
── and a fourth since, splitting that grey ────────────────────────────────────────────
A shell that ended and a connection that broke were still one dot, and they are the two
dead states with the least in common: one is work finished, the other is a machine that
stopped answering and may well still be there. Red for the second, matching the strip
under the terminal — see TerminalTabViewModel.IsDropped and SessionEndedBar.axaml, which
is where the sentence and the way back live.
-->
<Ellipse Classes="dot" Width="8" Height="8" Classes.live="{Binding IsLive}"
Classes.connecting="{Binding IsConnecting}"
Classes.dropped="{Binding IsDropped}"
VerticalAlignment="Center" />
<!--
Bounded. A label is whatever the host was called, or the address typed into the palette,
and one long one used to push every tab after it and the "+" past the strip's edge. The
whole of it is on the label's own tooltip; the tab's is the address, as before.
-->
<TextBlock Text="{Binding Label}" VerticalAlignment="Center"
MaxWidth="200" TextTrimming="CharacterEllipsis"
ToolTip.Tip="{Binding Label}" />
<Button Classes="flat close inline" Width="16" Height="16" Padding="0"
VerticalAlignment="Center"
Command="{Binding #Root.((vm:MainWindowViewModel)DataContext).CloseTabCommand}"
CommandParameter="{Binding}"
ToolTip.Tip="Closes this terminal and ends its shell. Middle-click the tab does the same.">
<TextBlock Text="&#x2715;" FontSize="10" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Button>
</StackPanel>
</Button>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!--
Opens the quick-connect palette, on both rows: "the existing new-connection/quick-connect meaning"
the notes ask this button to keep. See TerminalTabs' own remark, carried over unchanged, on why
this is a palette and never a flyout menu over the terminal's own rectangle.
-->
<Button Classes="sesstab plus"
Command="{Binding ToggleSearchCommand}"
ToolTip.Tip="Open a connection · Ctrl+K">
<TextBlock Text="+" FontSize="15" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Button>
</StackPanel>
</ScrollViewer>
</Border>
</UserControl>