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

Version 4.1.0 beta

This commit is contained in:
hawkeye 2024-02-29 01:11:56 -05:00
parent b2ca626439
commit 025246d6fa
23 changed files with 339 additions and 67 deletions

View file

@ -11,9 +11,9 @@
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl> <PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
<RootNamespace>MSFSPopoutPanelManager.DomainModel</RootNamespace> <RootNamespace>MSFSPopoutPanelManager.DomainModel</RootNamespace>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Version>4.1.0.1</Version> <Version>4.1.0.2</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion> <AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion> <FileVersion>4.1.0.2</FileVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>Embedded</DebugType> <DebugType>Embedded</DebugType>
<Configurations>Debug;Release;Local</Configurations> <Configurations>Debug;Release;Local</Configurations>

View file

@ -0,0 +1,11 @@
using MSFSPopoutPanelManager.Shared;
namespace MSFSPopoutPanelManager.DomainModel.Profile
{
public class FloatingPanel : ObservableObject
{
public bool IsEnabled { get; set; }
public string KeyBinding { get; set; }
}
}

View file

@ -18,15 +18,20 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
private void PanelConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) private void PanelConfig_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{ {
if (e.PropertyName == "FullScreen" && FullScreen) if (e.PropertyName == nameof(FullScreen) && FullScreen)
{ {
AlwaysOnTop = false; AlwaysOnTop = false;
HideTitlebar = false; HideTitlebar = false;
} }
else if (e.PropertyName == "TouchEnabled" && TouchEnabled) else if (e.PropertyName == nameof(TouchEnabled) && TouchEnabled)
{ {
AutoGameRefocus = true; AutoGameRefocus = true;
} }
else if (e.PropertyName == nameof(FloatingPanel))
{
if(!FloatingPanel.IsEnabled)
FloatingPanel.KeyBinding = null;
}
} }
public Guid Id { get; set; } public Guid Id { get; set; }
@ -53,6 +58,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
public bool AutoGameRefocus { get; set; } = true; public bool AutoGameRefocus { get; set; } = true;
public FloatingPanel FloatingPanel { get; set; } = new();
public PanelSource PanelSource { get; set; } = new(); public PanelSource PanelSource { get; set; } = new();
public FixedCameraConfig FixedCameraConfig { get; set; } = new(); public FixedCameraConfig FixedCameraConfig { get; set; } = new();
@ -85,6 +92,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
[JsonIgnore] [JsonIgnore]
public bool IsShownPanelSource { get; set; } public bool IsShownPanelSource { get; set; }
[JsonIgnore] public bool IsFloating { get; set; } = true;
[JsonIgnore] [JsonIgnore]
public bool IsDeletablePanel => PanelType != PanelType.HudBarWindow && PanelType != PanelType.RefocusDisplay && public bool IsDeletablePanel => PanelType != PanelType.HudBarWindow && PanelType != PanelType.RefocusDisplay &&
PanelType != PanelType.NumPadWindow; PanelType != PanelType.NumPadWindow;

View file

@ -21,6 +21,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
FullScreen, FullScreen,
TouchEnabled, TouchEnabled,
AutoGameRefocus, AutoGameRefocus,
AllowFloatPanel,
FloatPanelKeyBinding,
None None
} }
} }

View file

@ -34,6 +34,20 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
if (arg is PropertyChangedExtendedEventArgs { DisableSave: false }) if (arg is PropertyChangedExtendedEventArgs { DisableSave: false })
OnProfileChanged?.Invoke(this, EventArgs.Empty); OnProfileChanged?.Invoke(this, EventArgs.Empty);
if (arg is PropertyChangedExtendedEventArgs changedArg)
{
if (changedArg.ObjectName == QualifyFullName.Of(nameof(MSFSPopoutPanelManager.DomainModel.Profile.FloatingPanel)) &&
changedArg.PropertyName == nameof(FloatingPanel.IsEnabled))
{
if(PanelConfigs.Any(x => x.FloatingPanel.IsEnabled))
OnUseFloatingPanelChanged?.Invoke(this, true);
else
OnUseFloatingPanelChanged?.Invoke(this, false);
}
}
OnPanelConfigChanged(); OnPanelConfigChanged();
}; };
OnProfileChanged?.Invoke(this, EventArgs.Empty); OnProfileChanged?.Invoke(this, EventArgs.Empty);
@ -51,6 +65,7 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
InitializeChildPropertyChangeBinding(); InitializeChildPropertyChangeBinding();
} }
public event EventHandler<bool> OnUseFloatingPanelChanged;
public event EventHandler OnProfileChanged; public event EventHandler OnProfileChanged;
public Guid Id { get; set; } = Guid.NewGuid(); public Guid Id { get; set; } = Guid.NewGuid();

View file

@ -57,7 +57,7 @@ namespace MSFSPopoutPanelManager.MainApp
services.AddSingleton(s => new PanelPopOutOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>(), s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>())); services.AddSingleton(s => new PanelPopOutOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>(), s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>()));
services.AddSingleton(s => new PanelConfigurationOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>())); services.AddSingleton(s => new PanelConfigurationOrchestrator(SharedStorage, s.GetRequiredService<FlightSimOrchestrator>()));
services.AddSingleton(s => new FlightSimOrchestrator(SharedStorage)); services.AddSingleton(s => new FlightSimOrchestrator(SharedStorage));
services.AddSingleton(s => new KeyboardOrchestrator(SharedStorage, s.GetRequiredService<PanelPopOutOrchestrator>())); services.AddSingleton(s => new KeyboardOrchestrator(SharedStorage, s.GetRequiredService<PanelPopOutOrchestrator>(), s.GetRequiredService<PanelConfigurationOrchestrator>()));
services.AddSingleton(s => new HelpOrchestrator()); services.AddSingleton(s => new HelpOrchestrator());
services.AddSingleton(s => new OrchestratorUiHelper(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelPopOutOrchestrator>())); services.AddSingleton(s => new OrchestratorUiHelper(SharedStorage, s.GetRequiredService<PanelSourceOrchestrator>(), s.GetRequiredService<PanelPopOutOrchestrator>()));

View file

@ -52,9 +52,9 @@
x:Key="TextBlockLabel" x:Key="TextBlockLabel"
BasedOn="{StaticResource {x:Type TextBlock}}" BasedOn="{StaticResource {x:Type TextBlock}}"
TargetType="TextBlock"> TargetType="TextBlock">
<Setter Property="FontSize" Value="14" /> <Setter Property="FontSize" Value="13" />
<Setter Property="TextWrapping" Value="Wrap" /> <Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="Margin" Value="5,0,40,0" /> <Setter Property="Margin" Value="5,0,13,0" />
<Setter Property="LineHeight" Value="18" /> <Setter Property="LineHeight" Value="18" />
</Style> </Style>
<Style BasedOn="{StaticResource MaterialDesignIconForegroundButton}" TargetType="Button" /> <Style BasedOn="{StaticResource MaterialDesignIconForegroundButton}" TargetType="Button" />
@ -284,9 +284,9 @@
</Expander.Header> </Expander.Header>
<StackPanel <StackPanel
Margin="42,8,24,16" Margin="42,8,24,16"
Orientation="Horizontal" Orientation="Vertical"
TextBlock.Foreground="{DynamicResource MaterialDesignBody}"> TextBlock.Foreground="{DynamicResource MaterialDesignBody}">
<WrapPanel> <WrapPanel Orientation="Horizontal">
<ToggleButton <ToggleButton
x:Name="TglBtnAlwaysOnTop" x:Name="TglBtnAlwaysOnTop"
Margin="0,0,0,0" Margin="0,0,0,0"
@ -297,9 +297,6 @@
<TextBlock Style="{StaticResource TxtBlockDisableWhenFullScreen}" ToolTip="Set this panel to be always on top"> <TextBlock Style="{StaticResource TxtBlockDisableWhenFullScreen}" ToolTip="Set this panel to be always on top">
Always on Top Always on Top
</TextBlock> </TextBlock>
</WrapPanel>
<WrapPanel>
<ToggleButton <ToggleButton
x:Name="TglBtnFullScreen" x:Name="TglBtnFullScreen"
Margin="0,0,0,0" Margin="0,0,0,0"
@ -307,9 +304,6 @@
SourceUpdated="Data_SourceUpdated" SourceUpdated="Data_SourceUpdated"
Style="{StaticResource ToggleButton}" /> Style="{StaticResource ToggleButton}" />
<TextBlock Style="{StaticResource TextBlockLabel}" ToolTip="Expand this panel into full screen (emulate keystroke Alt-Enter)">Full Screen Mode</TextBlock> <TextBlock Style="{StaticResource TextBlockLabel}" ToolTip="Expand this panel into full screen (emulate keystroke Alt-Enter)">Full Screen Mode</TextBlock>
</WrapPanel>
<WrapPanel>
<ToggleButton <ToggleButton
x:Name="TglBtnHideTitlebar" x:Name="TglBtnHideTitlebar"
Margin="0,0,0,0" Margin="0,0,0,0"
@ -320,16 +314,37 @@
<TextBlock Style="{StaticResource TxtBlockDisableWhenFullScreen}" ToolTip="Hide the title bar for this panel"> <TextBlock Style="{StaticResource TxtBlockDisableWhenFullScreen}" ToolTip="Hide the title bar for this panel">
Hide Title Bar Hide Title Bar
</TextBlock> </TextBlock>
</WrapPanel>
<WrapPanel>
<ToggleButton <ToggleButton
x:Name="TglBtnAutoGameRefocus" x:Name="TglBtnAutoGameRefocus"
Margin="0,0,0,0" Margin="0,0,0,0"
IsChecked="{Binding DataItem.AutoGameRefocus, Mode=TwoWay, NotifyOnSourceUpdated=True}" IsChecked="{Binding DataItem.AutoGameRefocus, Mode=TwoWay, NotifyOnSourceUpdated=True}"
SourceUpdated="Data_SourceUpdated" SourceUpdated="Data_SourceUpdated"
Style="{StaticResource ToggleButton}" /> Style="{StaticResource ToggleButton}" />
<TextBlock Style="{StaticResource TextBlockLabel}" ToolTip="Automatic game refocus when clicking this panel or when using touch on this panel">Automatic Game Refocus</TextBlock> <TextBlock Style="{StaticResource TextBlockLabel}" ToolTip="Automatic game refocus when clicking this panel or when using touch on this panel">Auto Game Refocus</TextBlock>
<ToggleButton
x:Name="TglBtnAllowFloatPanel"
Margin="0"
IsChecked="{Binding DataItem.FloatingPanel.IsEnabled, Mode=TwoWay, NotifyOnSourceUpdated=True}"
SourceUpdated="Data_SourceUpdated"
Style="{StaticResource ToggleButton}" />
<TextBlock
Margin="5,0,10,0"
Style="{StaticResource TextBlockLabel}"
ToolTip="Set the pop out panel that can float above other windows">
Floating Window
</TextBlock>
<ComboBox
x:Name="ComboBoxFloatPanelKeyBinding"
Width="60"
Margin="0"
Padding="0"
VerticalAlignment="top"
Loaded="ComboBoxFloatPanelKeyBinding_OnLoaded"
PreviewMouseLeftButtonDown="ComboBoxFloatPanelKeyBinding_OnPreviewMouseLeftButtonDown"
SelectionChanged="ComboBoxFloatPanelKeyBinding_OnSelectionChanged"
ToolTip="Key binding to toggle floating pop out on and off"
Visibility="{c:Binding DataItem.FloatingPanel.IsEnabled}" />
</WrapPanel> </WrapPanel>
</StackPanel> </StackPanel>
</Expander> </Expander>

View file

@ -1,13 +1,15 @@
using System; using Microsoft.Extensions.DependencyInjection;
using MSFSPopoutPanelManager.DomainModel.Profile;
using MSFSPopoutPanelManager.MainApp.AppUserControl.PopOutPanelCard;
using MSFSPopoutPanelManager.MainApp.ViewModel;
using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Controls.Primitives; using System.Windows.Controls.Primitives;
using System.Windows.Input; using System.Windows.Input;
using Microsoft.Extensions.DependencyInjection;
using MSFSPopoutPanelManager.DomainModel.Profile;
using MSFSPopoutPanelManager.MainApp.AppUserControl.PopOutPanelCard;
using MSFSPopoutPanelManager.MainApp.ViewModel;
namespace MSFSPopoutPanelManager.MainApp.AppUserControl namespace MSFSPopoutPanelManager.MainApp.AppUserControl
{ {
@ -66,6 +68,75 @@ namespace MSFSPopoutPanelManager.MainApp.AppUserControl
if (!string.IsNullOrEmpty(param)) if (!string.IsNullOrEmpty(param))
_viewModel.PanelAttributeUpdatedCommand.Execute(param); _viewModel.PanelAttributeUpdatedCommand.Execute(param);
if (sender is ToggleButton { Name: "TglBtnAllowFloatPanel" })
ComboBoxFloatPanelKeyBinding.SelectedIndex = 0;
}
private void ComboBoxFloatPanelKeyBinding_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var comboBox = (ComboBox)sender;
if (comboBox.SelectedIndex is 0 or -1)
{
_viewModel.DataItem.FloatingPanel.KeyBinding = null;
return;
}
var selectedValue = comboBox.SelectedValue.ToString();
if (_viewModel.ActiveProfile.PanelConfigs.Any(x => x.FloatingPanel.KeyBinding == selectedValue && x.Id != _viewModel.DataItem.Id))
comboBox.SelectedIndex = 0;
_viewModel.DataItem.FloatingPanel.KeyBinding = selectedValue;
}
private readonly List<string> _floatKeyBindings = new()
{
"",
"Ctrl-1",
"Ctrl-2",
"Ctrl-3",
"Ctrl-4",
"Ctrl-5",
"Ctrl-6",
"Ctrl-7",
"Ctrl-8",
"Ctrl-9",
"Ctrl-0"
};
private void ComboBoxFloatPanelKeyBinding_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
BindFloatPanelKeyBinding();
}
private void ComboBoxFloatPanelKeyBinding_OnLoaded(object sender, RoutedEventArgs e)
{
BindFloatPanelKeyBinding();
}
private void BindFloatPanelKeyBinding()
{
var items = new List<string>();
items.AddRange(_floatKeyBindings);
foreach (var panelConfig in _viewModel.ActiveProfile.PanelConfigs)
{
if (panelConfig.FloatingPanel.KeyBinding != null && panelConfig.Id != _viewModel.DataItem.Id)
items.Remove(panelConfig.FloatingPanel.KeyBinding);
}
ComboBoxFloatPanelKeyBinding.ItemsSource = items;
var index = items.ToList().FindIndex(x => string.Equals(x, _viewModel.DataItem.FloatingPanel.KeyBinding, StringComparison.CurrentCultureIgnoreCase));
if (index == -1)
return;
this.ComboBoxFloatPanelKeyBinding.SelectedIndex = index;
} }
} }
} }

View file

@ -14,9 +14,9 @@
<RootNamespace>MSFSPopoutPanelManager.MainApp</RootNamespace> <RootNamespace>MSFSPopoutPanelManager.MainApp</RootNamespace>
<ApplicationIcon>logo.ico</ApplicationIcon> <ApplicationIcon>logo.ico</ApplicationIcon>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Version>4.1.0.1</Version> <Version>4.1.0.2</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion> <AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion> <FileVersion>4.1.0.2</FileVersion>
<DebugType>embedded</DebugType> <DebugType>embedded</DebugType>
<SatelliteResourceLanguages>en</SatelliteResourceLanguages> <SatelliteResourceLanguages>en</SatelliteResourceLanguages>
<!-- Publishing options --> <!-- Publishing options -->

View file

@ -108,7 +108,7 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel
ActiveProfile.CurrentMoveResizePanelId = DataItem.Id; ActiveProfile.CurrentMoveResizePanelId = DataItem.Id;
if (!AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled) if (!AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled)
InputHookManager.StartKeyboardHook(); InputHookManager.StartKeyboardHook("KeyboardShortcut");
InputHookManager.OnKeyUp -= HandleKeyUpEvent; InputHookManager.OnKeyUp -= HandleKeyUpEvent;
InputHookManager.OnKeyUp += HandleKeyUpEvent; InputHookManager.OnKeyUp += HandleKeyUpEvent;
@ -118,7 +118,7 @@ namespace MSFSPopoutPanelManager.MainApp.ViewModel
ActiveProfile.CurrentMoveResizePanelId = Guid.Empty; ActiveProfile.CurrentMoveResizePanelId = Guid.Empty;
if (!AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled) if (!AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled)
InputHookManager.EndKeyboardHook(); InputHookManager.EndKeyboardHook("KeyboardShortcut");
InputHookManager.OnKeyUp -= HandleKeyUpEvent; InputHookManager.OnKeyUp -= HandleKeyUpEvent;
} }

View file

@ -58,7 +58,7 @@ namespace MSFSPopoutPanelManager.Orchestration
_panelConfigurationOrchestrator.EndConfiguration(); _panelConfigurationOrchestrator.EndConfiguration();
_panelConfigurationOrchestrator.EndTouchHook(); _panelConfigurationOrchestrator.EndTouchHook();
InputHookManager.EndKeyboardHook(); InputHookManager.EndKeyboardHookForced();
_flightSimOrchestrator.EndSimConnectServer(true); _flightSimOrchestrator.EndSimConnectServer(true);
} }

View file

@ -1,46 +1,112 @@
using MSFSPopoutPanelManager.WindowsAgent; using System.Linq;
using System.Security.Cryptography.X509Certificates;
using MSFSPopoutPanelManager.DomainModel.Profile;
using MSFSPopoutPanelManager.WindowsAgent;
namespace MSFSPopoutPanelManager.Orchestration namespace MSFSPopoutPanelManager.Orchestration
{ {
public class KeyboardOrchestrator : BaseOrchestrator public class KeyboardOrchestrator : BaseOrchestrator
{ {
private readonly PanelPopOutOrchestrator _panelPopOutOrchestrator; private readonly PanelPopOutOrchestrator _panelPopOutOrchestrator;
private readonly PanelConfigurationOrchestrator _panelConfigurationOrchestrator;
public KeyboardOrchestrator(SharedStorage sharedStorage, PanelPopOutOrchestrator panelPopOutOrchestrator) : base(sharedStorage) public KeyboardOrchestrator(SharedStorage sharedStorage, PanelPopOutOrchestrator panelPopOutOrchestrator, PanelConfigurationOrchestrator panelConfigurationOrchestrator) : base(sharedStorage)
{ {
_panelPopOutOrchestrator = panelPopOutOrchestrator; _panelPopOutOrchestrator = panelPopOutOrchestrator;
_panelConfigurationOrchestrator = panelConfigurationOrchestrator;
} }
public void Initialize() public void Initialize()
{ {
if (AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled) if (AppSettingData.ApplicationSetting.KeyboardShortcutSetting.IsEnabled)
{ {
InputHookManager.StartKeyboardHook(); InputHookManager.StartKeyboardHook("KeyboardShortcut");
InputHookManager.OnKeyUp -= HandleKeyboardHookKeyUpEvent; InputHookManager.OnKeyUp -= HandleShortcutKeyboardHookKeyUpEvent;
InputHookManager.OnKeyUp += HandleKeyboardHookKeyUpEvent; InputHookManager.OnKeyUp += HandleShortcutKeyboardHookKeyUpEvent;
} }
AppSettingData.ApplicationSetting.OnIsUsedKeyboardShortcutChanged += (_, e) => AppSettingData.ApplicationSetting.OnIsUsedKeyboardShortcutChanged += (_, e) =>
{ {
if (e) if (e)
{ {
InputHookManager.StartKeyboardHook(); InputHookManager.StartKeyboardHook("KeyboardShortcut");
InputHookManager.OnKeyUp -= HandleKeyboardHookKeyUpEvent; InputHookManager.OnKeyUp -= HandleShortcutKeyboardHookKeyUpEvent;
InputHookManager.OnKeyUp += HandleKeyboardHookKeyUpEvent; InputHookManager.OnKeyUp += HandleShortcutKeyboardHookKeyUpEvent;
} }
else else
{ {
InputHookManager.EndKeyboardHook(); InputHookManager.EndKeyboardHook("KeyboardShortcut");
InputHookManager.OnKeyUp -= HandleKeyboardHookKeyUpEvent; InputHookManager.OnKeyUp -= HandleShortcutKeyboardHookKeyUpEvent;
}
};
if (ProfileData.ActiveProfile.PanelConfigs.Any(x => x.FloatingPanel.IsEnabled))
{
InputHookManager.StartKeyboardHook("FloatingPanel");
InputHookManager.OnKeyUp -= HandleFloatingPanelKeyboardHookKeyUpEvent;
InputHookManager.OnKeyUp += HandleFloatingPanelKeyboardHookKeyUpEvent;
}
ProfileData.ActiveProfile.OnUseFloatingPanelChanged += (_, e) =>
{
if (e)
{
InputHookManager.StartKeyboardHook("FloatingPanel");
InputHookManager.OnKeyUp -= HandleFloatingPanelKeyboardHookKeyUpEvent;
InputHookManager.OnKeyUp += HandleFloatingPanelKeyboardHookKeyUpEvent;
}
else
{
InputHookManager.EndKeyboardHook("FloatingPanel");
InputHookManager.OnKeyUp -= HandleFloatingPanelKeyboardHookKeyUpEvent;
} }
}; };
} }
public async void HandleKeyboardHookKeyUpEvent(object sender, KeyUpEventArgs e) public async void HandleShortcutKeyboardHookKeyUpEvent(object sender, KeyUpEventArgs e)
{ {
// Start pop out // Start pop out
if (e.IsHoldControl && e.IsHoldShift && e.KeyCode.ToUpper() == AppSettingData.ApplicationSetting.KeyboardShortcutSetting.StartPopOutKeyBinding) if (e.IsHoldControl && e.IsHoldShift && e.KeyCode.ToUpper() ==
AppSettingData.ApplicationSetting.KeyboardShortcutSetting.StartPopOutKeyBinding)
{
await _panelPopOutOrchestrator.ManualPopOut(); await _panelPopOutOrchestrator.ManualPopOut();
return;
}
}
public void HandleFloatingPanelKeyboardHookKeyUpEvent(object sender, KeyUpEventArgs e)
{
if (e.IsHoldControl)
{
switch (e.KeyCode)
{
case "D1":
case "D2":
case "D3":
case "D4":
case "D5":
case "D6":
case "D7":
case "D8":
case "D9":
case "D0":
_panelConfigurationOrchestrator.ToggleFloatPanel($"Ctrl-{e.KeyCode[1..]}");
break;
case "NumPad1":
case "NumPad2":
case "NumPad3":
case "NumPad4":
case "NumPad5":
case "NumPad6":
case "NumPad7":
case "NumPad8":
case "NumPad9":
case "NumPad0":
_panelConfigurationOrchestrator.ToggleFloatPanel($"Ctrl-{e.KeyCode[6..]}");
break;
}
}
} }
} }
} }

View file

@ -11,9 +11,9 @@
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl> <PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
<RootNamespace>MSFSPopoutPanelManager.Orchestration</RootNamespace> <RootNamespace>MSFSPopoutPanelManager.Orchestration</RootNamespace>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Version>4.1.0.1</Version> <Version>4.1.0.2</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion> <AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion> <FileVersion>4.1.0.2</FileVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>Embedded</DebugType> <DebugType>Embedded</DebugType>
<Configurations>Debug;Release;Local</Configurations> <Configurations>Debug;Release;Local</Configurations>

View file

@ -154,5 +154,34 @@ namespace MSFSPopoutPanelManager.Orchestration
ProfileData.WriteProfiles(); ProfileData.WriteProfiles();
} }
} }
public void ToggleFloatPanel(string keyBinding)
{
var panel = ActiveProfile.PanelConfigs.FirstOrDefault(x => string.Equals(x.FloatingPanel.KeyBinding, keyBinding, StringComparison.CurrentCultureIgnoreCase));
if (panel == null)
return;
if (!panel.FloatingPanel.IsEnabled || panel.FullScreen)
return;
if (panel.PanelType is not (PanelType.CustomPopout or PanelType.BuiltInPopout))
return;
if (panel.IsPopOutSuccess == null || !(bool)panel.IsPopOutSuccess)
return;
if (!panel.IsFloating)
{
panel.IsFloating = true;
WindowActionManager.RestoreWindow(panel.PanelHandle);
WindowActionManager.ApplyAlwaysOnTop(panel.PanelHandle, panel.PanelType, true);
}
else
{
panel.IsFloating = false;
WindowActionManager.MinimizeWindow(panel.PanelHandle);
}
}
} }
} }

View file

@ -2,12 +2,14 @@
* Added new method to select panel source for an aircraft profile using fixed camera view instead of relying saved custom camera view. Previous method of using saved custom camera view is still available to use if desire. * Added new method to select panel source for an aircraft profile using fixed camera view instead of relying saved custom camera view. Previous method of using saved custom camera view is still available to use if desire.
Video showing how to create a new profile using the new panel selection method: https://vimeo.com/917361559 Video showing how to create a new aircraft profile using the new panel selection method: https://vimeo.com/917361559
Video showing how to update existing profile to use the new panel selection method: https://vimeo.com/917364912 Video showing how to update existing aircraft profile to use the new panel selection method: https://vimeo.com/917364912
* Added new virtual number pad to be used for touch enabled screen. This number pad will first focus the game window before sending num pad keystroke to the game. * Added new virtual number pad to be used for touch enabled screen. This number pad will first focus the game window before sending num pad keystroke to the game.
* Added new feature to allow pop up panel as floating window. You can assign hotkeys (Ctrl-0 to Ctrl-9) to have the pop out to toggle either showing on screen or minimize.
* Added a new button to easily close all Pop Out Panel Manager's managed pop outs. * Added a new button to easily close all Pop Out Panel Manager's managed pop outs.
* Fixed few reported bugs in the application. * Fixed few reported bugs in the application.

14
Shared/QualifyFullName.cs Normal file
View file

@ -0,0 +1,14 @@
namespace MSFSPopoutPanelManager.Shared
{
public static class QualifyFullName
{
public static string Of(string _, [System.Runtime.CompilerServices.CallerArgumentExpression("_")] string fullTypeName = "")
{
if (fullTypeName.StartsWith("nameof(") && fullTypeName.EndsWith(")"))
{
return fullTypeName[7..^1];
}
return fullTypeName;
}
}
}

View file

@ -11,9 +11,9 @@
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl> <PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
<RootNamespace>MSFSPopoutPanelManager.Shared</RootNamespace> <RootNamespace>MSFSPopoutPanelManager.Shared</RootNamespace>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Version>4.1.0.1</Version> <Version>4.1.0.2</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion> <AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion> <FileVersion>4.1.0.2</FileVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>Embedded</DebugType> <DebugType>Embedded</DebugType>
<Configurations>Debug;Release;Local</Configurations> <Configurations>Debug;Release;Local</Configurations>

View file

@ -11,9 +11,9 @@
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl> <PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
<RootNamespace>MSFSPopoutPanelManager.SimConnectAgent</RootNamespace> <RootNamespace>MSFSPopoutPanelManager.SimConnectAgent</RootNamespace>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Version>4.1.0.1</Version> <Version>4.1.0.2</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion> <AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion> <FileVersion>4.1.0.2</FileVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>Embedded</DebugType> <DebugType>Embedded</DebugType>
<Configurations>Debug;Release;Local</Configurations> <Configurations>Debug;Release;Local</Configurations>

View file

@ -5,15 +5,17 @@
* Added new method to select panel source for an aircraft profile using fixed camera view instead of relying saved custom camera view. Previous method of using saved custom camera view is still available to use if desire. * Added new method to select panel source for an aircraft profile using fixed camera view instead of relying saved custom camera view. Previous method of using saved custom camera view is still available to use if desire.
Video showing how to create a new profile using the new panel selection method: https://vimeo.com/917361559 Video showing how to create a new aircraft profile using the new panel selection method: https://vimeo.com/917361559
Video showing how to update existing profile to use the new panel selection method: https://vimeo.com/917364912 Video showing how to update existing aircraft profile to use the new panel selection method: https://vimeo.com/917364912
* Added new virtual number pad to be used for touch enabled screen. This number pad will first focus the game window before sending num pad keystroke to the game. * Added new virtual number pad to be used for touch enabled screen. This number pad will first focus the game window before sending num pad keystroke to the game.
* Added new feature to allow pop up panel as floating window. You can assign hotkeys (Ctrl-0 to Ctrl-9) to have the pop out to toggle either showing on screen or minimize.
* Added a new button to easily close all Pop Out Panel Manager's managed pop outs. * Added a new button to easily close all Pop Out Panel Manager's managed pop outs.
* Fixed few outstanding bugs in the application. * Fixed few reported bugs in the application.
## Version 4.0.3 ## Version 4.0.3

View file

@ -1,6 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Linq;
using WindowsHook; using WindowsHook;
namespace MSFSPopoutPanelManager.WindowsAgent namespace MSFSPopoutPanelManager.WindowsAgent
@ -15,6 +17,8 @@ namespace MSFSPopoutPanelManager.WindowsAgent
private static IKeyboardMouseEvents _keyboardHook; private static IKeyboardMouseEvents _keyboardHook;
public static event EventHandler<KeyUpEventArgs> OnKeyUp; public static event EventHandler<KeyUpEventArgs> OnKeyUp;
private static List<string> _keyboardHookSubscribers = new List<string>();
public static void StartMouseHook() public static void StartMouseHook()
{ {
if (_mouseHook == null) if (_mouseHook == null)
@ -51,12 +55,12 @@ namespace MSFSPopoutPanelManager.WindowsAgent
OnLeftClick?.Invoke(null, new Point(e.X, e.Y)); OnLeftClick?.Invoke(null, new Point(e.X, e.Y));
} }
public static void StartKeyboardHook() public static void StartKeyboardHook(string subscriber)
{ {
if (_keyboardHook != null) if(!_keyboardHookSubscribers.Contains(subscriber))
EndKeyboardHook(); _keyboardHookSubscribers.Add(subscriber);
if (_keyboardHook == null) if (_keyboardHook == null && _keyboardHookSubscribers.Count > 0)
{ {
Debug.WriteLine("Starting Keyboard Hook..."); Debug.WriteLine("Starting Keyboard Hook...");
@ -65,14 +69,35 @@ namespace MSFSPopoutPanelManager.WindowsAgent
} }
} }
public static void EndKeyboardHook() public static void EndKeyboardHook(string subscriber)
{ {
if (_keyboardHook != null) _keyboardHookSubscribers.Remove(subscriber);
if (_keyboardHook != null && _keyboardHookSubscribers.Count == 0)
{ {
Debug.WriteLine("Ending Keyboard Hook..."); Debug.WriteLine("Ending Keyboard Hook...");
_keyboardHook.KeyUp -= HandleKeyboardHookKeyUp; _keyboardHook.KeyUp -= HandleKeyboardHookKeyUp;
_keyboardHook.Dispose(); _keyboardHook.Dispose();
_keyboardHook = null; _keyboardHook = null;
if (OnKeyUp != null)
{
foreach (Delegate d in OnKeyUp.GetInvocationList())
OnKeyUp -= (EventHandler<KeyUpEventArgs>)d;
}
}
}
public static void EndKeyboardHookForced()
{
_keyboardHookSubscribers.Clear();
if (_keyboardHook != null)
{
Debug.WriteLine("Ending Keyboard Hook (forced)...");
_keyboardHook.KeyUp -= HandleKeyboardHookKeyUp;
_keyboardHook.Dispose();
_keyboardHook = null;
} }
if (OnKeyUp != null) if (OnKeyUp != null)

View file

@ -89,6 +89,11 @@ namespace MSFSPopoutPanelManager.WindowsAgent
PInvoke.ShowWindow(hwnd, PInvokeConstant.SW_MINIMIZE); PInvoke.ShowWindow(hwnd, PInvokeConstant.SW_MINIMIZE);
} }
public static void RestoreWindow(IntPtr hwnd)
{
PInvoke.ShowWindow(hwnd, PInvokeConstant.SW_RESTORE);
}
public static void BringWindowToForeground(IntPtr hwnd) public static void BringWindowToForeground(IntPtr hwnd)
{ {
PInvoke.ShowWindowAsync(new HandleRef(null, hwnd), PInvokeConstant.SW_RESTORE); PInvoke.ShowWindowAsync(new HandleRef(null, hwnd), PInvokeConstant.SW_RESTORE);

View file

@ -110,6 +110,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent
case PInvokeConstant.EVENT_OBJECT_STATECHANGE: case PInvokeConstant.EVENT_OBJECT_STATECHANGE:
if (!ActiveProfile.IsLocked) if (!ActiveProfile.IsLocked)
{ {
if (panelConfig.FloatingPanel.IsEnabled && panelConfig.IsFloating) // do not update coordinate if floating window
return;
Thread.Sleep(300); Thread.Sleep(300);
UpdatePanelCoordinates(panelConfig); UpdatePanelCoordinates(panelConfig);
} }
@ -135,6 +138,9 @@ namespace MSFSPopoutPanelManager.WindowsAgent
break; break;
} }
if (panelConfig.FloatingPanel.IsEnabled && !panelConfig.IsFloating)
return;
switch (wp.showCmd) switch (wp.showCmd)
{ {
case PInvokeConstant.SW_SHOWMAXIMIZED when _prevShowWinCmd == PInvokeConstant.SW_SHOWNORMAL: case PInvokeConstant.SW_SHOWMAXIMIZED when _prevShowWinCmd == PInvokeConstant.SW_SHOWNORMAL:

View file

@ -11,9 +11,9 @@
<PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl> <PackageProjectUrl>https://github.com/hawkeye-stan/msfs-popout-panel-manager</PackageProjectUrl>
<RootNamespace>MSFSPopoutPanelManager.WindowsAgent</RootNamespace> <RootNamespace>MSFSPopoutPanelManager.WindowsAgent</RootNamespace>
<Platforms>x64</Platforms> <Platforms>x64</Platforms>
<Version>4.1.0.1</Version> <Version>4.1.0.2</Version>
<AssemblyVersion>4.1.0.1</AssemblyVersion> <AssemblyVersion>4.1.0.2</AssemblyVersion>
<FileVersion>4.1.0.1</FileVersion> <FileVersion>4.1.0.2</FileVersion>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<DebugType>Embedded</DebugType> <DebugType>Embedded</DebugType>
<Configurations>Debug;Release;Local</Configurations> <Configurations>Debug;Release;Local</Configurations>