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

Version 3.0.1

This commit is contained in:
hawkeye 2021-12-20 09:57:33 -05:00
parent ee61fdbe88
commit 0a3d485363
8 changed files with 118 additions and 48 deletions

View file

@ -5,7 +5,7 @@
<TargetFramework>net5.0-windows</TargetFramework> <TargetFramework>net5.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<Platforms>x64;AnyCPU</Platforms> <Platforms>x64;AnyCPU</Platforms>
<Version>3.0</Version> <Version>3.0.1</Version>
<AssemblyName>MSFSPopoutPanelManager</AssemblyName> <AssemblyName>MSFSPopoutPanelManager</AssemblyName>
<RootNamespace>MSFSPopoutPanelManager</RootNamespace> <RootNamespace>MSFSPopoutPanelManager</RootNamespace>
<ApplicationIcon>WindowManager.ico</ApplicationIcon> <ApplicationIcon>WindowManager.ico</ApplicationIcon>
@ -13,8 +13,8 @@
<Product>MSFS 2020 Popout Panel Manager</Product> <Product>MSFS 2020 Popout Panel Manager</Product>
<PackageId>MSFS 2020 Popout Panel Manager</PackageId> <PackageId>MSFS 2020 Popout Panel Manager</PackageId>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<AssemblyVersion>3.0.0.0</AssemblyVersion> <AssemblyVersion>3.0.1.0</AssemblyVersion>
<FileVersion>3.0.0.0</FileVersion> <FileVersion>3.0.1.0</FileVersion>
<WeaverConfiguration> <WeaverConfiguration>
<Weavers> <Weavers>
<PropertyChanged /> <PropertyChanged />

View file

@ -149,6 +149,12 @@ namespace MSFSPopoutPanelManager.Provider
// Add the built-in pop outs (ie. ATC, VFR Map) to the panel list // Add the built-in pop outs (ie. ATC, VFR Map) to the panel list
PInvoke.EnumWindows(new PInvoke.CallBack(EnumBuiltinPopoutCallBack), _profile.PanelSourceCoordinates.Count + 1); PInvoke.EnumWindows(new PInvoke.CallBack(EnumBuiltinPopoutCallBack), _profile.PanelSourceCoordinates.Count + 1);
// Add the MSFS Touch Panel (My other github project) windows to the panel list
PInvoke.EnumWindows(new PInvoke.CallBack(EnumMSFSTouchPanelPopoutCallBack), _profile.PanelSourceCoordinates.Count + 1);
if (_panels.Count == 0)
throw new PopoutManagerException("No panels have been found. Please select or open at least one in-game panel or MSFS Touch Panel App's panel.");
// Line up all the panels and fill in meta data // Line up all the panels and fill in meta data
for (var i = _panels.Count - 1; i >= 0; i--) for (var i = _panels.Count - 1; i >= 0; i--)
{ {
@ -158,7 +164,7 @@ namespace MSFSPopoutPanelManager.Provider
_panels[i].Width = 800; _panels[i].Width = 800;
_panels[i].Height = 600; _panels[i].Height = 600;
PInvoke.MoveWindow(_panels[i].PanelHandle, -8 + _panels[i].Top, _panels[i].Left, _panels[i].Width, _panels[i].Height, true); PInvoke.MoveWindow(_panels[i].PanelHandle, _panels[i].Top, _panels[i].Left, _panels[i].Width, _panels[i].Height, true);
PInvoke.SetForegroundWindow(_panels[i].PanelHandle); PInvoke.SetForegroundWindow(_panels[i].PanelHandle);
Thread.Sleep(200); Thread.Sleep(200);
} }
@ -295,6 +301,22 @@ namespace MSFSPopoutPanelManager.Provider
return true; return true;
} }
public bool EnumMSFSTouchPanelPopoutCallBack(IntPtr hwnd, int index)
{
var panelInfo = GetPanelWindowInfo(hwnd);
if (panelInfo != null && panelInfo.PanelType == PanelType.MSFSTouchPanel)
{
if (!_panels.Exists(x => x.PanelHandle == hwnd))
{
panelInfo.PanelIndex = index;
_panels.Add(panelInfo);
}
}
return true;
}
private PanelConfig GetPanelWindowInfo(IntPtr hwnd) private PanelConfig GetPanelWindowInfo(IntPtr hwnd)
{ {
var className = PInvoke.GetClassName(hwnd); var className = PInvoke.GetClassName(hwnd);
@ -316,6 +338,22 @@ namespace MSFSPopoutPanelManager.Provider
return panelInfo; return panelInfo;
} }
else // For MSFS Touch Panel window
{
var caption = PInvoke.GetWindowText(hwnd);
var panelInfo = new PanelConfig();
panelInfo.PanelHandle = hwnd;
panelInfo.PanelName = caption;
if (caption.IndexOf("MSFS Touch Panel |") > -1)
{
panelInfo.PanelType = PanelType.MSFSTouchPanel;
return panelInfo;
}
else
return null;
}
return null; return null;
} }

View file

@ -4,6 +4,7 @@
{ {
FlightSimMainWindow, FlightSimMainWindow,
BuiltInPopout, BuiltInPopout,
CustomPopout CustomPopout,
MSFSTouchPanel
} }
} }

View file

@ -31,7 +31,7 @@ namespace MSFSPopoutPanelManager.UI
panelSteps.Controls.Add(_ucPanelConfiguration); panelSteps.Controls.Add(_ucPanelConfiguration);
// Set version number // Set version number
lblVersion.Text += System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); lblVersion.Text += $"{System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Major}.{System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Minor}.{System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Build}";
_controller = new StartUpController(this); _controller = new StartUpController(this);
_controller.OnSimConnectionChanged += HandleSimConnectionChanged; _controller.OnSimConnectionChanged += HandleSimConnectionChanged;

View file

@ -22,7 +22,7 @@ namespace MSFSPopoutPanelManager.UI
dataGridViewPanels.DataSource = _controller.PanelConfigs; dataGridViewPanels.DataSource = _controller.PanelConfigs;
dataGridViewPanels.CellBeginEdit += HandleCellBeginEdit; dataGridViewPanels.CellBeginEdit += HandleCellBeginEdit;
dataGridViewPanels.CellValidating += HandleCellValidating; dataGridViewPanels.CellValidating += HandleCellValidating;
dataGridViewPanels.CellValueChanged += HandleCellValueChanged; dataGridViewPanels.CellEndEdit += HandleCellValueChanged;
dataGridViewPanels.CellContentClick += HandleCellValueChanged; dataGridViewPanels.CellContentClick += HandleCellValueChanged;
buttonSaveSettings.Click += (source, e) => { dataGridViewPanels.EndEdit(); _controller.SaveSettings(); }; buttonSaveSettings.Click += (source, e) => { dataGridViewPanels.EndEdit(); _controller.SaveSettings(); };

View file

@ -10,7 +10,8 @@ namespace MSFSPopoutPanelManager.UIController
public class PanelConfigurationController : BaseController public class PanelConfigurationController : BaseController
{ {
private const int WINEVENT_OUTOFCONTEXT = 0; private const int WINEVENT_OUTOFCONTEXT = 0;
private const uint EVENT_SYSTEM_MOVESIZEEND = 0x000B; //private const uint EVENT_SYSTEM_MOVESIZEEND = 0x000B;
private const uint EVENT_OBJECT_LOCATIONCHANGE = 0x800B;
private static PInvoke.WinEventProc _winEvent; // keep this as static to prevent garbage collect or the app will crash private static PInvoke.WinEventProc _winEvent; // keep this as static to prevent garbage collect or the app will crash
private IntPtr _winEventHook; private IntPtr _winEventHook;
@ -52,36 +53,33 @@ namespace MSFSPopoutPanelManager.UIController
public void CellValueChanged(int rowIndex, PanelConfigDataColumn column, object newCellValue) public void CellValueChanged(int rowIndex, PanelConfigDataColumn column, object newCellValue)
{ {
int orignalLeft = PanelConfigs[rowIndex].Left;
if (rowIndex != -1) if (rowIndex != -1)
{ {
switch (column) switch (column)
{ {
case PanelConfigDataColumn.PanelName: case PanelConfigDataColumn.PanelName:
PanelConfigs[rowIndex].PanelName = Convert.ToString(newCellValue);
PInvoke.SetWindowText(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].PanelName); PInvoke.SetWindowText(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].PanelName);
break; break;
case PanelConfigDataColumn.Left: case PanelConfigDataColumn.Left:
PanelConfigs[rowIndex].Left = Convert.ToInt32(newCellValue);
PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true); PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true);
break; break;
case PanelConfigDataColumn.Top: case PanelConfigDataColumn.Top:
PanelConfigs[rowIndex].Top = Convert.ToInt32(newCellValue);
PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true); PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true);
break; break;
case PanelConfigDataColumn.Width: case PanelConfigDataColumn.Width:
PanelConfigs[rowIndex].Width = Convert.ToInt32(newCellValue);
PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true); PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true);
MSFSBugPanelShiftWorkaround(PanelConfigs[rowIndex].PanelHandle, orignalLeft, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height);
break; break;
case PanelConfigDataColumn.Height: case PanelConfigDataColumn.Height:
PanelConfigs[rowIndex].Height = Convert.ToInt32(newCellValue);
PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true); PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true);
MSFSBugPanelShiftWorkaround(PanelConfigs[rowIndex].PanelHandle, orignalLeft, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height);
break; break;
case PanelConfigDataColumn.AlwaysOnTop: case PanelConfigDataColumn.AlwaysOnTop:
PanelConfigs[rowIndex].AlwaysOnTop = Convert.ToBoolean(newCellValue);
WindowManager.ApplyAlwaysOnTop(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].AlwaysOnTop, new Rectangle(PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height)); WindowManager.ApplyAlwaysOnTop(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].AlwaysOnTop, new Rectangle(PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height));
break; break;
case PanelConfigDataColumn.HideTitlebar: case PanelConfigDataColumn.HideTitlebar:
PanelConfigs[rowIndex].HideTitlebar = Convert.ToBoolean(newCellValue);
WindowManager.ApplyHidePanelTitleBar(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].HideTitlebar); WindowManager.ApplyHidePanelTitleBar(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].HideTitlebar);
break; break;
default: default:
@ -92,64 +90,89 @@ namespace MSFSPopoutPanelManager.UIController
public void CellValueIncrDecr(int rowIndex, PanelConfigDataColumn column, int changeAmount) public void CellValueIncrDecr(int rowIndex, PanelConfigDataColumn column, int changeAmount)
{ {
int orignalLeft = PanelConfigs[rowIndex].Left;
if (rowIndex != -1) if (rowIndex != -1)
{ {
switch (column) switch (column)
{ {
case PanelConfigDataColumn.Left: case PanelConfigDataColumn.Left:
PanelConfigs[rowIndex].Left += changeAmount; PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left + changeAmount, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, false);
break; break;
case PanelConfigDataColumn.Top: case PanelConfigDataColumn.Top:
PanelConfigs[rowIndex].Top += changeAmount; PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top + changeAmount, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, false);
break; break;
case PanelConfigDataColumn.Width: case PanelConfigDataColumn.Width:
PanelConfigs[rowIndex].Width += changeAmount; PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width + changeAmount, PanelConfigs[rowIndex].Height, false);
MSFSBugPanelShiftWorkaround(PanelConfigs[rowIndex].PanelHandle, orignalLeft, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width + changeAmount, PanelConfigs[rowIndex].Height);
break; break;
case PanelConfigDataColumn.Height: case PanelConfigDataColumn.Height:
PanelConfigs[rowIndex].Height += changeAmount; PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height + changeAmount, false);
MSFSBugPanelShiftWorkaround(PanelConfigs[rowIndex].PanelHandle, orignalLeft, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height + changeAmount);
break; break;
default: default:
return; return;
} }
RefreshDataUI?.Invoke(this, null);
PInvoke.MoveWindow(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].Left, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height, true);
} }
} }
private void MSFSBugPanelShiftWorkaround(IntPtr handle, int originalLeft, int top, int width, int height)
{
// Fixed MSFS bug, create workaround where on 2nd or later instance of width adjustment, the panel shift to the left by itself
// Wait for system to catch up on panel coordinate that were just applied
System.Threading.Thread.Sleep(200);
Rectangle rectangle;
PInvoke.GetWindowRect(handle, out rectangle);
if (rectangle.Left != originalLeft)
PInvoke.MoveWindow(handle, originalLeft, top, width, height, false);
}
private void HandlePopOutCompleted(object sender, EventArgs e) private void HandlePopOutCompleted(object sender, EventArgs e)
{ {
// Populate panel data // Populate panel data
BaseController.ActiveUserPlaneProfile.PanelConfigs.ForEach(p => PanelConfigs.Add(p)); BaseController.ActiveUserPlaneProfile.PanelConfigs.ForEach(p => PanelConfigs.Add(p));
// Setup panel config event hooks // Setup panel config event hooks
_winEventHook = PInvoke.SetWinEventHook(EVENT_SYSTEM_MOVESIZEEND, EVENT_SYSTEM_MOVESIZEEND, IntPtr.Zero, _winEvent, 0, 0, WINEVENT_OUTOFCONTEXT); _winEventHook = PInvoke.SetWinEventHook(EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, IntPtr.Zero, _winEvent, 0, 0, WINEVENT_OUTOFCONTEXT);
} }
private Rectangle _lastWindowRectangle;
private void EventCallback(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime) private void EventCallback(IntPtr hWinEventHook, uint iEvent, IntPtr hWnd, int idObject, int idChild, int dwEventThread, int dwmsEventTime)
{ {
if (hWnd == IntPtr.Zero) return;
var panelConfig = PanelConfigs.FirstOrDefault(panel => panel.PanelHandle == hWnd); var panelConfig = PanelConfigs.FirstOrDefault(panel => panel.PanelHandle == hWnd);
if (panelConfig != null) if (panelConfig != null)
{ {
var rowIndex = PanelConfigs.IndexOf(panelConfig); var rowIndex = PanelConfigs.IndexOf(panelConfig);
HightlightSelectedPanel?.Invoke(this, new EventArgs<int>(rowIndex));
if (panelConfig != null) if (panelConfig != null)
{ {
switch (iEvent) switch (iEvent)
{ {
case EVENT_SYSTEM_MOVESIZEEND: case EVENT_OBJECT_LOCATIONCHANGE:
Rectangle winRectangle; Rectangle winRectangle;
Rectangle clientRectangle;
PInvoke.GetWindowRect(panelConfig.PanelHandle, out winRectangle); PInvoke.GetWindowRect(panelConfig.PanelHandle, out winRectangle);
if (_lastWindowRectangle == winRectangle) // ignore duplicate callback messages
return;
_lastWindowRectangle = winRectangle;
Rectangle clientRectangle;
PInvoke.GetClientRect(panelConfig.PanelHandle, out clientRectangle); PInvoke.GetClientRect(panelConfig.PanelHandle, out clientRectangle);
panelConfig.Top = winRectangle.Top;
panelConfig.Left = winRectangle.Left; panelConfig.Left = winRectangle.Left;
panelConfig.Top = winRectangle.Top;
panelConfig.Width = clientRectangle.Width + 16; panelConfig.Width = clientRectangle.Width + 16;
panelConfig.Height = clientRectangle.Height + 39; panelConfig.Height = clientRectangle.Height + 39;
HightlightSelectedPanel?.Invoke(this, new EventArgs<int>(rowIndex));
break; break;
} }

View file

@ -140,10 +140,10 @@ namespace MSFSPopoutPanelManager.UIController
_panelSelectionManager.ShowPanelLocationOverlay(false); _panelSelectionManager.ShowPanelLocationOverlay(false);
ShowPanelLocationOverlay = false; ShowPanelLocationOverlay = false;
if (PanelCoordinates.Count == 0) //if (PanelCoordinates.Count == 0)
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.ProfileSelected)); // OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.ProfileSelected));
else //else
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid)); OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid));
} }
} }
@ -255,13 +255,13 @@ namespace MSFSPopoutPanelManager.UIController
if (_parentForm != null) if (_parentForm != null)
_parentForm.WindowState = FormWindowState.Normal; _parentForm.WindowState = FormWindowState.Normal;
if (PanelCoordinates.Count > 0) //if (PanelCoordinates.Count > 0)
{ //{
ActiveUserPlaneProfile.PanelSourceCoordinates = PanelCoordinates.ToList(); ActiveUserPlaneProfile.PanelSourceCoordinates = PanelCoordinates.ToList();
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid)); OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid));
} //}
else //else
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedInvalid)); // OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedInvalid));
ShowPanelLocationOverlay = true; ShowPanelLocationOverlay = true;

View file

@ -1,7 +1,15 @@
# Version History # Version History
<hr/> <hr/>
## Version 3.0.0.0 ## Version 3.0.1
* Added workaround for MSFS pop out panel adjustment bug so using the position data grid to adjust width and height will work as expected.
- In MSFS, when changing height or width of a pop out panel (2nd time for same panel and onward), there is an MSFS bug that will unexpectedly shifted the panel by 8px to the left for each adjustment.
* Improved realtime feedback of panel's current coordiates as you move panels around or adjust the top, left, height and width of panel.
* Fixed always on top issue when moving panel around for placement inside other overlay or bezel.
* Added support to create profile just to save locations of built-in panels only (VFR, ATC, etc).
* Added support to save locations for web panels from my other github project "MSFS Touch Panel".
## Version 3.0.0
* Provided 2X pop out and panel separation performance. * Provided 2X pop out and panel separation performance.
* Better support for all screen resolutions. * Better support for all screen resolutions.
* Added Cold Start feature. Panels can be popped out and recalled later even when they're not turned on. * Added Cold Start feature. Panels can be popped out and recalled later even when they're not turned on.
@ -11,7 +19,7 @@
* Added realtime readout during panel positioning. * Added realtime readout during panel positioning.
* Added exception tracing to help troubleshoot application issue. * Added exception tracing to help troubleshoot application issue.
## Vesion 2.2.0.0 ## Vesion 2.2.0
* Disabled ability to launch multiple instances of the application. * Disabled ability to launch multiple instances of the application.
* Added autostart feature when MSFS starts. The application will create or modify exe.xml. A backup copy of exe.xml will be created. * Added autostart feature when MSFS starts. The application will create or modify exe.xml. A backup copy of exe.xml will be created.
* Added better support for 4K display resolution and non-standard display resolution. * Added better support for 4K display resolution and non-standard display resolution.
@ -19,32 +27,32 @@
* Improved panel pop out separation accuracy and performance. * Improved panel pop out separation accuracy and performance.
* Updated application packaging to single file executable to reduce file clutter. * Updated application packaging to single file executable to reduce file clutter.
## Vesion 2.1.1.0 ## Vesion 2.1.1
* Fixed panel separation issue for super ultrawide monitor (for example: 3840x1080) * Fixed panel separation issue for super ultrawide monitor (for example: 3840x1080)
## Vesion 2.1.0.0 ## Vesion 2.1.0
* Added ability to delete built-in profile. * Added ability to delete built-in profile.
* Added ability to create and delete custom user profile. * Added ability to create and delete custom user profile.
* Improved image recognition algorithm using SUSAN Corner block matching algorithm. * Improved image recognition algorithm using SUSAN Corner block matching algorithm.
## Vesion 2.0.3.0 ## Vesion 2.0.3
* Fixed a crash bug when splitting out panel when trying to analyze the last split panel. * Fixed a crash bug when splitting out panel when trying to analyze the last split panel.
* Added PMS50.com GTN750 mod configuration * Added PMS50.com GTN750 mod configuration
## Vesion 2.0.2.0 ## Vesion 2.0.2
* Added one second delay on mouse click when the application is trying to separate the chained pop out windows. * Added one second delay on mouse click when the application is trying to separate the chained pop out windows.
## Vesion 2.0.1.0 ## Vesion 2.0.1
* Changed how screen resolution is detected. Used vertical instead of horizontal resolution to account for ultra wide monitors. * Changed how screen resolution is detected. Used vertical instead of horizontal resolution to account for ultra wide monitors.
## Version 2.0.0.0 ## Version 2.0.0
* Used new image recognition instead of OCR technology to determine pop outs. * Used new image recognition instead of OCR technology to determine pop outs.
* Added auto pop out feature. * Added auto pop out feature.
* Allowed moving pop out panels using coordinates/width/height after analysis. * Allowed moving pop out panels using coordinates/width/height after analysis.
* Added additional plane profiles. * Added additional plane profiles.
* Running on non-native monitor resolution will not work because of image scaling issue when doing image analysis. * Running on non-native monitor resolution will not work because of image scaling issue when doing image analysis.
## Version 1.2.0.0 ## Version 1.2.0
* Increase OCR image accuracy by raising image DPI before analysis. * Increase OCR image accuracy by raising image DPI before analysis.
* Added (very experimental) Asobo A320 and FlybyWire A320NX profiles as testing sample. These profiles do only work 100% of the time. Continue investigation into better OCR accuracy will be needed. * Added (very experimental) Asobo A320 and FlybyWire A320NX profiles as testing sample. These profiles do only work 100% of the time. Continue investigation into better OCR accuracy will be needed.
* Added profile dropdown sorted by profile name. * Added profile dropdown sorted by profile name.
@ -54,7 +62,7 @@
* Fixed application path issue for not able to find ocrdata.json file at startup. * Fixed application path issue for not able to find ocrdata.json file at startup.
* Removed MSFS Pop Out Panel Manager is always on top. This is intefering with image operations. * Removed MSFS Pop Out Panel Manager is always on top. This is intefering with image operations.
## Version 1.1.0.0 ## Version 1.1.0
* Added caption title for the "untitled" windows. After analysis, if the panel window matches the name in the profile/ocr definition file, it will now display a caption of "Custom - XXXXX" (ie. Custom - PFD). This allows user to use various 3rd party windows layout manager to organize pop out panel windows. * Added caption title for the "untitled" windows. After analysis, if the panel window matches the name in the profile/ocr definition file, it will now display a caption of "Custom - XXXXX" (ie. Custom - PFD). This allows user to use various 3rd party windows layout manager to organize pop out panel windows.
* Added hide panel title bar feature. * Added hide panel title bar feature.
* Added ability to have pop out panels to be always on top. * Added ability to have pop out panels to be always on top.
@ -62,5 +70,5 @@
* Made application flow more intuitive. * Made application flow more intuitive.
* Fixed various small bugs in the application. * Fixed various small bugs in the application.
## Version 1.0.0.0 ## Version 1.0.0
* Initial Release * Initial Release