mirror of
https://github.com/hawkeye-stan/msfs-popout-panel-manager.git
synced 2024-11-25 23:30:10 +00:00
Version 3.0.1
This commit is contained in:
parent
ee61fdbe88
commit
0a3d485363
8 changed files with 118 additions and 48 deletions
|
@ -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 />
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
{
|
{
|
||||||
FlightSimMainWindow,
|
FlightSimMainWindow,
|
||||||
BuiltInPopout,
|
BuiltInPopout,
|
||||||
CustomPopout
|
CustomPopout,
|
||||||
|
MSFSTouchPanel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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(); };
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
30
VERSION.md
30
VERSION.md
|
@ -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
|
Loading…
Reference in a new issue