Top bar and scene strip: EDIT toggle beside REC (orange on, blue off); fixed-size centered mini screens; fixed 360px left column so the empty cell matches the layers panel
- TopBar: EDIT ToggleButton, spaced from the REC/ON-AIR segments - MainViewModel: explicit EditingActive drives IsEditMode; YouTube go-live turns edit off, stop turns it on - SceneThumbnailStrip: tiles fixed 196x130 and centered; dark background fills the column so its edge does not move on resize; strip row fixed 154px - MainWindow: left column fixed at 360px; WIDTHS diagnostic log on resize Not pushed.
This commit is contained in:
@@ -1,17 +1,16 @@
|
||||
<UserControl x:Class="ytLive.Controls.SceneThumbnailStrip"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<Viewbox Stretch="Uniform">
|
||||
<Border Width="1000" Height="150" Background="#0d1117" CornerRadius="4" Margin="0,0,0,4" Padding="4">
|
||||
<ItemsControl ItemsSource="{Binding Scenes}">
|
||||
<Border Background="#0d1117" CornerRadius="4" Padding="4">
|
||||
<ItemsControl ItemsSource="{Binding Scenes}" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<UniformGrid Rows="1" Columns="5"/>
|
||||
<StackPanel Orientation="Horizontal"/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border CornerRadius="4" Margin="2" Padding="2"
|
||||
<Border Width="196" Height="130" CornerRadius="4" Margin="2" Padding="2"
|
||||
BorderThickness="2"
|
||||
Cursor="Hand"
|
||||
MouseLeftButtonDown="Thumbnail_MouseLeftButtonDown">
|
||||
@@ -83,5 +82,4 @@
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Border>
|
||||
</Viewbox>
|
||||
</UserControl>
|
||||
|
||||
@@ -8,12 +8,9 @@ namespace ytLive.Controls;
|
||||
|
||||
public partial class SceneThumbnailStrip : UserControl
|
||||
{
|
||||
private const double DesignAspect = 154.0 / 1000.0;
|
||||
|
||||
public SceneThumbnailStrip()
|
||||
{
|
||||
InitializeComponent();
|
||||
SizeChanged += (_, _) => Height = ActualWidth * DesignAspect;
|
||||
Loaded += (_, _) =>
|
||||
{
|
||||
if (DataContext is MainViewModel vm)
|
||||
|
||||
@@ -54,6 +54,21 @@
|
||||
reality line + End so nothing mid-session can be re-armed. -->
|
||||
<StackPanel Grid.Column="1" Orientation="Horizontal"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<!-- EDIT: explicit toggle. Blue = off (chat), orange = on (layers/properties). -->
|
||||
<ToggleButton IsChecked="{Binding EditingActive, Mode=TwoWay}" Content="EDIT"
|
||||
Cursor="Hand" Height="32" Padding="14,0" Margin="0,0,24,0" VerticalAlignment="Center"
|
||||
FontWeight="Bold" FontSize="12" Foreground="#0b1326" BorderThickness="0">
|
||||
<ToggleButton.Style>
|
||||
<Style TargetType="ToggleButton">
|
||||
<Setter Property="Background" Value="#38bdf8"/>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Background" Value="#ff8c3a"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ToggleButton.Style>
|
||||
</ToggleButton>
|
||||
<!-- 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. -->
|
||||
|
||||
+2
-2
@@ -74,12 +74,12 @@
|
||||
<RowDefinition Height="*"/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="1*" MinWidth="220" MaxWidth="360"/>
|
||||
<ColumnDefinition Width="360"/>
|
||||
<ColumnDefinition Width="3*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- ═══ THUMBNAIL STRIP (over the preview column; left column stays empty) ═══ -->
|
||||
<controls:SceneThumbnailStrip Grid.Row="0" Grid.Column="1" Margin="8,0"/>
|
||||
<controls:SceneThumbnailStrip x:Name="SceneStrip" Grid.Row="0" Grid.Column="1" Margin="8,0" Height="154"/>
|
||||
|
||||
<!-- LEFT PANEL: one panel, two states.
|
||||
Offline (edit mode): LAYERS + PROPERTIES
|
||||
|
||||
@@ -20,6 +20,8 @@ public partial class MainWindow : Window
|
||||
{
|
||||
AppLog.Write("MainWindow ctor: before InitializeComponent");
|
||||
InitializeComponent();
|
||||
SizeChanged += (_, e) => Helpers.AppLog.Write($"WIDTHS window={e.NewSize.Width:F0} "
|
||||
+ $"layers={LeftPanel.ActualWidth:F0} strip={SceneStrip.ActualWidth:F0} preview={PreviewPane.ActualWidth:F0}");
|
||||
AppLog.Write("MainWindow ctor: after InitializeComponent");
|
||||
_viewModel = (MainViewModel)DataContext;
|
||||
_viewModel.PropertyChanged += OnViewModelPropertyChanged;
|
||||
|
||||
@@ -76,7 +76,21 @@ public partial class MainViewModel
|
||||
|
||||
/// <summary>True when offline — edit mode is available. When live/recording,
|
||||
/// all edit operations are locked out (gun safety).</summary>
|
||||
public bool IsEditMode => StreamStatus == StreamStatus.Offline && !IsRecording;
|
||||
private bool _editingActive = true;
|
||||
|
||||
/// <summary>The edit toggle (TopBar). On by default; going live on YouTube turns it off
|
||||
/// and shows the live chat; stopping turns it back on.</summary>
|
||||
public bool EditingActive
|
||||
{
|
||||
get => _editingActive;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _editingActive, value))
|
||||
OnPropertyChanged(nameof(IsEditMode));
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsEditMode => EditingActive;
|
||||
|
||||
// ─── Transitions (TASK 19/23) ───
|
||||
|
||||
|
||||
@@ -224,6 +224,7 @@ public partial class MainViewModel : ViewModelBase
|
||||
// before that (2026-09-25 diagnosis), so chat resolution runs AFTER the pump
|
||||
// starts. Chat is non-fatal — if it fails, the stream continues without chat.
|
||||
LiveScene = StagedScene;
|
||||
EditingActive = false;
|
||||
await _framePump.StartAsync(); // never throws; failures log + surface via Failed
|
||||
|
||||
string? liveChatId = null;
|
||||
@@ -327,6 +328,7 @@ public partial class MainViewModel : ViewModelBase
|
||||
StreamStatus = StreamStatus.Offline;
|
||||
IsRecording = false;
|
||||
LiveScene = null;
|
||||
EditingActive = true;
|
||||
// TASK 41: a stopped test broadcast forgets its drawer session (idempotent)
|
||||
// and drops the TEST face — a test never outlives its run.
|
||||
TestSession.EndTestSilently();
|
||||
|
||||
Reference in New Issue
Block a user