1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-29 09:10:09 +00:00
msfs-popout-panel-manager/Provider/PanelSelectionManager.cs

160 lines
6.5 KiB
C#
Raw Normal View History

2022-01-27 13:40:04 +00:00
using MSFSPopoutPanelManager.Model;
2021-12-14 05:40:07 +00:00
using MSFSPopoutPanelManager.Shared;
2021-09-30 02:17:20 +00:00
using System;
using System.Collections.Generic;
2022-01-27 13:40:04 +00:00
using System.Drawing;
using System.Linq;
2021-09-30 02:17:20 +00:00
2021-12-14 05:40:07 +00:00
namespace MSFSPopoutPanelManager.Provider
2021-09-30 02:17:20 +00:00
{
2021-12-14 05:40:07 +00:00
public class PanelSelectionManager
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
private UserProfileManager _userProfileManager;
2021-09-30 02:17:20 +00:00
private int _panelIndex;
2022-01-27 13:40:04 +00:00
private List<PanelSourceCoordinate> _panelCoordinates;
private IntPtr _winEventHook;
private static PInvoke.WinEventProc _winEvent; // keep this as static to prevent garbage collect or the app will crash
private Rectangle _lastWindowRectangle;
private bool _isEditingPanelCoordinates;
2021-09-30 02:17:20 +00:00
2022-01-27 13:40:04 +00:00
public event EventHandler OnPanelSelectionCompleted;
public event EventHandler<EventArgs<PanelSourceCoordinate>> OnPanelLocationAdded;
public event EventHandler OnPanelLocationRemoved;
public event EventHandler OnAllPanelLocationsRemoved;
2021-09-30 02:17:20 +00:00
2022-01-27 13:40:04 +00:00
public UserProfile UserProfile { get; set; }
2021-12-14 05:40:07 +00:00
2022-01-27 13:40:04 +00:00
public AppSetting AppSetting { get; set; }
public PanelSelectionManager(UserProfileManager userProfileManager)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
_userProfileManager = userProfileManager;
InputHookManager.OnPanelSelectionAdded += HandleOnPanelSelectionAdded;
InputHookManager.OnPanelSelectionRemoved += HandleOnPanelSelectionRemoved;
InputHookManager.OnPanelSelectionCompleted += HandleOnPanelSelectionCompleted;
2021-09-30 02:17:20 +00:00
}
public void Start()
{
2022-01-27 13:40:04 +00:00
_panelIndex = 1;
_panelCoordinates = new List<PanelSourceCoordinate>();
ShowPanelLocationOverlay(_panelCoordinates, true);
InputHookManager.SubscribeToPanelSelectionEvent = true;
}
public void ShowPanelLocationOverlay(List<PanelSourceCoordinate> panelCoordinates, bool show)
{
// close all overlays
OnAllPanelLocationsRemoved?.Invoke(this, null);
if (show && panelCoordinates.Count > 0)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
foreach (var coor in panelCoordinates)
{
var panelSourceCoordinate = new PanelSourceCoordinate() { PanelIndex = coor.PanelIndex, X = coor.X, Y = coor.Y };
OnPanelLocationAdded?.Invoke(this, new EventArgs<PanelSourceCoordinate>(panelSourceCoordinate));
}
2021-09-30 02:17:20 +00:00
}
}
2022-01-27 13:40:04 +00:00
private void HandleOnPanelSelectionAdded(object sender, System.Drawing.Point e)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
var newPanelCoordinates = new PanelSourceCoordinate() { PanelIndex = _panelIndex, X = e.X, Y = e.Y };
_panelCoordinates.Add(newPanelCoordinates);
_panelIndex++;
OnPanelLocationAdded?.Invoke(this, new EventArgs<PanelSourceCoordinate>(newPanelCoordinates));
2021-09-30 02:17:20 +00:00
}
2022-01-27 13:40:04 +00:00
private void HandleOnPanelSelectionRemoved(object sender, EventArgs e)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
if(_panelCoordinates.Count > 0)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
_panelCoordinates.RemoveAt(_panelCoordinates.Count - 1);
_panelIndex--;
OnPanelLocationRemoved?.Invoke(this, null);
2021-09-30 02:17:20 +00:00
}
2022-01-27 13:40:04 +00:00
}
2021-09-30 02:17:20 +00:00
2022-01-27 13:40:04 +00:00
private void HandleOnPanelSelectionCompleted(object sender, EventArgs e)
{
// If enable, save the current viewport into custom view by Ctrl-Alt-0
if (AppSetting.UseAutoPanning)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
var simualatorProcess = DiagnosticManager.GetSimulatorProcess();
if (simualatorProcess != null)
{
2022-04-18 03:38:33 +00:00
InputEmulationManager.SaveCustomView(simualatorProcess.Handle, AppSetting.AutoPanningKeyBinding);
2022-01-27 13:40:04 +00:00
}
2021-09-30 02:17:20 +00:00
}
2022-01-27 13:40:04 +00:00
// Assign and save panel coordinates to active profile
UserProfile.PanelSourceCoordinates.Clear();
_panelCoordinates.ForEach(c => UserProfile.PanelSourceCoordinates.Add(c));
UserProfile.PanelConfigs.Clear();
UserProfile.IsLocked = false;
_userProfileManager.WriteUserProfiles();
InputHookManager.SubscribeToPanelSelectionEvent = false;
OnPanelSelectionCompleted?.Invoke(this, null);
}
public void StartEditPanelLocations()
{
_winEvent = new PInvoke.WinEventProc(PanelLocationEditEventCallback);
_winEventHook = PInvoke.SetWinEventHook(PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND, PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE, DiagnosticManager.GetApplicationProcess().Handle, _winEvent, 0, 0, PInvokeConstant.WINEVENT_OUTOFCONTEXT);
_isEditingPanelCoordinates = true;
2021-09-30 02:17:20 +00:00
}
2022-01-27 13:40:04 +00:00
public void EndEditPanelLocations()
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
PInvoke.UnhookWinEvent(_winEventHook);
_isEditingPanelCoordinates = false;
}
private void PanelLocationEditEventCallback(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime)
{
// check by priority to minimize escaping constraint
if (hWnd == IntPtr.Zero
|| idObject != 0
|| hWinEventHook != _winEventHook
|| !_isEditingPanelCoordinates
|| !(iEvent == PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE || iEvent == PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND)
|| UserProfile.PanelSourceCoordinates == null || UserProfile.PanelSourceCoordinates.Count == 0)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
return;
}
2021-09-30 02:17:20 +00:00
2022-01-27 13:40:04 +00:00
var panelSourceCoordinate = UserProfile.PanelSourceCoordinates.FirstOrDefault(panel => panel.PanelHandle == hWnd);
if (panelSourceCoordinate != null)
{
switch (iEvent)
2021-09-30 02:17:20 +00:00
{
2022-01-27 13:40:04 +00:00
case PInvokeConstant.EVENT_OBJECT_LOCATIONCHANGE:
Rectangle winRectangle;
PInvoke.GetWindowRect(panelSourceCoordinate.PanelHandle, out winRectangle);
if (_lastWindowRectangle == winRectangle) // ignore duplicate callback messages
return;
_lastWindowRectangle = winRectangle;
Rectangle clientRectangle;
PInvoke.GetClientRect(panelSourceCoordinate.PanelHandle, out clientRectangle);
panelSourceCoordinate.X = winRectangle.Left;
panelSourceCoordinate.Y = winRectangle.Top;
break;
case PInvokeConstant.EVENT_SYSTEM_MOVESIZEEND:
_userProfileManager.WriteUserProfiles();
break;
2021-09-30 02:17:20 +00:00
}
}
}
}
2022-01-27 13:40:04 +00:00
}