1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-21 21:30:12 +00:00
msfs-popout-panel-manager/Orchestration/PanelPopOutOrchestrator.cs

614 lines
24 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;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
2023-07-12 22:41:31 +00:00
using System.Windows;
2022-07-23 19:23:32 +00:00
namespace MSFSPopoutPanelManager.Orchestration
{
public class PanelPopOutOrchestrator : ObservableObject
{
2023-08-16 06:42:18 +00:00
private const int READY_TO_FLY_BUTTON_APPEARANCE_DELAY = 2000;
private const int CAMERA_VIEW_HOME_COCKPIT_MODE = 8;
private const int CAMERA_VIEW_CUSTOM_CAMERA = 7;
2023-08-16 06:42:18 +00:00
2023-07-12 22:41:31 +00:00
private ProfileData _profileData;
private AppSettingData _appSettingData;
private FlightSimData _flightSimData;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
public PanelPopOutOrchestrator(ProfileData profileData, AppSettingData appSettingData, FlightSimData flightSimData)
{
_profileData = profileData;
_appSettingData = appSettingData;
_flightSimData = flightSimData;
IsDisabledStartPopOut = false;
2023-07-12 22:41:31 +00:00
}
2022-07-23 19:23:32 +00:00
internal FlightSimOrchestrator FlightSimOrchestrator { private get; set; }
internal PanelSourceOrchestrator PanelSourceOrchestrator { private get; set; }
2023-07-12 22:41:31 +00:00
internal PanelConfigurationOrchestrator PanelConfigurationOrchestrator { private get; set; }
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private UserProfile ActiveProfile { get { return _profileData == null ? null : _profileData.ActiveProfile; } }
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private ApplicationSetting AppSetting { get { return _appSettingData == null ? null : _appSettingData.ApplicationSetting; } }
2022-07-23 19:23:32 +00:00
public bool IsDisabledStartPopOut { get; set; }
2022-07-23 19:23:32 +00:00
public event EventHandler OnPopOutStarted;
2023-07-12 22:41:31 +00:00
public event EventHandler OnPopOutCompleted;
public event EventHandler<PanelConfig> OnHudBarOpened;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
public async void ManualPopOut()
2022-07-23 19:23:32 +00:00
{
if (IsDisabledStartPopOut || !_flightSimData.IsInCockpit)
return;
2023-07-12 22:41:31 +00:00
await CoreSteps(false);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
public async void AutoPopOut()
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
await Application.Current.Dispatcher.Invoke(async () =>
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
_profileData.AutoSwitchProfile();
2022-07-23 19:23:32 +00:00
2023-07-26 20:22:44 +00:00
if (ActiveProfile == null)
return;
2023-07-12 22:41:31 +00:00
// Do not do auto pop out if no profile matches the current aircraft
if (!ActiveProfile.AircraftBindings.Any(p => p == _flightSimData.AircraftName))
return;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Do not do auto pop out if no panel configs defined
if (ActiveProfile.PanelConfigs.Count == 0)
return;
2022-10-16 13:11:01 +00:00
2023-07-12 22:41:31 +00:00
// Do not do auto pop out if not all custom panels have panel source defined
if (ActiveProfile.PanelConfigs.Count(p => p.PanelType == PanelType.CustomPopout) > 0 &&
ActiveProfile.PanelConfigs.Count(p => p.PanelType == PanelType.CustomPopout && p.HasPanelSource) != ActiveProfile.PanelConfigs.Count(p => p.PanelType == PanelType.CustomPopout))
return;
2023-08-16 06:42:18 +00:00
await StepReadyToFlyDelay(true);
2023-07-12 22:41:31 +00:00
await CoreSteps(true);
});
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
private async Task CoreSteps(bool isAutoPopOut)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (ActiveProfile == null || ActiveProfile.IsEditingPanelSource || ActiveProfile.HasUnidentifiedPanelSource)
return;
2023-07-12 22:41:31 +00:00
OnPopOutStarted?.Invoke(this, null);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
StatusMessageWriter.IsEnabled = true;
StatusMessageWriter.ClearMessage();
2023-08-16 03:41:14 +00:00
StatusMessageWriter.WriteMessageWithNewLine("Pop out in progress. Please refrain from moving your mouse.", StatusMessageType.Info);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
StepPopoutPrep();
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// *** THIS MUST BE DONE FIRST. Get the built-in panel list to be configured later
List<IntPtr> builtInPanelHandles = WindowActionManager.GetWindowsByPanelType(new List<PanelType>() { PanelType.BuiltInPopout });
2022-07-23 19:23:32 +00:00
2023-11-05 02:10:03 +00:00
await StepAddCustomPanels(builtInPanelHandles);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
StepAddBuiltInPanels(builtInPanelHandles);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
StepAddHudBar();
2022-07-23 19:23:32 +00:00
2023-07-23 05:13:23 +00:00
SetupRefocusDisplay();
2023-07-12 22:41:31 +00:00
StepApplyPanelConfig();
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
await StepPostPopout();
2022-07-23 19:23:32 +00:00
OnPopOutCompleted?.Invoke(this, null);
2023-07-12 22:41:31 +00:00
StatusMessageWriter.IsEnabled = false;
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private void StepPopoutPrep()
{
PanelConfigurationOrchestrator.EndConfiguration();
// Set profile pop out status
_profileData.ResetActiveProfile();
2022-07-23 19:23:32 +00:00
// Close all existing custom pop out panels
WindowActionManager.CloseAllPopOuts();
// Close all panel source overlays
PanelSourceOrchestrator.CloseAllPanelSource();
2023-07-12 22:41:31 +00:00
}
2022-07-23 19:23:32 +00:00
2023-08-16 06:42:18 +00:00
private async Task StepReadyToFlyDelay(bool isAutoPopOut)
{
if (!isAutoPopOut)
return;
if (AppSetting.AutoPopOutSetting.ReadyToFlyDelay == 0)
return;
await Task.Run(() =>
{
WorkflowStepWithMessage.Execute("Waiting on ready to fly button delay", () =>
{
// Ready to fly button plugin default delay
Thread.Sleep(READY_TO_FLY_BUTTON_APPEARANCE_DELAY);
// Extra wait for cockpit view to appear and align
Thread.Sleep(AppSetting.AutoPopOutSetting.ReadyToFlyDelay * 1000);
});
});
}
2023-11-05 02:10:03 +00:00
private async Task StepAddCustomPanels(List<IntPtr> builtInPanelHandles)
2023-07-12 22:41:31 +00:00
{
if (!ActiveProfile.HasCustomPanels)
2022-07-23 19:23:32 +00:00
return;
if (!await StepPreCustomPanelPopOut())
{
ActiveProfile.PanelConfigs.Where(p => p.PanelType == PanelType.CustomPopout).ToList().ForEach(p => p.PanelHandle = IntPtr.Zero);
return;
}
2023-07-12 22:41:31 +00:00
await StepCustomPanelPopOut(builtInPanelHandles);
2023-07-12 22:41:31 +00:00
await StepPostCustomPanelPopOut();
2022-07-23 19:23:32 +00:00
}
private async Task<bool> StepPreCustomPanelPopOut()
2022-07-23 19:23:32 +00:00
{
return await Task.Run(() =>
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
// Set Windowed Display Mode window's configuration if needed
if (_appSettingData.ApplicationSetting.WindowedModeSetting.AutoResizeMsfsGameWindow && WindowActionManager.IsMsfsGameInWindowedMode())
2022-07-23 19:23:32 +00:00
{
2023-08-16 03:41:14 +00:00
WorkflowStepWithMessage.Execute("Moving and resizing MSFS game window", () =>
{
WindowActionManager.SetMsfsGameWindowLocation(ActiveProfile.MsfsGameWindowConfig);
Thread.Sleep(1000);
});
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
// Turn on power and avionics if required to pop out panels at least one (fix Cessna 208b grand caravan mod bug where battery is reported as on)
if (ActiveProfile.ProfileSetting.PowerOnRequiredForColdStart)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
FlightSimOrchestrator.TurnOnPower();
FlightSimOrchestrator.TurnOnAvionics();
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
// Turn off TrackIR if TrackIR is started
FlightSimOrchestrator.TurnOffTrackIR();
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Turn on Active Pause
FlightSimOrchestrator.TurnOnActivePause();
2023-08-19 01:44:35 +00:00
2023-07-12 22:41:31 +00:00
// Setting custom camera angle for auto panning
if (AppSetting.PopOutSetting.AutoPanning.IsEnabled)
{
2023-08-16 03:41:14 +00:00
StatusMessageWriter.WriteMessageWithNewLine("Setting auto panning camera view", StatusMessageType.Info);
if (_flightSimData.CameraViewTypeAndIndex1 == CAMERA_VIEW_HOME_COCKPIT_MODE)
2023-08-16 03:41:14 +00:00
{
2023-09-29 06:15:02 +00:00
SetCockpitZoomLevel(_profileData.ActiveProfile.PanelSourceCockpitZoomFactor, AppSetting.GeneralSetting.TurboMode);
}
else
2023-08-16 03:41:14 +00:00
{
WorkflowStepWithMessage.Execute("Resetting camera view", () =>
{
2023-09-29 06:15:02 +00:00
ResetCockpitView(AppSetting.GeneralSetting.TurboMode);
}, true);
var success = WorkflowStepWithMessage.Execute("Loading custom camera view", () =>
{
2023-11-05 02:10:03 +00:00
return LoadCustomView(AppSetting.PopOutSetting.AutoPanning.KeyBinding, AppSetting.GeneralSetting.TurboMode, false);
}, true);
if (!success)
return false;
WorkflowStepWithMessage.Execute("Setting camera zoom level", () =>
{
2023-09-29 06:15:02 +00:00
SetCockpitZoomLevel(50, AppSetting.GeneralSetting.TurboMode);
}, true);
}
2023-07-12 22:41:31 +00:00
}
return 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
private async Task StepCustomPanelPopOut(List<IntPtr> builtInPanelHandles)
{
2023-07-12 22:41:31 +00:00
await Task.Run(() =>
{
2023-07-12 22:41:31 +00:00
// Save current application location to restore it after pop out
var appLocation = WindowActionManager.GetWindowRectangle(WindowProcessManager.GetApplicationProcess().Handle);
2023-08-16 03:41:14 +00:00
if(ActiveProfile.PanelConfigs.Count > 0)
StatusMessageWriter.WriteMessageWithNewLine("Popping out user defined panels", StatusMessageType.Info);
2023-07-12 22:41:31 +00:00
int index = 0;
foreach (var panelConfig in ActiveProfile.PanelConfigs)
{
2023-07-12 22:41:31 +00:00
if (panelConfig.PanelType == PanelType.CustomPopout)
{
2023-08-16 03:41:14 +00:00
WorkflowStepWithMessage.Execute(panelConfig.PanelName, () =>
{
panelConfig.IsSelectedPanelSource = true;
2023-11-05 02:10:03 +00:00
PanelSourceOrchestrator.ShowPanelSourceNonEdit(panelConfig);
InputEmulationManager.PrepareToPopOutPanel((int)panelConfig.PanelSource.X, (int)panelConfig.PanelSource.Y, AppSetting.GeneralSetting.TurboMode);
PanelSourceOrchestrator.ClosePanelSourceNonEdit(panelConfig);
ExecuteCustomPopout(panelConfig, builtInPanelHandles, index++);
2023-09-29 06:15:02 +00:00
2023-08-16 03:41:14 +00:00
ApplyPanelLocation(panelConfig);
panelConfig.IsSelectedPanelSource = false;
if (panelConfig.IsPopOutSuccess != null && !(bool)panelConfig.IsPopOutSuccess)
return false;
else
return true;
}, true);
2023-07-12 22:41:31 +00:00
}
}
2023-07-12 22:41:31 +00:00
// Restore current application location
WindowActionManager.MoveWindow(WindowProcessManager.GetApplicationProcess().Handle, appLocation);
});
}
2023-07-12 22:41:31 +00:00
private async Task StepPostCustomPanelPopOut()
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
await Task.Run(() =>
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (ActiveProfile.ProfileSetting.PowerOnRequiredForColdStart)
{
FlightSimOrchestrator.TurnOffAvionics();
FlightSimOrchestrator.TurnOffPower();
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Turn TrackIR back on
FlightSimOrchestrator.TurnOnTrackIR();
2023-08-16 06:42:18 +00:00
Thread.Sleep(500);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Turn on Active Pause
FlightSimOrchestrator.TurnOffActivePause();
2023-08-16 06:42:18 +00:00
Thread.Sleep(500);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Return to custom camera view if set
2023-08-16 03:41:14 +00:00
ReturnToAfterPopOutCameraView();
2023-07-12 22:41:31 +00:00
});
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private void StepAddBuiltInPanels(List<IntPtr> builtInPanelHandles)
{
if (ActiveProfile.ProfileSetting.IncludeInGamePanels)
{
2023-08-16 03:41:14 +00:00
WorkflowStepWithMessage.Execute("Configuring built-in panel", () =>
2023-07-12 22:41:31 +00:00
{
2023-08-16 03:41:14 +00:00
int count = 0;
while (builtInPanelHandles.Count == 0 && count < 5)
{
builtInPanelHandles = WindowActionManager.GetWindowsByPanelType(new List<PanelType>() { PanelType.BuiltInPopout });
count++;
2023-08-16 03:41:14 +00:00
}
2023-07-12 22:41:31 +00:00
2023-08-16 03:41:14 +00:00
var builtInPanels = new List<PanelConfig>();
foreach (var panelHandle in builtInPanelHandles)
2022-07-23 19:23:32 +00:00
{
2023-08-16 03:41:14 +00:00
var panelCaption = WindowActionManager.GetWindowCaption(panelHandle);
var panelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(p => p.PanelName == panelCaption);
if (panelConfig == null)
2022-07-23 19:23:32 +00:00
{
2023-08-16 03:41:14 +00:00
if (!ActiveProfile.IsLocked)
2022-07-23 19:23:32 +00:00
{
2023-08-16 03:41:14 +00:00
var rectangle = WindowActionManager.GetWindowRectangle(panelHandle);
panelConfig = new PanelConfig()
{
PanelHandle = panelHandle,
PanelType = PanelType.BuiltInPopout,
PanelName = panelCaption,
Top = rectangle.Top,
Left = rectangle.Left,
Width = rectangle.Width,
Height = rectangle.Height,
AutoGameRefocus = false
};
ActiveProfile.PanelConfigs.Add(panelConfig);
}
2022-07-23 19:23:32 +00:00
}
2023-08-16 03:41:14 +00:00
else
{
panelConfig.PanelHandle = panelHandle;
2022-07-23 19:23:32 +00:00
2023-08-16 03:41:14 +00:00
// Need to do it twice for MSFS to take this setting (MSFS bug)
ApplyPanelLocation(panelConfig);
ApplyPanelLocation(panelConfig);
}
2023-07-12 22:41:31 +00:00
}
2022-07-23 19:23:32 +00:00
2023-08-16 03:41:14 +00:00
// Set handles for missing built-in panels
foreach (var panelConfig in ActiveProfile.PanelConfigs)
{
if (panelConfig.PanelType == PanelType.BuiltInPopout && panelConfig.PanelHandle == IntPtr.MaxValue)
panelConfig.PanelHandle = IntPtr.Zero;
}
2022-07-23 19:23:32 +00:00
2023-08-16 03:41:14 +00:00
if (ActiveProfile.PanelConfigs.Any(p => p.PanelType == PanelType.BuiltInPopout && p.IsPopOutSuccess != null && !(bool)p.IsPopOutSuccess) ||
ActiveProfile.PanelConfigs.Count(p => p.PanelType == PanelType.BuiltInPopout) == 0)
return false;
else
return 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
private void StepAddHudBar()
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
if (!ActiveProfile.ProfileSetting.HudBarConfig.IsEnabled)
return;
2023-08-16 03:41:14 +00:00
WorkflowStepWithMessage.Execute("Opening HUD Bar", () =>
{
var panelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(p => p.PanelType == PanelType.HudBarWindow);
OnHudBarOpened?.Invoke(this, panelConfig);
});
2023-07-12 22:41:31 +00:00
}
2022-07-23 19:23:32 +00:00
2023-07-23 05:13:23 +00:00
public void SetupRefocusDisplay()
{
if (!ActiveProfile.ProfileSetting.RefocusOnDisplay.IsEnabled)
return;
2023-08-16 03:41:14 +00:00
var panelConfigs = ActiveProfile.PanelConfigs.Where(p => p.PanelType == PanelType.RefocusDisplay);
if (panelConfigs.Count() == 0)
return;
StatusMessageWriter.WriteMessageWithNewLine("Configurating panels for auto refocus on touch", StatusMessageType.Info);
foreach (var panelConfig in panelConfigs)
2023-07-23 05:13:23 +00:00
{
2023-07-27 14:50:57 +00:00
if (panelConfig != null)
{
2023-08-16 03:41:14 +00:00
WorkflowStepWithMessage.Execute(panelConfig.PanelName, () =>
{
panelConfig.PanelHandle = new IntPtr(1);
}, true);
2023-07-27 14:50:57 +00:00
}
2023-07-23 05:13:23 +00:00
}
}
2023-07-12 22:41:31 +00:00
private void StepApplyPanelConfig()
{
// Must apply other panel config after pop out since MSFS popping out action will overwrite panel config such as Always on Top
foreach (var panelConfig in ActiveProfile.PanelConfigs)
{
ApplyPanelConfig(panelConfig);
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Set title bar color
if (_appSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled && !panelConfig.FullScreen)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
WindowActionManager.SetWindowTitleBarColor(panelConfig.PanelHandle, _appSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
}
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private async Task StepPostPopout()
{
await Task.Run(() =>
{
// Set profile pop out status
ActiveProfile.IsPoppedOut = true;
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
// Must use application dispatcher to dispatch UI events (winEventHook)
PanelConfigurationOrchestrator.StartConfiguration();
2023-07-12 22:41:31 +00:00
// Start touch hook
PanelConfigurationOrchestrator.StartTouchHook();
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
if (CheckForPopOutError())
2023-08-16 03:41:14 +00:00
StatusMessageWriter.WriteMessageWithNewLine("Pop out has been completed with error.", StatusMessageType.Info);
2023-07-12 22:41:31 +00:00
else
2023-08-16 03:41:14 +00:00
StatusMessageWriter.WriteMessageWithNewLine("Pop out has been completed successfully.", StatusMessageType.Info);
2023-08-17 06:03:17 +00:00
Thread.Sleep(1000);
2022-07-23 19:23:32 +00:00
});
2023-07-12 22:41:31 +00:00
}
2022-07-23 19:23:32 +00:00
2023-07-12 22:41:31 +00:00
private void ExecuteCustomPopout(PanelConfig panel, List<IntPtr> builtInPanelHandles, int index)
{
2023-09-29 06:15:02 +00:00
// There should only be one handle that is not in both builtInPanelHandles vs latestAceAppWindowsWithCaptionHandles
var handle = TryPopOutCustomPanel(panel.PanelSource, builtInPanelHandles, AppSetting.GeneralSetting.TurboMode);
2022-10-16 13:11:01 +00:00
2023-09-29 06:15:02 +00:00
if (handle == IntPtr.Zero)
{
panel.PanelHandle = IntPtr.Zero;
return;
}
2022-09-11 13:50:04 +00:00
2023-09-29 06:15:02 +00:00
// Unable to pop out panel, the handle was previously popped out's handle
if (_profileData.ActiveProfile.PanelConfigs.Any(p => p.PanelHandle.Equals(handle)) || handle.Equals(WindowProcessManager.SimulatorProcess.Handle) || handle == IntPtr.Zero)
{
panel.PanelHandle = IntPtr.Zero;
return;
}
2022-09-11 13:50:04 +00:00
2023-09-29 06:15:02 +00:00
panel.PanelHandle = handle;
WindowActionManager.SetWindowCaption(panel.PanelHandle, $"{panel.PanelName} (Custom)");
2023-07-12 22:41:31 +00:00
2023-09-29 06:15:02 +00:00
// First time popping out
if (panel.Width == 0 && panel.Height == 0)
{
var rect = WindowActionManager.GetWindowRectangle(panel.PanelHandle);
panel.Top = 0 + index * 30;
panel.Left = 0 + index * 30;
panel.Width = rect.Width;
panel.Height = rect.Height;
2022-09-11 13:50:04 +00:00
}
2023-07-12 22:41:31 +00:00
}
2023-09-29 06:15:02 +00:00
private IntPtr TryPopOutCustomPanel(PanelSource panelSource, List<IntPtr> builtInPanelHandles, bool isTurbo)
2023-07-12 22:41:31 +00:00
{
2023-09-29 06:15:02 +00:00
// Try to pop out 5 times before failure with 1/2 second wait in between
2023-07-12 22:41:31 +00:00
int count = 0;
do
{
2023-09-29 06:15:02 +00:00
InputEmulationManager.PopOutPanel((int)panelSource.X, (int)panelSource.Y, AppSetting.PopOutSetting.UseLeftRightControlToPopOut, isTurbo);
2023-07-12 22:41:31 +00:00
var latestAceAppWindowsWithCaptionHandles = WindowActionManager.GetWindowsByPanelType(new List<PanelType>() { PanelType.BuiltInPopout });
// There should only be one handle that is not in both builtInPanelHandles vs latestAceAppWindowsWithCaptionHandles
var handle = latestAceAppWindowsWithCaptionHandles.Except(builtInPanelHandles).FirstOrDefault();
if (handle != IntPtr.Zero)
return handle;
2023-09-10 16:19:41 +00:00
Thread.Sleep(500);
2023-07-12 22:41:31 +00:00
count++;
}
2023-09-29 06:15:02 +00:00
while (count < 5);
2023-07-12 22:41:31 +00:00
return IntPtr.Zero;
}
private void ApplyPanelLocation(PanelConfig panel)
{
if (panel.IsPopOutSuccess == null || !((bool)panel.IsPopOutSuccess) || panel.PanelHandle == IntPtr.Zero)
return;
// Apply top/left/width/height
WindowActionManager.MoveWindow(panel.PanelHandle, panel.Left, panel.Top, panel.Width, panel.Height);
}
private void ApplyPanelConfig(PanelConfig panel)
{
if (panel.IsPopOutSuccess == null || !((bool)panel.IsPopOutSuccess) || panel.PanelHandle == IntPtr.Zero)
return;
2022-09-11 13:50:04 +00:00
2023-07-12 22:41:31 +00:00
if (!panel.FullScreen)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
// Apply always on top
if (panel.AlwaysOnTop)
2022-07-23 19:23:32 +00:00
{
2023-07-12 22:41:31 +00:00
WindowActionManager.ApplyAlwaysOnTop(panel.PanelHandle, panel.PanelType, panel.AlwaysOnTop);
2022-07-23 19:23:32 +00:00
Thread.Sleep(250);
2023-07-12 22:41:31 +00:00
}
2022-09-11 13:50:04 +00:00
2023-07-12 22:41:31 +00:00
// Apply hide title bar
if (panel.HideTitlebar)
{
WindowActionManager.ApplyHidePanelTitleBar(panel.PanelHandle, true);
Thread.Sleep(250);
2022-07-23 19:23:32 +00:00
}
2023-07-12 22:41:31 +00:00
}
if (panel.FullScreen && !panel.AlwaysOnTop && !panel.HideTitlebar)
{
Thread.Sleep(500);
InputEmulationManager.ToggleFullScreenPanel(panel.PanelHandle);
Thread.Sleep(250);
}
2022-07-23 19:23:32 +00:00
}
private void ReturnToAfterPopOutCameraView()
{
2023-07-12 22:41:31 +00:00
if (!AppSetting.PopOutSetting.AfterPopOutCameraView.IsEnabled)
2022-07-23 19:23:32 +00:00
return;
2023-08-16 03:41:14 +00:00
StatusMessageWriter.WriteMessageWithNewLine("Applying cockpit view after pop out", StatusMessageType.Info);
if (_flightSimData.CameraViewTypeAndIndex1 == CAMERA_VIEW_HOME_COCKPIT_MODE)
2022-07-23 19:23:32 +00:00
{
FlightSimOrchestrator.ResetCameraView();
}
else
{
switch (AppSetting.PopOutSetting.AfterPopOutCameraView.CameraView)
{
case AfterPopOutCameraViewType.CockpitCenterView:
WorkflowStepWithMessage.Execute("Resetting camera view", () =>
{
2023-09-29 06:15:02 +00:00
ResetCockpitView(AppSetting.GeneralSetting.TurboMode);
}, true);
2023-08-16 03:41:14 +00:00
break;
case AfterPopOutCameraViewType.CustomCameraView:
WorkflowStepWithMessage.Execute("Resetting camera view", () =>
{
2023-09-29 06:15:02 +00:00
ResetCockpitView(AppSetting.GeneralSetting.TurboMode);
}, true);
2023-08-16 03:41:14 +00:00
WorkflowStepWithMessage.Execute("Loading custom camera view", () =>
{
2023-11-05 02:10:03 +00:00
return LoadCustomView(AppSetting.PopOutSetting.AfterPopOutCameraView.KeyBinding, AppSetting.GeneralSetting.TurboMode, true);
}, true);
2023-08-16 03:41:14 +00:00
break;
}
2022-07-23 19:23:32 +00:00
}
}
2023-07-12 22:41:31 +00:00
private bool CheckForPopOutError()
{
return ActiveProfile.PanelConfigs.Count(p => p.IsPopOutSuccess != null && (bool)p.IsPopOutSuccess) != ActiveProfile.PanelConfigs.Count(p => p.IsPopOutSuccess != null);
}
2023-08-14 04:35:14 +00:00
2023-09-29 06:15:02 +00:00
private void ResetCockpitView(bool isTurboMode)
2023-08-16 03:41:14 +00:00
{
int retry = 10;
for (var i = 0; i < retry; i++)
{
FlightSimOrchestrator.ResetCameraView();
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurboMode ? 600 : 1000); // wait for flightsimdata to be updated
2023-08-16 03:41:14 +00:00
if (_flightSimData.CameraViewTypeAndIndex1 == 0) // 0 = reset view
break;
}
}
2023-11-05 02:10:03 +00:00
private bool LoadCustomView(string keybinding, bool isTurboMode, bool ignoreError)
2023-08-14 04:35:14 +00:00
{
2023-08-17 06:03:17 +00:00
int retry = 10;
2023-08-14 04:35:14 +00:00
for(var i = 0; i < retry; i++)
{
InputEmulationManager.LoadCustomView(keybinding);
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurboMode ? 600 : 1000); // wait for flightsimdata to be updated
if (_flightSimData.CameraViewTypeAndIndex1 == CAMERA_VIEW_CUSTOM_CAMERA) // custom camera view enum
return true;
2023-08-14 04:35:14 +00:00
}
2023-11-05 02:10:03 +00:00
return ignoreError;
2023-08-14 04:35:14 +00:00
}
2023-09-29 06:15:02 +00:00
private void SetCockpitZoomLevel(int zoom, bool isTurboMode)
{
int retry = 10;
for (var i = 0; i < retry; i++)
{
FlightSimOrchestrator.SetCockpitCameraZoomLevel(zoom);
2023-09-29 06:15:02 +00:00
Thread.Sleep(isTurboMode ? 600 : 1000); // wait for flightsimdata to be updated
if (_flightSimData.CockpitCameraZoom == zoom)
break;
}
}
2022-07-23 19:23:32 +00:00
}
}