1
0
Fork 0
mirror of https://github.com/hawkeye-stan/msfs-popout-panel-manager.git synced 2024-11-29 17:20:11 +00:00
msfs-popout-panel-manager/WpfApp/ViewModel/ApplicationViewModel.cs

320 lines
13 KiB
C#
Raw Normal View History

2022-02-07 03:05:05 +00:00
using AutoUpdaterDotNET;
2022-06-30 23:53:08 +00:00
using CommunityToolkit.Mvvm.ComponentModel;
2022-01-27 13:40:04 +00:00
using MSFSPopoutPanelManager.Model;
using MSFSPopoutPanelManager.Provider;
using MSFSPopoutPanelManager.Shared;
using System;
2022-02-07 03:05:05 +00:00
using System.IO;
2022-01-27 13:40:04 +00:00
using System.Linq;
using System.Threading;
using System.Windows;
namespace MSFSPopoutPanelManager.WpfApp.ViewModel
{
2022-06-30 23:53:08 +00:00
public class ApplicationViewModel : ObservableObject
2022-01-27 13:40:04 +00:00
{
private UserProfileManager _userProfileManager;
private PanelPopOutManager _panelPopoutManager;
private SimConnectManager _simConnectManager;
public event EventHandler<EventArgs<StatusMessage>> ShowContextMenuBalloonTip;
public PanelSelectionViewModel PanelSelectionViewModel { get; private set; }
public PanelConfigurationViewModel PanelConfigurationViewModel { get; private set; }
2022-06-30 23:53:08 +00:00
public PreferencesViewModel PreferencesViewModel { get; private set; }
2022-01-27 13:40:04 +00:00
public DataStore DataStore { get; set; }
public int ActiveUserProfileId { get; set; }
public string ApplicationVersion { get; private set; }
public WindowState InitialWindowState { get; private set; }
public StatusMessage StatusMessage { get; set; }
public bool IsShownPanelConfigurationScreen { get; set; }
public bool IsShownPanelSelectionScreen { get; set; }
public bool IsMinimizedAllPanels { get; set; }
2022-06-30 23:53:08 +00:00
public IntPtr WindowHandle { get; set; }
2022-01-27 13:40:04 +00:00
public DelegateCommand RestartCommand => new DelegateCommand(OnRestart, CanExecute);
public DelegateCommand MinimizeAllPanelsCommand => new DelegateCommand(OnMinimizeAllPanels, CanExecute);
public DelegateCommand ExitCommand => new DelegateCommand(OnExit, CanExecute);
public DelegateCommand UserGuideCommand => new DelegateCommand((o) => { DiagnosticManager.OpenOnlineUserGuide(); }, CanExecute);
public DelegateCommand DownloadLatestReleaseCommand => new DelegateCommand((o) => { DiagnosticManager.OpenOnlineLatestDownload(); }, CanExecute);
public DelegateCommand UserProfileSelectCommand => new DelegateCommand(OnUserProfileSelected, CanExecute);
public DelegateCommand ShowPanelCoorOverlayCommand => new DelegateCommand(OnShowPanelCoorOverlay, CanExecute);
public DelegateCommand StartPopOutCommand => new DelegateCommand(OnStartPopOut, CanExecute);
public ApplicationViewModel()
{
Logger.OnStatusLogged += (sender, e) => { OnStatusMessageLogged(e); };
DataStore = new DataStore();
_userProfileManager = new UserProfileManager();
_simConnectManager = new SimConnectManager();
2022-06-30 23:53:08 +00:00
_simConnectManager.OnSimConnectDataRefreshed += (sender, e) =>
{
2022-04-18 03:38:33 +00:00
// Automatic switching of active profile when SimConnect active aircraft livery changes
2022-06-30 23:53:08 +00:00
if (DataStore.CurrentMsfsPlaneTitle != e.Value.Title)
2022-04-18 03:38:33 +00:00
{
DataStore.CurrentMsfsPlaneTitle = e.Value.Title;
AutoSwitchProfile(e.Value.Title);
}
2022-06-30 23:53:08 +00:00
2022-01-27 13:40:04 +00:00
DataStore.ElectricalMasterBatteryStatus = e.Value.ElectricalMasterBattery;
};
_simConnectManager.OnConnected += (sender, e) => { DataStore.IsSimulatorStarted = true; };
_simConnectManager.OnDisconnected += (sender, e) => { DataStore.IsSimulatorStarted = false; };
_panelPopoutManager = new PanelPopOutManager(_userProfileManager, _simConnectManager);
_panelPopoutManager.OnPopOutCompleted += (sender, e) =>
{
Application.Current.Dispatcher.Invoke(() =>
{
if (e.Value)
{
var messageDialog = new OnScreenMessageDialog("Panels have been popped out succesfully.", MessageIcon.Success);
messageDialog.ShowDialog();
}
else
{
var messageDialog = new OnScreenMessageDialog("Unable to pop out panels.\nPlease see error message in the app.", MessageIcon.Failed);
messageDialog.ShowDialog();
}
});
};
PanelSelectionViewModel = new PanelSelectionViewModel(DataStore, _userProfileManager, _panelPopoutManager, _simConnectManager);
PanelSelectionViewModel.OnPopOutCompleted += (sender, e) => { ShowPanelSelection(false); PanelConfigurationViewModel.Initialize(); };
PanelConfigurationViewModel = new PanelConfigurationViewModel(DataStore, _userProfileManager);
2022-06-30 23:53:08 +00:00
PreferencesViewModel = new PreferencesViewModel(DataStore);
2022-01-27 13:40:04 +00:00
InputHookManager.OnStartPopout += (source, e) => { OnStartPopOut(null); };
}
public void Initialize()
{
var appSetting = new AppSetting();
appSetting.Load();
DataStore.AppSetting = appSetting;
DataStore.AppSetting.AlwaysOnTopChanged += OnAlwaysOnTopChanged;
DataStore.AppSetting.AutoPopOutPanelsChanged += (sender, e) =>
{
if (e.Value)
ActivateAutoPanelPopOut();
else
DeativateAutoPanelPopOut();
};
2022-02-07 03:05:05 +00:00
CheckForAutoUpdate();
2022-01-27 13:40:04 +00:00
// Set application version
ApplicationVersion = DiagnosticManager.GetApplicationVersion();
// Set window state
if (DataStore.AppSetting.StartMinimized)
InitialWindowState = WindowState.Minimized;
// Set Always on Top
if (DataStore.AppSetting.AlwaysOnTop)
OnAlwaysOnTopChanged(this, new EventArgs<bool>(DataStore.AppSetting.AlwaysOnTop));
// Activate auto pop out panels
2022-04-18 19:52:39 +00:00
_simConnectManager.OnFlightStopped += HandleOnFlightStopped;
2022-01-27 13:40:04 +00:00
if (DataStore.AppSetting.AutoPopOutPanels)
ActivateAutoPanelPopOut();
ShowPanelSelection(true);
IsMinimizedAllPanels = false;
2022-02-07 03:05:05 +00:00
InputHookManager.StartHook();
2022-01-27 13:40:04 +00:00
}
2022-06-30 23:53:08 +00:00
public void Exit()
{
// This method gets call on Windows_Closing
InputHookManager.EndHook();
_simConnectManager.Stop();
}
2022-01-27 13:40:04 +00:00
private void OnRestart(object commandParameter)
{
// Un-minimize all panels if applicable
2022-06-30 23:53:08 +00:00
if (IsMinimizedAllPanels)
2022-01-27 13:40:04 +00:00
{
DataStore.AllowEdit = true;
IsMinimizedAllPanels = false;
WindowManager.MinimizeAllPopoutPanels(false);
}
// Unhook all win events
PanelConfigurationViewModel.UnhookWinEvents();
// Clear logger
Logger.ClearStatus();
// Try to close all Cutome Panel window
DataStore.ActiveUserProfile.PanelConfigs.ToList().FindAll(p => p.PanelType == PanelType.CustomPopout).ForEach(panel => WindowManager.CloseWindow(panel.PanelHandle));
// Clear all panel windows handle for active profile
DataStore.ActiveUserProfile.PanelConfigs.ToList().ForEach(p => p.PanelHandle = IntPtr.Zero);
ShowPanelSelection(true);
}
private void OnExit(object commandParameter)
{
2022-06-30 23:53:08 +00:00
if (Application.Current != null)
Application.Current.Dispatcher.Invoke(() => Application.Current.Shutdown());
}
2022-01-27 13:40:04 +00:00
2022-06-30 23:53:08 +00:00
private void ShutDownApplication()
{
if (Application.Current != null)
Application.Current.Shutdown();
2022-01-27 13:40:04 +00:00
}
private void OnMinimizeAllPanels(object commandParameter)
{
IsMinimizedAllPanels = !IsMinimizedAllPanels;
if (IsMinimizedAllPanels)
{
DataStore.AllowEdit = false;
WindowManager.MinimizeAllPopoutPanels(true);
Logger.LogStatus("All pop out panels have been minimized. Panel configuration has been disabled.", StatusMessageType.Info);
}
else
{
DataStore.AllowEdit = true;
WindowManager.MinimizeAllPopoutPanels(false);
Logger.ClearStatus();
}
}
private void OnUserProfileSelected(object commandParameter)
{
var profileId = Convert.ToInt32(commandParameter);
if (profileId != DataStore.ActiveUserProfileId)
DataStore.ActiveUserProfileId = profileId;
}
private void OnShowPanelCoorOverlay(object commandParameter)
{
PanelSelectionViewModel.IsEditingPanelCoorOverlay = !PanelSelectionViewModel.IsEditingPanelCoorOverlay;
PanelSelectionViewModel.EditPanelCoorOverlayCommand.Execute(null);
}
private void OnStartPopOut(object commandParameter)
{
ShowPanelSelection(true);
PanelSelectionViewModel.StartPopOutCommand.Execute(null);
}
private void OnAlwaysOnTopChanged(object sender, EventArgs<bool> e)
{
WindowManager.ApplyAlwaysOnTop(DataStore.ApplicationHandle, e.Value);
}
private void ShowPanelSelection(bool show)
{
IsShownPanelSelectionScreen = show;
IsShownPanelConfigurationScreen = !show;
}
private void OnStatusMessageLogged(EventArgs<StatusMessage> e)
{
StatusMessage = e.Value;
ShowContextMenuBalloonTip?.Invoke(this, new EventArgs<StatusMessage>(e.Value));
}
private bool CanExecute(object commandParameter)
{
return true;
}
private void ActivateAutoPanelPopOut()
{
_simConnectManager.OnFlightStarted += HandleOnFlightStarted;
}
private void DeativateAutoPanelPopOut()
{
DataStore.IsEnteredFlight = false;
_simConnectManager.OnFlightStarted -= HandleOnFlightStarted;
}
private void HandleOnFlightStarted(object sender, EventArgs e)
{
2022-04-18 03:38:33 +00:00
Application.Current.Dispatcher.Invoke(() =>
{
AutoSwitchProfile(DataStore.CurrentMsfsPlaneTitle);
2022-01-27 13:40:04 +00:00
2022-04-18 03:38:33 +00:00
DataStore.IsEnteredFlight = true;
ShowPanelSelection(true);
2022-01-27 13:40:04 +00:00
2022-04-18 03:38:33 +00:00
// find the profile with the matching binding plane title
2022-04-18 16:24:00 +00:00
var profile = DataStore.UserProfiles.FirstOrDefault(p => p.BindingAircraftLiveries.ToList().Exists(p => p == DataStore.CurrentMsfsPlaneTitle));
2022-04-18 03:38:33 +00:00
if (profile == null || profile.PanelSourceCoordinates.Count == 0)
return;
var messageDialog = new OnScreenMessageDialog($"Automatic pop out is starting for profile:\n{profile.ProfileName}", DataStore.AppSetting.AutoPopOutPanelsWaitDelay.ReadyToFlyButton); // Wait for the ready to fly button
messageDialog.ShowDialog();
2022-01-27 13:40:04 +00:00
InputEmulationManager.LeftClickReadyToFly();
2022-04-18 03:38:33 +00:00
Thread.Sleep(DataStore.AppSetting.AutoPopOutPanelsWaitDelay.InitialCockpitView * 1000); // Wait for the initial cockpit view
2022-01-27 13:40:04 +00:00
2022-04-18 03:38:33 +00:00
// Turn on power if required to pop out panels
_simConnectManager.TurnOnPower(profile.PowerOnRequiredForColdStart);
Thread.Sleep(DataStore.AppSetting.AutoPopOutPanelsWaitDelay.InstrumentationPowerOn * 1000); // Wait for battery to be turned on
2022-01-27 13:40:04 +00:00
2022-04-18 03:38:33 +00:00
DataStore.ActiveUserProfileId = profile.ProfileId;
_panelPopoutManager.UserProfile = profile;
_panelPopoutManager.AppSetting = DataStore.AppSetting;
_panelPopoutManager.StartPopout();
2022-01-27 13:40:04 +00:00
2022-04-18 03:38:33 +00:00
// Turn off power if needed after pop out
_simConnectManager.TurnOffpower();
});
2022-01-27 13:40:04 +00:00
}
private void HandleOnFlightStopped(object sender, EventArgs e)
{
DataStore.IsEnteredFlight = false;
2022-04-18 03:38:33 +00:00
OnRestart(null);
2022-01-27 13:40:04 +00:00
}
2022-02-07 03:05:05 +00:00
private void CheckForAutoUpdate()
{
string jsonPath = Path.Combine(Path.Combine(FileIo.GetUserDataFilePath(), "autoupdate.json"));
AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath);
AutoUpdater.Synchronous = true;
AutoUpdater.AppTitle = "MSFS Pop Out Panel Manager";
2022-04-18 22:07:30 +00:00
AutoUpdater.RunUpdateAsAdmin = false;
2022-02-07 03:05:05 +00:00
AutoUpdater.UpdateFormSize = new System.Drawing.Size(930, 675);
2022-05-04 15:11:04 +00:00
AutoUpdater.Start(DataStore.AppSetting.AutoUpdaterUrl);
2022-04-18 03:38:33 +00:00
}
private void AutoSwitchProfile(string activeAircraftTitle)
{
// Automatic switching of active profile when SimConnect active aircraft livery changes
if (DataStore.UserProfiles != null)
{
2022-04-18 16:24:00 +00:00
var matchedProfile = DataStore.UserProfiles.ToList().Find(p => p.BindingAircraftLiveries.ToList().Exists(t => t == activeAircraftTitle));
2022-04-18 03:38:33 +00:00
if (matchedProfile != null)
DataStore.ActiveUserProfileId = matchedProfile.ProfileId;
}
2022-02-07 03:05:05 +00:00
}
2022-01-27 13:40:04 +00:00
}
2022-06-30 23:53:08 +00:00
}