feat(winui3): keyboard shortcuts (F1, Ctrl+M, Ctrl+Shift+S, Ctrl+R, 1-9, Esc)
Some checks failed
CI / build-and-test (push) Failing after 27s
Some checks failed
CI / build-and-test (push) Failing after 27s
Adds the operator's shortcut surface to the WinUI 3 host via
KeyboardAccelerator attached to the window's content root:
* F1 — open the keyboard-cheat-sheet HelpDialog as a ContentDialog.
* Ctrl+M — drop a recording marker (invokes
MainViewModel.DropRecordingMarkerCommand, which fans out to every
active recorder via IIsoController.AddRecordingMarker).
* Ctrl+Shift+S — panic stop (invokes StopAllIsosCommand).
* Ctrl+R — refresh NDI discovery.
* 1-9 + NumPad 1-9 — toggle ISO for the Nth visible participant
(invokes ToggleByIndexCommand with the digit as the parameter).
* Esc — dismiss the settings drawer when open.
Mirrors the WPF host's <Window.InputBindings> verbatim so the
operator's muscle memory transfers across hosts.
Wire-up note: WinUI 3 KeyboardAccelerator uses
TypedEventHandler<KeyboardAccelerator, KeyboardAcceleratorInvokedEvent
Args>, not System.EventHandler<T> like XAML islands suggest in some
docs. The Bind local fn takes the correct type explicitly so the
compiler doesn't trip on the conversion.
Verified: dotnet build clean, app launches and accelerators register
without crashing the XAML parser.
This commit is contained in:
parent
7ac56c2661
commit
7c269f2c40
1 changed files with 114 additions and 0 deletions
|
|
@ -29,6 +29,120 @@ public sealed partial class MainWindow : Window
|
|||
|
||||
ThemeManager.Current.Themed += (_, theme) => ApplyResolvedTheme(theme);
|
||||
ApplyResolvedTheme(ThemeManager.Current.ResolveTheme());
|
||||
|
||||
WireKeyboardShortcuts();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
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<Microsoft.UI.Xaml.Input.KeyboardAccelerator,
|
||||
Microsoft.UI.Xaml.Input.KeyboardAcceleratorInvokedEventArgs> 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}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Reference in a new issue