feat(topbar): the output stage — Output [YouTube] [Local MP4] One output at a time
Unit B (creator ruling 2026-11-12). Pressing Record / Go Live now changes the bar: the REC/ON-AIR pill pair becomes two labelled switches with glyphs (the YouTube mark, the record dot), under an "Output" label and beside "One output at a time". Build world shows nothing but its own segment. Two things this exposed that were not cosmetic: - **Local MP4 was not actually the default.** Both pills started unarmed, so the stage opened with no output selected; the old screen got away with it because the primary button inferred "record" from "nothing armed". RecordPillOn now starts true, which is what "pos = ON (default)" means in code. - **The stage gates the whole idle cluster, not just the switch.** Gating only the switch left the start button visible in the Build world — a Start with no output chosen. ShowOutputStage (output world, idle, not recording) wraps the cluster, so a running session hides the stage too: its output cannot change. Exclusivity stays in the view model (arming one drops the other); the XAML merely reflects it. TopBarWorldTests pins the stage's visibility and the radio pair starting at Local MP4. 680 pass, 0 warnings. Next: unit C (output-dependent primary action, End labels). 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:
+27
-9
@@ -109,24 +109,42 @@
|
||||
<!-- 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
|
||||
family — segments host, Start/Go Live, and Test all sit at 32. -->
|
||||
<!-- THE OUTPUT STAGE (creator ruling 2026-11-12): which single output, and the one action
|
||||
that starts it. Appears only in the Record / Go Live world and only while nothing is
|
||||
running — a live session cannot change its output. YouTube and Local MP4 are one axis,
|
||||
so the two switches are radio-exclusive in the view model, not by luck here. -->
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Visibility="{Binding ShowIdleWorld, Converter={StaticResource BoolToVis}}">
|
||||
Visibility="{Binding ShowOutputStage, Converter={StaticResource BoolToVis}}">
|
||||
<TextBlock Text="Output" FontSize="12" FontWeight="Bold" VerticalAlignment="Center"
|
||||
Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="0,0,8,0"/>
|
||||
<Border Background="{StaticResource Brush.SurfaceContainerLowest}" CornerRadius="4" Padding="2" Height="32" VerticalAlignment="Center">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<ToggleButton Style="{StaticResource RecordPillToggle}"
|
||||
IsChecked="{Binding RecordPillOn}">
|
||||
<!-- the label follows the pill's own foreground: muted when armed-off,
|
||||
dark on red when armed (SegmentLabel pins its own colour) -->
|
||||
<TextBlock Text="REC" FontSize="12" FontWeight="Bold" VerticalAlignment="Center"
|
||||
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}"/>
|
||||
IsChecked="{Binding OnAirPillOn}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="14" Height="14" Stretch="Uniform" VerticalAlignment="Center"
|
||||
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}"
|
||||
Data="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/>
|
||||
<TextBlock Text="YouTube" FontSize="12" FontWeight="Bold" Margin="6,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}"/>
|
||||
</StackPanel>
|
||||
</ToggleButton>
|
||||
<ToggleButton Style="{StaticResource RecordPillToggle}"
|
||||
IsChecked="{Binding OnAirPillOn}">
|
||||
<TextBlock Text="ON-AIR" FontSize="12" FontWeight="Bold" VerticalAlignment="Center"
|
||||
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}"/>
|
||||
IsChecked="{Binding RecordPillOn}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Path Width="14" Height="14" Stretch="Uniform" VerticalAlignment="Center"
|
||||
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}"
|
||||
Data="M12,2a10,10 0 1,0 0,20a10,10 0 1,0 0,-20zM12,4a8,8 0 1,1 0,16a8,8 0 1,1 0,-16zM12,7.5a4.5,4.5 0 1,1 0,9a4.5,4.5 0 1,1 0,-9z"/>
|
||||
<TextBlock Text="Local MP4" FontSize="12" FontWeight="Bold" Margin="6,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=ToggleButton}}"/>
|
||||
</StackPanel>
|
||||
</ToggleButton>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<TextBlock Text="One output at a time" FontSize="11" VerticalAlignment="Center"
|
||||
Foreground="{StaticResource Brush.OnSurfaceVariant}" Margin="8,0,0,0"/>
|
||||
<!-- Go face names the world: "Start Recording" vs "Go Live".
|
||||
(Signed-out ON-AIR Start routes to the sign-in — StartSession.) -->
|
||||
<Button Content="{Binding PrimaryStartButtonLabel}" Style="{StaticResource YtButton}"
|
||||
|
||||
Reference in New Issue
Block a user