teamsiso/src/TeamsISO.App/Converters/LevelThresholdConverter.cs
Zac Gaetano d282e1b0f8
Some checks failed
CI / build-and-test (push) Failing after 30s
feat(wpf): v2 task 39+40 - studio table redesign + Ctrl+K command palette
Task 39: 5-column participants table - state LED, name+codec caption, 5-bar audio meter, mono output name, ISO pill. Row height 52, full-row active-speaker tint (no left stripe). New converter LevelThresholdConverter, OutputName property on ParticipantViewModel.

Task 40: Ctrl+K / Ctrl+P command palette - chromeless centered floating window, fuzzy Contains match across Label/Category/Keywords, arrow nav, Enter invoke, Esc close. Quick/Teams/Network/App categories cover top operator verbs and theme switching.

Also: log startup exceptions to Serilog before the modal MessageBox fires - much better triage signal than user-pasted dialog text.
2026-05-15 11:15:00 -04:00

42 lines
1.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.Globalization;
using System.Windows.Data;
namespace TeamsISO.App.Converters;
/// <summary>
/// Maps an audio level (0.01.0) to an opacity for a single audio-meter
/// segment. The XAML binds five copies, each with a different
/// <see cref="Binding.ConverterParameter"/> threshold (0.2, 0.4, 0.6,
/// 0.8, 1.0). A segment renders at full opacity when the live level
/// exceeds its threshold; below that it dims to a faint silhouette so the
/// inactive segments still read as "the meter has 5 steps" rather than
/// blank space.
///
/// Designed for the v2 "Studio Terminal" participants table's audio meter.
/// Broadcast engineers expect instantaneous (non-averaged) bars; the
/// converter is stateless and trusts the caller to push raw levels.
/// </summary>
public sealed class LevelThresholdConverter : IValueConverter
{
/// <summary>Opacity for an above-threshold segment. Defaults to 1.0.</summary>
public double ActiveOpacity { get; set; } = 1.0;
/// <summary>Opacity for a below-threshold segment. Defaults to 0.18 — visible enough to read the segment shape but clearly off.</summary>
public double InactiveOpacity { get; set; } = 0.18;
public object Convert(object value, System.Type targetType, object parameter, CultureInfo culture)
{
var level = value switch
{
double d => d,
float f => f,
_ => 0.0,
};
if (!double.TryParse(parameter?.ToString(), NumberStyles.Float, CultureInfo.InvariantCulture, out var threshold))
threshold = 1.0;
return level >= threshold ? ActiveOpacity : InactiveOpacity;
}
public object ConvertBack(object value, System.Type targetType, object parameter, CultureInfo culture) =>
System.Windows.Data.Binding.DoNothing;
}