diff --git a/DomainModel/DomainModel.csproj b/DomainModel/DomainModel.csproj index 591a6a0..6848d72 100644 --- a/DomainModel/DomainModel.csproj +++ b/DomainModel/DomainModel.csproj @@ -11,9 +11,9 @@ https://github.com/hawkeye-stan/msfs-popout-panel-manager MSFSPopoutPanelManager.DomainModel x64 - 4.1.1.0 - 4.1.1.0 - 4.1.1.0 + 4.1.2.0 + 4.1.2.0 + 4.1.2.0 win-x64 Embedded Debug;Release;Local diff --git a/DomainModel/Profile/PanelConfig.cs b/DomainModel/Profile/PanelConfig.cs index 26fe447..5f9a89c 100644 --- a/DomainModel/Profile/PanelConfig.cs +++ b/DomainModel/Profile/PanelConfig.cs @@ -94,11 +94,11 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile [JsonIgnore] public bool IsDeletablePanel => PanelType != PanelType.HudBarWindow && PanelType != PanelType.RefocusDisplay && - PanelType != PanelType.NumPadWindow; + PanelType != PanelType.NumPadWindow && PanelType != PanelType.SwitchWindow; [JsonIgnore] public bool IsTouchEnablePanel => PanelType != PanelType.HudBarWindow && PanelType != PanelType.RefocusDisplay && - PanelType != PanelType.NumPadWindow; + PanelType != PanelType.NumPadWindow && PanelType != PanelType.SwitchWindow; [JsonIgnore] public bool IsCustomPopOut => PanelType == PanelType.CustomPopout; @@ -116,6 +116,9 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile [JsonIgnore] public bool IsNumPadWindow => PanelType == PanelType.NumPadWindow; + [JsonIgnore] + public bool IsSwitchWindow => PanelType == PanelType.SwitchWindow; + [JsonIgnore] public string PanelSourceCoordinateText { diff --git a/DomainModel/Profile/PanelType.cs b/DomainModel/Profile/PanelType.cs index 9fc1d9a..5b4943f 100644 --- a/DomainModel/Profile/PanelType.cs +++ b/DomainModel/Profile/PanelType.cs @@ -12,6 +12,7 @@ StatusMessageWindow = 7, RefocusDisplay = 8, NumPadWindow = 9, + SwitchWindow = 20, Unknown = 100 } } diff --git a/DomainModel/Profile/ProfileSetting.cs b/DomainModel/Profile/ProfileSetting.cs index d5157ea..85d4eca 100644 --- a/DomainModel/Profile/ProfileSetting.cs +++ b/DomainModel/Profile/ProfileSetting.cs @@ -18,5 +18,7 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile public RefocusOnDisplay RefocusOnDisplay { get; set; } = new(); public NumPadConfig NumPadConfig { get; set; } = new(); + + public SwitchWindowConfig SwitchWindowConfig { get; set; } = new(); } } diff --git a/DomainModel/Profile/SwitchWindowConfig.cs b/DomainModel/Profile/SwitchWindowConfig.cs new file mode 100644 index 0000000..82d1057 --- /dev/null +++ b/DomainModel/Profile/SwitchWindowConfig.cs @@ -0,0 +1,9 @@ +using MSFSPopoutPanelManager.Shared; + +namespace MSFSPopoutPanelManager.DomainModel.Profile +{ + public class SwitchWindowConfig : ObservableObject + { + public bool IsEnabled { get; set; } = false; + } +} \ No newline at end of file diff --git a/MainApp/App.xaml.cs b/MainApp/App.xaml.cs index 6604a77..519d330 100644 --- a/MainApp/App.xaml.cs +++ b/MainApp/App.xaml.cs @@ -82,6 +82,7 @@ namespace MSFSPopoutPanelManager.MainApp services.AddTransient(s => new MessageWindowViewModel(SharedStorage, s.GetRequiredService(), s.GetRequiredService())); services.AddTransient(s => new HudBarViewModel(SharedStorage, s.GetRequiredService())); services.AddTransient(_ => new NumPadViewModel(SharedStorage)); + services.AddTransient(_ => new SwitchWindowViewModel(SharedStorage)); }).Build(); diff --git a/MainApp/AppUserControl/PopOutPanelConfigCard.xaml b/MainApp/AppUserControl/PopOutPanelConfigCard.xaml index 6e176c2..f6e17dd 100644 --- a/MainApp/AppUserControl/PopOutPanelConfigCard.xaml +++ b/MainApp/AppUserControl/PopOutPanelConfigCard.xaml @@ -224,7 +224,7 @@ x:Name="StackPanelAdjustment" Width="440" Orientation="Horizontal" - Visibility="{c:Binding 'DataItem.IsBuiltInPopOut or DataItem.IsHudBarWindow or DataItem.IsNumPadWindow or (DataItem.IsCustomPopOut and DataItem.PanelSource.X != null)'}"> + Visibility="{c:Binding 'DataItem.IsBuiltInPopOut or DataItem.IsHudBarWindow or DataItem.IsNumPadWindow or DataItem.IsSwitchWindow or (DataItem.IsCustomPopOut and DataItem.PanelSource.X != null)'}"> Include in-game menu bar panels for pop out management and touch screen support + Add a virtual keyboard NumPad + + + Add a switch window command bar + + (); Loaded += (_, _) => { DataContext = _viewModel; }; + +#if LOCAL + this.wrapPanelSwitchWindow.Visibility = Visibility.Visible; +#else + this.wrapPanelSwitchWindow.Visibility = Visibility.Collapsed; +#endif } private void ToggleButtonEditProfileTitle_Click(object sender, RoutedEventArgs e) @@ -46,22 +52,27 @@ namespace MSFSPopoutPanelManager.MainApp.AppUserControl private void IncludeInGamePanel_TargetUpdated(object sender, DataTransferEventArgs e) { - _viewModel.IncludeInGamePanelUpdatedCommand.Execute(null); + _viewModel.IncludeInGamePanelUpdatedCommand?.Execute(null); } private void AddHudBar_TargetUpdated(object sender, DataTransferEventArgs e) { - _viewModel.AddHudBarUpdatedCommand.Execute(null); + _viewModel.AddHudBarUpdatedCommand?.Execute(null); } private void AddRefocusDisplay_TargetUpdated(object sender, DataTransferEventArgs e) { - _viewModel.RefocusDisplayUpdatedCommand.Execute(null); + _viewModel.RefocusDisplayUpdatedCommand?.Execute(null); } private void AddNumPad_TargetUpdated(object sender, DataTransferEventArgs e) { - _viewModel.AddNumPadUpdatedCommand.Execute(null); + _viewModel.AddNumPadUpdatedCommand?.Execute(null); + } + + private void AddSwitchWindow_TargetUpdated(object sender, DataTransferEventArgs e) + { + _viewModel.AddSwitchWindowUpdatedCommand?.Execute(null); } } diff --git a/MainApp/AppWindow/SwitchWindow.xaml b/MainApp/AppWindow/SwitchWindow.xaml new file mode 100644 index 0000000..28e5ba1 --- /dev/null +++ b/MainApp/AppWindow/SwitchWindow.xaml @@ -0,0 +1,69 @@ + + + 28 + + + + + + + + + + + + + diff --git a/MainApp/AppWindow/SwitchWindow.xaml.cs b/MainApp/AppWindow/SwitchWindow.xaml.cs new file mode 100644 index 0000000..ded57ff --- /dev/null +++ b/MainApp/AppWindow/SwitchWindow.xaml.cs @@ -0,0 +1,65 @@ +using Microsoft.Extensions.DependencyInjection; +using MSFSPopoutPanelManager.MainApp.ViewModel; +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Input; +using System.Windows.Interop; + +namespace MSFSPopoutPanelManager.MainApp.AppWindow +{ + /// + /// Interaction logic for SwitchWindow.xaml + /// + public partial class SwitchWindow : Window + { + private readonly SwitchWindowViewModel _viewModel; + + public SwitchWindow(Guid panelId, int initialWidth, int initialHeight) + { + InitializeComponent(); + if (DesignerProperties.GetIsInDesignMode(new DependencyObject())) + return; + + _viewModel = App.AppHost.Services.GetRequiredService(); + _viewModel.PanelId = panelId; + + Loaded += (_, _) => + { + DataContext = _viewModel; + + var window = Window.GetWindow(this); + if (window == null) + throw new ApplicationException("Unable to instantiate switchWindow window"); + + _viewModel.PanelConfig.PanelHandle = new WindowInteropHelper(window).Handle; + + if (initialWidth == 0 && initialHeight == 0) + { + this.Width = 410; + this.Height = 75; + _viewModel.PanelConfig.Width = Convert.ToInt16(this.Width); + _viewModel.PanelConfig.Height = Convert.ToInt32(this.Height); + } + else + { + this.Width = initialWidth; + this.Height = initialHeight; + } + }; + + this.MouseLeftButtonDown += SwitchWindow_MouseLeftButtonDown; + this.Topmost = true; + } + + private void SwitchWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) + { + DragMove(); + } + + private void BtnClose_Click(object sender, RoutedEventArgs e) + { + this.Close(); + } + } +} diff --git a/MainApp/MainApp.csproj b/MainApp/MainApp.csproj index 4e2fcfc..7e2be53 100644 --- a/MainApp/MainApp.csproj +++ b/MainApp/MainApp.csproj @@ -14,9 +14,9 @@ MSFSPopoutPanelManager.MainApp logo.ico x64 - 4.1.1.0 - 4.1.1.0 - 4.1.1.0 + 4.1.2.0 + 4.1.2.0 + 4.1.2.0 embedded en diff --git a/MainApp/Styles/CustomMaterialDesignExpander.xaml b/MainApp/Styles/CustomMaterialDesignExpander.xaml index f8c3697..1e7932e 100644 --- a/MainApp/Styles/CustomMaterialDesignExpander.xaml +++ b/MainApp/Styles/CustomMaterialDesignExpander.xaml @@ -25,7 +25,7 @@ Kind="ChevronDown" Opacity="0.5" RenderTransformOrigin="0.5 0.5" - Visibility="{c:Binding '!DataItem.IsHudBarWindow and !DataItem.IsRefocusDisplay and !DataItem.IsNumPadWindow and !ActiveProfile.IsEditingPanelSource'}"> + Visibility="{c:Binding '!DataItem.IsHudBarWindow and !DataItem.IsRefocusDisplay and !DataItem.IsNumPadWindow and !DataItem.IsSwitchWindow and !ActiveProfile.IsEditingPanelSource'}"> diff --git a/MainApp/ViewModel/OrchestratorUIHelper.cs b/MainApp/ViewModel/OrchestratorUIHelper.cs index bd0bc66..20c2e51 100644 --- a/MainApp/ViewModel/OrchestratorUIHelper.cs +++ b/MainApp/ViewModel/OrchestratorUIHelper.cs @@ -36,6 +36,9 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel panelPopOutOrchestrator.OnNumPadOpened -= HandleOnNumPadOpened; panelPopOutOrchestrator.OnNumPadOpened += HandleOnNumPadOpened; + + panelPopOutOrchestrator.OnSwitchWindowOpened -= HandleOnSwitchWindowOpened; + panelPopOutOrchestrator.OnSwitchWindowOpened += HandleOnSwitchWindowOpened; } private void HandleShowOverlay(object sender, PanelConfig panelConfig) @@ -99,6 +102,22 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel }); } + private void HandleOnSwitchWindowOpened(object sender, PanelConfig panelConfig) + { + Application.Current.Dispatcher.Invoke(async () => + { + var switchWindow = new SwitchWindow(panelConfig.Id, panelConfig.Width, panelConfig.Height); + switchWindow.Show(); + + await Task.Run(() => + { + Thread.Sleep(1000); + WindowActionManager.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height); + WindowActionManager.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height); + }); + }); + } + private void HandleOnPopOutStarted(object sender, EventArgs e) { if (!AppSettingData.ApplicationSetting.PopOutSetting.MinimizeDuringPopOut) diff --git a/MainApp/ViewModel/ProfileCardViewModel.cs b/MainApp/ViewModel/ProfileCardViewModel.cs index c93c74f..1084705 100644 --- a/MainApp/ViewModel/ProfileCardViewModel.cs +++ b/MainApp/ViewModel/ProfileCardViewModel.cs @@ -41,6 +41,8 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel public ICommand AddNumPadUpdatedCommand { get; } + public ICommand AddSwitchWindowUpdatedCommand { get; } + public ICommand RefocusDisplayRefreshedCommand { get; } public DelegateCommand RefocusDisplaySelectionUpdatedCommand { get; } @@ -100,7 +102,9 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel AddHudBarUpdatedCommand = new DelegateCommand(OnAddHudBarUpdated); AddNumPadUpdatedCommand = new DelegateCommand(OnAddNumPadUpdated); - +#if LOCAL + AddSwitchWindowUpdatedCommand = new DelegateCommand(OnAddSwitchWindowUpdated); +#endif RefocusDisplayUpdatedCommand = new DelegateCommand(OnRefocusDisplayUpdated); RefocusDisplayRefreshedCommand = new DelegateCommand(OnRefocusDisplayRefreshed); @@ -239,6 +243,35 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel } } + private void OnAddSwitchWindowUpdated() + { + if (ActiveProfile == null) + return; + + + if (ActiveProfile.ProfileSetting.SwitchWindowConfig.IsEnabled) + { + if (ActiveProfile.PanelConfigs.Any(p => p.PanelType == PanelType.SwitchWindow)) + return; + + ActiveProfile.PanelConfigs.Add(new PanelConfig + { + PanelName = "Switch Window", + PanelType = PanelType.SwitchWindow, + Left = 0, + Top = 0, + Width = 0, + Height = 0, + AutoGameRefocus = false + }); + } + else + { + ActiveProfile.PanelConfigs.RemoveAll(p => p.PanelType == PanelType.SwitchWindow); + } + + } + private void OnRefocusDisplayUpdated() { if (ActiveProfile == null) diff --git a/MainApp/ViewModel/SwitchWindowViewModel.cs b/MainApp/ViewModel/SwitchWindowViewModel.cs new file mode 100644 index 0000000..ad8a58c --- /dev/null +++ b/MainApp/ViewModel/SwitchWindowViewModel.cs @@ -0,0 +1,37 @@ +using System; +using System.Linq; +using MSFSPopoutPanelManager.DomainModel.Profile; +using MSFSPopoutPanelManager.Orchestration; +using MSFSPopoutPanelManager.WindowsAgent; +using Prism.Commands; + +namespace MSFSPopoutPanelManager.MainApp.ViewModel +{ + public class SwitchWindowViewModel : BaseViewModel + { + public DelegateCommand ButtonCommand { get; private set; } + + public Guid PanelId { get; set; } + + public PanelConfig PanelConfig => ActiveProfile.PanelConfigs.FirstOrDefault(p => p.Id == PanelId); + + + public SwitchWindowViewModel(SharedStorage sharedStorage) : base(sharedStorage) + { + ButtonCommand = new DelegateCommand(OnButtonActivated); + } + + private void OnButtonActivated(string commandParameter) + { + switch (commandParameter) + { + case "VerticalPanel": + PInvoke.SwitchToThisWindow(PInvoke.GetWindowHandle("737 Instruments Vertical"), true); + break; + case "OverheadPanel": + PInvoke.SwitchToThisWindow(PInvoke.GetWindowHandle("737 Instruments Overhead"), true); + break; + } + } + } +} diff --git a/Orchestration/DynamicLodOrchestrator.cs b/Orchestration/DynamicLodOrchestrator.cs index 0d7a02f..f304014 100644 --- a/Orchestration/DynamicLodOrchestrator.cs +++ b/Orchestration/DynamicLodOrchestrator.cs @@ -133,7 +133,7 @@ namespace MSFSPopoutPanelManager.Orchestration if (!FlightSimData.IsFlightStarted || !FlightSimData.IsInCockpit) return; - if (DateTime.Now - _lastLodUpdateTime <= TimeSpan.FromSeconds(1)) + if (DateTime.Now - _lastLodUpdateTime <= TimeSpan.FromSeconds(3)) return; var deltaFps = DynamicLodSimData.Fps - DynamicLodSetting.TargetedFps; @@ -239,7 +239,7 @@ namespace MSFSPopoutPanelManager.Orchestration private void SetTlod(int deltaFps) { - var tlodStep = Math.Max(5, Math.Abs(deltaFps / 2)); + var tlodStep = Math.Max(10, Math.Abs(deltaFps / 2)); var newTlod = DynamicLodSimData.Tlod + Math.Sign(deltaFps) * tlodStep; if (DynamicLodSetting.TlodMinOnGround && DynamicLodSimData.AltAboveGround <= DynamicLodSetting.AltTlodBase) diff --git a/Orchestration/Orchestration.csproj b/Orchestration/Orchestration.csproj index 6cf921a..fac2f5f 100644 --- a/Orchestration/Orchestration.csproj +++ b/Orchestration/Orchestration.csproj @@ -11,9 +11,9 @@ https://github.com/hawkeye-stan/msfs-popout-panel-manager MSFSPopoutPanelManager.Orchestration x64 - 4.1.1.0 - 4.1.1.0 - 4.1.1.0 + 4.1.2.0 + 4.1.2.0 + 4.1.2.0 win-x64 Embedded Debug;Release;Local diff --git a/Orchestration/PanelPopOutOrchestrator.cs b/Orchestration/PanelPopOutOrchestrator.cs index 744fbfc..015d779 100644 --- a/Orchestration/PanelPopOutOrchestrator.cs +++ b/Orchestration/PanelPopOutOrchestrator.cs @@ -50,6 +50,7 @@ namespace MSFSPopoutPanelManager.Orchestration public event EventHandler OnPopOutCompleted; public event EventHandler OnHudBarOpened; public event EventHandler OnNumPadOpened; + public event EventHandler OnSwitchWindowOpened; public async Task ManualPopOut() { @@ -122,7 +123,9 @@ namespace MSFSPopoutPanelManager.Orchestration StepAddHudBar(); StepAddNumPad(); - + + StepAddSwitchWindow(); + SetupRefocusDisplay(); StepApplyPanelConfig(); @@ -390,6 +393,18 @@ namespace MSFSPopoutPanelManager.Orchestration }); } + private void StepAddSwitchWindow() + { + if (!ActiveProfile.ProfileSetting.SwitchWindowConfig.IsEnabled) + return; + + WorkflowStepWithMessage.Execute("Opening Switch Window", () => + { + var panelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(p => p.PanelType == PanelType.SwitchWindow); + OnSwitchWindowOpened?.Invoke(this, panelConfig); + }); + } + public void SetupRefocusDisplay() { if (!ActiveProfile.ProfileSetting.RefocusOnDisplay.IsEnabled) diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index 08c68ae..1c410bb 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -11,9 +11,9 @@ https://github.com/hawkeye-stan/msfs-popout-panel-manager MSFSPopoutPanelManager.Shared x64 - 4.1.1.0 - 4.1.1.0 - 4.1.1.0 + 4.1.2.0 + 4.1.2.0 + 4.1.2.0 win-x64 Embedded Debug;Release;Local diff --git a/SimconnectAgent/SimconnectAgent.csproj b/SimconnectAgent/SimconnectAgent.csproj index 818840d..7ca62cf 100644 --- a/SimconnectAgent/SimconnectAgent.csproj +++ b/SimconnectAgent/SimconnectAgent.csproj @@ -11,9 +11,9 @@ https://github.com/hawkeye-stan/msfs-popout-panel-manager MSFSPopoutPanelManager.SimConnectAgent x64 - 4.1.1.0 - 4.1.1.0 - 4.1.1.0 + 4.1.2.0 + 4.1.2.0 + 4.1.2.0 win-x64 Embedded Debug;Release;Local diff --git a/WindowsAgent/PInvoke.cs b/WindowsAgent/PInvoke.cs index 97a7909..5461970 100644 --- a/WindowsAgent/PInvoke.cs +++ b/WindowsAgent/PInvoke.cs @@ -143,6 +143,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent [DllImport("user32.dll", SetLastError = true)] public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); + [DllImport("user32.dll", SetLastError = true)] + public static extern void SwitchToThisWindow(IntPtr hWnd, bool turnOn); + [DllImport("user32.dll", SetLastError = true)] public static extern int UnhookWinEvent(IntPtr hWinEventHook); @@ -193,6 +196,23 @@ namespace MSFSPopoutPanelManager.WindowsAgent return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); } + + public static IntPtr GetWindowHandle(string windowCaption) + { + IntPtr windowHandle = IntPtr.Zero; + + EnumWindows((hwnd, _) => + { + var caption = GetWindowText(hwnd); + + if (caption == windowCaption) + windowHandle = hwnd; + + return true; + }, 0); + + return windowHandle; + } } public struct RECT diff --git a/WindowsAgent/WindowActionManager.cs b/WindowsAgent/WindowActionManager.cs index ffd5a8c..9ea692d 100644 --- a/WindowsAgent/WindowActionManager.cs +++ b/WindowsAgent/WindowActionManager.cs @@ -181,6 +181,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent if (caption.IndexOf("Virtual NumPad", StringComparison.Ordinal) > -1) return PanelType.NumPadWindow; + + if (caption.IndexOf("Switch Window", StringComparison.Ordinal) > -1) + return PanelType.SwitchWindow; return PanelType.PopOutManager; } @@ -194,7 +197,7 @@ namespace MSFSPopoutPanelManager.WindowsAgent { var panelType = GetWindowPanelType(hwnd); - if (panelType == PanelType.CustomPopout || panelType == PanelType.HudBarWindow || panelType == PanelType.NumPadWindow) + if (panelType == PanelType.CustomPopout || panelType == PanelType.HudBarWindow || panelType == PanelType.NumPadWindow || panelType == PanelType.SwitchWindow) CloseWindow(hwnd); return true; diff --git a/WindowsAgent/WindowsAgent.csproj b/WindowsAgent/WindowsAgent.csproj index 337f6b8..c8f4d3d 100644 --- a/WindowsAgent/WindowsAgent.csproj +++ b/WindowsAgent/WindowsAgent.csproj @@ -11,9 +11,9 @@ https://github.com/hawkeye-stan/msfs-popout-panel-manager MSFSPopoutPanelManager.WindowsAgent x64 - 4.1.1.0 - 4.1.1.0 - 4.1.1.0 + 4.1.2.0 + 4.1.2.0 + 4.1.2.0 win-x64 Embedded Debug;Release;Local