Files
LlamaCasty/Controls/AudioDock.xaml.cs
T
gramps 7339df5fcd feat(dock): the TRAX bay — track, play/pause, level, duck badge
Unit 7. The bay shows the track name (left-click toggles playback, right-click opens the picker —
the label stays the control), a play/pause button, the duck badge, and a dB level.

No ladder here, deliberately: nothing measures the music bed, and a decorative ladder would break
the measured-not-painted rule. A test asserts the bay has no SegmentMeter.

The level is real: `ITraxPlayer.UserGain` is a new creator gain multiplied onto the fixed design
volume, separate from `LocalGain` (which follows the desktop mute). The VM's `TraxVolumeDb` is the
same dB scale as the other faders, so unity means the bed's design level.
2026-10-30 13:15:17 -07:00

77 lines
2.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Windows;
using System.Windows.Controls;
using ytLive.Models;
namespace ytLive.Controls;
/// <summary>The sound bars (creator ruling 2026-10-30). This unit owns the SHELL: the piece of the
/// window it occupies and the collapse behaviour. The bays and the master readouts fill in over
/// the following units, so nothing here pretends to be a working meter.
///
/// <para>Collapse is driven by the window height, not a user setting: at 1366×768 a full dock
/// squeezes the preview, and the creator should not have to manage that.</para></summary>
public partial class AudioDock : UserControl
{
private Window? _window;
public AudioDock()
{
InitializeComponent();
Loaded += OnLoaded;
Unloaded += OnUnloaded;
}
/// <summary>Is the dock showing only the telemetry strip?</summary>
internal bool IsCollapsed { get; private set; }
/// <summary>Test seam: the same code the window's SizeChanged runs, without a window.</summary>
internal void ApplyWindowHeight(double windowHeight)
{
var collapsed = AudioDockLayout.IsCollapsed(windowHeight);
IsCollapsed = collapsed;
Height = AudioDockLayout.HeightFor(windowHeight);
Bays.Visibility = collapsed ? Visibility.Collapsed : Visibility.Visible;
}
private void MicLabel_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (DataContext is ViewModels.MainViewModel vm && vm.OpenMicPickerCommand.CanExecute(null))
vm.OpenMicPickerCommand.Execute(null);
}
private void TraxPlayPause_Click(object sender, RoutedEventArgs e)
{
if (DataContext is ViewModels.MainViewModel vm) vm.TraxLeftClick();
}
private void TraxLabel_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (DataContext is ViewModels.MainViewModel vm) vm.TraxLeftClick();
}
private void TraxLabel_MouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (DataContext is ViewModels.MainViewModel vm) vm.ChooseTrack();
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
_window = Window.GetWindow(this);
if (_window == null)
{
ApplyWindowHeight(AudioDockLayout.CollapseBelowHeight); // no host: show the dock
return;
}
_window.SizeChanged += OnWindowSizeChanged;
ApplyWindowHeight(_window.ActualHeight > 0 ? _window.ActualHeight : _window.Height);
}
private void OnUnloaded(object sender, RoutedEventArgs e)
{
if (_window != null) _window.SizeChanged -= OnWindowSizeChanged;
_window = null;
}
private void OnWindowSizeChanged(object sender, SizeChangedEventArgs e) => ApplyWindowHeight(e.NewSize.Height);
}