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.
59 lines
2.3 KiB
C#
59 lines
2.3 KiB
C#
using System.Windows.Input;
|
|
using ytLive.Helpers;
|
|
|
|
namespace ytLive.ViewModels;
|
|
|
|
/// <summary>Which half of the top bar's dual segment is in force.</summary>
|
|
public enum BarWorld
|
|
{
|
|
/// <summary>Build Scenes — the edit surface. The default at launch (creator ruling 2026-11-12).</summary>
|
|
Build,
|
|
|
|
/// <summary>Record / Go Live — the output surface: which output, and the one action that starts it.</summary>
|
|
Output,
|
|
}
|
|
|
|
/// <summary>
|
|
/// The top bar's one decision (creator ruling 2026-11-12): <c>[ Build Scenes ][ Record / Go Live ]</c>.
|
|
/// Build Scenes <b>is</b> edit mode — there is no separate EDIT toggle any more, so "may I edit?" and
|
|
/// "which world am I in?" cannot disagree.
|
|
///
|
|
/// <para>Clicking the highlighted segment is not a no-op: it re-enters that world, which matters while a
|
|
/// session runs because Build Scenes is the only way back to the layers (see
|
|
/// <see cref="LockEditWhileLive"/>).</para>
|
|
/// </summary>
|
|
public partial class MainViewModel
|
|
{
|
|
private BarWorld _barWorld = BarWorld.Build;
|
|
|
|
public BarWorld BarWorld => _barWorld;
|
|
|
|
public bool IsBuildWorld => _barWorld == BarWorld.Build;
|
|
public bool IsOutputWorld => _barWorld == BarWorld.Output;
|
|
|
|
/// <summary>The output stage belongs to the Record / Go Live world, and only while nothing is
|
|
/// running — a live session cannot change its output, so its switch is not offered.</summary>
|
|
public bool ShowOutputStage => IsOutputWorld && IsOffline && !IsRecording;
|
|
|
|
public ICommand EnterBuildWorldCommand { get; private set; } = null!;
|
|
public ICommand EnterOutputWorldCommand { get; private set; } = null!;
|
|
|
|
private void InitializeWorldCommands()
|
|
{
|
|
EnterBuildWorldCommand = new RelayCommand(_ => EnterWorld(BarWorld.Build));
|
|
EnterOutputWorldCommand = new RelayCommand(_ => EnterWorld(BarWorld.Output));
|
|
}
|
|
|
|
/// <summary>Switches worlds. Re-entering the current one still re-asserts its edit state, which is
|
|
/// what lets a creator take EDIT back mid-show by clicking Build Scenes.</summary>
|
|
internal void EnterWorld(BarWorld world)
|
|
{
|
|
_barWorld = world;
|
|
OnPropertyChanged(nameof(BarWorld));
|
|
OnPropertyChanged(nameof(IsBuildWorld));
|
|
OnPropertyChanged(nameof(IsOutputWorld));
|
|
EditingActive = world == BarWorld.Build;
|
|
OnPropertyChanged(nameof(ShowOutputStage));
|
|
}
|
|
}
|