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

332 lines
14 KiB
C#
Raw Normal View History

2022-06-30 23:53:08 +00:00
using CommunityToolkit.Mvvm.ComponentModel;
using MSFSPopoutPanelManager.Model;
2022-01-27 13:40:04 +00:00
using MSFSPopoutPanelManager.Provider;
using MSFSPopoutPanelManager.Shared;
using System;
using System.Linq;
using System.Threading;
using System.Windows;
namespace MSFSPopoutPanelManager.WpfApp.ViewModel
{
2022-06-30 23:53:08 +00:00
public class PanelSelectionViewModel : ObservableObject
2022-01-27 13:40:04 +00:00
{
private UserProfileManager _userProfileManager;
private PanelSelectionManager _panelSelectionManager;
private PanelPopOutManager _panelPopoutManager;
private SimConnectManager _simConnectManager;
private bool _minimizeForPopOut;
public event EventHandler OnPopOutStarted;
public event EventHandler OnPopOutCompleted;
2022-06-30 23:53:08 +00:00
public event EventHandler OnUserProfileChanged;
2022-01-27 13:40:04 +00:00
2022-06-30 23:53:08 +00:00
public DataStore DataStore { get; private set; }
2022-01-27 13:40:04 +00:00
public bool IsEditingPanelCoorOverlay { get; set; }
public DelegateCommand AddProfileCommand => new DelegateCommand(OnAddProfile, CanExecute);
public DelegateCommand DeleteProfileCommand => new DelegateCommand(OnDeleteProfile, CanExecute);
2022-04-18 16:24:00 +00:00
public DelegateCommand ChangeProfileCommand => new DelegateCommand(OnChangeProfile, CanExecute);
2022-01-27 13:40:04 +00:00
public DelegateCommand AddProfileBindingCommand => new DelegateCommand(OnAddProfileBinding, CanExecute);
public DelegateCommand DeleteProfileBindingCommand => new DelegateCommand(OnDeleteProfileBinding, CanExecute);
public DelegateCommand SetPowerOnRequiredCommand => new DelegateCommand((e) => _userProfileManager.WriteUserProfiles(), CanExecute);
public DelegateCommand StartPanelSelectionCommand => new DelegateCommand(OnStartPanelSelection, CanExecute);
public DelegateCommand StartPopOutCommand => new DelegateCommand(OnStartPopOut, CanExecute);
public DelegateCommand SaveAutoPanningCameraCommand => new DelegateCommand(OnSaveAutoPanningCamera, CanExecute);
public DelegateCommand EditPanelCoorOverlayCommand => new DelegateCommand(OnEditPanelCoorOverlay, CanExecute);
public PanelSelectionViewModel(DataStore dataStore, UserProfileManager userProfileManager, PanelPopOutManager panelPopoutManager, SimConnectManager simConnectManager)
{
DataStore = dataStore;
2022-06-30 23:53:08 +00:00
DataStore.OnActiveUserProfileChanged += (sender, e) =>
{
2022-07-06 18:09:10 +00:00
if (IsEditingPanelCoorOverlay && DataStore.AppSetting.AutoDisableTrackIR)
_simConnectManager.TurnOnTrackIR();
ShowPanelOverlay(false);
2022-04-18 16:24:00 +00:00
};
2022-01-27 13:40:04 +00:00
_userProfileManager = userProfileManager;
_simConnectManager = simConnectManager;
_panelSelectionManager = new PanelSelectionManager(userProfileManager);
_panelSelectionManager.OnPanelLocationAdded += (sender, e) => { AddPanelCoorOverlay(e.Value); };
_panelSelectionManager.OnPanelLocationRemoved += (sender, e) => { RemoveLastAddedPanelCoorOverlay(); };
_panelSelectionManager.OnAllPanelLocationsRemoved += (sender, e) => { RemoveAllPanelCoorOverlay(); };
_panelSelectionManager.OnPanelSelectionCompleted += HandlePanelSelectionCompleted;
_panelPopoutManager = panelPopoutManager;
_panelPopoutManager.OnPopOutStarted += HandleOnPopOutStarted;
_panelPopoutManager.OnPopOutCompleted += HandleOnPopOutCompleted;
}
public void Initialize()
{
_userProfileManager.ReadUserProfiles();
DataStore.UserProfiles = _userProfileManager.UserProfiles;
2022-04-18 16:24:00 +00:00
DataStore.ActiveUserProfileId = DataStore.UserProfiles.ToList().Exists(p => p.ProfileId == DataStore.AppSetting.LastUsedProfileId) ? DataStore.AppSetting.LastUsedProfileId : -1;
2022-01-27 13:40:04 +00:00
IsEditingPanelCoorOverlay = false;
InputHookManager.SubscribeToStartPopOutEvent = true;
}
private void OnAddProfile(object commandParameter)
{
var param = commandParameter as AddProfileCommandParameter;
if (param.CopyProfileId == -1)
DataStore.ActiveUserProfileId = _userProfileManager.AddUserProfile(param.ProfileName);
else
DataStore.ActiveUserProfileId = _userProfileManager.AddUserProfileByCopyingProfile(param.ProfileName, param.CopyProfileId);
2022-04-18 16:24:00 +00:00
DataStore.AppSetting.LastUsedProfileId = DataStore.ActiveUserProfileId;
2022-01-27 13:40:04 +00:00
}
private void OnDeleteProfile(object commandParameter)
{
if (_userProfileManager.DeleteUserProfile(DataStore.ActiveUserProfileId))
DataStore.ActiveUserProfileId = -1;
}
2022-04-18 16:24:00 +00:00
private void OnChangeProfile(object commandParameter)
2022-01-27 13:40:04 +00:00
{
2022-04-18 16:24:00 +00:00
DataStore.AppSetting.LastUsedProfileId = DataStore.ActiveUserProfileId;
2022-06-30 23:53:08 +00:00
OnUserProfileChanged?.Invoke(this, null);
2022-01-27 13:40:04 +00:00
}
private void OnAddProfileBinding(object commandParameter)
{
2022-04-18 03:38:33 +00:00
var index = DataStore.ActiveUserProfileId;
2022-01-27 13:40:04 +00:00
_userProfileManager.AddProfileBinding(DataStore.CurrentMsfsPlaneTitle, DataStore.ActiveUserProfileId);
2022-04-18 03:38:33 +00:00
// force profile refresh
DataStore.ActiveUserProfileId = -1;
DataStore.ActiveUserProfileId = index;
2022-01-27 13:40:04 +00:00
}
private void OnDeleteProfileBinding(object commandParameter)
{
2022-04-18 03:38:33 +00:00
var index = DataStore.ActiveUserProfileId;
_userProfileManager.DeleteProfileBinding(DataStore.CurrentMsfsPlaneTitle, DataStore.ActiveUserProfileId);
// force profile refresh
DataStore.ActiveUserProfileId = -1;
DataStore.ActiveUserProfileId = index;
2022-01-27 13:40:04 +00:00
}
private void OnStartPanelSelection(object commandParameter)
{
2022-05-04 15:11:04 +00:00
// Turn off TrackIR if TrackIR is started
if (DataStore.AppSetting.AutoDisableTrackIR)
_simConnectManager.TurnOffTrackIR();
2022-07-06 18:09:10 +00:00
RemoveAllPanelCoorOverlay();
2022-01-27 13:40:04 +00:00
WindowManager.MinimizeWindow(DataStore.ApplicationHandle); // Window hide doesn't work when try to reshow window after selection completes. So need to use minimize.
_panelSelectionManager.UserProfile = DataStore.ActiveUserProfile;
_panelSelectionManager.AppSetting = DataStore.AppSetting;
_panelSelectionManager.Start();
}
private void OnStartPopOut(object commandParameter)
{
Thread.Sleep(500); // allow time for the mouse to be stopped moving by the user
2022-07-06 18:09:10 +00:00
ShowPanelOverlay(false);
InputHookManager.EndHook();
2022-01-27 13:40:04 +00:00
2022-07-06 18:09:10 +00:00
if (!(DataStore.IsSimulatorStarted))
2022-01-27 13:40:04 +00:00
{
Logger.LogStatus("MSFS/SimConnect has not been started. Please try again at a later time.", StatusMessageType.Error);
return;
}
2022-07-06 18:09:10 +00:00
if(DataStore.ActiveUserProfile.PanelSourceCoordinates.Count == 0)
{
Logger.LogStatus("No panel has been selected for the profile. Please select at least one panel.", StatusMessageType.Error);
return;
}
2022-02-07 03:05:05 +00:00
if (DataStore.ActiveUserProfile != null && DataStore.ActiveUserProfile.PanelSourceCoordinates.Count > 0)
2022-01-27 13:40:04 +00:00
{
2022-07-06 18:09:10 +00:00
// Turn off TrackIR if TrackIR is started
if (DataStore.AppSetting.AutoDisableTrackIR)
_simConnectManager.TurnOffTrackIR();
2022-01-27 13:40:04 +00:00
Logger.LogStatus("Panels pop out in progress.....", StatusMessageType.Info);
var messageDialog = new OnScreenMessageDialog($"Panels pop out in progress for profile:\n{DataStore.ActiveUserProfile.ProfileName}", DataStore.AppSetting.AutoPopOutPanelsWaitDelay.InitialCockpitView);
messageDialog.ShowDialog();
// Turn on power if required to pop out panels
_simConnectManager.TurnOnPower(DataStore.ActiveUserProfile.PowerOnRequiredForColdStart);
Thread.Sleep(DataStore.AppSetting.AutoPopOutPanelsWaitDelay.InstrumentationPowerOn * 1000); // Wait for battery to be turned on
_panelPopoutManager.UserProfile = DataStore.ActiveUserProfile;
_panelPopoutManager.AppSetting = DataStore.AppSetting;
_panelPopoutManager.StartPopout();
// Turn off power if needed after pop out
_simConnectManager.TurnOffpower();
}
}
private void OnSaveAutoPanningCamera(object commandParameter)
{
var simualatorProcess = DiagnosticManager.GetSimulatorProcess();
2022-07-06 18:09:10 +00:00
if (simualatorProcess == null)
2022-01-27 13:40:04 +00:00
{
2022-07-06 18:09:10 +00:00
Logger.LogStatus("MSFS/SimConnect has not been started. Please try again at a later time.", StatusMessageType.Error);
return;
2022-01-27 13:40:04 +00:00
}
2022-07-06 18:09:10 +00:00
InputEmulationManager.SaveCustomView(simualatorProcess.Handle, DataStore.AppSetting.AutoPanningKeyBinding);
Logger.LogStatus("Auto Panning Camera has been saved succesfully.", StatusMessageType.Info);
2022-01-27 13:40:04 +00:00
}
private void OnEditPanelCoorOverlay(object commandParameter)
{
2022-05-04 15:11:04 +00:00
// Turn off TrackIR if TrackIR is started
2022-07-06 18:09:10 +00:00
if (DataStore.AppSetting.AutoDisableTrackIR)
2022-05-04 15:11:04 +00:00
{
2022-06-30 23:53:08 +00:00
if (IsEditingPanelCoorOverlay)
2022-05-04 15:11:04 +00:00
_simConnectManager.TurnOffTrackIR();
else
_simConnectManager.TurnOnTrackIR();
}
2022-01-27 13:40:04 +00:00
if (IsEditingPanelCoorOverlay)
{
2022-07-06 18:09:10 +00:00
ShowPanelOverlay(true);
2022-01-27 13:40:04 +00:00
_panelSelectionManager.UserProfile = DataStore.ActiveUserProfile;
_panelSelectionManager.AppSetting = DataStore.AppSetting;
2022-07-06 18:09:10 +00:00
if (DataStore.AppSetting.UseAutoPanning)
InputEmulationManager.LoadCustomView(DataStore.AppSetting.AutoPanningKeyBinding);
InputHookManager.StartHook();
2022-01-27 13:40:04 +00:00
}
else
{
2022-07-06 18:09:10 +00:00
InputHookManager.EndHook();
ShowPanelOverlay(false);
2022-01-27 13:40:04 +00:00
}
}
private void AddPanelCoorOverlay(PanelSourceCoordinate panelSourceCoordinate)
{
PanelCoorOverlay overlay = new PanelCoorOverlay(panelSourceCoordinate.PanelIndex);
overlay.IsEditingPanelLocation = IsEditingPanelCoorOverlay;
2022-07-06 18:09:10 +00:00
overlay.WindowStartupLocation = WindowStartupLocation.Manual;
overlay.MoveWindow(panelSourceCoordinate.X, panelSourceCoordinate.Y);
2022-01-27 13:40:04 +00:00
overlay.ShowInTaskbar = false;
overlay.Show();
2022-07-06 18:09:10 +00:00
overlay.WindowLocationChanged += (sender, e) =>
{
panelSourceCoordinate.X = e.Value.X;
panelSourceCoordinate.Y = e.Value.Y;
_userProfileManager.WriteUserProfiles();
};
2022-01-27 13:40:04 +00:00
}
private void RemoveLastAddedPanelCoorOverlay()
{
RemovePanelCoorOverlay(false);
}
private void RemoveAllPanelCoorOverlay()
{
RemovePanelCoorOverlay(true);
}
private void RemovePanelCoorOverlay(bool removeAll)
{
for (int i = Application.Current.Windows.Count - 1; i >= 1; i--)
{
if (Application.Current.Windows[i].GetType() == typeof(PanelCoorOverlay))
{
Application.Current.Windows[i].Close();
if (!removeAll)
break;
}
}
}
private void HandleOnPopOutStarted(object sender, EventArgs e)
{
// Hide panel coordinate overlays
2022-07-06 18:09:10 +00:00
ShowPanelOverlay(false);
2022-01-27 13:40:04 +00:00
// Close all pop out panels
WindowManager.CloseAllCustomPopoutPanels();
2022-05-04 15:11:04 +00:00
// Turn off TrackIR if TrackIR is started
if (DataStore.AppSetting.AutoDisableTrackIR)
_simConnectManager.TurnOffTrackIR();
2022-01-27 13:40:04 +00:00
// Temporary minimize the app for pop out process
_minimizeForPopOut = DataStore.ApplicationWindow.WindowState != WindowState.Minimized;
if (_minimizeForPopOut)
WindowManager.MinimizeWindow(DataStore.ApplicationHandle);
OnPopOutStarted?.Invoke(this, null);
}
private void HandleOnPopOutCompleted(object sender, EventArgs<bool> hasResult)
{
// Restore window state
if (_minimizeForPopOut)
{
WindowManager.BringWindowToForeground(DataStore.ApplicationHandle);
DataStore.ApplicationWindow.Show();
}
if (hasResult.Value)
{
OnPopOutCompleted?.Invoke(this, null);
}
2022-05-04 15:11:04 +00:00
if (DataStore.AppSetting.AutoDisableTrackIR)
_simConnectManager.TurnOnTrackIR();
2022-01-27 13:40:04 +00:00
}
private void HandlePanelSelectionCompleted(object sender, EventArgs e)
{
WindowManager.BringWindowToForeground(DataStore.ApplicationHandle);
DataStore.ApplicationWindow.Show();
if (DataStore.ActiveUserProfile.PanelSourceCoordinates.Count > 0)
Logger.LogStatus("Panels selection is completed. Please click 'Start Pop Out' to start popping out these panels.", StatusMessageType.Info);
else
Logger.LogStatus("Panels selection is completed. No panel has been selected.", StatusMessageType.Info);
2022-05-04 15:11:04 +00:00
2022-07-06 18:09:10 +00:00
IsEditingPanelCoorOverlay = true;
2022-01-27 13:40:04 +00:00
}
private bool CanExecute(object commandParameter)
{
return true;
}
2022-07-06 18:09:10 +00:00
private void ShowPanelOverlay(bool show)
{
IsEditingPanelCoorOverlay = show;
RemoveAllPanelCoorOverlay();
if (show && DataStore.ActiveUserProfile != null)
DataStore.ActiveUserProfile.PanelSourceCoordinates.ToList().ForEach(c => AddPanelCoorOverlay(c));
}
2022-01-27 13:40:04 +00:00
}
public class AddProfileCommandParameter
{
public string ProfileName { get; set; }
public int CopyProfileId { get; set; }
}
}