2024-03-03 05:02:21 +00:00
|
|
|
|
using System;
|
2024-03-01 11:28:09 +00:00
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using System.Linq;
|
2023-08-14 19:51:28 +00:00
|
|
|
|
|
|
|
|
|
namespace MSFSPopoutPanelManager.Orchestration
|
|
|
|
|
{
|
2024-02-28 02:44:21 +00:00
|
|
|
|
public class KeyboardOrchestrator : BaseOrchestrator
|
2023-08-14 19:51:28 +00:00
|
|
|
|
{
|
2024-03-01 11:28:09 +00:00
|
|
|
|
private GlobalKeyboardHook _globalKeyboardHook;
|
2023-08-14 19:51:28 +00:00
|
|
|
|
|
2024-03-03 05:02:21 +00:00
|
|
|
|
private readonly List<KeyboardHookClientType> _keyboardHookClients = new();
|
|
|
|
|
private List<string> _keyPressCaptureList = new();
|
|
|
|
|
private bool _isCapturingKeyPress;
|
|
|
|
|
private KeyboardHookClientType _clientType;
|
|
|
|
|
private Guid? _panelId;
|
|
|
|
|
|
|
|
|
|
public event EventHandler<DetectKeystrokeEventArg> OnKeystrokeDetected;
|
|
|
|
|
|
2024-03-01 11:28:09 +00:00
|
|
|
|
public KeyboardOrchestrator(SharedStorage sharedStorage) : base(sharedStorage)
|
2023-08-14 19:51:28 +00:00
|
|
|
|
{
|
|
|
|
|
}
|
2024-03-01 11:28:09 +00:00
|
|
|
|
|
2023-08-14 19:51:28 +00:00
|
|
|
|
public void Initialize()
|
|
|
|
|
{
|
2024-02-28 02:44:21 +00:00
|
|
|
|
if (AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled)
|
2023-08-14 19:51:28 +00:00
|
|
|
|
{
|
2024-03-03 05:02:21 +00:00
|
|
|
|
StartGlobalKeyboardHook(KeyboardHookClientType.StartPopOutKeyboardShortcut);
|
2023-08-14 19:51:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-02-28 02:44:21 +00:00
|
|
|
|
AppSettingData.ApplicationSetting.OnIsUsedKeyboardShortcutChanged += (_, e) =>
|
2023-08-14 19:51:28 +00:00
|
|
|
|
{
|
|
|
|
|
if (e)
|
2024-03-03 05:02:21 +00:00
|
|
|
|
StartGlobalKeyboardHook(KeyboardHookClientType.StartPopOutKeyboardShortcut);
|
2023-08-14 19:51:28 +00:00
|
|
|
|
else
|
2024-03-03 05:02:21 +00:00
|
|
|
|
EndGlobalKeyboardHook(KeyboardHookClientType.StartPopOutKeyboardShortcut);
|
2024-02-29 06:11:56 +00:00
|
|
|
|
};
|
2023-08-14 19:51:28 +00:00
|
|
|
|
}
|
2024-03-03 05:02:21 +00:00
|
|
|
|
|
|
|
|
|
public void StartGlobalKeyboardHook(KeyboardHookClientType clientType, Guid? panelId = null)
|
2023-08-14 19:51:28 +00:00
|
|
|
|
{
|
2024-03-03 05:02:21 +00:00
|
|
|
|
if(!_keyboardHookClients.Exists(x => x == clientType))
|
|
|
|
|
_keyboardHookClients.Add(clientType);
|
2024-03-01 11:28:09 +00:00
|
|
|
|
|
2024-03-03 05:02:21 +00:00
|
|
|
|
_clientType = clientType;
|
2024-03-01 11:28:09 +00:00
|
|
|
|
_isCapturingKeyPress = true;
|
|
|
|
|
_panelId = panelId;
|
|
|
|
|
|
|
|
|
|
if (_globalKeyboardHook != null)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Debug.WriteLine("Starts Global Keyboard Hook");
|
|
|
|
|
_globalKeyboardHook ??= new GlobalKeyboardHook();
|
2024-03-04 03:10:13 +00:00
|
|
|
|
_globalKeyboardHook.OnKeyboardPressed -= HandleGlobalKeyboardHookOnKeyboardPressed;
|
|
|
|
|
_globalKeyboardHook.OnKeyboardPressed += HandleGlobalKeyboardHookOnKeyboardPressed;
|
2024-03-01 11:28:09 +00:00
|
|
|
|
}
|
|
|
|
|
|
2024-03-03 05:02:21 +00:00
|
|
|
|
public void EndGlobalKeyboardHook(KeyboardHookClientType clientType)
|
2024-03-01 11:28:09 +00:00
|
|
|
|
{
|
2024-03-03 05:02:21 +00:00
|
|
|
|
_keyboardHookClients.Remove(clientType);
|
|
|
|
|
|
|
|
|
|
if (_globalKeyboardHook == null || _keyboardHookClients.Count > 0)
|
2024-03-01 11:28:09 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2024-03-03 05:02:21 +00:00
|
|
|
|
EndGlobalKeyboardHookForced();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void EndGlobalKeyboardHookForced()
|
|
|
|
|
{
|
|
|
|
|
Debug.WriteLine("Ends Global Keyboard Hook (Forced)");
|
2024-03-01 11:28:09 +00:00
|
|
|
|
_keyPressCaptureList = new List<string>();
|
2024-03-04 03:10:13 +00:00
|
|
|
|
_globalKeyboardHook.OnKeyboardPressed -= HandleGlobalKeyboardHookOnKeyboardPressed;
|
2024-03-01 11:28:09 +00:00
|
|
|
|
_globalKeyboardHook?.Dispose();
|
|
|
|
|
_globalKeyboardHook = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void HandleGlobalKeyboardHookOnKeyboardPressed(object sender, GlobalKeyboardHookEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
switch (e.KeyboardState)
|
2024-02-29 06:11:56 +00:00
|
|
|
|
{
|
2024-03-01 11:28:09 +00:00
|
|
|
|
case GlobalKeyboardHook.KeyboardState.KeyDown or GlobalKeyboardHook.KeyboardState.SysKeyDown:
|
|
|
|
|
_isCapturingKeyPress = true;
|
|
|
|
|
_keyPressCaptureList.Add(e.KeyboardData.Key.ToString());
|
|
|
|
|
break;
|
|
|
|
|
case GlobalKeyboardHook.KeyboardState.KeyUp or GlobalKeyboardHook.KeyboardState.SysKeyUp when _isCapturingKeyPress:
|
2024-02-29 06:11:56 +00:00
|
|
|
|
{
|
2024-03-01 11:28:09 +00:00
|
|
|
|
_isCapturingKeyPress = false;
|
|
|
|
|
|
|
|
|
|
var keyBinding = string.Join("|", _keyPressCaptureList.DistinctBy(x => x).OrderBy(x => x).ToArray().Select(x => x));
|
|
|
|
|
|
2024-03-03 05:02:21 +00:00
|
|
|
|
if(CheckForRegisteredKeystrokeEvent(keyBinding))
|
|
|
|
|
OnKeystrokeDetected?.Invoke(this, new DetectKeystrokeEventArg {PanelId = _panelId, KeyBinding = keyBinding});
|
|
|
|
|
|
|
|
|
|
_clientType = KeyboardHookClientType.Unknown;
|
2024-03-01 11:28:09 +00:00
|
|
|
|
_panelId = null;
|
|
|
|
|
_keyPressCaptureList.Clear();
|
|
|
|
|
break;
|
2024-02-29 06:11:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2023-08-14 19:51:28 +00:00
|
|
|
|
}
|
2024-03-03 05:02:21 +00:00
|
|
|
|
|
|
|
|
|
private bool CheckForRegisteredKeystrokeEvent(string keyBinding)
|
|
|
|
|
{
|
|
|
|
|
if (_clientType is KeyboardHookClientType.FloatingPanelDetection or KeyboardHookClientType.PreferenceConfigurationDetection)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (!FlightSimData.IsFlightStarted)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Check if keystrokes are registered keyboard events
|
|
|
|
|
bool isRegistered = AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled;
|
|
|
|
|
|
|
|
|
|
if (ProfileData.ActiveProfile != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var panelConfig in ProfileData.ActiveProfile.PanelConfigs)
|
|
|
|
|
{
|
|
|
|
|
if (panelConfig.FloatingPanel.IsEnabled &&
|
|
|
|
|
panelConfig.PanelHandle != IntPtr.MaxValue &&
|
|
|
|
|
panelConfig.PanelHandle != IntPtr.Zero &&
|
|
|
|
|
panelConfig.FloatingPanel.KeyboardBinding == keyBinding)
|
|
|
|
|
isRegistered = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return isRegistered;
|
|
|
|
|
}
|
2023-08-14 19:51:28 +00:00
|
|
|
|
}
|
2024-03-01 11:28:09 +00:00
|
|
|
|
|
|
|
|
|
public class DetectKeystrokeEventArg : EventArgs
|
|
|
|
|
{
|
|
|
|
|
public Guid? PanelId { get; set; }
|
|
|
|
|
|
|
|
|
|
public string KeyBinding { get; set; }
|
|
|
|
|
}
|
2024-03-03 05:02:21 +00:00
|
|
|
|
|
|
|
|
|
public enum KeyboardHookClientType
|
|
|
|
|
{
|
|
|
|
|
Unknown,
|
|
|
|
|
PreferenceConfigurationDetection,
|
|
|
|
|
StartPopOutKeyboardShortcut,
|
|
|
|
|
FloatingPanelDetection,
|
2024-03-12 13:14:17 +00:00
|
|
|
|
FloatingPanel
|
2024-03-03 05:02:21 +00:00
|
|
|
|
}
|
2023-08-14 19:51:28 +00:00
|
|
|
|
}
|