diff --git a/ExtLibs/Controls/BackstageView/BackstageView.cs b/ExtLibs/Controls/BackstageView/BackstageView.cs
index 2345b6beaf..e23602e91c 100644
--- a/ExtLibs/Controls/BackstageView/BackstageView.cs
+++ b/ExtLibs/Controls/BackstageView/BackstageView.cs
@@ -10,7 +10,8 @@
namespace MissionPlanner.Controls.BackstageView
{
///
- /// A Control to somewhat emulate the 'backstage view' as in MS Office 2010
+ /// A Control to emulate the 'backstage view' (File Menu style) seen in MS Office 2010/2013.
+ /// Handles navigation between different configuration and setup screens.
///
///
/// 'Tabs' are added as a control in a
@@ -61,6 +62,7 @@ public int WidthMenu
}
}
+ // Tracks the currently popped-out page (if any)
private BackstageViewPage popoutPage = null;
private int ButtonTopPos = 0;
@@ -75,8 +77,6 @@ public BackstageView()
pnlMenu.BackColor = _buttonsAreaBgColor;
pnlMenu.PencilBorderColor = _buttonsAreaPencilColor;
pnlMenu.GradColor = this.BackColor;
-
-
}
public void UpdateDisplay()
@@ -86,7 +86,6 @@ public void UpdateDisplay()
if (!itemType.Show)
continue;
-
if (itemType.Page != null)
{
itemType.Page.Location = new Point(0, 0);
@@ -127,7 +126,6 @@ public Color ButtonsAreaPencilColor
}
}
-
[Description("Background color for the buttons region"), Category("Appearance")]
[DefaultValue(typeof(Color), "White")]
public Color ButtonsAreaBgColor
@@ -234,21 +232,19 @@ private void CreateLinkButton(BackstageViewPage page, bool haschild = false, boo
}
var lnkButton = new BackstageViewButton
- {
- Text = label,
- Tag = page,
- Top = ButtonTopPos,
- // Top = _items.TakeWhile(i => i != page).Sum(i => i.Spacing),
- Width = this.pnlMenu.Width,
- Height = ButtonHeight + heightextra,
- ContentPageColor = this.BackColor,
- PencilBorderColor = _buttonsAreaPencilColor,
- SelectedTextColor = _selectedTextColor,
- UnSelectedTextColor = _unSelectedTextColor,
- HighlightColor1 = _highlightColor1,
- HighlightColor2 = _highlightColor2,
- //Dock = DockStyle.Bottom
- };
+ {
+ Text = label,
+ Tag = page,
+ Top = ButtonTopPos,
+ Width = this.pnlMenu.Width,
+ Height = ButtonHeight + heightextra,
+ ContentPageColor = this.BackColor,
+ PencilBorderColor = _buttonsAreaPencilColor,
+ SelectedTextColor = _selectedTextColor,
+ UnSelectedTextColor = _unSelectedTextColor,
+ HighlightColor1 = _highlightColor1,
+ HighlightColor2 = _highlightColor2,
+ };
pnlMenu.Controls.Add(lnkButton);
lnkButton.Click += this.ButtonClick;
@@ -331,7 +327,6 @@ public void DrawMenu(BackstageViewPage CurrentPage, bool force = false)
}
continue;
}
-
}
else
{
@@ -355,7 +350,6 @@ private bool PageHasChildren(BackstageViewPage parent)
}
}
}
-
return false;
}
@@ -374,17 +368,45 @@ private void UpdateButtonAppearance()
}
}
- /*
- * Experimental - double clicking a button will spawn it out into a new form
- * Care must be given to lifecycle here - two pages can now be interacted with
- * 'simultaneously'
- */
+ ///
+ /// Experimental - double clicking a button will spawn it out into a new form
+ /// Allows interacting with two pages simultaneously.
+ ///
private void lnkButton_DoubleClick(object sender, EventArgs e)
{
var backstageViewButton = ((BackstageViewButton)sender);
var associatedPage = backstageViewButton.Tag as BackstageViewPage;
var popoutForm = new Form();
+
+ // ----------------------------------------------------------------------
+ // FIX for missing icon in pop-out window
+ // ----------------------------------------------------------------------
+
+ // Strategy 1: Attempt to copy the icon from the main parent form
+ if (this.FindForm() != null)
+ {
+ popoutForm.Icon = this.FindForm().Icon;
+ }
+
+ // Strategy 2: If strategy 1 fails, try to extract the icon from the executable.
+ // This is wrapped in a preprocessor directive because ExtractAssociatedIcon is only available on Windows.
+#if !NETSTANDARD
+ try
+ {
+ if (popoutForm.Icon == null)
+ {
+ popoutForm.Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath);
+ }
+ }
+ catch { /* Ignore failure to extract icon */ }
+#endif
+
+ // Ensure the icon is visible
+ popoutForm.ShowIcon = true;
+
+ // ----------------------------------------------------------------------
+
popoutForm.FormClosing += popoutForm_FormClosing;
int maxright = 0, maxdown = 0;
@@ -395,10 +417,9 @@ private void lnkButton_DoubleClick(object sender, EventArgs e)
maxdown = Math.Max(ctl.Bottom, maxdown);
}
- // set the height to 0, so we can derive the header height in the next step
popoutForm.Height = 0;
-
popoutForm.Size = new Size(maxright + 20, maxdown + 20 + popoutForm.Height);
+
popoutForm.Controls.Add(associatedPage.Page);
popoutForm.Tag = associatedPage;
@@ -432,6 +453,10 @@ private void ButtonClick(object sender, EventArgs e)
this.ActivatePage(associatedPage);
}
+ ///
+ /// Activates the selected page and displays it in the content panel.
+ /// Also handles closing any existing pop-out windows.
+ ///
public void ActivatePage(BackstageViewPage associatedPage)
{
if (associatedPage == null)
@@ -455,7 +480,7 @@ public void ActivatePage(BackstageViewPage associatedPage)
{
try
{
- ((IDeactivate) (_activePage.Page)).Deactivate();
+ ((IDeactivate)(_activePage.Page)).Deactivate();
}
catch (Exception ex)
{
@@ -463,14 +488,12 @@ public void ActivatePage(BackstageViewPage associatedPage)
}
}
- // deactivate the old page - obsolete way of notifying activation
- //_activePage.Page.Close();
-
if (_activePage != null && _activePage.Page != null)
_activePage.Page.Visible = false;
try
- { // if the button was on an expanded tab. when we leave it no longer exits
+ {
+ // if the button was on an expanded tab. when we leave it no longer exits
if (_activePage != null)
{
var oldButton = this.pnlMenu.Controls.OfType().Single(b => b.Tag == _activePage);
@@ -484,19 +507,38 @@ public void ActivatePage(BackstageViewPage associatedPage)
associatedPage.Page.ResumeLayout(false);
this.ResumeLayout(false);
+
// show it
associatedPage.Page.Visible = true;
+ // ---------------------------------------------------------
+ // FIX for Issue #3633: Pop-out window not closing when re-docking
+ // ---------------------------------------------------------
+ // If a different page is currently popped out in an external window,
+ // close it before navigating to prevent leaving an empty "ghost" window.
+ if (popoutPage != null && popoutPage != associatedPage)
+ {
+ Form parentWindow = popoutPage.Page.Parent as Form;
+ if (parentWindow != null && !parentWindow.IsDisposed)
+ {
+ parentWindow.Close();
+ }
+
+ // Reset the popped-out page reference so we don't repeatedly
+ // attempt to close an already-closed window on subsequent navigations.
+ popoutPage = null;
+ }
+ // ---------------------------------------------------------
+
if (!pnlPages.Controls.Contains(associatedPage.Page))
this.pnlPages.Controls.Add(associatedPage.Page);
- // new way of notifying activation. Goal is to get rid of BackStageViewContentPanel
- // so plain old user controls can be added
+ // new way of notifying activation.
if (associatedPage.Page is IActivate)
{
try
{
- ((IActivate) (associatedPage.Page)).Activate();
+ ((IActivate)(associatedPage.Page)).Activate();
}
catch (Exception ex)
{
@@ -544,7 +586,7 @@ protected override void OnPaint(PaintEventArgs e)
{
try
{
- ((IDeactivate) ((BackstageViewPage) (page)).Page).Deactivate();
+ ((IDeactivate)((BackstageViewPage)(page)).Page).Deactivate();
}
catch (Exception ex)
{