2020-07-07 07:15:45 +12:00
|
|
|
|
// <copyright file="KeyboardInput.cs" company="PlaceholderCompany">
|
|
|
|
|
// Copyright (c) PlaceholderCompany. All rights reserved.
|
|
|
|
|
// </copyright>
|
2020-06-21 03:38:21 +12:00
|
|
|
|
|
|
|
|
|
namespace SystemTrayMenu.Handler
|
|
|
|
|
{
|
2020-07-07 07:15:45 +12:00
|
|
|
|
using System;
|
2023-05-03 10:34:30 +12:00
|
|
|
|
using System.Windows.Controls;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
using System.Windows.Input;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
using SystemTrayMenu.DataClasses;
|
2023-04-17 00:17:33 +12:00
|
|
|
|
using SystemTrayMenu.Helpers;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
using SystemTrayMenu.Utilities;
|
2023-04-25 10:24:48 +12:00
|
|
|
|
using static SystemTrayMenu.UserInterface.Menu;
|
2021-06-27 21:35:07 +12:00
|
|
|
|
using Menu = SystemTrayMenu.UserInterface.Menu;
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
internal class KeyboardInput : IDisposable
|
|
|
|
|
{
|
2021-11-17 12:13:46 +13:00
|
|
|
|
private readonly KeyboardHook hook = new();
|
2020-06-21 03:38:21 +12:00
|
|
|
|
|
2023-05-04 09:18:03 +12:00
|
|
|
|
private Menu? focussedMenu;
|
2023-05-04 10:34:23 +12:00
|
|
|
|
private ListViewItemData? focussedRow;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
|
2022-12-04 10:41:03 +13:00
|
|
|
|
internal event Action? HotKeyPressed;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
|
2022-12-04 10:41:03 +13:00
|
|
|
|
internal event Action? ClosePressed;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
|
2023-05-05 10:08:39 +12:00
|
|
|
|
internal event Action<Menu, ListViewItemData>? RowSelected;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
|
2023-05-10 10:55:18 +12:00
|
|
|
|
internal event Action<Menu>? RowDeselected;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
|
2023-05-05 10:08:39 +12:00
|
|
|
|
internal event Action<Menu, ListViewItemData>? EnterPressed;
|
2020-07-07 09:37:55 +12:00
|
|
|
|
|
2023-05-10 10:55:18 +12:00
|
|
|
|
internal bool IsSelectedByKey { get; set; }
|
2020-07-08 03:05:19 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
public void Dispose()
|
|
|
|
|
{
|
|
|
|
|
hook.Dispose();
|
2020-05-31 05:59:33 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 10:14:23 +12:00
|
|
|
|
internal bool RegisterHotKey(string hotKey)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-08 10:14:23 +12:00
|
|
|
|
if (!string.IsNullOrEmpty(hotKey))
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2020-07-04 08:02:16 +12:00
|
|
|
|
hook.RegisterHotKey();
|
2021-10-27 09:09:40 +13:00
|
|
|
|
hook.KeyPressed += (sender, e) => HotKeyPressed?.Invoke();
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
catch (InvalidOperationException ex)
|
|
|
|
|
{
|
2023-05-08 10:14:23 +12:00
|
|
|
|
Log.Warn($"Hotkey cannot be set: '{hotKey}'", ex);
|
|
|
|
|
return false;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-08 10:14:23 +12:00
|
|
|
|
|
|
|
|
|
return true;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
internal void ResetSelectedByKey()
|
|
|
|
|
{
|
2023-05-04 09:18:03 +12:00
|
|
|
|
focussedMenu = null;
|
2023-05-04 10:34:23 +12:00
|
|
|
|
focussedRow = null;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-03 08:04:32 +12:00
|
|
|
|
internal void CmdKeyProcessed(Menu sender, Key key, ModifierKeys modifiers)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2022-11-29 08:27:52 +13:00
|
|
|
|
switch (key)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Enter:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
if (modifiers == ModifierKeys.None)
|
|
|
|
|
{
|
|
|
|
|
SelectByKey(key, modifiers);
|
2023-05-04 09:18:03 +12:00
|
|
|
|
focussedMenu?.FocusTextBox();
|
2022-11-29 08:27:52 +13:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-11 11:39:52 +13:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Left:
|
|
|
|
|
case Key.Right:
|
|
|
|
|
case Key.Home:
|
|
|
|
|
case Key.End:
|
|
|
|
|
case Key.Up:
|
|
|
|
|
case Key.Down:
|
|
|
|
|
case Key.Escape:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
if (modifiers == ModifierKeys.None)
|
|
|
|
|
{
|
|
|
|
|
SelectByKey(key, modifiers);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
2022-11-29 08:27:52 +13:00
|
|
|
|
case Key.F4:
|
|
|
|
|
if (modifiers == ModifierKeys.Alt)
|
|
|
|
|
{
|
|
|
|
|
SelectByKey(key, modifiers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case Key.F:
|
|
|
|
|
if (modifiers == ModifierKeys.Control)
|
|
|
|
|
{
|
2023-05-04 09:18:03 +12:00
|
|
|
|
focussedMenu?.FocusTextBox();
|
2022-11-29 08:27:52 +13:00
|
|
|
|
}
|
|
|
|
|
|
2020-05-31 05:59:33 +12:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Tab:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
if (modifiers == ModifierKeys.None)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-08 10:14:23 +12:00
|
|
|
|
// Walk to previous text box and warp around when main menu reached
|
|
|
|
|
Menu? menu = sender.ParentMenu;
|
|
|
|
|
if (menu == null)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-08 10:14:23 +12:00
|
|
|
|
menu = sender;
|
|
|
|
|
while (menu.SubMenu != null)
|
|
|
|
|
{
|
|
|
|
|
menu = menu.SubMenu;
|
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-08 10:14:23 +12:00
|
|
|
|
menu.FocusTextBox();
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
2022-11-29 08:27:52 +13:00
|
|
|
|
else if (modifiers == ModifierKeys.Shift)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-08 10:14:23 +12:00
|
|
|
|
// Walk to next text box and warp around back to main menu on last sub menu
|
|
|
|
|
Menu? menu = sender.SubMenu ?? sender.MainMenu;
|
|
|
|
|
menu.FocusTextBox();
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Apps:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
if (modifiers == ModifierKeys.None)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-04 09:18:03 +12:00
|
|
|
|
ListView? dgv = focussedMenu?.GetDataGridView();
|
2022-12-04 10:41:03 +13:00
|
|
|
|
if (dgv != null)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-04 10:34:23 +12:00
|
|
|
|
if (focussedRow != null)
|
2022-12-04 10:41:03 +13:00
|
|
|
|
{
|
2022-11-30 10:48:45 +13:00
|
|
|
|
#if TODO // WPF: Better way to open context menu (as it looks like this is the code's intention)
|
2022-12-04 10:41:03 +13:00
|
|
|
|
Point point = dgv.GetCellDisplayRectangle(2, iRowKey, false).Location;
|
|
|
|
|
RowData trigger = (RowData)dgv.Rows[iRowKey].Cells[2].Value;
|
|
|
|
|
MouseEventArgs mouseEventArgs = new(MouseButtons.Right, 1, point.X, point.Y, 0);
|
|
|
|
|
trigger.MouseDown(dgv, mouseEventArgs);
|
2022-10-23 11:02:31 +13:00
|
|
|
|
#endif
|
2022-12-04 10:41:03 +13:00
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-06 08:19:00 +12:00
|
|
|
|
internal void SearchTextChanged(Menu menu, bool isSearchStringEmpty)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
DeselectFoccussedRow();
|
2020-06-21 03:38:21 +12:00
|
|
|
|
|
2023-05-06 08:19:00 +12:00
|
|
|
|
if (!isSearchStringEmpty)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-05 10:08:39 +12:00
|
|
|
|
ListView dgv = menu.GetDataGridView();
|
|
|
|
|
if (dgv.Items.Count > 0)
|
2022-12-04 10:41:03 +13:00
|
|
|
|
{
|
2023-05-06 08:19:00 +12:00
|
|
|
|
MouseSelect(menu, (ListViewItemData)dgv.Items[0]);
|
2022-12-04 10:41:03 +13:00
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-10 10:55:18 +12:00
|
|
|
|
internal void DeselectFoccussedRow() => focussedMenu?.GetDataGridView().SelectedItems.Remove(focussedRow);
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2023-05-06 08:19:00 +12:00
|
|
|
|
internal void MouseSelect(Menu menu, ListViewItemData itemData)
|
2020-07-08 03:05:19 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
IsSelectedByKey = false;
|
2021-11-11 11:39:52 +13:00
|
|
|
|
|
2023-05-10 10:55:18 +12:00
|
|
|
|
DeselectFoccussedRow();
|
2023-04-25 10:24:48 +12:00
|
|
|
|
|
2023-05-06 08:19:00 +12:00
|
|
|
|
focussedMenu = menu;
|
|
|
|
|
Select(menu.GetDataGridView(), itemData);
|
2020-07-08 03:05:19 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-05 10:08:39 +12:00
|
|
|
|
private void SelectByKey(Key key, ModifierKeys modifiers)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-05 10:08:39 +12:00
|
|
|
|
Menu? menuFromSelected;
|
|
|
|
|
Menu? menuBefore;
|
2023-05-04 10:34:23 +12:00
|
|
|
|
ListViewItemData? rowBefore = focussedRow;
|
2023-05-06 06:01:49 +12:00
|
|
|
|
bool doClearOldSelection = false;
|
2023-05-09 10:19:29 +12:00
|
|
|
|
bool wasSelected = focussedRow?.IsSelected ?? false;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
|
2023-05-06 06:01:49 +12:00
|
|
|
|
if (wasSelected)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-06 04:52:05 +12:00
|
|
|
|
menuFromSelected = focussedRow?.data.SubMenu;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
menuBefore = focussedMenu;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ResetSelectedByKey();
|
2023-05-06 04:52:05 +12:00
|
|
|
|
menuFromSelected = null;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
menuBefore = null;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-29 08:27:52 +13:00
|
|
|
|
switch (key)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Enter:
|
2023-05-05 10:08:39 +12:00
|
|
|
|
if ((modifiers == ModifierKeys.None) && rowBefore != null && menuBefore != null)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
// When not sub menu already open, open the sub menu,
|
|
|
|
|
// but when already opened, open the actual folder instead.
|
|
|
|
|
// In case it is a single file, open it right away
|
2023-05-05 10:08:39 +12:00
|
|
|
|
RowData trigger = rowBefore.data;
|
2023-05-09 10:19:29 +12:00
|
|
|
|
if (trigger.SubMenu != null || !trigger.IsPointingToFolder)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-09 10:19:29 +12:00
|
|
|
|
rowBefore.OpenItem(out bool doCloseAfterOpen);
|
2023-04-25 08:38:36 +12:00
|
|
|
|
if (doCloseAfterOpen)
|
2021-05-02 23:12:18 +12:00
|
|
|
|
{
|
|
|
|
|
ClosePressed?.Invoke();
|
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-05 10:08:39 +12:00
|
|
|
|
EnterPressed?.Invoke(menuBefore, rowBefore);
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Up:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
if ((modifiers == ModifierKeys.None) &&
|
2023-05-06 06:01:49 +12:00
|
|
|
|
menuBefore != null &&
|
|
|
|
|
(TrySelectPrevious(menuBefore, menuBefore.GetDataGridView().Items.IndexOf(rowBefore)) ||
|
|
|
|
|
TrySelectPrevious(menuBefore, menuBefore.GetDataGridView().Items.Count - 1)))
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Down:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
if ((modifiers == ModifierKeys.None) &&
|
2023-05-06 06:01:49 +12:00
|
|
|
|
menuBefore != null &&
|
|
|
|
|
(TrySelectNext(menuBefore, menuBefore.GetDataGridView().Items.IndexOf(rowBefore)) ||
|
|
|
|
|
TrySelectNext(menuBefore, 0)))
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2022-02-05 02:37:37 +13:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Home:
|
2023-05-05 10:08:39 +12:00
|
|
|
|
if ((modifiers == ModifierKeys.None) &&
|
2023-05-06 06:01:49 +12:00
|
|
|
|
menuBefore != null &&
|
|
|
|
|
TrySelectNext(menuBefore, 0))
|
2022-02-05 02:37:37 +13:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2022-02-05 02:37:37 +13:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.End:
|
2023-04-17 09:27:27 +12:00
|
|
|
|
if ((modifiers == ModifierKeys.None) &&
|
2023-05-06 06:01:49 +12:00
|
|
|
|
menuBefore != null &&
|
|
|
|
|
TrySelectPrevious(menuBefore, menuBefore.GetDataGridView().Items.Count - 1))
|
2022-02-05 02:37:37 +13:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2022-02-05 02:37:37 +13:00
|
|
|
|
}
|
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Left:
|
2023-05-05 10:08:39 +12:00
|
|
|
|
case Key.Right:
|
2023-04-17 09:27:27 +12:00
|
|
|
|
if (modifiers == ModifierKeys.None &&
|
2023-05-06 06:01:49 +12:00
|
|
|
|
menuBefore != null &&
|
2023-05-05 10:08:39 +12:00
|
|
|
|
focussedMenu != null)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-05 10:08:39 +12:00
|
|
|
|
// True, when next is left and key is left = true OR next is right (=not left) and key is right (not left)
|
|
|
|
|
bool nextMenuInKeyDirection = (focussedMenu?.SubMenu?.Location.X < focussedMenu?.Location.X) == (key == Key.Left);
|
2022-11-29 08:27:52 +13:00
|
|
|
|
|
2023-05-05 10:08:39 +12:00
|
|
|
|
// TODO: Check what this actually does as it is only true for wrap arounds on screen corners
|
|
|
|
|
// but why not simply just select prev menu instead?
|
|
|
|
|
// True, when prev is right (=not left) but key is left = true OR prev is left but key is right (not left)
|
|
|
|
|
bool prevMenuAgainstKeyDirection = (focussedMenu?.Location.X < focussedMenu?.ParentMenu?.Location.X) == (key == Key.Left);
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2023-05-05 10:08:39 +12:00
|
|
|
|
if (nextMenuInKeyDirection || prevMenuAgainstKeyDirection)
|
2022-11-29 08:27:52 +13:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
// Next is in key direction or prev is opposite of key direction ==> Select sub/next menu
|
|
|
|
|
if (wasSelected)
|
2023-05-05 10:08:39 +12:00
|
|
|
|
{
|
2023-05-06 04:52:05 +12:00
|
|
|
|
if (menuFromSelected != null &&
|
|
|
|
|
menuFromSelected == focussedMenu?.SubMenu)
|
2023-05-05 10:08:39 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
focussedMenu = menuFromSelected;
|
|
|
|
|
focussedRow = null;
|
|
|
|
|
if (TrySelectNext(menuFromSelected, 0))
|
2023-05-05 10:08:39 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
while (focussedMenu?.SubMenu != null)
|
|
|
|
|
{
|
|
|
|
|
focussedMenu = focussedMenu.SubMenu;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
focussedRow = null;
|
|
|
|
|
Menu? lastMenu = focussedMenu;
|
2023-05-06 06:01:49 +12:00
|
|
|
|
if (lastMenu != null && TrySelectNext(lastMenu, 0))
|
2023-05-05 10:08:39 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-11-29 08:27:52 +13:00
|
|
|
|
}
|
2023-05-05 10:08:39 +12:00
|
|
|
|
else if (focussedMenu?.ParentMenu != null)
|
2022-11-29 08:27:52 +13:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
// Next is in opposite key direction and prev is in key direction ==> Select parent/prev menu
|
2023-05-09 10:19:29 +12:00
|
|
|
|
int index = focussedMenu.RowDataParent?.RowIndex ?? -1;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
focussedMenu = focussedMenu.ParentMenu;
|
|
|
|
|
focussedRow = null;
|
2023-05-09 10:19:29 +12:00
|
|
|
|
if (TrySelectNext(focussedMenu, index) ||
|
2023-05-06 06:01:49 +12:00
|
|
|
|
TrySelectNext(focussedMenu, 0))
|
2023-05-05 10:08:39 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
}
|
2022-11-29 08:27:52 +13:00
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
2022-10-23 11:02:31 +13:00
|
|
|
|
case Key.Escape:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
case Key.F4:
|
|
|
|
|
if ((key == Key.Escape && modifiers == ModifierKeys.None) ||
|
|
|
|
|
(key == Key.F4 && modifiers == ModifierKeys.Alt))
|
|
|
|
|
{
|
2023-05-03 10:34:30 +12:00
|
|
|
|
ResetSelectedByKey();
|
2023-05-10 10:55:18 +12:00
|
|
|
|
if (menuBefore != null)
|
|
|
|
|
{
|
|
|
|
|
RaiseRowSelectionChanged(menuBefore);
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-06 06:01:49 +12:00
|
|
|
|
doClearOldSelection = wasSelected;
|
2022-11-29 08:27:52 +13:00
|
|
|
|
ClosePressed?.Invoke();
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
break;
|
|
|
|
|
default:
|
2022-11-29 08:27:52 +13:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-06 06:01:49 +12:00
|
|
|
|
if (doClearOldSelection)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
menuBefore?.GetDataGridView().SelectedItems.Remove(rowBefore);
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-10 10:55:18 +12:00
|
|
|
|
private void RaiseRowSelectionChanged(Menu menuBefore)
|
2021-12-10 08:00:33 +13:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
RowDeselected?.Invoke(menuBefore);
|
2021-12-10 08:00:33 +13:00
|
|
|
|
|
2023-05-05 10:08:39 +12:00
|
|
|
|
if (focussedMenu != null && focussedRow != null)
|
2023-04-17 09:27:27 +12:00
|
|
|
|
{
|
2023-05-10 10:55:18 +12:00
|
|
|
|
IsSelectedByKey = true;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
RowSelected?.Invoke(focussedMenu, focussedRow);
|
2023-04-17 09:27:27 +12:00
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-06 06:01:49 +12:00
|
|
|
|
private bool TrySelectNext(Menu menu, int indexStart)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
|
|
|
|
bool found = false;
|
2023-05-05 10:08:39 +12:00
|
|
|
|
if (indexStart >= 0)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
ListView dgv = menu.GetDataGridView();
|
2023-05-04 10:34:23 +12:00
|
|
|
|
for (uint i = (uint)indexStart; i < dgv.Items.Count; i++)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
ListViewItemData itemData = (ListViewItemData)dgv.Items[(int)i];
|
|
|
|
|
if (itemData != focussedRow)
|
2023-04-17 09:27:27 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
Select(dgv, itemData);
|
2023-05-06 08:19:00 +12:00
|
|
|
|
dgv.ScrollIntoView(itemData);
|
2023-04-17 09:27:27 +12:00
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
return found;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-06 06:01:49 +12:00
|
|
|
|
private bool TrySelectPrevious(Menu menu, int indexStart)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
|
|
|
|
bool found = false;
|
2023-05-04 10:34:23 +12:00
|
|
|
|
if (indexStart > 0)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
ListView dgv = menu.GetDataGridView();
|
2023-05-05 10:08:39 +12:00
|
|
|
|
if (dgv.Items.Count <= indexStart)
|
|
|
|
|
{
|
|
|
|
|
indexStart = dgv.Items.Count - 1;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-04 10:34:23 +12:00
|
|
|
|
for (int i = indexStart; i > -1; i--)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
ListViewItemData itemData = (ListViewItemData)dgv.Items[i];
|
|
|
|
|
if (itemData != focussedRow)
|
2023-05-04 10:34:23 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
Select(dgv, itemData);
|
2023-05-06 08:19:00 +12:00
|
|
|
|
dgv.ScrollIntoView(itemData);
|
2023-05-04 10:34:23 +12:00
|
|
|
|
found = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-07 07:15:45 +12:00
|
|
|
|
|
2020-06-21 03:38:21 +12:00
|
|
|
|
return found;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-06 06:01:49 +12:00
|
|
|
|
private void Select(ListView dgv, ListViewItemData itemData)
|
2020-06-21 03:38:21 +12:00
|
|
|
|
{
|
2023-05-06 06:01:49 +12:00
|
|
|
|
focussedRow = itemData;
|
|
|
|
|
dgv.SelectedItems.Add(itemData);
|
2020-06-21 03:38:21 +12:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-05-03 10:34:30 +12:00
|
|
|
|
}
|