Public Access
Take the group headings out of the host grid, and drop onto a group card
A first group turned the wrap of host cards into an accordion: SidebarRows interleaves a full-width fold-away heading — chevron, name, count — between the cards, and in a grid that reads as a dropdown somebody left open. The desktop grid binds VisibleHosts now. The headings and the fold stay for the phone, whose list has no room for the row of group cards the desktop draws above the grid. What a heading said, the card says: HostRowViewModel.GroupLabel, resolved once per reload like the tag names, drawn as an accent chip and absent from a host in no group — or in one that has been deleted, which is the same thing to look at. What a heading also was is the drop target, and that moves to the group cards. Two things go with it. A host dropped onto another host card used to be filed beside it, which was legible while a heading named the band of cards it landed in and is guesswork now; it is refused. And UNGROUPED was how a host was dragged back out of a group; the way out is the picker in its own editor, which is the one place "no group" can be said in words. A drag held at either edge of the grid scrolls it. Without that the gesture only works for whoever can see both ends of it: the group cards are the first thing in the scroller, the host may be the fortieth card down, and a drag cannot use the wheel. A step per drag event rather than a timer, so it follows the pointer and stops when it stops. The two heading-shaped tests are replaced. TheHostsGridHoldsCardsAndNoGroupHeadings asserts the grid's contents rather than only measuring them, because a heading that came back would lay out perfectly cleanly. TheGroupCardsAreWhatAcceptsADroppedHost raises a real DragOver over both kinds of card and checks the effects and the mark — the nearest a headless test gets to a gesture no headless test can synthesise. manual-checks 3.1-3.2 and 7.6-7.9 follow.
This commit is contained in:
@@ -151,8 +151,17 @@
|
||||
|
||||
</StackPanel>
|
||||
|
||||
<!-- ============ THE GRID ============ -->
|
||||
<ScrollViewer Grid.Row="3" HorizontalScrollBarVisibility="Disabled">
|
||||
<!--
|
||||
============ THE GRID ============
|
||||
|
||||
A drop target that takes nothing itself. Everything the pointer can be over during a drag is inside
|
||||
this control, and it has to accept one so that the group cards at the top of it stay reachable from
|
||||
the bottom of a long grid: a host dragged off the fortieth card cannot be dropped on a group card
|
||||
that has scrolled out of sight, so a drag held at either edge scrolls this while it is in flight.
|
||||
See HostsScreen.axaml.cs.
|
||||
-->
|
||||
<ScrollViewer Grid.Row="3" x:Name="Scroll" HorizontalScrollBarVisibility="Disabled"
|
||||
DragDrop.AllowDrop="True">
|
||||
<StackPanel Margin="16,14" Spacing="16">
|
||||
|
||||
<!-- ============ GROUPS ============ -->
|
||||
@@ -198,10 +207,18 @@
|
||||
SelectedItem is GroupFilter and not SelectedGroup. The two are nearly the same thing here —
|
||||
GroupFilter assigns SelectedGroup — but only one of them may narrow the grid; see the property
|
||||
for why the phone's own use of SelectedGroup must not.
|
||||
|
||||
◆ THESE CARDS ARE THE DROP TARGET. A host card dragged onto one is filed under that group, and
|
||||
that is the whole of what a drag does on this screen. It used to be a heading inside the host
|
||||
grid, and the headings are gone — see the note on the host grid below. A group is a thing that
|
||||
is drawn once, at the top, where the eye already goes to narrow the grid; a target that is also
|
||||
the label of what you are aiming at needs no explaining. See the code-behind for the gesture.
|
||||
-->
|
||||
<ListBox Classes="tiles" x:Name="GroupGrid"
|
||||
DragDrop.AllowDrop="True"
|
||||
ItemsSource="{Binding Groups}"
|
||||
SelectedItem="{Binding GroupFilter}">
|
||||
SelectedItem="{Binding GroupFilter}"
|
||||
ToolTip.Tip="Press a group to show only its hosts. Drag a host card onto one to file it there.">
|
||||
<ListBox.ItemsPanel>
|
||||
<ItemsPanelTemplate><WrapPanel /></ItemsPanelTemplate>
|
||||
</ListBox.ItemsPanel>
|
||||
@@ -257,15 +274,31 @@
|
||||
focus off the terminal's child window and then calls Focus() on something that refuses it,
|
||||
leaving the window with nothing focused and the keystrokes going nowhere.
|
||||
|
||||
It binds SidebarRows rather than VisibleHosts, so the group headings are still in it. Two
|
||||
reasons, and neither is decoration: a grid showing every group at once has to say which cards
|
||||
belong to which, and a heading is the drop target that takes a host out of one group and into
|
||||
another. See VaultViewModel.RebuildSidebarRows for why a heading is a row rather than a
|
||||
container, and the code-behind for what a drag does with one.
|
||||
◆ CARDS ONLY, AND NO HEADINGS. It binds VisibleHosts rather than SidebarRows, which is the
|
||||
collection with the group headings folded into it. Those headings were a full-width fold-away
|
||||
bar between the cards — a chevron, a name and a count — and in a wrap of cards they read as a
|
||||
collapsed dropdown that had somehow been dealt the hosts: the moment a first group existed the
|
||||
grid stopped being a grid. Two controls saying "group" on one screen was one too many, and the
|
||||
cards above are the better of the two. SidebarRows and the fold are still the phone's, whose
|
||||
list has no room for a row of group cards; see Android's HostsScreen.
|
||||
|
||||
What a heading also was is the drop target, and that moved to the group cards rather than
|
||||
going away with it — see the note on them above, and the code-behind for the gesture. A host is
|
||||
taken back out of a group through its own editor, which is the one place "no group" can be said
|
||||
plainly.
|
||||
|
||||
Which group a card is in is on the card, as a chip. That is what the heading above it used to
|
||||
say, and one chip per card says it without an accordion.
|
||||
|
||||
SelectedItem is still SelectedSidebarRow and deliberately not SelectedHost, though every item
|
||||
here is now a host. That property swallows the null the ListBox writes back whenever the
|
||||
collection is rebuilt — which is every filter keystroke and every background sync — where
|
||||
binding the host selection directly would let that null through, and a null host selection
|
||||
closes the drawer and disarms a delete somebody is in the middle of confirming. See the
|
||||
property, and RebuildVisibleHosts on where the real clearing is done.
|
||||
-->
|
||||
<ListBox Classes="tiles" x:Name="HostGrid" Focusable="True"
|
||||
DragDrop.AllowDrop="True"
|
||||
ItemsSource="{Binding SidebarRows}"
|
||||
ItemsSource="{Binding VisibleHosts}"
|
||||
SelectedItem="{Binding SelectedSidebarRow}">
|
||||
|
||||
<ListBox.ItemsPanel>
|
||||
@@ -279,7 +312,8 @@
|
||||
one per card: a ContextMenu inside a DataTemplate would have the row for its data context,
|
||||
and the commands here are the vault's. The code-behind selects whatever was right-clicked
|
||||
before the menu opens, so the selection-based commands act on the card under the pointer,
|
||||
and cancels the menu outright over a group heading, which has no host to act on.
|
||||
and cancels the menu outright over the space around the cards, where there is no host to act
|
||||
on.
|
||||
-->
|
||||
<ListBox.ContextMenu>
|
||||
<ContextMenu>
|
||||
@@ -290,35 +324,9 @@
|
||||
</ContextMenu>
|
||||
</ListBox.ContextMenu>
|
||||
|
||||
<ListBox.DataTemplates>
|
||||
<ListBox.ItemTemplate>
|
||||
|
||||
<!--
|
||||
A heading, and it takes a whole row of the wrap rather than sitting in the flow as another
|
||||
card: it names the run of cards under it, and a heading the width of one card would read
|
||||
as the first of them. The stretch is what MinWidth buys — a WrapPanel gives a child the
|
||||
width it asks for and starts a new line when the line cannot hold it, so a child asking
|
||||
for more than one line holds is alone on its own.
|
||||
-->
|
||||
<DataTemplate DataType="vm:SidebarGroupHeader">
|
||||
<Button Classes="flat grouphead" MinWidth="640"
|
||||
Command="{Binding $parent[ListBox].((vm:VaultViewModel)DataContext).ToggleGroupCommand}"
|
||||
CommandParameter="{Binding}"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<Grid ColumnDefinitions="Auto,Auto,*">
|
||||
<TextBlock Grid.Column="0" Text="{Binding Chevron}"
|
||||
Foreground="{StaticResource TextFaint}" FontSize="9"
|
||||
VerticalAlignment="Center" Margin="0,0,6,0" />
|
||||
<TextBlock Grid.Column="1" Classes="label" Text="{Binding Label}"
|
||||
Foreground="{StaticResource TextDim}" VerticalAlignment="Center"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock Grid.Column="2" Classes="mono" Text="{Binding Count}" FontSize="11"
|
||||
Foreground="{StaticResource TextFaint}" VerticalAlignment="Center"
|
||||
Margin="8,0,0,0" HorizontalAlignment="Left" />
|
||||
</Grid>
|
||||
</Button>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="vm:HostRowViewModel">
|
||||
<DataTemplate x:DataType="vm:HostRowViewModel">
|
||||
<Border Classes="tile">
|
||||
<StackPanel Spacing="6">
|
||||
<Grid ColumnDefinitions="Auto,*,Auto">
|
||||
@@ -389,6 +397,26 @@
|
||||
VerticalAlignment="Top" Margin="6,3,0,0" />
|
||||
</Grid>
|
||||
|
||||
<!--
|
||||
The group this host is filed under, and only when it is filed under one — which is
|
||||
the same rule the group cards above follow, and the reason a keychain nobody has
|
||||
filed anything in looks exactly as it did before groups existed.
|
||||
|
||||
This is what the fold-away heading over a run of cards used to say. A chip on the
|
||||
card says it per host instead, which is the shape the rest of this card already is
|
||||
and the shape a wrap of cards can carry: it survives the cards being reflowed, it
|
||||
needs no row of its own, and it is what changes when a card is dropped onto a group.
|
||||
|
||||
Accent rather than plain, so the one chip that is a *place* is not read as another
|
||||
tag. A group whose name the vault cannot resolve leaves this empty rather than
|
||||
printing an id, for the reason a tag does. See HostRowViewModel.GroupLabel.
|
||||
-->
|
||||
<Border Classes="chip accent" Padding="5,0" HorizontalAlignment="Left"
|
||||
IsVisible="{Binding HasGroup}">
|
||||
<TextBlock Text="{Binding GroupLabel}" FontSize="9.5"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
</Border>
|
||||
|
||||
<!--
|
||||
The tags this host wears. Under the summary rather than beside it, because a host
|
||||
can wear several and the line above is three fixed-width facts where these are not.
|
||||
@@ -412,7 +440,7 @@
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
|
||||
</ListBox.DataTemplates>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
|
||||
<!--
|
||||
|
||||
Reference in New Issue
Block a user