1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-25 23:30:10 +00:00
msfs-popout-panel-manager/Orchestration/PanelSourceOrchestrator.cs

329 lines
12 KiB
C#
Raw Normal View History

2023-07-12 22:41:31 +00:00
using MSFSPopoutPanelManager.DomainModel.Profile;
using MSFSPopoutPanelManager.DomainModel.Setting;
using MSFSPopoutPanelManager.Shared;
2022-07-23 19:23:32 +00:00
using MSFSPopoutPanelManager.WindowsAgent;
using System;
2024-02-28 02:44:21 +00:00
using System.Collections.Generic;
using System.Collections.ObjectModel;
2023-07-30 21:30:47 +00:00
using System.Threading;
2023-07-12 22:41:31 +00:00
using System.Threading.Tasks;
using Point = System.Drawing.Point;
2022-07-23 19:23:32 +00:00
namespace MSFSPopoutPanelManager.Orchestration
{
2024-02-28 02:44:21 +00:00
public class PanelSourceOrchestrator : BaseOrchestrator
2022-07-23 19:23:32 +00:00
{
private const int CAMERA_VIEW_HOME_COCKPIT_MODE = 8;
private const int CAMERA_VIEW_CUSTOM_CAMERA = 7;
2024-02-28 02:44:21 +00:00
private readonly FlightSimOrchestrator _flightSimOrchestrator;
private bool _isEditingPanelSourceLock;
2022-07-23 19:23:32 +00:00
2023-11-05 02:10:03 +00:00
public event EventHandler OnStatusMessageStarted;
public event EventHandler OnStatusMessageEnded;
2024-02-28 02:44:21 +00:00
public PanelSourceOrchestrator(SharedStorage sharedStorage, FlightSimOrchestrator flightSimOrchestrator) : base(sharedStorage)
2023-07-12 22:41:31 +00:00
{
2024-02-28 02:44:21 +00:00
_flightSimOrchestrator = flightSimOrchestrator;
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
ProfileData.OnActiveProfileChanged += (_, _) => { CloseAllPanelSource(); };
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
flightSimOrchestrator.OnFlightStopped += (_, _) => { CloseAllPanelSource(); };
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
internal IntPtr ApplicationHandle { get; set; }
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
private UserProfile ActiveProfile => ProfileData?.ActiveProfile;
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
private ApplicationSetting AppSetting => AppSettingData?.ApplicationSetting;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
public event EventHandler<PanelConfig> OnOverlayShowed;
2023-08-17 06:03:17 +00:00
public event EventHandler<PanelConfig> OnNonEditOverlayShowed;
2023-07-12 22:41:31 +00:00
public event EventHandler<PanelConfig> OnOverlayRemoved;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
public void StartPanelSelectionEvent()
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
if (ActiveProfile.IsSelectingPanelSource)
return;
ActiveProfile.IsSelectingPanelSource = true;
2023-07-12 22:41:31 +00:00
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
public void StartPanelSelection(PanelConfig panelConfig)
{
2024-02-28 02:44:21 +00:00
// ReSharper disable once EventUnsubscriptionViaAnonymousDelegate
InputHookManager.OnLeftClick -= (_, e) => HandleOnPanelSelectionAdded(panelConfig, e);
InputHookManager.OnLeftClick += (_, e) => HandleOnPanelSelectionAdded(panelConfig, e);
2023-07-12 22:41:31 +00:00
InputHookManager.StartMouseHook();
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
public async Task StartEditPanelSources()
{
2023-08-18 05:03:56 +00:00
if (_isEditingPanelSourceLock)
return;
_isEditingPanelSourceLock = true;
2024-02-28 02:44:21 +00:00
// Turn off TrackIR if TrackIR is started
_flightSimOrchestrator.TurnOffTrackIR();
2023-11-05 02:10:03 +00:00
2024-02-28 02:44:21 +00:00
if (ActiveProfile.IsUsedLegacyCameraSystem)
await StartEditPanelSourcesLegacyCamera();
else
await StartEditPanelSourcesFixedCamera();
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
public async Task EndEditPanelSources()
2022-07-23 19:23:32 +00:00
{
2023-08-18 05:03:56 +00:00
if (!_isEditingPanelSourceLock)
return;
2024-02-28 02:44:21 +00:00
if (ActiveProfile.IsUsedLegacyCameraSystem)
EndEditPanelSourcesLegacyCamera();
else
EndEditPanelSourcesFixedCamera();
2022-07-23 19:23:32 +00:00
2023-08-18 05:03:56 +00:00
_isEditingPanelSourceLock = false;
2024-02-28 02:44:21 +00:00
foreach (var panelConfig in ProfileData.ActiveProfile.PanelConfigs)
2023-08-18 05:03:56 +00:00
{
2024-02-28 02:44:21 +00:00
panelConfig.IsEditingPanel = false;
panelConfig.IsSelectedPanelSource = false;
OnOverlayRemoved?.Invoke(this, panelConfig);
2023-08-18 05:03:56 +00:00
}
2024-02-28 02:44:21 +00:00
ActiveProfile.IsSelectingPanelSource = false;
2023-07-12 22:41:31 +00:00
await Task.Run(() =>
{
WindowActionManager.BringWindowToForeground(ApplicationHandle);
// Turn TrackIR back on
2024-02-28 02:44:21 +00:00
_flightSimOrchestrator.TurnOnTrackIR();
2023-07-12 22:41:31 +00:00
});
2024-02-28 02:44:21 +00:00
// End all mouse hook if active
InputHookManager.EndMouseHook();
}
public void ShowPanelSourceForEdit(PanelConfig panel)
{
foreach (var panelConfig in ActiveProfile.PanelConfigs)
{
OnOverlayRemoved?.Invoke(this, panelConfig);
panelConfig.IsEditingPanel = false;
}
panel.IsEditingPanel = true;
if (panel.HasPanelSource)
OnOverlayShowed?.Invoke(this, panel);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
public void ShowPanelSourceNonEdit(PanelConfig panel)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (panel.HasPanelSource)
2023-08-17 06:03:17 +00:00
OnNonEditOverlayShowed?.Invoke(this, panel);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
public void ClosePanelSourceNonEdit(PanelConfig panel)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
OnOverlayRemoved?.Invoke(this, panel);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
public void CloseAllPanelSource()
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (ActiveProfile != null)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
ActiveProfile.IsEditingPanelSource = false;
2023-08-18 05:03:56 +00:00
_isEditingPanelSourceLock = false;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
foreach (var panelConfig in ActiveProfile.PanelConfigs)
OnOverlayRemoved?.Invoke(this, panelConfig);
2022-07-23 19:23:32 +00:00
}
}
2024-02-28 02:44:21 +00:00
public void SetCamera(PanelConfig panel)
{
if (!FlightSimData.IsInCockpit)
return;
if (panel.FixedCameraConfig == null)
return;
Task.Run(() =>
{
if (panel.FixedCameraConfig.CameraType == CameraType.Cockpit)
{
_flightSimOrchestrator.ResetCameraView();
Thread.Sleep(250);
}
_flightSimOrchestrator.SetFixedCamera(panel.FixedCameraConfig.CameraType, panel.FixedCameraConfig.CameraIndex);
});
Thread.Sleep(250);
}
2023-07-12 22:41:31 +00:00
public void HandleOnPanelSelectionAdded(PanelConfig panelConfig, Point e)
2022-07-23 19:23:32 +00:00
{
2024-02-28 02:44:21 +00:00
if (WindowActionManager.IsPointInsideAppWindow(e))
return;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
InputHookManager.EndMouseHook();
2022-07-23 19:23:32 +00:00
if (ActiveProfile == null)
return;
2023-07-12 22:41:31 +00:00
panelConfig.PanelSource.X = e.X;
panelConfig.PanelSource.Y = e.Y;
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
ProfileData.WriteProfiles();
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Show source circle on screen
OnOverlayShowed?.Invoke(this, panelConfig);
2022-07-23 19:23:32 +00:00
// If using windows mode, save MSFS game window configuration
2024-02-28 02:44:21 +00:00
if (AppSettingData.ApplicationSetting.WindowedModeSetting.AutoResizeMsfsGameWindow)
ProfileData.SaveMsfsGameWindowConfig();
2023-07-12 22:41:31 +00:00
panelConfig.IsSelectedPanelSource = false;
2024-02-28 02:44:21 +00:00
ActiveProfile.IsSelectingPanelSource = false;
2023-07-12 22:41:31 +00:00
}
public void RemovePanelSource(PanelConfig panelConfig)
{
// Disable hooks if active
InputHookManager.EndMouseHook();
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
ProfileData.ActiveProfile.CurrentMoveResizePanelId = Guid.Empty;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
OnOverlayRemoved?.Invoke(this, panelConfig);
2022-07-23 19:23:32 +00:00
2024-02-28 02:44:21 +00:00
ProfileData.ActiveProfile.PanelConfigs.Remove(panelConfig);
2022-07-23 19:23:32 +00:00
}
2023-08-14 04:35:14 +00:00
2024-02-28 02:44:21 +00:00
private void LoadCustomView(string keyBinding)
2023-08-14 04:35:14 +00:00
{
int retry = 3;
2023-08-14 04:35:14 +00:00
for (var i = 0; i < retry; i++)
{
2024-02-28 02:44:21 +00:00
InputEmulationManager.LoadCustomView(keyBinding);
Thread.Sleep(750); // wait for flightsimdata to be updated
2024-02-28 02:44:21 +00:00
if (FlightSimData.CameraViewTypeAndIndex1 == CAMERA_VIEW_CUSTOM_CAMERA) // custom camera view enum
2023-08-14 04:35:14 +00:00
break;
}
}
private void SetCockpitZoomLevel(int zoom)
{
2024-02-28 02:44:21 +00:00
var retry = 3;
for (var i = 0; i < retry; i++)
{
2024-02-28 02:44:21 +00:00
_flightSimOrchestrator.SetCockpitCameraZoomLevel(zoom);
2023-08-16 06:42:18 +00:00
Thread.Sleep(750); // wait for flightsimdata to be updated
2024-02-28 02:44:21 +00:00
if (FlightSimData.CockpitCameraZoom == zoom)
break;
}
}
2024-02-28 02:44:21 +00:00
private async Task StartEditPanelSourcesLegacyCamera()
{
await Task.Run(() =>
{
OnStatusMessageStarted?.Invoke(this, EventArgs.Empty);
StatusMessageWriter.IsEnabled = true;
StatusMessageWriter.ClearMessage();
StatusMessageWriter.WriteMessage("Loading camera view. Please wait......", StatusMessageType.Info);
// Set Windowed Display Mode window's configuration if needed
if (AppSettingData.ApplicationSetting.WindowedModeSetting.AutoResizeMsfsGameWindow)
WindowActionManager.SetMsfsGameWindowLocation(ActiveProfile.MsfsGameWindowConfig);
if (AppSetting.PopOutSetting.AutoPanning.IsEnabled)
{
if (FlightSimData.CameraViewTypeAndIndex1 == CAMERA_VIEW_HOME_COCKPIT_MODE)
{
_flightSimOrchestrator.SetCockpitCameraZoomLevel(ProfileData.ActiveProfile.PanelSourceCockpitZoomFactor);
}
else
{
LoadCustomView(AppSetting.PopOutSetting.AutoPanning.KeyBinding);
_flightSimOrchestrator.SetCockpitCameraZoomLevel(50);
}
WindowActionManager.BringWindowToForeground(ApplicationHandle);
}
foreach (var panel in ProfileData.ActiveProfile.PanelConfigs)
{
if (panel.HasPanelSource)
OnOverlayShowed?.Invoke(this, panel);
}
Thread.Sleep(500);
StatusMessageWriter.IsEnabled = false;
OnStatusMessageEnded?.Invoke(this, EventArgs.Empty);
});
}
private Task StartEditPanelSourcesFixedCamera()
{
return Task.CompletedTask;
}
private void EndEditPanelSourcesLegacyCamera()
{
// Save last auto panning camera angle
if (AppSetting.PopOutSetting.AutoPanning.IsEnabled)
{
// If using windows mode, save MSFS game window configuration
if (AppSettingData.ApplicationSetting.WindowedModeSetting.AutoResizeMsfsGameWindow)
ProfileData.SaveMsfsGameWindowConfig();
if (FlightSimData.CameraViewTypeAndIndex1 == CAMERA_VIEW_HOME_COCKPIT_MODE)
{
ProfileData.ActiveProfile.PanelSourceCockpitZoomFactor = FlightSimData.CockpitCameraZoom;
}
else
{
// !!! Fix MSFS issue that without setting zoom, everything will be off by few pixels at a time
SetCockpitZoomLevel(FlightSimData.CockpitCameraZoom);
InputEmulationManager.SaveCustomView(AppSetting.PopOutSetting.AutoPanning.KeyBinding);
}
}
Thread.Sleep(500); // wait for custom view save to be completed
}
private void EndEditPanelSourcesFixedCamera()
{
_flightSimOrchestrator.ResetCameraView();
}
public ObservableCollection<FixedCameraConfig> GetFixedCameraConfigs()
{
var configs = new List<FixedCameraConfig>
{
new() { Id = 0, Name = "Cockpit Pilot", CameraType = CameraType.Cockpit, CameraIndex = 1 },
new() { Id = 1, Name = "Cockpit Copilot", CameraType = CameraType.Cockpit, CameraIndex = 5 }
};
for (var i = 0; i < FlightSimData.CameraViewTypeAndIndex2Max; i++)
{
var item = new FixedCameraConfig
{
Id = i + 2,
Name = $"Instrument {i + 1}",
CameraType = CameraType.Instrument,
CameraIndex = i
};
configs.Add(item);
}
return new ObservableCollection<FixedCameraConfig>(configs);
}
2022-07-23 19:23:32 +00:00
}
}