feat(winui3): colored ISO pills + active-speaker accent on rows
Some checks failed
CI / build-and-test (push) Has been cancelled
Some checks failed
CI / build-and-test (push) Has been cancelled
Two visual upgrades on the participant rows:
* The ISO state pill now flips background / border / text colors
based on the engine's reported state — green for LIVE, coral for
ERROR, amber for STARTING / NO SIGNAL, neutral surface for OFF.
Brushes pulled from the ThemeResource ramp (StatusLiveBg /
StatusLive / AccentCoralBg / AccentCoral / StatusWarnBg /
StatusWarn / BgSurface / BorderStrong). Mirrors the WPF host's
IsoToggle data-trigger behavior but built imperatively.
* The active-speaker left accent — a 3px cyan border at the row's
left edge — appears when MainViewModel's 1Hz stats tick marks the
loudest participant. Hidden by default; flips Visibility on
PropertyChanged(IsActiveSpeaker).
Row layout extended to accommodate: column 0 = 3px accent strip,
column 1 = 20px spacer, column 2 = name + codec (1*), column 3 =
output name (140px fixed), column 4 = ISO pill (auto).
ApplyIsoPillStyling is the brush-mapping helper — called once at row
construct and again on every IsoStateLabel / IsEnabled change. The
brush keys all resolve via Application.Current.Resources rather than
ThemeResource markup since the row is constructed imperatively (no
XAML to apply ThemeResource markup against).
Verified end-to-end: dotnet build clean, app launches with 3 live
participants in the row, all pills showing OFF (neutral surface +
strong border). Once a participant goes through OFF → STARTING (amber)
→ LIVE (green), the pill colors will update on the 1Hz stats tick.
This commit is contained in:
parent
f7249c31c2
commit
9ae14c8ee9
1 changed files with 72 additions and 9 deletions
|
|
@ -213,22 +213,35 @@ public sealed partial class MainWindow : Window
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal participant row — name + ISO state + toggle button. Drops
|
||||
/// the brushed avatar / theme-resource lookups that may have been
|
||||
/// triggering the crash. The full visual row template comes back
|
||||
/// after we've verified the binding path works.
|
||||
/// Participant row — name + ISO state pill, with the cyan-accent
|
||||
/// left border when the participant is the active speaker, and the
|
||||
/// pill background flipping green/coral/amber based on ISO state.
|
||||
/// Imperative construction so we sidestep the WinUI 3 DataTemplate
|
||||
/// parser path that crashes on this build host.
|
||||
/// </summary>
|
||||
private static Microsoft.UI.Xaml.Controls.Grid BuildSimpleRow(ParticipantViewModel p)
|
||||
{
|
||||
var grid = new Microsoft.UI.Xaml.Controls.Grid
|
||||
{
|
||||
Height = 56,
|
||||
Padding = new Thickness(20, 0, 20, 0),
|
||||
Padding = new Thickness(0, 0, 20, 0),
|
||||
};
|
||||
grid.ColumnDefinitions.Add(new Microsoft.UI.Xaml.Controls.ColumnDefinition { Width = new Microsoft.UI.Xaml.GridLength(3) });
|
||||
grid.ColumnDefinitions.Add(new Microsoft.UI.Xaml.Controls.ColumnDefinition { Width = new Microsoft.UI.Xaml.GridLength(20) });
|
||||
grid.ColumnDefinitions.Add(new Microsoft.UI.Xaml.Controls.ColumnDefinition { Width = new Microsoft.UI.Xaml.GridLength(1, Microsoft.UI.Xaml.GridUnitType.Star) });
|
||||
grid.ColumnDefinitions.Add(new Microsoft.UI.Xaml.Controls.ColumnDefinition { Width = new Microsoft.UI.Xaml.GridLength(120) });
|
||||
grid.ColumnDefinitions.Add(new Microsoft.UI.Xaml.Controls.ColumnDefinition { Width = new Microsoft.UI.Xaml.GridLength(140) });
|
||||
grid.ColumnDefinitions.Add(new Microsoft.UI.Xaml.Controls.ColumnDefinition { Width = Microsoft.UI.Xaml.GridLength.Auto });
|
||||
|
||||
// Active-speaker left accent. Visible only when IsActiveSpeaker
|
||||
// flips on (driven by MainViewModel.OnStatsTick at 1Hz).
|
||||
var accent = new Microsoft.UI.Xaml.Controls.Border
|
||||
{
|
||||
Background = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["AccentCyanText"],
|
||||
Visibility = p.IsActiveSpeaker ? Visibility.Visible : Visibility.Collapsed,
|
||||
};
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(accent, 0);
|
||||
grid.Children.Add(accent);
|
||||
|
||||
var nameStack = new Microsoft.UI.Xaml.Controls.StackPanel
|
||||
{
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
|
|
@ -248,7 +261,7 @@ public sealed partial class MainWindow : Window
|
|||
};
|
||||
nameStack.Children.Add(nameText);
|
||||
nameStack.Children.Add(codecText);
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(nameStack, 0);
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(nameStack, 2);
|
||||
grid.Children.Add(nameStack);
|
||||
|
||||
var outputText = new Microsoft.UI.Xaml.Controls.TextBlock
|
||||
|
|
@ -258,7 +271,7 @@ public sealed partial class MainWindow : Window
|
|||
FontSize = 12,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
};
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(outputText, 1);
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(outputText, 3);
|
||||
grid.Children.Add(outputText);
|
||||
|
||||
var pillText = new Microsoft.UI.Xaml.Controls.TextBlock
|
||||
|
|
@ -277,7 +290,8 @@ public sealed partial class MainWindow : Window
|
|||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Content = pillText,
|
||||
};
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(pill, 2);
|
||||
ApplyIsoPillStyling(pill, pillText, p.IsoStateLabel);
|
||||
Microsoft.UI.Xaml.Controls.Grid.SetColumn(pill, 4);
|
||||
grid.Children.Add(pill);
|
||||
|
||||
p.PropertyChanged += (_, e) =>
|
||||
|
|
@ -298,6 +312,12 @@ public sealed partial class MainWindow : Window
|
|||
case nameof(ParticipantViewModel.IsoStateLabel):
|
||||
case nameof(ParticipantViewModel.IsEnabled):
|
||||
pillText.Text = p.IsoStateLabel;
|
||||
ApplyIsoPillStyling(pill, pillText, p.IsoStateLabel);
|
||||
break;
|
||||
case nameof(ParticipantViewModel.IsActiveSpeaker):
|
||||
accent.Visibility = p.IsActiveSpeaker
|
||||
? Visibility.Visible
|
||||
: Visibility.Collapsed;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
|
@ -306,6 +326,49 @@ public sealed partial class MainWindow : Window
|
|||
return grid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Re-color the ISO pill based on the engine's reported state.
|
||||
/// LIVE = green on green-tinted background. ERROR = coral on coral-
|
||||
/// tinted background. STARTING = amber. NO SIGNAL = amber. OFF =
|
||||
/// neutral surface. Mirrors the WPF host's IsoToggle data-trigger
|
||||
/// behavior but built imperatively from theme-resource brush keys.
|
||||
/// </summary>
|
||||
private static void ApplyIsoPillStyling(
|
||||
Microsoft.UI.Xaml.Controls.Button pill,
|
||||
Microsoft.UI.Xaml.Controls.TextBlock pillText,
|
||||
string state)
|
||||
{
|
||||
Microsoft.UI.Xaml.Media.Brush bg, border, fg;
|
||||
switch (state)
|
||||
{
|
||||
case "LIVE":
|
||||
bg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["StatusLiveBg"];
|
||||
border = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["StatusLive"];
|
||||
fg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["StatusLive"];
|
||||
break;
|
||||
case "ERROR":
|
||||
bg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["AccentCoralBg"];
|
||||
border = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["AccentCoral"];
|
||||
fg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["AccentCoral"];
|
||||
break;
|
||||
case "NO SIGNAL":
|
||||
case "STARTING":
|
||||
bg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["StatusWarnBg"];
|
||||
border = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["StatusWarn"];
|
||||
fg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["StatusWarn"];
|
||||
break;
|
||||
default: // OFF / —
|
||||
bg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["BgSurface"];
|
||||
border = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["BorderStrong"];
|
||||
fg = (Microsoft.UI.Xaml.Media.Brush)Application.Current.Resources["FgPrimary"];
|
||||
break;
|
||||
}
|
||||
pill.Background = bg;
|
||||
pill.BorderBrush = border;
|
||||
pill.BorderThickness = new Thickness(1);
|
||||
pillText.Foreground = fg;
|
||||
}
|
||||
|
||||
/// <summary>Full rich row template — replaces BuildSimpleRow once we've verified the simple version doesn't crash.</summary>
|
||||
private static Microsoft.UI.Xaml.Controls.Grid BuildParticipantRow(ParticipantViewModel p)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue