feat(topbar): glyphs on the world segment — layout, record dot, and a padlock
Creator ruling 2026-11-12: an icon left of each label, and Build Scenes' glyph becomes a padlock while Record / Go Live is the active world. - Build Scenes: a four-pane layout glyph while it is the active world, a padlock while the output world is — the door is still there, it is just behind the session. Clicking it swaps the glyph back and takes the creator into the layers, which is the only route back mid-show now that EDIT is gone. - Record / Go Live: the ring-and-dot record glyph, the same "armed" language the REC sign speaks, so the halves are read apart at a glance. Both glyphs fill from the button's own Foreground, so the selected (red) and unselected states keep legible ink without a second colour pair. UiShellTests guards both paths and the padlock's world flag. 679 pass, 0 warnings. 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:
+31
-4
@@ -69,14 +69,41 @@
|
|||||||
<Border Background="{StaticResource Brush.SurfaceContainerLowest}" CornerRadius="4"
|
<Border Background="{StaticResource Brush.SurfaceContainerLowest}" CornerRadius="4"
|
||||||
Padding="2" Height="32" VerticalAlignment="Center" Margin="0,0,12,0">
|
Padding="2" Height="32" VerticalAlignment="Center" Margin="0,0,12,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<!-- Build Scenes carries a LAYOUT glyph while it is the active world and a PADLOCK
|
||||||
|
once Record / Go Live is: the door is still there, it is just behind the
|
||||||
|
session. Clicking it swaps the glyph back and takes the creator into the
|
||||||
|
layers (creator ruling 2026-11-12). -->
|
||||||
<Button Style="{StaticResource WorldSegmentButton}" Tag="{Binding IsBuildWorld}"
|
<Button Style="{StaticResource WorldSegmentButton}" Tag="{Binding IsBuildWorld}"
|
||||||
Command="{Binding EnterBuildWorldCommand}" Padding="12,0"
|
Command="{Binding EnterBuildWorldCommand}" Padding="12,0"
|
||||||
Content="Build Scenes" FontSize="12" FontWeight="Bold"
|
ToolTip="Edit layers, scenes and webcam placement">
|
||||||
ToolTip="Edit layers, scenes and webcam placement"/>
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Path Width="14" Height="14" Stretch="Uniform" VerticalAlignment="Center"
|
||||||
|
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
|
||||||
|
Visibility="{Binding IsBuildWorld, Converter={StaticResource BoolToVis}}"
|
||||||
|
Data="M3,4h8v6H3V4zM13,4h8v6h-8V4zM3,12h8v8H3V12zM13,12h8v8h-8V12z"/>
|
||||||
|
<Path Width="14" Height="14" Stretch="Uniform" VerticalAlignment="Center"
|
||||||
|
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
|
||||||
|
Visibility="{Binding IsOutputWorld, Converter={StaticResource BoolToVis}}"
|
||||||
|
Data="M7,10V7a5,5 0 0,1 10,0v3h1a1,1 0 0,1 1,1v9a1,1 0 0,1 -1,1H6a1,1 0 0,1 -1,-1v-9a1,1 0 0,1 1,-1h1zM9,10h6V7a3,3 0 0,0 -6,0v3z"/>
|
||||||
|
<TextBlock Text="Build Scenes" FontSize="12" FontWeight="Bold" Margin="6,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
|
<!-- Record / Go Live: a record dot in a ring, the same "armed" language the REC sign
|
||||||
|
uses, so the two halves are read apart at a glance. -->
|
||||||
<Button Style="{StaticResource WorldSegmentButton}" Tag="{Binding IsOutputWorld}"
|
<Button Style="{StaticResource WorldSegmentButton}" Tag="{Binding IsOutputWorld}"
|
||||||
Command="{Binding EnterOutputWorldCommand}" Padding="12,0"
|
Command="{Binding EnterOutputWorldCommand}" Padding="12,0"
|
||||||
Content="Record / Go Live" FontSize="12" FontWeight="Bold"
|
ToolTip="Choose the output and start the session">
|
||||||
ToolTip="Choose the output and start the session"/>
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Path Width="14" Height="14" Stretch="Uniform" VerticalAlignment="Center"
|
||||||
|
Fill="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"
|
||||||
|
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="Record / Go Live" FontSize="12" FontWeight="Bold" Margin="6,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Foreground="{Binding Foreground, RelativeSource={RelativeSource AncestorType=Button}}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Button>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Border>
|
</Border>
|
||||||
<!-- 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
|
||||||
|
|||||||
@@ -29,12 +29,18 @@ public class UiShellTests
|
|||||||
|
|
||||||
// 2. The world segment replaced the EDIT toggle (creator ruling 2026-11-12): both halves are
|
// 2. The world segment replaced the EDIT toggle (creator ruling 2026-11-12): both halves are
|
||||||
// present, each lit by its own world flag through the shared style.
|
// present, each lit by its own world flag through the shared style.
|
||||||
Assert.Contains("Content=\"Build Scenes\"", topBar);
|
Assert.Contains("Text=\"Build Scenes\"", topBar);
|
||||||
Assert.Contains("Content=\"Record / Go Live\"", topBar);
|
Assert.Contains("Text=\"Record / Go Live\"", topBar);
|
||||||
Assert.Contains("Tag=\"{Binding IsBuildWorld}\"", topBar);
|
Assert.Contains("Tag=\"{Binding IsBuildWorld}\"", topBar);
|
||||||
Assert.Contains("Tag=\"{Binding IsOutputWorld}\"", topBar);
|
Assert.Contains("Tag=\"{Binding IsOutputWorld}\"", topBar);
|
||||||
Assert.DoesNotContain("x:Name=\"EditBody\"", topBar);
|
Assert.DoesNotContain("x:Name=\"EditBody\"", topBar);
|
||||||
|
|
||||||
|
// 2b. Build Scenes carries a layout glyph while it is the active world, and a padlock once
|
||||||
|
// Record / Go Live is — each lit by its own world flag (creator ruling 2026-11-12).
|
||||||
|
Assert.Contains("Data=\"M3,4h8v6H3V4zM13,4h8v6h-8V4zM3,12h8v8H3V12zM13,12h8v8h-8V12z\"", topBar);
|
||||||
|
Assert.Contains("Data=\"M7,10V7a5,5 0 0,1 10,0v3h1", topBar);
|
||||||
|
Assert.Contains("Visibility=\"{Binding IsOutputWorld, Converter={StaticResource BoolToVis}}\"", topBar);
|
||||||
|
|
||||||
// 3. Active scene = orange; live stays red.
|
// 3. Active scene = orange; live stays red.
|
||||||
Assert.Contains("IsStaged}\" Value=\"True\">\n <Setter Property=\"BorderBrush\" Value=\"{StaticResource Brush.Attention}\"/>", strip);
|
Assert.Contains("IsStaged}\" Value=\"True\">\n <Setter Property=\"BorderBrush\" Value=\"{StaticResource Brush.Attention}\"/>", strip);
|
||||||
|
|
||||||
@@ -94,7 +100,7 @@ public class UiShellTests
|
|||||||
|
|
||||||
// The world segment leads the centre cluster; the brand column carries no edit control.
|
// The world segment leads the centre cluster; the brand column carries no edit control.
|
||||||
var centre = topBar.IndexOf("<StackPanel Grid.Column=\"1\"", System.StringComparison.Ordinal);
|
var centre = topBar.IndexOf("<StackPanel Grid.Column=\"1\"", System.StringComparison.Ordinal);
|
||||||
var segment = topBar.IndexOf("Content=\"Build Scenes\"", System.StringComparison.Ordinal);
|
var segment = topBar.IndexOf("Text=\"Build Scenes\"", System.StringComparison.Ordinal);
|
||||||
Assert.True(centre > 0 && segment > centre,
|
Assert.True(centre > 0 && segment > centre,
|
||||||
"the [ Build Scenes ][ Record / Go Live ] segment must lead the centre cluster");
|
"the [ Build Scenes ][ Record / Go Live ] segment must lead the centre cluster");
|
||||||
Assert.DoesNotContain("x:Name=\"EditBody\"", topBar);
|
Assert.DoesNotContain("x:Name=\"EditBody\"", topBar);
|
||||||
|
|||||||
Reference in New Issue
Block a user