mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-11-22 05:40:11 +00:00
Version 3.2 Release
This commit is contained in:
parent
39d4d98be6
commit
973ebd3dd7
18 changed files with 164 additions and 72 deletions
|
@ -16,6 +16,8 @@ EndProject
|
|||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{15FC98CD-0A69-437B-A5E5-67D025DB5CDC}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.gitignore = .gitignore
|
||||
autoupdate.xml = autoupdate.xml
|
||||
latestreleasenotes.txt = latestreleasenotes.txt
|
||||
LICENSE = LICENSE
|
||||
README.md = README.md
|
||||
VERSION.md = VERSION.md
|
||||
|
|
|
@ -141,7 +141,7 @@ namespace MSFSPopoutPanelManager.Model
|
|||
{
|
||||
public AutoPopOutPanelsWaitDelay()
|
||||
{
|
||||
ReadyToFlyButton = 2;
|
||||
ReadyToFlyButton = 4;
|
||||
InitialCockpitView = 2;
|
||||
InstrumentationPowerOn = 2;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using MSFSPopoutPanelManager.Shared;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Threading;
|
||||
|
@ -9,6 +10,9 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
{
|
||||
public static Bitmap TakeScreenShot(IntPtr windowHandle)
|
||||
{
|
||||
if (!PInvoke.IsWindow(windowHandle))
|
||||
throw new PopoutManagerException("Pop out windows were closed unexpectedly.");
|
||||
|
||||
// Set window to foreground so nothing can hide the window
|
||||
PInvoke.SetForegroundWindow(windowHandle);
|
||||
Thread.Sleep(300);
|
||||
|
@ -16,19 +20,30 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
Rectangle rectangle;
|
||||
PInvoke.GetWindowRect(windowHandle, out rectangle);
|
||||
|
||||
var left = rectangle.Left;
|
||||
var top = rectangle.Top;
|
||||
var width = rectangle.Right - rectangle.Left;
|
||||
var height = rectangle.Bottom - rectangle.Top;
|
||||
Rectangle clientRectangle;
|
||||
PInvoke.GetClientRect(windowHandle, out clientRectangle);
|
||||
|
||||
var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
|
||||
// Take a screen shot by removing the titlebar of the window
|
||||
var left = rectangle.Left;
|
||||
var top = rectangle.Top + (rectangle.Height - clientRectangle.Height) - 8; // 8 pixels adjustments
|
||||
|
||||
var bmp = new Bitmap(clientRectangle.Width, clientRectangle.Height, PixelFormat.Format24bppRgb);
|
||||
|
||||
using (Graphics g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.CopyFromScreen(new Point(left, top), Point.Empty, rectangle.Size);
|
||||
}
|
||||
|
||||
return bmp;
|
||||
// Place the above image in the same canvas size as before
|
||||
Bitmap backingImage = new Bitmap(rectangle.Width, rectangle.Height);
|
||||
using (Graphics gfx = Graphics.FromImage(backingImage))
|
||||
using (SolidBrush brush = new SolidBrush(Color.FromArgb(255, 0, 0)))
|
||||
{
|
||||
gfx.FillRectangle(brush, 0, 0, rectangle.Width, rectangle.Height);
|
||||
gfx.DrawImage(bmp, new Point(0, top));
|
||||
}
|
||||
|
||||
return backingImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using WindowsInput.Events;
|
||||
|
||||
namespace MSFSPopoutPanelManager.Provider
|
||||
{
|
||||
public class InputEmulationManager
|
||||
{
|
||||
const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
|
||||
const uint MOUSEEVENTF_MOVE = 0x0001;
|
||||
const uint MOUSEEVENTF_LEFTDOWN = 0x02;
|
||||
const uint MOUSEEVENTF_LEFTUP = 0x04;
|
||||
const uint KEYEVENTF_EXTENDEDKEY = 0x01;
|
||||
|
@ -30,6 +33,9 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
public static void PopOutPanel(int x, int y)
|
||||
{
|
||||
LeftClick(x, y);
|
||||
Thread.Sleep(300);
|
||||
|
||||
PInvoke.SetCursorPos(x, y);
|
||||
Thread.Sleep(300);
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
public static void EndHook()
|
||||
{
|
||||
if (_mouseHook == null)
|
||||
if (_mouseHook != null)
|
||||
{
|
||||
_mouseHook.MouseDownExt -= HandleMouseHookMouseDownExt;
|
||||
_mouseHook.Dispose();
|
||||
|
|
|
@ -39,10 +39,14 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
public class PInvoke
|
||||
{
|
||||
[DllImport("user32")]
|
||||
public static extern int EnumWindows(CallBack x, int y);
|
||||
public static extern int EnumWindows(CallBack callback, int lParam);
|
||||
|
||||
[DllImport("user32")]
|
||||
private static extern bool EnumChildWindows(IntPtr window, CallBack callback, IntPtr lParam);
|
||||
public static extern bool EnumChildWindows(IntPtr window, CallBack callback, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern int GetClassName(IntPtr hWnd, StringBuilder strPtrClassName, Int32 nMaxCount);
|
||||
|
@ -81,6 +85,10 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool IsWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
|
||||
|
||||
|
|
|
@ -61,10 +61,18 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
break;
|
||||
case PanelConfigPropertyName.Left:
|
||||
case PanelConfigPropertyName.Top:
|
||||
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
|
||||
if (panelConfig.HideTitlebar)
|
||||
return;
|
||||
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, true);
|
||||
break;
|
||||
case PanelConfigPropertyName.Width:
|
||||
case PanelConfigPropertyName.Height:
|
||||
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
|
||||
if (panelConfig.HideTitlebar)
|
||||
return;
|
||||
|
||||
int orignalLeft = panelConfig.Left;
|
||||
PInvoke.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height, true);
|
||||
MSFSBugPanelShiftWorkaround(panelConfig.PanelHandle, orignalLeft, panelConfig.Top, panelConfig.Width, panelConfig.Height);
|
||||
|
@ -92,6 +100,10 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
{
|
||||
var panelConfig = UserProfile.PanelConfigs[index];
|
||||
|
||||
// Do not allow changes to panel if title bar is hidden. This will cause the panel to resize incorrectly
|
||||
if (panelConfig.HideTitlebar)
|
||||
return;
|
||||
|
||||
int orignalLeft = panelConfig.Left;
|
||||
|
||||
switch (panelConfigItem.PanelConfigProperty)
|
||||
|
|
|
@ -3,6 +3,7 @@ using MSFSPopoutPanelManager.Shared;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
|
@ -115,57 +116,35 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
try
|
||||
{
|
||||
for (var i = 0; i < UserProfile.PanelSourceCoordinates.Count; i++)
|
||||
// PanelIndex starts at 1
|
||||
for (var i = 1; i <= UserProfile.PanelSourceCoordinates.Count; i++)
|
||||
{
|
||||
PopoutPanel(UserProfile.PanelSourceCoordinates[i].X, UserProfile.PanelSourceCoordinates[i].Y);
|
||||
PopoutPanel(UserProfile.PanelSourceCoordinates[i - 1].X, UserProfile.PanelSourceCoordinates[i - 1].Y);
|
||||
|
||||
if (i == 0)
|
||||
if (i > 1)
|
||||
{
|
||||
int retry = 0;
|
||||
while (retry < RETRY_COUNT)
|
||||
{
|
||||
PInvoke.EnumWindows(new PInvoke.CallBack(EnumCustomPopoutCallBack), 0);
|
||||
|
||||
if (GetPopoutPanelCountByType(PanelType.CustomPopout) == 0)
|
||||
retry += 1;
|
||||
else
|
||||
{
|
||||
var panel = GetCustomPopoutPanelByIndex(i);
|
||||
panel.PanelName = $"Panel{i + 1}";
|
||||
PInvoke.SetWindowText(panel.PanelHandle, panel.PanelName + " (Custom)");
|
||||
break;
|
||||
}
|
||||
SeparatePanel(i - 1, _panels[0].PanelHandle); // The joined panel is always the first panel that got popped out
|
||||
}
|
||||
|
||||
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != i + 1)
|
||||
var handle = PInvoke.FindWindow("AceApp", String.Empty);
|
||||
|
||||
if(handle == IntPtr.Zero && i == 1)
|
||||
throw new PopoutManagerException("Unable to pop out the first panel. Please check the first panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
|
||||
}
|
||||
if (i >= 1) // only separate with 2 or more panels
|
||||
{
|
||||
int retry = 0;
|
||||
while (retry < RETRY_COUNT)
|
||||
{
|
||||
SeparatePanel(i, _panels[0].PanelHandle); // The joined panel is always the first panel that got popped out
|
||||
PInvoke.EnumWindows(new PInvoke.CallBack(EnumCustomPopoutCallBack), i);
|
||||
else if(handle == IntPtr.Zero)
|
||||
throw new PopoutManagerException($"Unable to pop out panel number {i}. Please check panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
|
||||
|
||||
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != i + 1)
|
||||
retry += 1;
|
||||
else
|
||||
{
|
||||
// Panel has successfully popped out
|
||||
var panel = GetCustomPopoutPanelByIndex(i);
|
||||
var panelInfo = GetPanelWindowInfo(handle);
|
||||
panelInfo.PanelIndex = i;
|
||||
panelInfo.PanelName = $"Panel{i}";
|
||||
_panels.Add(panelInfo);
|
||||
|
||||
PInvoke.MoveWindow(panel.PanelHandle, 0, 0, 800, 600, true);
|
||||
panel.PanelName = $"Panel{i + 1}";
|
||||
PInvoke.SetWindowText(panel.PanelHandle, panel.PanelName + " (Custom)");
|
||||
break;
|
||||
}
|
||||
PInvoke.SetWindowText(panelInfo.PanelHandle, panelInfo.PanelName + " (Custom)");
|
||||
|
||||
if (i > 1)
|
||||
PInvoke.MoveWindow(panelInfo.PanelHandle, 0, 0, 800, 600, true);
|
||||
}
|
||||
|
||||
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != i + 1)
|
||||
throw new PopoutManagerException($"Unable to pop out panel number {i + 1}. Please check panel's number circle is positioned inside the panel, check for panel obstruction, and check if panel can be popped out. Pop out process stopped.");
|
||||
}
|
||||
}
|
||||
_currentPanelIndex = _panels.Count;
|
||||
|
||||
// Performance validation, make sure the number of pop out panels is equal to the number of selected panel
|
||||
if (GetPopoutPanelCountByType(PanelType.CustomPopout) != UserProfile.PanelSourceCoordinates.Count)
|
||||
|
@ -293,8 +272,6 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
private void PopoutPanel(int x, int y)
|
||||
{
|
||||
InputEmulationManager.LeftClick(x, y);
|
||||
Thread.Sleep(200);
|
||||
InputEmulationManager.PopOutPanel(x, y);
|
||||
}
|
||||
|
||||
|
@ -309,13 +286,10 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
// Find the magnifying glass coordinate
|
||||
var point = AnalyzeMergedWindows(hwnd);
|
||||
|
||||
if (point.Y <= 39) // false positive
|
||||
return;
|
||||
|
||||
InputEmulationManager.LeftClick(point.X, point.Y);
|
||||
}
|
||||
|
||||
public bool EnumCustomPopoutCallBack(IntPtr hwnd, int index)
|
||||
public bool EnumCustomPopoutCallBack(IntPtr hwnd, int lParam)
|
||||
{
|
||||
var panelInfo = GetPanelWindowInfo(hwnd);
|
||||
|
||||
|
@ -324,7 +298,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
if (!_panels.Exists(x => x.PanelHandle == hwnd))
|
||||
{
|
||||
Interlocked.Increment(ref _currentPanelIndex);
|
||||
panelInfo.PanelIndex = _currentPanelIndex; // PanelIndex starts at 1
|
||||
panelInfo.PanelIndex = _currentPanelIndex;
|
||||
_panels.Add(panelInfo);
|
||||
}
|
||||
}
|
||||
|
@ -332,7 +306,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
return true;
|
||||
}
|
||||
|
||||
public bool EnumBuiltinPopoutCallBack(IntPtr hwnd, int index)
|
||||
public bool EnumBuiltinPopoutCallBack(IntPtr hwnd, int lParam)
|
||||
{
|
||||
var panelInfo = GetPanelWindowInfo(hwnd);
|
||||
|
||||
|
@ -360,6 +334,9 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
Interlocked.Increment(ref _currentPanelIndex);
|
||||
panelInfo.PanelIndex = _currentPanelIndex;
|
||||
_panels.Add(panelInfo);
|
||||
|
||||
// Apply always on top to these panels
|
||||
WindowManager.ApplyAlwaysOnTop(panelInfo.PanelHandle, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,9 +351,16 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
{
|
||||
var caption = PInvoke.GetWindowText(hwnd);
|
||||
|
||||
Rectangle rectangle;
|
||||
PInvoke.GetWindowRect(hwnd, out rectangle);
|
||||
|
||||
var panelInfo = new PanelConfig();
|
||||
panelInfo.PanelHandle = hwnd;
|
||||
panelInfo.PanelName = caption;
|
||||
panelInfo.Top = rectangle.Top;
|
||||
panelInfo.Left = rectangle.Left;
|
||||
panelInfo.Width = rectangle.Width;
|
||||
panelInfo.Height = rectangle.Height;
|
||||
|
||||
if (String.IsNullOrEmpty(caption) || caption.IndexOf("Custom") > -1)
|
||||
panelInfo.PanelType = PanelType.CustomPopout;
|
||||
|
@ -411,6 +395,9 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
{
|
||||
var sourceImage = ImageOperation.TakeScreenShot(hwnd);
|
||||
|
||||
if (sourceImage == null)
|
||||
return new Point(0, 0);
|
||||
|
||||
Rectangle rectangle;
|
||||
PInvoke.GetClientRect(hwnd, out rectangle);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="MouseKeyHook" Version="5.6.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||
<PackageReference Include="WindowsInput" Version="6.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -137,6 +137,8 @@ The user plane profile data and application settings data are stored as JSON fil
|
|||
|
||||
## Current Known Issue
|
||||
|
||||
* Automatic power on for Auto Pop Out Panel feature will not work if you're using any flight control hardware (such as Honeycomb Alpha or Bravo) that permanently binds the master battery switch or master avionics switch. If the hardware control switch is in the off position, pop out manager won't be able to temporary turn on the instrumentation panels to pop them out. This seems to be a bug on Asobo side and only affects the G1000 instrumentation at the moment.
|
||||
|
||||
* Sometimes when using the auto-panning feature, the keyboard combination of Ctrl-Alt-0 and Alt-0 do not work to save and load panel panning coordinates. First try to restart the flightsim and it usually fixes the problem. Otherwise, the only way to fix this is to redo the profile if you want the auto-panning feature since the camera angle is only being saved during the initial creation of the profile. The is another MSFS bug.
|
||||
|
||||
* Current application package size is bigger than previous version of the application because it is not a single EXE file package. With added feature of exception logging and stack trace to support user feedback and troubleshooting, a Single EXE package in .NET 5.0 as well as .NET 6.0 has a bug that stack trace information is not complete. Hopefully, Microsoft will be fixing this problem.
|
||||
|
@ -180,3 +182,5 @@ Thank you for your super kind support of this app!
|
|||
|
||||
[WPF CalcBinding](https://github.com/Alex141/CalcBinding) by Alexander Zinchenko
|
||||
|
||||
[AutoUpdater.NET](https://github.com/ravibpatel/AutoUpdater.NET) by Ravi Patel
|
||||
|
||||
|
|
|
@ -2,7 +2,13 @@
|
|||
<hr/>
|
||||
|
||||
|
||||
## Version 3.2.0 (Release)
|
||||
* Added application auto update support. By installing this version of the app, auto update functionality will be available for all future versions of the application.
|
||||
* Disabled panel adjustments when Hide Title Bar is checked for a panel. This is to fix an issue where panel adjustments (X-Pos, Y-Pos, Width, and Height) will behave erratically when Hide Title Bar is checked.
|
||||
* Increased default delay for auto-clicking "Ready to Fly" button from 2 seconds to 4 seconds in regard to Auto Pop Out Panels feature . [Fixed Issue #9](https://github.com/hawkeye-stan/msfs-popout-panel-manager/issues/9)
|
||||
|
||||
## Version 3.2.0 (Beta)
|
||||
* Added new Auto Pop Out Panels when flight start feature. Now the app will match a profile to the plane you're flying and perform all the pop outs for you, even help you to click the "ready to fly" button when a flying session is about to start!
|
||||
* Added per monitor DPI-awareness support. The application should run and display correctly when using combination of mixed monitor (with high-DPI and low-DPI) resolutions and scaling.
|
||||
* Added system tray icon access. Application can start minimize or minimize to system tray. System tray icon features a context menu to allow quick access to application functions.
|
||||
* Added user requested feature to provide keyboard shortcut (Ctrl-Alt-P) to start panel pop out with either an active profile or a default profile selected.
|
||||
|
|
|
@ -76,7 +76,6 @@ namespace MSFSPopoutPanelManager.WpfApp
|
|||
var messageBoxMessage = "Application has encountered a critical error and will be closed.\nPlease see the file 'error.log' for information.";
|
||||
var messageBoxButtons = MessageBoxButton.OK;
|
||||
|
||||
// Let the user decide if the app should die or not (if applicable).
|
||||
if (MessageBox.Show(messageBoxMessage, messageBoxTitle, messageBoxButtons) == MessageBoxResult.OK)
|
||||
{
|
||||
Application.Current.Shutdown();
|
||||
|
|
|
@ -17,6 +17,17 @@
|
|||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="Background" Value="#FF576573" />
|
||||
</Trigger>
|
||||
<Trigger Property="IsEnabled" Value="False">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="TextBox">
|
||||
<Border Background="Transparent" BorderBrush="Transparent" BorderThickness="0">
|
||||
<TextBlock Text="{TemplateBinding Text}" Padding="4" />
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
|
@ -110,7 +121,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Left" Width="100" BorderThickness="0" Text="{Binding Path=Left, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -118,7 +129,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Top" Width="100" BorderThickness="0" Text="{Binding Path=Top, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -126,7 +137,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Width" Width="100" BorderThickness="0" Text="{Binding Path=Width, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
@ -134,7 +145,7 @@
|
|||
<DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<TextBox Name="Height" Width="100" BorderThickness="0" Text="{Binding Path=Height, Mode=TwoWay, NotifyOnSourceUpdated=True, UpdateSourceTrigger=LostFocus}"
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" />
|
||||
SourceUpdated="GridData_SourceUpdated" Style="{StaticResource TextBoxColumnFocus}" IsReadOnly="{c:Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path='DataContext.DataStore.ActiveUserProfile.IsLocked or !DataContext.DataStore.AllowEdit'}" IsEnabled="{c:Binding Path='!HideTitlebar', Mode=TwoWay}" />
|
||||
</DataTemplate>
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</DataGridTemplateColumn>
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
using MSFSPopoutPanelManager.FsConnector;
|
||||
using AutoUpdaterDotNET;
|
||||
using MSFSPopoutPanelManager.Model;
|
||||
using MSFSPopoutPanelManager.Provider;
|
||||
using MSFSPopoutPanelManager.Shared;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Windows;
|
||||
|
@ -92,7 +93,6 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
PanelConfigurationViewModel = new PanelConfigurationViewModel(DataStore, _userProfileManager);
|
||||
|
||||
InputHookManager.OnStartPopout += (source, e) => { OnStartPopOut(null); };
|
||||
InputHookManager.StartHook();
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
|
@ -110,6 +110,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
DeativateAutoPanelPopOut();
|
||||
};
|
||||
|
||||
CheckForAutoUpdate();
|
||||
|
||||
// Set application version
|
||||
ApplicationVersion = DiagnosticManager.GetApplicationVersion();
|
||||
|
||||
|
@ -128,6 +130,8 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
ShowPanelSelection(true);
|
||||
|
||||
IsMinimizedAllPanels = false;
|
||||
|
||||
InputHookManager.StartHook();
|
||||
}
|
||||
|
||||
private void OnRestart(object commandParameter)
|
||||
|
@ -274,5 +278,17 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
{
|
||||
DataStore.IsEnteredFlight = false;
|
||||
}
|
||||
|
||||
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";
|
||||
AutoUpdater.RunUpdateAsAdmin = false;
|
||||
AutoUpdater.UpdateFormSize = new System.Drawing.Size(930, 675);
|
||||
//AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/autoupdate.xml");
|
||||
AutoUpdater.Start("https://raw.githubusercontent.com/hawkeye-stan/AutoUpdateTest/main/autoupdate.xml");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -125,7 +125,7 @@ namespace MSFSPopoutPanelManager.WpfApp.ViewModel
|
|||
return;
|
||||
}
|
||||
|
||||
if (DataStore.ActiveUserProfile.PanelSourceCoordinates.Count > 0)
|
||||
if (DataStore.ActiveUserProfile != null && DataStore.ActiveUserProfile.PanelSourceCoordinates.Count > 0)
|
||||
{
|
||||
Logger.LogStatus("Panels pop out in progress.....", StatusMessageType.Info);
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Version>3.2.0</Version>
|
||||
<Version>3.2.0.0</Version>
|
||||
<PackageId>MSFS 2020 Popout Panel Manager</PackageId>
|
||||
<Authors>Stanley Kwok</Authors>
|
||||
<Product>MSFS 2020 Popout Panel Manager</Product>
|
||||
|
@ -50,6 +50,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.7.0" />
|
||||
<PackageReference Include="CalcBinding" Version="2.5.2" />
|
||||
<PackageReference Include="Fody" Version="6.6.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
|
7
autoupdate.xml
Normal file
7
autoupdate.xml
Normal file
|
@ -0,0 +1,7 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<item>
|
||||
<version>3.2.0.0</version>
|
||||
<url>https://github.com/hawkeye-stan/msfs-popout-panel-manager/releases/download/v3.2b/msfs-popout-panel-manager.zip</url>
|
||||
<changelog>https://raw.githubusercontent.com/hawkeye-stan/msfs-popout-panel-manager/master/latestreleasenotes.txt</changelog>
|
||||
<mandatory>false</mandatory>
|
||||
</item>
|
17
latestreleasenotes.txt
Normal file
17
latestreleasenotes.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
- Added per monitor DPI-awareness support. The application should run and display correctly when using combination of mixed monitor (with high-DPI and low-DPI) resolutions and scaling.
|
||||
|
||||
- Added system tray icon access. Application can start minimize or minimize to system tray. System tray icon features a context menu to allow quick access to application functions.
|
||||
|
||||
- Added user requested feature to provide keyboard shortcut (Ctrl-Alt-P) to start panel pop out with either an active profile or a default profile selected.
|
||||
|
||||
- New copy profile feature. You can reuse your defined panel settings for another plane or plane/livery combination.
|
||||
|
||||
- Added quick panel location selection adjustment feature. You can now adjust panel locations without redoing the entire profile.
|
||||
|
||||
- Added Save Auto Panning Camera Angle function if you need to adjust the in-game camera angle during panel selection.
|
||||
|
||||
- Added application auto update feature.
|
||||
|
||||
- New logo icon for the app.
|
||||
|
||||
- New dark theme for the entire UI.
|
Loading…
Reference in a new issue