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
}