diff --git a/src/TeamsISO.App.WinUI/Views/MainWindow.xaml.cs b/src/TeamsISO.App.WinUI/Views/MainWindow.xaml.cs index d30c5a3..a03cca3 100644 --- a/src/TeamsISO.App.WinUI/Views/MainWindow.xaml.cs +++ b/src/TeamsISO.App.WinUI/Views/MainWindow.xaml.cs @@ -29,6 +29,120 @@ public sealed partial class MainWindow : Window ThemeManager.Current.Themed += (_, theme) => ApplyResolvedTheme(theme); ApplyResolvedTheme(ThemeManager.Current.ResolveTheme()); + + WireKeyboardShortcuts(); + } + + /// + /// Attaches the window-scoped keyboard accelerators that match the + /// WPF host's KeyBindings: F1 help, Ctrl+M marker, Ctrl+Shift+S + /// panic stop, Ctrl+R refresh, 1-9 + NumPad 1-9 toggle ISO by visible + /// row index. WinUI 3 KeyboardAccelerators live on UIElement, so we + /// attach them to the content root. + /// + private void WireKeyboardShortcuts() + { + if (Content is not Microsoft.UI.Xaml.UIElement root) return; + + void Bind(Windows.System.VirtualKey key, + Windows.System.VirtualKeyModifiers mods, + Windows.Foundation.TypedEventHandler handler) + { + var acc = new Microsoft.UI.Xaml.Input.KeyboardAccelerator + { + Key = key, + Modifiers = mods, + ScopeOwner = root, + }; + acc.Invoked += handler; + root.KeyboardAccelerators.Add(acc); + } + + // F1 — help dialog + Bind(Windows.System.VirtualKey.F1, + Windows.System.VirtualKeyModifiers.None, + (s, e) => { e.Handled = true; _ = ShowHelpDialogAsync(); }); + + // Ctrl+M — drop a recording marker + Bind(Windows.System.VirtualKey.M, + Windows.System.VirtualKeyModifiers.Control, + (s, e) => + { + e.Handled = true; + if (_viewModel?.DropRecordingMarkerCommand.CanExecute(null) == true) + _viewModel.DropRecordingMarkerCommand.Execute(null); + }); + + // Ctrl+Shift+S — panic stop all ISOs + Bind(Windows.System.VirtualKey.S, + Windows.System.VirtualKeyModifiers.Control | Windows.System.VirtualKeyModifiers.Shift, + (s, e) => + { + e.Handled = true; + if (_viewModel?.StopAllIsosCommand.CanExecute(null) == true) + _viewModel.StopAllIsosCommand.Execute(null); + }); + + // Ctrl+R — refresh NDI discovery + Bind(Windows.System.VirtualKey.R, + Windows.System.VirtualKeyModifiers.Control, + (s, e) => + { + e.Handled = true; + if (_viewModel?.RefreshDiscoveryCommand.CanExecute(null) == true) + _viewModel.RefreshDiscoveryCommand.Execute(null); + }); + + // 1-9 and NumPad1-9 — toggle ISO for the Nth visible participant + for (var i = 1; i <= 9; i++) + { + var idx = i.ToString(); + Bind((Windows.System.VirtualKey)(0x30 + i), // VK '1'..'9' + Windows.System.VirtualKeyModifiers.None, + (s, e) => + { + e.Handled = true; + if (_viewModel?.ToggleByIndexCommand.CanExecute(idx) == true) + _viewModel.ToggleByIndexCommand.Execute(idx); + }); + Bind((Windows.System.VirtualKey)(0x60 + i), // VK NumPad1..NumPad9 + Windows.System.VirtualKeyModifiers.None, + (s, e) => + { + e.Handled = true; + if (_viewModel?.ToggleByIndexCommand.CanExecute(idx) == true) + _viewModel.ToggleByIndexCommand.Execute(idx); + }); + } + + // Esc — dismiss the settings drawer if open + Bind(Windows.System.VirtualKey.Escape, + Windows.System.VirtualKeyModifiers.None, + (s, e) => + { + if (_drawerOpen) + { + e.Handled = true; + OnDrawerCloseRequested(this, System.EventArgs.Empty); + } + }); + } + + private async System.Threading.Tasks.Task ShowHelpDialogAsync() + { + try + { + var dlg = new HelpDialog + { + XamlRoot = (Content as Microsoft.UI.Xaml.FrameworkElement)?.XamlRoot, + }; + await dlg.ShowAsync(); + } + catch (System.Exception ex) + { + StatusBarText.Text = $"Help failed: {ex.Message}"; + } } ///