ui(audio): master meter centred and biggest; TRAX gets its own bay and meter

Creator rulings, 2026-11-01.

- Master strip is 44px (from 36) and its meter is now the largest on screen: 420x14 with 32
  segments, centred under the preview, with a 12px MASTER label — bigger than the 9px bay
  labels. L/R imbalance is a flag on the left, MONO and the session clock on the right.
- The kbps / fps / dropped counters are gone from that line: the live readouts already sit
  above the preview, and the duplicate was noise rather than telemetry.
- TRAX is its own bay (MIC | GAME | TRAX | LIP-SYNC) with its own meter bound to
  TraxMeterFraction. It lived inside the game bay with no ladder, which meant whether the bed
  was actually playing could not be answered from the dock — and the player already measures
  its own output.
- Lip-sync is narrow (0.45 star) since it is one slider and three presets; the three sound bays
  are equal width, so their meters keep the same relative size.

AudioDockLayout moves with it (156 = 112 + 44; collapsed 44) and the layout test is updated.
TraxBayTests now asserts the opposite of the old ruling: the bay HAS a meter, and the game bay
no longer carries it.
This commit is contained in:
2026-11-01 13:48:28 -08:00
parent 9b337ad91b
commit f8e4f2cf29
5 changed files with 128 additions and 106 deletions
+2 -2
View File
@@ -26,7 +26,7 @@ public class AudioDockLayoutTests
Assert.True(AudioDockLayout.IsCollapsed(AudioDockLayout.CollapseBelowHeight - 1));
// The two heights are the design's numbers, not whatever looked fine.
Assert.Equal(148, AudioDockLayout.ExpandedHeight); // 112 bays + 36 strip
Assert.Equal(36, AudioDockLayout.CollapsedHeight);
Assert.Equal(156, AudioDockLayout.ExpandedHeight); // 112 bays + 44 master strip
Assert.Equal(44, AudioDockLayout.CollapsedHeight);
}
}
+16 -10
View File
@@ -5,14 +5,15 @@ using ytLive.ViewModels;
namespace ytLive.Tests;
/// <summary>The TRAX bay shows the track, plays/pauses it, and carries a level — but no meter:
/// nothing measures the bed, and a decorative ladder would be a lie. Its fader moves a gain the
/// player actually applies, separate from the desktop-mute follow.
/// <summary>The TRAX bay shows the track, plays/pauses it, and carries a level. It got its OWN bay
/// and its own meter on 2026-11-01 (creator ruling): the player measures its real output, so the
/// ladder is not decorative, and living inside the game bay hid whether the bed was playing.
/// Its fader moves a gain the player actually applies, separate from the desktop-mute follow.
/// </summary>
public class TraxBayTests
{
[Fact]
public void The_trax_bay_binds_the_track_level_and_play_state_without_inventing_a_meter()
public void The_trax_bay_is_its_own_bay_with_a_real_meter()
{
var dock = SourceAssert.Text("Controls", "AudioDock.xaml");
Assert.Contains("Text=\"{Binding TraxTrackLabel}\"", dock);
@@ -26,13 +27,18 @@ public class TraxBayTests
Assert.Contains("Binding=\"{Binding IsMusicPlaying}\" Value=\"True\"", dock);
Assert.Contains("Click=\"TraxPlayPause_Click\"", dock);
// The bay DOES carry a ladder now — the player measures its own output, so "is music making
// sound" is answerable without hearing it (a play glyph cannot answer that).
// The TRAX row lives under the desktop volume, inside the GAME bay.
var traxRow = dock[dock.IndexOf("Text=\"TRAX\"", System.StringComparison.Ordinal)
..dock.IndexOf("Text=\"LIP-SYNC\"", System.StringComparison.Ordinal)];
// TRAX is its own bay, between GAME and LIP-SYNC, and it carries a real ladder bound to the
// player's own level — "is the bed making sound" is not answerable from a play glyph.
var traxRow = dock[dock.IndexOf("<!-- TRAX: its own bay", System.StringComparison.Ordinal)
..dock.IndexOf("<!-- LIP-SYNC", System.StringComparison.Ordinal)];
Assert.Contains("TraxTrackLabel", traxRow);
Assert.DoesNotContain("SegmentMeter", traxRow);
Assert.Contains("SegmentMeter", traxRow);
Assert.Contains("Level=\"{Binding TraxMeterFraction}\"", traxRow);
// …and the GAME bay no longer embeds it.
var gameBay = dock[dock.IndexOf("<!-- GAME / PC", System.StringComparison.Ordinal)
..dock.IndexOf("<!-- TRAX: its own bay", System.StringComparison.Ordinal)];
Assert.DoesNotContain("TraxTrackLabel", gameBay);
foreach (var name in new[] { "TraxVolumeDb", "TraxVolumeDbLabel", "TraxTrackLabel", "CanRaiseTrax", "CanLowerTrax" })
Assert.NotNull(typeof(MainViewModel).GetProperty(name));