diff --git a/Business/KeyboardInput.cs b/Business/KeyboardInput.cs index 81cc18d..5ad179d 100644 --- a/Business/KeyboardInput.cs +++ b/Business/KeyboardInput.cs @@ -74,38 +74,51 @@ namespace SystemTrayMenu.Handler iMenuKey = 0; } - internal void CmdKeyProcessed(object sender, Key keys) + internal void CmdKeyProcessed(Menu sender, Key key, ModifierKeys modifiers) { sender ??= menus[iMenuKey]; - switch (keys) + switch (key) { case Key.Enter: - SelectByKey(keys); - menus[iMenuKey]?.FocusTextBox(); + if (modifiers == ModifierKeys.None) + { + SelectByKey(key, modifiers); + menus[iMenuKey]?.FocusTextBox(); + } + break; case Key.Left: - SelectByKey(keys); - break; case Key.Right: - SelectByKey(keys); - break; case Key.Home: case Key.End: case Key.Up: case Key.Down: case Key.Escape: -#if TODO // WPF Key Modifier! - case Key.Alt | Key.F4: - SelectByKey(keys); + if (modifiers == ModifierKeys.None) + { + SelectByKey(key, modifiers); + } + break; - case Key.Control | Key.F: - menus[iMenuKey]?.FocusTextBox(); + case Key.F4: + if (modifiers == ModifierKeys.Alt) + { + SelectByKey(key, modifiers); + } + + break; + case Key.F: + if (modifiers == ModifierKeys.Control) + { + menus[iMenuKey]?.FocusTextBox(); + } + break; case Key.Tab: + if (modifiers == ModifierKeys.None) { - Menu currentMenu = (Menu)sender; - int indexOfTheCurrentMenu = GetMenuIndex(currentMenu); + int indexOfTheCurrentMenu = GetMenuIndex(sender); int indexMax = menus.Where(m => m != null).Count() - 1; int indexNew = 0; if (indexOfTheCurrentMenu > 0) @@ -119,12 +132,9 @@ namespace SystemTrayMenu.Handler menus[indexNew]?.FocusTextBox(); } - - break; - case Key.Tab | Key.LeftShift: + else if (modifiers == ModifierKeys.Shift) { - Menu currentMenu = (Menu)sender; - int indexOfTheCurrentMenu = GetMenuIndex(currentMenu); + int indexOfTheCurrentMenu = GetMenuIndex(sender); int indexMax = menus.Where(m => m != null).Count() - 1; int indexNew = 0; if (indexOfTheCurrentMenu < indexMax) @@ -140,8 +150,8 @@ namespace SystemTrayMenu.Handler } break; -#endif case Key.Apps: + if (modifiers == ModifierKeys.None) { ListView dgv = menus[iMenuKey]?.GetDataGridView(); @@ -261,7 +271,7 @@ namespace SystemTrayMenu.Handler return isStillSelected; } - private void SelectByKey(Key keys, string keyInput = "", bool keepSelection = false) + private void SelectByKey(Key key, ModifierKeys modifiers, string keyInput = "", bool keepSelection = false) { int iRowBefore = iRowKey; int iMenuBefore = iMenuKey; @@ -293,10 +303,11 @@ namespace SystemTrayMenu.Handler } bool toClear = false; - switch (keys) + bool handled = false; + switch (key) { case Key.Enter: - if (iRowKey > -1 && dgv.Items.Count > iRowKey) + if ((modifiers == ModifierKeys.None) && (iRowKey > -1 && dgv.Items.Count > iRowKey)) { RowData trigger = ((Menu.ListViewItemData)dgv.Items[iRowKey]).data; if (trigger.IsMenuOpen || !trigger.ContainsMenu) @@ -327,110 +338,136 @@ namespace SystemTrayMenu.Handler SelectRow(dgv, iRowKey); EnterPressed.Invoke(dgv, iRowKey); } + + handled = true; } break; case Key.Up: - if (SelectMatchedReverse(dgv, iRowKey) || - SelectMatchedReverse(dgv, dgv.Items.Count - 1)) + if ((modifiers == ModifierKeys.None) && + (SelectMatchedReverse(dgv, iRowKey) || + SelectMatchedReverse(dgv, dgv.Items.Count - 1))) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; + handled = true; } break; case Key.Down: - if (SelectMatched(dgv, iRowKey) || - SelectMatched(dgv, 0)) + if ((modifiers == ModifierKeys.None) && + (SelectMatched(dgv, iRowKey) || + SelectMatched(dgv, 0))) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; + handled = true; } break; case Key.Home: - if (SelectMatched(dgv, 0)) + if ((modifiers == ModifierKeys.None) && SelectMatched(dgv, 0)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; + handled = true; } break; case Key.End: - if (SelectMatchedReverse(dgv, dgv.Items.Count - 1)) + if ((modifiers == ModifierKeys.None) && SelectMatchedReverse(dgv, dgv.Items.Count - 1)) { RowDeselected(iRowBefore, dgvBefore); SelectRow(dgv, iRowKey); toClear = true; + handled = true; } break; case Key.Left: - bool nextMenuLocationIsLeft = menus[iMenuKey + 1] != null && menus[iMenuKey + 1].Location.X < menus[iMenuKey].Location.X; - bool previousMenuLocationIsRight = iMenuKey > 0 && menus[iMenuKey]?.Location.X < menus[iMenuKey - 1]?.Location.X; - if (nextMenuLocationIsLeft || previousMenuLocationIsRight) + if (modifiers == ModifierKeys.None) { - SelectNextMenu(iRowBefore, ref dgv, dgvBefore, menuFromSelected, isStillSelected, ref toClear); - } - else if (iMenuKey > 0) - { - SelectPreviousMenu(iRowBefore, ref menu, ref dgv, dgvBefore, ref toClear); + bool nextMenuLocationIsLeft = menus[iMenuKey + 1] != null && menus[iMenuKey + 1].Location.X < menus[iMenuKey].Location.X; + bool previousMenuLocationIsRight = iMenuKey > 0 && menus[iMenuKey]?.Location.X < menus[iMenuKey - 1]?.Location.X; + if (nextMenuLocationIsLeft || previousMenuLocationIsRight) + { + SelectNextMenu(iRowBefore, ref dgv, dgvBefore, menuFromSelected, isStillSelected, ref toClear); + } + else if (iMenuKey > 0) + { + SelectPreviousMenu(iRowBefore, ref menu, ref dgv, dgvBefore, ref toClear); + } + + handled = true; } break; case Key.Right: - bool nextMenuLocationIsRight = menus[iMenuKey + 1]?.Location.X > menus[iMenuKey]?.Location.X; - bool previousMenuLocationIsLeft = iMenuKey > 0 && menus[iMenuKey]?.Location.X > menus[iMenuKey - 1]?.Location.X; - if (nextMenuLocationIsRight || previousMenuLocationIsLeft) + if (modifiers == ModifierKeys.None) { - SelectNextMenu(iRowBefore, ref dgv, dgvBefore, menuFromSelected, isStillSelected, ref toClear); - } - else if (iMenuKey > 0) - { - SelectPreviousMenu(iRowBefore, ref menu, ref dgv, dgvBefore, ref toClear); + bool nextMenuLocationIsRight = menus[iMenuKey + 1]?.Location.X > menus[iMenuKey]?.Location.X; + bool previousMenuLocationIsLeft = iMenuKey > 0 && menus[iMenuKey]?.Location.X > menus[iMenuKey - 1]?.Location.X; + if (nextMenuLocationIsRight || previousMenuLocationIsLeft) + { + SelectNextMenu(iRowBefore, ref dgv, dgvBefore, menuFromSelected, isStillSelected, ref toClear); + } + else if (iMenuKey > 0) + { + SelectPreviousMenu(iRowBefore, ref menu, ref dgv, dgvBefore, ref toClear); + } + + handled = true; } break; case Key.Escape: -#if TODO // WPF Key Modifier! - case Key.Alt | Key.F4: -#endif - RowDeselected(iRowBefore, dgvBefore); - iMenuKey = 0; - iRowKey = -1; - toClear = true; - ClosePressed?.Invoke(); + case Key.F4: + if ((key == Key.Escape && modifiers == ModifierKeys.None) || + (key == Key.F4 && modifiers == ModifierKeys.Alt)) + { + RowDeselected(iRowBefore, dgvBefore); + iMenuKey = 0; + iRowKey = -1; + toClear = true; + ClosePressed?.Invoke(); + + handled = true; + } + break; default: - if (!string.IsNullOrEmpty(keyInput)) + break; + } + + if (!handled) + { + if (!string.IsNullOrEmpty(keyInput)) + { + if (SelectMatched(dgv, iRowKey, keyInput) || + SelectMatched(dgv, 0, keyInput)) { + RowDeselected(iRowBefore, null); + SelectRow(dgv, iRowKey); + toClear = true; + } + else if (isStillSelected) + { + iRowKey = iRowBefore - 1; if (SelectMatched(dgv, iRowKey, keyInput) || SelectMatched(dgv, 0, keyInput)) { RowDeselected(iRowBefore, null); SelectRow(dgv, iRowKey); - toClear = true; } - else if (isStillSelected) + else { - iRowKey = iRowBefore - 1; - if (SelectMatched(dgv, iRowKey, keyInput) || - SelectMatched(dgv, 0, keyInput)) - { - RowDeselected(iRowBefore, null); - SelectRow(dgv, iRowKey); - } - else - { - iRowKey = iRowBefore; - } + iRowKey = iRowBefore; } } - - break; + } } if (isStillSelected && toClear) diff --git a/Business/Menus.cs b/Business/Menus.cs index 5f73c48..e5ea688 100644 --- a/Business/Menus.cs +++ b/Business/Menus.cs @@ -271,7 +271,7 @@ namespace SystemTrayMenu.Business keyboardInput.RowSelected += waitToOpenMenu.RowSelected; joystickHelper = new(); - joystickHelper.KeyPressed += (key) => menus[0].Dispatcher.Invoke(keyboardInput.CmdKeyProcessed, new object[] { null, key }); + joystickHelper.KeyPressed += (key, modifiers) => menus[0].Dispatcher.Invoke(keyboardInput.CmdKeyProcessed, new object[] { null, key, modifiers }); timerShowProcessStartedAsLoadingIcon.Interval = TimeSpan.FromMilliseconds(Properties.Settings.Default.TimeUntilClosesAfterEnterPressed); timerStillActiveCheck.Interval = TimeSpan.FromMilliseconds(Properties.Settings.Default.TimeUntilClosesAfterEnterPressed + 20); @@ -618,7 +618,9 @@ namespace SystemTrayMenu.Business menu.MouseWheel += AdjustMenusSizeAndLocation; menu.MouseLeave += waitLeave.Start; menu.MouseEnter += waitLeave.Stop; +#endif menu.CmdKeyProcessed += keyboardInput.CmdKeyProcessed; +#if TODO menu.KeyPressCheck += Menu_KeyPressCheck; menu.SearchTextChanging += Menu_SearchTextChanging; menu.SearchTextChanged += Menu_SearchTextChanged; diff --git a/Helpers/JoystickHelper.cs b/Helpers/JoystickHelper.cs index 3f2de2f..649deea 100644 --- a/Helpers/JoystickHelper.cs +++ b/Helpers/JoystickHelper.cs @@ -9,6 +9,7 @@ namespace SystemTrayMenu.Helpers using System.Diagnostics.Metrics; using System.Reflection.Metadata; using System.Threading; + using System.Windows.Input; using SharpDX.DirectInput; using Key = System.Windows.Input.Key; @@ -37,7 +38,7 @@ namespace SystemTrayMenu.Helpers Dispose(false); } - public event Action KeyPressed; + public event Action KeyPressed; public void Enable() { @@ -144,7 +145,7 @@ namespace SystemTrayMenu.Helpers Key key = ReadKeyFromState(state); if (key != Key.None) { - KeyPressed?.Invoke(key); + KeyPressed?.Invoke(key, ModifierKeys.None); if (state.Offset == JoystickOffset.PointOfViewControllers0) { pressingKeyCounter = 0; @@ -158,7 +159,7 @@ namespace SystemTrayMenu.Helpers pressingKeyCounter += 1; if (pressingKeyCounter > 1) { - KeyPressed?.Invoke(pressingKey); + KeyPressed?.Invoke(pressingKey, ModifierKeys.None); } } } diff --git a/UserInterface/Menu.xaml b/UserInterface/Menu.xaml index cdc7d9c..17afcec 100644 --- a/UserInterface/Menu.xaml +++ b/UserInterface/Menu.xaml @@ -9,7 +9,8 @@ xmlns:utils="clr-namespace:SystemTrayMenu.Utilities" xmlns:local="clr-namespace:SystemTrayMenu.UserInterface" x:Class="SystemTrayMenu.UserInterface.Menu" - mc:Ignorable="d" ResizeMode="NoResize" WindowStyle="None" Topmost="True" Background="Transparent" AllowsTransparency="True" SizeToContent="WidthAndHeight" ShowInTaskbar="False" SnapsToDevicePixels="True" UseLayoutRounding="True"> + mc:Ignorable="d" ResizeMode="NoResize" WindowStyle="None" Topmost="True" Background="Transparent" AllowsTransparency="True" SizeToContent="WidthAndHeight" ShowInTaskbar="False" SnapsToDevicePixels="True" UseLayoutRounding="True" + PreviewKeyDown="HandlePreviewKeyDown"> @@ -42,7 +43,7 @@ --> - + diff --git a/UserInterface/Menu.xaml.cs b/UserInterface/Menu.xaml.cs index 39160c4..ba7d8ea 100644 --- a/UserInterface/Menu.xaml.cs +++ b/UserInterface/Menu.xaml.cs @@ -20,6 +20,7 @@ namespace SystemTrayMenu.UserInterface using SystemTrayMenu.DllImports; using SystemTrayMenu.Helper; using SystemTrayMenu.Utilities; + using KeyEventArgs = System.Windows.Input.KeyEventArgs; /// /// Logic of Menu window. @@ -231,9 +232,9 @@ namespace SystemTrayMenu.UserInterface #endif internal event Action? UserClickedOpenFolder; -#if TODO - internal event EventHandler CmdKeyProcessed; + internal event Action CmdKeyProcessed; +#if TODO internal event EventHandler KeyPressCheck; @@ -762,11 +763,32 @@ namespace SystemTrayMenu.UserInterface labelItems.Content = $"{filesAndFoldersCount} {Translator.GetText(elements)}"; } -#if TODO - protected override bool ProcessCmdKey(ref Message msg, Key keys) + private void HandlePreviewKeyDown(object sender, KeyEventArgs e) { - switch (keys) + ModifierKeys modifiers = Keyboard.Modifiers; + switch (e.Key) { + case Key.F4: + if (modifiers != ModifierKeys.Alt) + { + return; + } + + break; + case Key.F: + if (modifiers != ModifierKeys.Control) + { + return; + } + + break; + case Key.Tab: + if ((modifiers != ModifierKeys.Shift) && (modifiers != ModifierKeys.None)) + { + return; + } + + break; case Key.Enter: case Key.Home: case Key.End: @@ -775,20 +797,21 @@ namespace SystemTrayMenu.UserInterface case Key.Left: case Key.Right: case Key.Escape: - case Key.Alt | Key.F4: - case Key.Control | Key.F: - case Key.Tab: - case Key.Tab | Key.Shift: case Key.Apps: - CmdKeyProcessed.Invoke(this, keys); - return true; - default: + if (modifiers != ModifierKeys.None) + { + return; + } + break; + default: + return; } - return base.ProcessCmdKey(ref msg, keys); + CmdKeyProcessed?.Invoke(this, e.Key, modifiers); + e.Handled = true; } -#endif + private void AdjustDataGridViewHeight(Menu menuPredecessor, double screenHeightMax) { double factor = Properties.Settings.Default.RowHeighteInPercentage / 100f;