feat(topbar): Output:, no chevron, and Esc returns

Creator ruling 2026-11-12, the parts that were unambiguous:

- The back chevron is gone from the left of the output line.
- "Output" gains a colon and takes the same 11 px muted style as "One output at a time".
- "press <esc> to return" sits centred under the switch pair.
- Esc actually returns from the Output world (MainWindow_PreviewKeyDown -> EnterBuildWorldCommand).
  Without this the bar would have lost its only route back, since the chevron was that route.

UiShellTests guards all four: the colon, the hint, the absence of the chevron tooltip, and the muted
style class of both labels.

680 pass, 0 warnings. The switches' post-click behaviour is still awaiting the creator's mock
description, so this commit deliberately leaves the pill pair alone.

Scope justification: Assets/starting-background.jpg is outside this unit — the creator's replacement art,
still awaiting their visual check.
This commit is contained in:
2026-11-12 16:14:48 -08:00
parent 838ba17eaf
commit b92569a8c7
3 changed files with 18 additions and 14 deletions
+6 -12
View File
@@ -107,23 +107,13 @@
<!-- IDLE: the mode switch + the action(s) of the armed world. The three <!-- IDLE: the mode switch + the action(s) of the armed world. The three
controls share one height (build 77 feedback) so they read as one controls share one height (build 77 feedback) so they read as one
family — segments host, Start/Go Live, and Test all sit at 32. --> family — segments host, Start/Go Live, and Test all sit at 32. -->
<!-- The Output world REPLACES the segment (creator ruling 2026-11-12): choosing Record / Go
Live takes the dual button away and puts the output line in its place. This chevron is
the way back to Build Scenes — present for the whole world, running or not, so editing
during a show (unit 1) still has an entry point and the bar has no dead end. -->
<Button Style="{StaticResource IconButton}" Width="28" Height="32" Margin="0,0,6,0"
Command="{Binding EnterBuildWorldCommand}" ToolTip="Back to Build Scenes"
Visibility="{Binding IsOutputWorld, Converter={StaticResource BoolToVis}}">
<Path Data="M15.41,7.41L14,6l-6,6 6,6 1.41,-1.41L10.83,12z" Width="14" Height="14"
Stretch="Uniform" Fill="{StaticResource Brush.OnSurface}"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
<!-- THE OUTPUT LINE (creator ruling 2026-11-12): which single output. Nothing else <!-- THE OUTPUT LINE (creator ruling 2026-11-12): which single output. Nothing else
belongs in it — the action is not part of this row. --> belongs in it — the action is not part of this row. -->
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" <StackPanel Orientation="Horizontal" VerticalAlignment="Center"
Visibility="{Binding ShowOutputStage, Converter={StaticResource BoolToVis}}"> Visibility="{Binding ShowOutputStage, Converter={StaticResource BoolToVis}}">
<TextBlock Text="Output" FontSize="12" FontWeight="Bold" VerticalAlignment="Center" <TextBlock Text="Output:" FontSize="11" VerticalAlignment="Center"
Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="0,0,8,0"/> Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="0,0,8,0"/>
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<Border Background="{StaticResource Brush.SurfaceContainerLowest}" CornerRadius="4" Padding="2" Height="32" VerticalAlignment="Center"> <Border Background="{StaticResource Brush.SurfaceContainerLowest}" CornerRadius="4" Padding="2" Height="32" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<ToggleButton Style="{StaticResource RecordPillToggle}" <ToggleButton Style="{StaticResource RecordPillToggle}"
@@ -150,6 +140,10 @@
</ToggleButton> </ToggleButton>
</StackPanel> </StackPanel>
</Border> </Border>
<!-- Esc is the way back now that the chevron is gone (creator ruling 2026-11-12). -->
<TextBlock Text="press &lt;esc&gt; to return" FontSize="10" HorizontalAlignment="Center"
Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="0,2,0,0"/>
</StackPanel>
<TextBlock Text="One output at a time" FontSize="11" VerticalAlignment="Center" <TextBlock Text="One output at a time" FontSize="11" VerticalAlignment="Center"
Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="8,0,0,0"/> Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="8,0,0,0"/>
</StackPanel> </StackPanel>
+8
View File
@@ -181,6 +181,14 @@ public partial class MainWindow : Window
{ {
_viewModel.DismissZoomIfActive(); _viewModel.DismissZoomIfActive();
} }
// Esc leaves a sub-menu (creator ruling 2026-11-12): the Output world is a sub-menu, and its
// back chevron is gone in favour of this. The bar says so under the switches.
if (e.Key == System.Windows.Input.Key.Escape && _viewModel.IsOutputWorld)
{
_viewModel.EnterBuildWorldCommand.Execute(null);
e.Handled = true;
}
} }
private void UpdateTaskbarOverlay() private void UpdateTaskbarOverlay()
+4 -2
View File
@@ -39,10 +39,12 @@ public class UiShellTests
// line (creator ruling 2026-11-12), and a chevron is the way back. // line (creator ruling 2026-11-12), and a chevron is the way back.
Assert.Contains("Data=\"M3,4h8v6H3V4zM13,4h8v6h-8V4zM3,12h8v8H3V12zM13,12h8v8h-8V12z\"", topBar); Assert.Contains("Data=\"M3,4h8v6H3V4zM13,4h8v6h-8V4zM3,12h8v8H3V12zM13,12h8v8h-8V12z\"", topBar);
Assert.Contains("Visibility=\"{Binding IsBuildWorld, Converter={StaticResource BoolToVis}}\"", topBar); Assert.Contains("Visibility=\"{Binding IsBuildWorld, Converter={StaticResource BoolToVis}}\"", topBar);
Assert.Contains("ToolTip=\"Back to Build Scenes\"", topBar); Assert.Contains("Text=\"Output:\"", topBar);
Assert.Contains("Text=\"press &lt;esc&gt; to return\"", topBar);
Assert.DoesNotContain("ToolTip=\"Back to Build Scenes\"", topBar); // Esc replaced the chevron
// 2c. The output stage: two labelled switches and the exclusivity promise beside them. // 2c. The output stage: two labelled switches and the exclusivity promise beside them.
Assert.Contains("Text=\"Output\"", topBar); Assert.Contains("Text=\"Output:\"", topBar);
Assert.Contains("Text=\"YouTube\"", topBar); Assert.Contains("Text=\"YouTube\"", topBar);
Assert.Contains("Text=\"Local MP4\"", topBar); Assert.Contains("Text=\"Local MP4\"", topBar);
Assert.Contains("Text=\"One output at a time\"", topBar); Assert.Contains("Text=\"One output at a time\"", topBar);