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:
parent
ee61fdbe88
commit
0a3d485363
8 changed files with 118 additions and 48 deletions
|
@ -5,7 +5,7 @@
|
|||
<TargetFramework>net5.0-windows</TargetFramework>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
<Platforms>x64;AnyCPU</Platforms>
|
||||
<Version>3.0</Version>
|
||||
<Version>3.0.1</Version>
|
||||
<AssemblyName>MSFSPopoutPanelManager</AssemblyName>
|
||||
<RootNamespace>MSFSPopoutPanelManager</RootNamespace>
|
||||
<ApplicationIcon>WindowManager.ico</ApplicationIcon>
|
||||
|
@ -13,8 +13,8 @@
|
|||
<Product>MSFS 2020 Popout Panel Manager</Product>
|
||||
<PackageId>MSFS 2020 Popout Panel Manager</PackageId>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<AssemblyVersion>3.0.0.0</AssemblyVersion>
|
||||
<FileVersion>3.0.0.0</FileVersion>
|
||||
<AssemblyVersion>3.0.1.0</AssemblyVersion>
|
||||
<FileVersion>3.0.1.0</FileVersion>
|
||||
<WeaverConfiguration>
|
||||
<Weavers>
|
||||
<PropertyChanged />
|
||||
|
|
|
@ -149,6 +149,12 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
// Add the built-in pop outs (ie. ATC, VFR Map) to the panel list
|
||||
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
|
||||
for (var i = _panels.Count - 1; i >= 0; i--)
|
||||
{
|
||||
|
@ -158,7 +164,7 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
_panels[i].Width = 800;
|
||||
_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);
|
||||
Thread.Sleep(200);
|
||||
}
|
||||
|
@ -295,6 +301,22 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
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)
|
||||
{
|
||||
var className = PInvoke.GetClassName(hwnd);
|
||||
|
@ -316,6 +338,22 @@ namespace MSFSPopoutPanelManager.Provider
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
{
|
||||
FlightSimMainWindow,
|
||||
BuiltInPopout,
|
||||
CustomPopout
|
||||
CustomPopout,
|
||||
MSFSTouchPanel
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace MSFSPopoutPanelManager.UI
|
|||
panelSteps.Controls.Add(_ucPanelConfiguration);
|
||||
|
||||
// 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.OnSimConnectionChanged += HandleSimConnectionChanged;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace MSFSPopoutPanelManager.UI
|
|||
dataGridViewPanels.DataSource = _controller.PanelConfigs;
|
||||
dataGridViewPanels.CellBeginEdit += HandleCellBeginEdit;
|
||||
dataGridViewPanels.CellValidating += HandleCellValidating;
|
||||
dataGridViewPanels.CellValueChanged += HandleCellValueChanged;
|
||||
dataGridViewPanels.CellEndEdit += HandleCellValueChanged;
|
||||
dataGridViewPanels.CellContentClick += HandleCellValueChanged;
|
||||
|
||||
buttonSaveSettings.Click += (source, e) => { dataGridViewPanels.EndEdit(); _controller.SaveSettings(); };
|
||||
|
|
|
@ -10,7 +10,8 @@ namespace MSFSPopoutPanelManager.UIController
|
|||
public class PanelConfigurationController : BaseController
|
||||
{
|
||||
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 IntPtr _winEventHook;
|
||||
|
@ -52,36 +53,33 @@ namespace MSFSPopoutPanelManager.UIController
|
|||
|
||||
public void CellValueChanged(int rowIndex, PanelConfigDataColumn column, object newCellValue)
|
||||
{
|
||||
int orignalLeft = PanelConfigs[rowIndex].Left;
|
||||
|
||||
if (rowIndex != -1)
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
case PanelConfigDataColumn.PanelName:
|
||||
PanelConfigs[rowIndex].PanelName = Convert.ToString(newCellValue);
|
||||
PInvoke.SetWindowText(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].PanelName);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
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);
|
||||
MSFSBugPanelShiftWorkaround(PanelConfigs[rowIndex].PanelHandle, orignalLeft, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height);
|
||||
break;
|
||||
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);
|
||||
MSFSBugPanelShiftWorkaround(PanelConfigs[rowIndex].PanelHandle, orignalLeft, PanelConfigs[rowIndex].Top, PanelConfigs[rowIndex].Width, PanelConfigs[rowIndex].Height);
|
||||
break;
|
||||
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));
|
||||
break;
|
||||
case PanelConfigDataColumn.HideTitlebar:
|
||||
PanelConfigs[rowIndex].HideTitlebar = Convert.ToBoolean(newCellValue);
|
||||
WindowManager.ApplyHidePanelTitleBar(PanelConfigs[rowIndex].PanelHandle, PanelConfigs[rowIndex].HideTitlebar);
|
||||
break;
|
||||
default:
|
||||
|
@ -92,64 +90,89 @@ namespace MSFSPopoutPanelManager.UIController
|
|||
|
||||
public void CellValueIncrDecr(int rowIndex, PanelConfigDataColumn column, int changeAmount)
|
||||
{
|
||||
int orignalLeft = PanelConfigs[rowIndex].Left;
|
||||
|
||||
if (rowIndex != -1)
|
||||
{
|
||||
switch (column)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
default:
|
||||
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)
|
||||
{
|
||||
// Populate panel data
|
||||
BaseController.ActiveUserPlaneProfile.PanelConfigs.ForEach(p => PanelConfigs.Add(p));
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (hWnd == IntPtr.Zero) return;
|
||||
|
||||
var panelConfig = PanelConfigs.FirstOrDefault(panel => panel.PanelHandle == hWnd);
|
||||
|
||||
if (panelConfig != null)
|
||||
{
|
||||
var rowIndex = PanelConfigs.IndexOf(panelConfig);
|
||||
|
||||
HightlightSelectedPanel?.Invoke(this, new EventArgs<int>(rowIndex));
|
||||
|
||||
if (panelConfig != null)
|
||||
{
|
||||
switch (iEvent)
|
||||
{
|
||||
case EVENT_SYSTEM_MOVESIZEEND:
|
||||
case EVENT_OBJECT_LOCATIONCHANGE:
|
||||
Rectangle winRectangle;
|
||||
Rectangle clientRectangle;
|
||||
PInvoke.GetWindowRect(panelConfig.PanelHandle, out winRectangle);
|
||||
|
||||
if (_lastWindowRectangle == winRectangle) // ignore duplicate callback messages
|
||||
return;
|
||||
|
||||
_lastWindowRectangle = winRectangle;
|
||||
Rectangle clientRectangle;
|
||||
PInvoke.GetClientRect(panelConfig.PanelHandle, out clientRectangle);
|
||||
|
||||
panelConfig.Top = winRectangle.Top;
|
||||
panelConfig.Left = winRectangle.Left;
|
||||
panelConfig.Top = winRectangle.Top;
|
||||
panelConfig.Width = clientRectangle.Width + 16;
|
||||
panelConfig.Height = clientRectangle.Height + 39;
|
||||
|
||||
HightlightSelectedPanel?.Invoke(this, new EventArgs<int>(rowIndex));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,10 +140,10 @@ namespace MSFSPopoutPanelManager.UIController
|
|||
_panelSelectionManager.ShowPanelLocationOverlay(false);
|
||||
ShowPanelLocationOverlay = false;
|
||||
|
||||
if (PanelCoordinates.Count == 0)
|
||||
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.ProfileSelected));
|
||||
else
|
||||
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid));
|
||||
//if (PanelCoordinates.Count == 0)
|
||||
// OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.ProfileSelected));
|
||||
//else
|
||||
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,13 +255,13 @@ namespace MSFSPopoutPanelManager.UIController
|
|||
if (_parentForm != null)
|
||||
_parentForm.WindowState = FormWindowState.Normal;
|
||||
|
||||
if (PanelCoordinates.Count > 0)
|
||||
{
|
||||
//if (PanelCoordinates.Count > 0)
|
||||
//{
|
||||
ActiveUserPlaneProfile.PanelSourceCoordinates = PanelCoordinates.ToList();
|
||||
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedValid));
|
||||
}
|
||||
else
|
||||
OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedInvalid));
|
||||
//}
|
||||
//else
|
||||
// OnUIStateChanged?.Invoke(this, new EventArgs<PanelSelectionUIState>(PanelSelectionUIState.PanelSelectionCompletedInvalid));
|
||||
|
||||
ShowPanelLocationOverlay = true;
|
||||
|
||||
|
|
30
VERSION.md
30
VERSION.md
|
@ -1,7 +1,15 @@
|
|||
# Version History
|
||||
<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.
|
||||
* 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.
|
||||
|
@ -11,7 +19,7 @@
|
|||
* Added realtime readout during panel positioning.
|
||||
* 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.
|
||||
* 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.
|
||||
|
@ -19,32 +27,32 @@
|
|||
* Improved panel pop out separation accuracy and performance.
|
||||
* 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)
|
||||
|
||||
## Vesion 2.1.0.0
|
||||
## Vesion 2.1.0
|
||||
* Added ability to delete built-in profile.
|
||||
* Added ability to create and delete custom user profile.
|
||||
* 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.
|
||||
* 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.
|
||||
|
||||
## 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.
|
||||
|
||||
## Version 2.0.0.0
|
||||
## Version 2.0.0
|
||||
* Used new image recognition instead of OCR technology to determine pop outs.
|
||||
* Added auto pop out feature.
|
||||
* Allowed moving pop out panels using coordinates/width/height after analysis.
|
||||
* Added additional plane profiles.
|
||||
* 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.
|
||||
* 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.
|
||||
|
@ -54,7 +62,7 @@
|
|||
* 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.
|
||||
|
||||
## 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 hide panel title bar feature.
|
||||
* Added ability to have pop out panels to be always on top.
|
||||
|
@ -62,5 +70,5 @@
|
|||
* Made application flow more intuitive.
|
||||
* Fixed various small bugs in the application.
|
||||
|
||||
## Version 1.0.0.0
|
||||
## Version 1.0.0
|
||||
* Initial Release
|
Loading…
Reference in a new issue