feat(winui3): scaffold TeamsISO.App.WinUI alongside the WPF host
First step of the WinUI 3 replatform per the approved redesign brief.
The new project coexists with the existing src/TeamsISO.App (WPF) so the
WPF host keeps building and shipping while the WinUI 3 redesign lands
incrementally. Once the WinUI 3 build is feature-complete and tested
against a real Teams meeting, the WPF project is retired.
Scaffold contents:
* src/TeamsISO.App.WinUI/TeamsISO.App.WinUI.csproj
Windows App SDK 1.6 LTS (250602001), unpackaged mode
(WindowsPackageType=None) so the existing MSI installer keeps working.
Target framework net8.0-windows10.0.19041.0, min platform 10.0.17763.0
to preserve Win10 1809+ compatibility for working broadcast hardware.
Pins WindowsSdkPackageVersion=10.0.19041.38 so .NET SDK 8.0.301 builds
cleanly without an SDK upgrade on the build host.
* src/TeamsISO.App.WinUI/app.manifest
PerMonitorV2 DPI awareness + gdiScaling for crisp text on high-DPI
broadcast monitors. asInvoker trust level (control surface :9755 and
OSC :9000 bind to 127.0.0.1, no admin needed).
* App.xaml + App.xaml.cs
Minimal startup: brings up MainWindow. The full pipeline (NDI runtime
preflight, IsoController wiring, single-instance mutex, REST + OSC
bridge, tray icon, crash diagnostics, auto-update banner, onboarding)
migrates in subsequent commits.
* Themes/Tokens.xaml
Wild Dragon design tokens as ThemeDictionary entries (Default = Dark,
Light). Colors as Color resources, Brushes paired per theme so
{ThemeResource} auto-swaps when RequestedTheme flips — no app restart,
no flicker. Spacing/radii/typography tokens are theme-agnostic at the
outer level. Light palette maintains brand recognition via cyan-tinted
off-whites (#FAFAFB canvas, #F0F1F3 rail) rather than pure white, and
splits cyan into accent.cyan.surface (#97EDF0, works in both modes
because text on top is near-black) and accent.cyan.text (#97EDF0 dark
/ #0E7C82 light) so captions and inline labels keep AA contrast.
* Themes/Controls.xaml
Button hierarchy with real commitments: Primary (cyan fill, one per
surface), Secondary (transparent bordered), Tertiary (text only),
Destructive (coral border + text), Caption (titlebar), RailIcon.
Typographic ramp (Display / Title / Heading / Body / Subtle / Caption
/ Mono) at the DESIGN.md 1.25 ratio.
* CommunityToolkit.WinUI.UI.Controls.DataGrid 7.1.2 referenced for the
participants table migration. (Toolkit 8.x dropped DataGrid; 7.x is
the only currently-maintained free option for WinUI 3.)
* Inter.ttf + JetBrainsMono.ttf + dragon-mark.png + teamsiso.ico copied
from the WPF project's Assets/ so the WinUI 3 host is self-contained.
* TeamsISO.sln + TeamsISO.Windows.slnf updated to include the new
project. The .slnf paths switch to backslash form so MSBuild can match
them against the .sln's canonical path representation.
Verified: dotnet build TeamsISO.Windows.slnf -c Debug succeeds with 0
warnings and 0 errors for all 8 projects (WPF host, WinUI 3 host, engine,
NDI interop, console, three test projects).
2026-05-12 23:52:35 -04:00
|
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
|
<Window
|
|
|
|
|
x:Class="TeamsISO.App.WinUI.Views.MainWindow"
|
|
|
|
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
2026-05-13 00:20:23 -04:00
|
|
|
xmlns:models="using:TeamsISO.App.WinUI.Models"
|
|
|
|
|
xmlns:views="using:TeamsISO.App.WinUI.Views">
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
TeamsISO MainWindow — redesigned IA per the approved shape brief.
|
|
|
|
|
|
|
|
|
|
Structure:
|
|
|
|
|
[64 rail] [content]
|
|
|
|
|
[44 title bar — drag region]
|
|
|
|
|
[section header]
|
|
|
|
|
[participants list — hero]
|
|
|
|
|
[in-call control — conditional]
|
|
|
|
|
[32 status bar]
|
|
|
|
|
|
|
|
|
|
The rail's bottom puck opens the engine-status popover that absorbs
|
|
|
|
|
what used to live in the WPF footer (logs path, version, control
|
|
|
|
|
surface URL details). The title bar absorbs the live state pills
|
|
|
|
|
(session timer · REC · disk free) so the operator's at-a-glance
|
|
|
|
|
read stays in peripheral vision regardless of scroll position.
|
|
|
|
|
|
|
|
|
|
Settings is a right-side drawer (opened from the rail settings icon)
|
|
|
|
|
rather than a permanent 380px panel — the participants list claims
|
|
|
|
|
the full content width when settings aren't being actively edited.
|
|
|
|
|
-->
|
|
|
|
|
|
feat(winui3): scaffold TeamsISO.App.WinUI alongside the WPF host
First step of the WinUI 3 replatform per the approved redesign brief.
The new project coexists with the existing src/TeamsISO.App (WPF) so the
WPF host keeps building and shipping while the WinUI 3 redesign lands
incrementally. Once the WinUI 3 build is feature-complete and tested
against a real Teams meeting, the WPF project is retired.
Scaffold contents:
* src/TeamsISO.App.WinUI/TeamsISO.App.WinUI.csproj
Windows App SDK 1.6 LTS (250602001), unpackaged mode
(WindowsPackageType=None) so the existing MSI installer keeps working.
Target framework net8.0-windows10.0.19041.0, min platform 10.0.17763.0
to preserve Win10 1809+ compatibility for working broadcast hardware.
Pins WindowsSdkPackageVersion=10.0.19041.38 so .NET SDK 8.0.301 builds
cleanly without an SDK upgrade on the build host.
* src/TeamsISO.App.WinUI/app.manifest
PerMonitorV2 DPI awareness + gdiScaling for crisp text on high-DPI
broadcast monitors. asInvoker trust level (control surface :9755 and
OSC :9000 bind to 127.0.0.1, no admin needed).
* App.xaml + App.xaml.cs
Minimal startup: brings up MainWindow. The full pipeline (NDI runtime
preflight, IsoController wiring, single-instance mutex, REST + OSC
bridge, tray icon, crash diagnostics, auto-update banner, onboarding)
migrates in subsequent commits.
* Themes/Tokens.xaml
Wild Dragon design tokens as ThemeDictionary entries (Default = Dark,
Light). Colors as Color resources, Brushes paired per theme so
{ThemeResource} auto-swaps when RequestedTheme flips — no app restart,
no flicker. Spacing/radii/typography tokens are theme-agnostic at the
outer level. Light palette maintains brand recognition via cyan-tinted
off-whites (#FAFAFB canvas, #F0F1F3 rail) rather than pure white, and
splits cyan into accent.cyan.surface (#97EDF0, works in both modes
because text on top is near-black) and accent.cyan.text (#97EDF0 dark
/ #0E7C82 light) so captions and inline labels keep AA contrast.
* Themes/Controls.xaml
Button hierarchy with real commitments: Primary (cyan fill, one per
surface), Secondary (transparent bordered), Tertiary (text only),
Destructive (coral border + text), Caption (titlebar), RailIcon.
Typographic ramp (Display / Title / Heading / Body / Subtle / Caption
/ Mono) at the DESIGN.md 1.25 ratio.
* CommunityToolkit.WinUI.UI.Controls.DataGrid 7.1.2 referenced for the
participants table migration. (Toolkit 8.x dropped DataGrid; 7.x is
the only currently-maintained free option for WinUI 3.)
* Inter.ttf + JetBrainsMono.ttf + dragon-mark.png + teamsiso.ico copied
from the WPF project's Assets/ so the WinUI 3 host is self-contained.
* TeamsISO.sln + TeamsISO.Windows.slnf updated to include the new
project. The .slnf paths switch to backslash form so MSBuild can match
them against the .sln's canonical path representation.
Verified: dotnet build TeamsISO.Windows.slnf -c Debug succeeds with 0
warnings and 0 errors for all 8 projects (WPF host, WinUI 3 host, engine,
NDI interop, console, three test projects).
2026-05-12 23:52:35 -04:00
|
|
|
<Grid Background="{ThemeResource BgCanvas}">
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
<ColumnDefinition Width="64"/>
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
</Grid.ColumnDefinitions>
|
2026-05-13 00:20:23 -04:00
|
|
|
<Grid.Resources>
|
|
|
|
|
<!-- Drawer slide-in: 220ms ease-out-quart, translates 400px → 0 -->
|
|
|
|
|
<Storyboard x:Key="DrawerSlideIn">
|
|
|
|
|
<DoubleAnimation Storyboard.TargetName="DrawerTransform"
|
|
|
|
|
Storyboard.TargetProperty="X"
|
|
|
|
|
To="0"
|
|
|
|
|
Duration="0:0:0.22">
|
|
|
|
|
<DoubleAnimation.EasingFunction>
|
|
|
|
|
<QuarticEase EasingMode="EaseOut"/>
|
|
|
|
|
</DoubleAnimation.EasingFunction>
|
|
|
|
|
</DoubleAnimation>
|
|
|
|
|
</Storyboard>
|
|
|
|
|
<Storyboard x:Key="DrawerSlideOut">
|
|
|
|
|
<DoubleAnimation Storyboard.TargetName="DrawerTransform"
|
|
|
|
|
Storyboard.TargetProperty="X"
|
|
|
|
|
To="400"
|
|
|
|
|
Duration="0:0:0.18">
|
|
|
|
|
<DoubleAnimation.EasingFunction>
|
|
|
|
|
<QuarticEase EasingMode="EaseIn"/>
|
|
|
|
|
</DoubleAnimation.EasingFunction>
|
|
|
|
|
</DoubleAnimation>
|
|
|
|
|
</Storyboard>
|
|
|
|
|
</Grid.Resources>
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
|
|
|
|
|
<!-- ═══════════════════════ LEFT RAIL ═══════════════════════ -->
|
|
|
|
|
<Border Grid.Column="0"
|
|
|
|
|
Background="{ThemeResource BgRail}"
|
|
|
|
|
BorderBrush="{ThemeResource BorderSubtle}"
|
|
|
|
|
BorderThickness="0,0,1,0">
|
|
|
|
|
<Grid>
|
|
|
|
|
<Grid.RowDefinitions>
|
|
|
|
|
<RowDefinition Height="*"/>
|
|
|
|
|
<RowDefinition Height="Auto"/>
|
|
|
|
|
</Grid.RowDefinitions>
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Row="0" Spacing="2" Padding="0,12,0,0">
|
|
|
|
|
<!-- Wild Dragon brand mark -->
|
|
|
|
|
<Button x:Name="BrandButton"
|
|
|
|
|
Style="{StaticResource ButtonRailIcon}"
|
|
|
|
|
Width="48" Height="56"
|
|
|
|
|
Margin="8,0,8,8"
|
|
|
|
|
ToolTipService.ToolTip="About TeamsISO">
|
|
|
|
|
<Border Width="40" Height="40"
|
|
|
|
|
CornerRadius="{ThemeResource RadiusM}"
|
|
|
|
|
Background="{ThemeResource AccentCyanMuted}">
|
|
|
|
|
<TextBlock Text="W"
|
|
|
|
|
FontFamily="{ThemeResource FontSans}"
|
|
|
|
|
FontSize="22"
|
|
|
|
|
FontWeight="Bold"
|
|
|
|
|
Foreground="{ThemeResource AccentCyanText}"
|
|
|
|
|
HorizontalAlignment="Center"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</Border>
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<Border Height="1"
|
|
|
|
|
Background="{ThemeResource BorderSubtle}"
|
|
|
|
|
Margin="14,4,14,12"/>
|
|
|
|
|
|
|
|
|
|
<!-- Participants / Home (active) -->
|
|
|
|
|
<Button Style="{StaticResource ButtonRailIcon}"
|
|
|
|
|
Margin="8,0"
|
|
|
|
|
ToolTipService.ToolTip="Participants">
|
|
|
|
|
<Grid>
|
|
|
|
|
<Border Width="48" Height="48"
|
|
|
|
|
CornerRadius="{ThemeResource RadiusM}"
|
|
|
|
|
Background="{ThemeResource AccentCyanMuted}"/>
|
|
|
|
|
<FontIcon Glyph=""
|
|
|
|
|
FontSize="20"
|
|
|
|
|
Foreground="{ThemeResource AccentCyanText}"
|
|
|
|
|
HorizontalAlignment="Center"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</Grid>
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<!-- Launch / surface Teams -->
|
|
|
|
|
<Button Style="{StaticResource ButtonRailIcon}"
|
|
|
|
|
Margin="8,0"
|
|
|
|
|
ToolTipService.ToolTip="Launch Microsoft Teams (or surface its window)">
|
|
|
|
|
<FontIcon Glyph=""
|
|
|
|
|
FontSize="20"
|
|
|
|
|
Foreground="{ThemeResource FgSecondary}"/>
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<!-- Hide / show Teams windows -->
|
|
|
|
|
<Button Style="{StaticResource ButtonRailIcon}"
|
|
|
|
|
Margin="8,0"
|
|
|
|
|
ToolTipService.ToolTip="Hide / show Microsoft Teams windows">
|
|
|
|
|
<FontIcon Glyph=""
|
|
|
|
|
FontSize="20"
|
|
|
|
|
Foreground="{ThemeResource FgSecondary}"/>
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<!-- Settings drawer trigger -->
|
|
|
|
|
<Button x:Name="SettingsButton"
|
|
|
|
|
Style="{StaticResource ButtonRailIcon}"
|
|
|
|
|
Margin="8,0"
|
2026-05-13 00:20:23 -04:00
|
|
|
Click="OnSettingsClick"
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
ToolTipService.ToolTip="Settings">
|
|
|
|
|
<FontIcon Glyph=""
|
|
|
|
|
FontSize="20"
|
|
|
|
|
Foreground="{ThemeResource FgSecondary}"/>
|
|
|
|
|
</Button>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
<!-- Engine status puck — opens the status popover -->
|
|
|
|
|
<Button x:Name="StatusPuckButton"
|
|
|
|
|
Grid.Row="1"
|
|
|
|
|
Style="{StaticResource ButtonRailIcon}"
|
|
|
|
|
Width="48" Height="48"
|
|
|
|
|
Margin="8,12"
|
|
|
|
|
CornerRadius="24"
|
|
|
|
|
Background="{ThemeResource StatusLiveBg}"
|
|
|
|
|
ToolTipService.ToolTip="Engine status">
|
|
|
|
|
<Ellipse Width="10" Height="10"
|
|
|
|
|
Fill="{ThemeResource StatusLive}"/>
|
|
|
|
|
</Button>
|
|
|
|
|
</Grid>
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
<!-- ═══════════════════════ CONTENT ═══════════════════════ -->
|
|
|
|
|
<Grid Grid.Column="1">
|
|
|
|
|
<Grid.RowDefinitions>
|
|
|
|
|
<RowDefinition Height="44"/>
|
|
|
|
|
<RowDefinition Height="Auto"/>
|
|
|
|
|
<RowDefinition Height="*"/>
|
|
|
|
|
<RowDefinition Height="Auto"/>
|
|
|
|
|
<RowDefinition Height="32"/>
|
|
|
|
|
</Grid.RowDefinitions>
|
|
|
|
|
|
|
|
|
|
<!-- ─── Title bar ─── -->
|
|
|
|
|
<!--
|
|
|
|
|
AppTitleBar is the drag region. Window.SetTitleBar(AppTitleBar)
|
|
|
|
|
in code-behind makes this element the operating-system-defined
|
|
|
|
|
drag area. The system Min/Max/Close buttons render to the right
|
|
|
|
|
of this element automatically (their colors come from
|
|
|
|
|
AppWindow.TitleBar.ButtonForegroundColor etc.); we draw
|
|
|
|
|
everything else.
|
|
|
|
|
-->
|
|
|
|
|
<Grid x:Name="AppTitleBar"
|
|
|
|
|
Grid.Row="0"
|
|
|
|
|
Background="{ThemeResource BgCanvas}">
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Column="0"
|
|
|
|
|
Orientation="Horizontal"
|
|
|
|
|
Spacing="12"
|
|
|
|
|
Padding="24,0,0,0"
|
|
|
|
|
VerticalAlignment="Center">
|
|
|
|
|
<TextBlock Text="TeamsISO"
|
|
|
|
|
Style="{StaticResource TextHeading}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
<TextBlock x:Name="VersionLabel"
|
|
|
|
|
Text="v1.0.0-alpha"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource FgTertiary}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
<!-- Live pills (session timer / REC count / disk) live in the
|
|
|
|
|
title bar so peripheral-vision status reads from the same
|
|
|
|
|
place whether the operator is scrolled, settings-drawer
|
|
|
|
|
open, or in-call. Conditionally shown via code-behind. -->
|
|
|
|
|
<StackPanel x:Name="LivePillsPanel"
|
|
|
|
|
Grid.Column="2"
|
|
|
|
|
Orientation="Horizontal"
|
|
|
|
|
Spacing="8"
|
|
|
|
|
VerticalAlignment="Center"
|
|
|
|
|
Padding="0,0,12,0">
|
|
|
|
|
<Border CornerRadius="{ThemeResource RadiusPill}"
|
|
|
|
|
Background="{ThemeResource StatusLiveBg}"
|
|
|
|
|
Padding="10,4">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
|
|
|
<Ellipse Width="7" Height="7"
|
|
|
|
|
Fill="{ThemeResource StatusLive}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
<TextBlock x:Name="SessionTimerText"
|
|
|
|
|
Text="live · 00:14:32"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource StatusLive}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
<Border CornerRadius="{ThemeResource RadiusPill}"
|
|
|
|
|
Background="{ThemeResource AccentCoralBg}"
|
|
|
|
|
Padding="10,4">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
|
|
|
<Ellipse Width="7" Height="7"
|
|
|
|
|
Fill="{ThemeResource AccentCoral}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
<TextBlock x:Name="RecPillText"
|
|
|
|
|
Text="rec 3 · 00:11:08"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource AccentCoral}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Border>
|
|
|
|
|
|
|
|
|
|
<Border CornerRadius="{ThemeResource RadiusPill}"
|
|
|
|
|
Background="{ThemeResource BgSurface}"
|
|
|
|
|
BorderBrush="{ThemeResource BorderSubtle}"
|
|
|
|
|
BorderThickness="1"
|
|
|
|
|
Padding="10,4">
|
|
|
|
|
<TextBlock x:Name="DiskFreeText"
|
|
|
|
|
Text="482 GB free"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource FgSecondary}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</Border>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
<!-- Theme toggle — single-click cycle between Dark and Light.
|
|
|
|
|
Persisted to UIPreferences.Theme on click. -->
|
|
|
|
|
<Button x:Name="ThemeToggleButton"
|
|
|
|
|
Grid.Column="3"
|
|
|
|
|
Style="{StaticResource ButtonCaption}"
|
|
|
|
|
Click="OnThemeToggleClick"
|
|
|
|
|
ToolTipService.ToolTip="Toggle theme (dark / light)">
|
|
|
|
|
<FontIcon x:Name="ThemeToggleIcon"
|
|
|
|
|
Glyph=""
|
|
|
|
|
FontSize="14"/>
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
<!-- The Min / Max / Close buttons that follow in Grid.Column 4,5
|
|
|
|
|
are NOT drawn here — the WindowsAppSDK title-bar API draws
|
|
|
|
|
them itself, overlaid on the drag region we've defined.
|
|
|
|
|
The reserved columns 4 and 5 are just visual placeholders
|
|
|
|
|
in this layout to remind future readers where they land. -->
|
|
|
|
|
<Border Grid.Column="4" Width="138" Background="Transparent"/>
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
<!-- ─── Section header ─── -->
|
|
|
|
|
<Grid Grid.Row="1" Padding="32,18,32,12">
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Column="0"
|
|
|
|
|
Orientation="Horizontal"
|
|
|
|
|
Spacing="12"
|
|
|
|
|
VerticalAlignment="Center">
|
|
|
|
|
<TextBlock Text="Participants"
|
|
|
|
|
Style="{StaticResource TextDisplay}"/>
|
|
|
|
|
<Border CornerRadius="{ThemeResource RadiusPill}"
|
|
|
|
|
Background="{ThemeResource BgSurface}"
|
|
|
|
|
BorderBrush="{ThemeResource BorderSubtle}"
|
|
|
|
|
BorderThickness="1"
|
|
|
|
|
Padding="10,3"
|
|
|
|
|
VerticalAlignment="Center">
|
|
|
|
|
<TextBlock x:Name="ParticipantCountText"
|
|
|
|
|
Text="4"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource FgSecondary}"/>
|
|
|
|
|
</Border>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Column="2"
|
|
|
|
|
Orientation="Horizontal"
|
|
|
|
|
Spacing="8"
|
|
|
|
|
VerticalAlignment="Center">
|
|
|
|
|
<TextBox x:Name="FilterInput"
|
|
|
|
|
PlaceholderText="Filter"
|
|
|
|
|
Width="200"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
<Button Style="{StaticResource ButtonSecondary}"
|
|
|
|
|
Content="Refresh"
|
|
|
|
|
ToolTipService.ToolTip="Refresh NDI discovery"/>
|
|
|
|
|
<Button Style="{StaticResource ButtonSecondary}"
|
|
|
|
|
Content="Presets"
|
|
|
|
|
ToolTipService.ToolTip="Save or load operator presets"/>
|
|
|
|
|
<Button Style="{StaticResource ButtonPrimary}"
|
|
|
|
|
Content="Enable all online"
|
|
|
|
|
HorizontalAlignment="Right"
|
|
|
|
|
ToolTipService.ToolTip="Enable ISOs for every online participant"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Grid>
|
|
|
|
|
|
|
|
|
|
<!-- ─── Participants list (hero) ─── -->
|
2026-05-13 00:39:43 -04:00
|
|
|
<!--
|
|
|
|
|
ItemsRepeater + DataTemplate with bindings deferred to the
|
|
|
|
|
view-model-wiring commit (Phase 4 of the migration plan).
|
|
|
|
|
For now, a single stub row renders so the layout's vertical
|
|
|
|
|
rhythm is verifiable even without real data. The full row
|
|
|
|
|
template (with active-speaker accent, avatar circle, signal
|
|
|
|
|
lock, audio meter, ISO toggle) is captured in the HTML
|
|
|
|
|
preview at docs/preview/redesigned-mainwindow.html and the
|
|
|
|
|
git history of this file shows the binding-heavy version
|
|
|
|
|
we'll re-introduce once the engine is wired in.
|
|
|
|
|
-->
|
|
|
|
|
<Grid Grid.Row="2" Padding="32,0,32,0">
|
|
|
|
|
<StackPanel x:Name="ParticipantsStub"
|
|
|
|
|
VerticalAlignment="Center"
|
|
|
|
|
HorizontalAlignment="Center"
|
|
|
|
|
Spacing="8">
|
|
|
|
|
<TextBlock Text="Participants list renders here"
|
|
|
|
|
Style="{StaticResource TextHeading}"
|
|
|
|
|
HorizontalAlignment="Center"/>
|
|
|
|
|
<TextBlock Text="View-model wiring queued for the next session."
|
|
|
|
|
Style="{StaticResource TextSubtle}"
|
|
|
|
|
HorizontalAlignment="Center"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Grid>
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
|
|
|
|
|
<!-- ─── In-call control (conditional) ─── -->
|
|
|
|
|
<Border Grid.Row="3"
|
|
|
|
|
Padding="32,12,32,12"
|
|
|
|
|
BorderBrush="{ThemeResource BorderSubtle}"
|
|
|
|
|
BorderThickness="0,1,0,0"
|
|
|
|
|
Background="{ThemeResource BgCanvas}">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
|
|
|
|
<TextBlock Text="IN-CALL"
|
|
|
|
|
Style="{StaticResource TextCaption}"
|
|
|
|
|
VerticalAlignment="Center"
|
|
|
|
|
Margin="0,0,8,0"/>
|
|
|
|
|
<Button Style="{StaticResource ButtonDestructive}"
|
|
|
|
|
ToolTipService.ToolTip="Toggle microphone mute">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
|
|
|
<FontIcon Glyph="" FontSize="14"/>
|
|
|
|
|
<TextBlock Text="Muted"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Button>
|
|
|
|
|
<Button Style="{StaticResource ButtonSecondary}"
|
|
|
|
|
ToolTipService.ToolTip="Toggle camera">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
|
|
|
<FontIcon Glyph="" FontSize="14"/>
|
|
|
|
|
<TextBlock Text="Camera"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Button>
|
|
|
|
|
<Button Style="{StaticResource ButtonSecondary}"
|
|
|
|
|
ToolTipService.ToolTip="Open Teams share tray">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
|
|
|
<FontIcon Glyph="" FontSize="14"/>
|
|
|
|
|
<TextBlock Text="Share"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Button>
|
|
|
|
|
<Button Style="{StaticResource ButtonSecondary}"
|
|
|
|
|
ToolTipService.ToolTip="Drop a timestamped marker into every active recording">
|
|
|
|
|
<StackPanel Orientation="Horizontal" Spacing="6">
|
|
|
|
|
<FontIcon Glyph="" FontSize="14"/>
|
|
|
|
|
<TextBlock Text="Marker"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Button>
|
|
|
|
|
<Button Style="{StaticResource ButtonDestructive}"
|
|
|
|
|
ToolTipService.ToolTip="Leave the Teams call">
|
|
|
|
|
<TextBlock Text="Leave"/>
|
|
|
|
|
</Button>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
</Border>
|
|
|
|
|
|
2026-05-13 00:20:23 -04:00
|
|
|
<!-- ─── Settings drawer (slides over rows 1-3) ─── -->
|
|
|
|
|
<views:SettingsDrawer x:Name="SettingsDrawerHost"
|
|
|
|
|
Grid.Row="0"
|
|
|
|
|
Grid.RowSpan="4"
|
|
|
|
|
HorizontalAlignment="Right"
|
|
|
|
|
Width="400"
|
|
|
|
|
IsHitTestVisible="False">
|
|
|
|
|
<views:SettingsDrawer.RenderTransform>
|
|
|
|
|
<TranslateTransform x:Name="DrawerTransform" X="400"/>
|
|
|
|
|
</views:SettingsDrawer.RenderTransform>
|
|
|
|
|
</views:SettingsDrawer>
|
|
|
|
|
|
feat(winui3): redesigned MainWindow + custom title bar + theme toggle
Lands the approved shape brief as the WinUI 3 MainWindow:
* 64px left rail with brand mark, primary nav (participants), Teams
launch / hide / settings buttons, and the engine-status puck at the
bottom. All five rail buttons use Segoe Fluent Icons glyphs at a
uniform 20px optical size; no more bespoke <Path Data> shapes with
inconsistent stroke weights.
* 44px custom title bar via ExtendsContentIntoTitleBar +
SetTitleBar(AppTitleBar). The drag region absorbs the three live-state
pills inline (session timer 'live * 00:14:32', REC count + elapsed,
disk free) and a slim sun/moon theme-toggle button to the left of the
system Min/Max/Close controls. System buttons inherit ButtonForeground
Color etc. from AppWindow.TitleBar so they match palette in both
themes.
* Section header with 'Participants * count' display, filter input,
Refresh + Presets (Secondary buttons), and 'Enable all online' as
the single cyan Primary button - finally a real button hierarchy
instead of seven indistinguishable ghost buttons.
* Participants list rendered as ItemsRepeater + DataTemplate for now;
the CommunityToolkit DataGrid migration follows in a separate commit.
Row template at 64px height with: 3px cyan left border for active
speaker, avatar with initials in cyan-muted circle, name + codec line,
signal lock state with dot, audio meter via ProgressBar, output name
in JetBrains Mono, ISO state pill (LIVE/OFF/ERROR) at right.
* Conditional in-call control bar below the table: Mute / Camera /
Share / Marker / Leave + overflow kebab. Muted state binds the
destructive coral treatment to the Mute button; Leave is also
destructive (coral border + text); everything else is Secondary.
Tight 8px spacing keeps the bar dense without crowding.
* Slim 32px status bar at the bottom: control-surface URL on the left
(cyan dot indicator), keyboard-shortcut hints on the right in
tertiary mono. Replaces the WPF host's six-column footer.
Implementation notes:
* MockParticipant model populates the table with representative data
(Maya / Daniel / Aicha / Sam, one as active speaker) until the
ParticipantViewModel binding migrates over from the WPF host.
* Custom Program.cs takes ownership of Main from the XAML compiler
(DISABLE_XAML_GENERATED_MAIN). Calls Bootstrap.TryInitialize(0x00010006)
before Application.Start so the unpackaged .exe can locate the
WindowsAppSDK 1.6 framework MSIX at launch. Shutdown is paired in
a finally block.
* Theme toggle in code-behind flips Window.Content.RequestedTheme
between Dark and Light. {ThemeResource} bindings auto-swap across
the visual tree; system title-bar buttons (outside the XAML tree)
get color updates inline so they stay readable in both modes.
* app.manifest deferred from build - the framework-emitted manifest
covers DPI awareness and supportedOS GUIDs; reintroducing our own
goes in the next commit alongside the bootstrapper hardening.
Known issue: the unpackaged .exe currently fails to activate on this
build host with 'this application could not be started' before Main
runs. Build is clean; published output runs the same way. Diagnosing
the activation failure is the next session's first task (likely the
runtimeconfig.json including Microsoft.WindowsDesktop.App which WinUI 3
doesn't want, or a missing CRT redistributable). The WPF host remains
the running build until that's resolved.
dotnet build TeamsISO.Windows.slnf -c Debug: 0 warnings, 0 errors.
2026-05-13 00:03:12 -04:00
|
|
|
<!-- ─── Status bar ─── -->
|
|
|
|
|
<Grid Grid.Row="4"
|
|
|
|
|
Padding="32,8,32,8"
|
|
|
|
|
Background="{ThemeResource BgCanvas}"
|
|
|
|
|
BorderBrush="{ThemeResource BorderSubtle}"
|
|
|
|
|
BorderThickness="0,1,0,0">
|
|
|
|
|
<Grid.ColumnDefinitions>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
<ColumnDefinition Width="*"/>
|
|
|
|
|
<ColumnDefinition Width="Auto"/>
|
|
|
|
|
</Grid.ColumnDefinitions>
|
|
|
|
|
|
|
|
|
|
<StackPanel Grid.Column="0"
|
|
|
|
|
Orientation="Horizontal"
|
|
|
|
|
Spacing="8"
|
|
|
|
|
VerticalAlignment="Center">
|
|
|
|
|
<Ellipse Width="6" Height="6"
|
|
|
|
|
Fill="{ThemeResource AccentCyanText}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
<TextBlock Text="control surface · 127.0.0.1:9755"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource FgSecondary}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</StackPanel>
|
|
|
|
|
|
|
|
|
|
<TextBlock Grid.Column="2"
|
|
|
|
|
Text="F1 help · Ctrl+M marker · Ctrl+Shift+S panic stop · Ctrl+K command palette"
|
|
|
|
|
Style="{StaticResource TextMono}"
|
|
|
|
|
FontSize="11"
|
|
|
|
|
Foreground="{ThemeResource FgTertiary}"
|
|
|
|
|
VerticalAlignment="Center"/>
|
|
|
|
|
</Grid>
|
|
|
|
|
</Grid>
|
feat(winui3): scaffold TeamsISO.App.WinUI alongside the WPF host
First step of the WinUI 3 replatform per the approved redesign brief.
The new project coexists with the existing src/TeamsISO.App (WPF) so the
WPF host keeps building and shipping while the WinUI 3 redesign lands
incrementally. Once the WinUI 3 build is feature-complete and tested
against a real Teams meeting, the WPF project is retired.
Scaffold contents:
* src/TeamsISO.App.WinUI/TeamsISO.App.WinUI.csproj
Windows App SDK 1.6 LTS (250602001), unpackaged mode
(WindowsPackageType=None) so the existing MSI installer keeps working.
Target framework net8.0-windows10.0.19041.0, min platform 10.0.17763.0
to preserve Win10 1809+ compatibility for working broadcast hardware.
Pins WindowsSdkPackageVersion=10.0.19041.38 so .NET SDK 8.0.301 builds
cleanly without an SDK upgrade on the build host.
* src/TeamsISO.App.WinUI/app.manifest
PerMonitorV2 DPI awareness + gdiScaling for crisp text on high-DPI
broadcast monitors. asInvoker trust level (control surface :9755 and
OSC :9000 bind to 127.0.0.1, no admin needed).
* App.xaml + App.xaml.cs
Minimal startup: brings up MainWindow. The full pipeline (NDI runtime
preflight, IsoController wiring, single-instance mutex, REST + OSC
bridge, tray icon, crash diagnostics, auto-update banner, onboarding)
migrates in subsequent commits.
* Themes/Tokens.xaml
Wild Dragon design tokens as ThemeDictionary entries (Default = Dark,
Light). Colors as Color resources, Brushes paired per theme so
{ThemeResource} auto-swaps when RequestedTheme flips — no app restart,
no flicker. Spacing/radii/typography tokens are theme-agnostic at the
outer level. Light palette maintains brand recognition via cyan-tinted
off-whites (#FAFAFB canvas, #F0F1F3 rail) rather than pure white, and
splits cyan into accent.cyan.surface (#97EDF0, works in both modes
because text on top is near-black) and accent.cyan.text (#97EDF0 dark
/ #0E7C82 light) so captions and inline labels keep AA contrast.
* Themes/Controls.xaml
Button hierarchy with real commitments: Primary (cyan fill, one per
surface), Secondary (transparent bordered), Tertiary (text only),
Destructive (coral border + text), Caption (titlebar), RailIcon.
Typographic ramp (Display / Title / Heading / Body / Subtle / Caption
/ Mono) at the DESIGN.md 1.25 ratio.
* CommunityToolkit.WinUI.UI.Controls.DataGrid 7.1.2 referenced for the
participants table migration. (Toolkit 8.x dropped DataGrid; 7.x is
the only currently-maintained free option for WinUI 3.)
* Inter.ttf + JetBrainsMono.ttf + dragon-mark.png + teamsiso.ico copied
from the WPF project's Assets/ so the WinUI 3 host is self-contained.
* TeamsISO.sln + TeamsISO.Windows.slnf updated to include the new
project. The .slnf paths switch to backslash form so MSBuild can match
them against the .sln's canonical path representation.
Verified: dotnet build TeamsISO.Windows.slnf -c Debug succeeds with 0
warnings and 0 errors for all 8 projects (WPF host, WinUI 3 host, engine,
NDI interop, console, three test projects).
2026-05-12 23:52:35 -04:00
|
|
|
</Grid>
|
|
|
|
|
</Window>
|