Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 80 additions & 38 deletions ExtLibs/Controls/BackstageView/BackstageView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
namespace MissionPlanner.Controls.BackstageView
{
/// <summary>
/// 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.
/// </summary>
/// <remarks>
/// 'Tabs' are added as a control in a <see cref="BackstageViewPage"/>
Expand Down Expand Up @@ -61,6 +62,7 @@ public int WidthMenu
}
}

// Tracks the currently popped-out page (if any)
private BackstageViewPage popoutPage = null;

private int ButtonTopPos = 0;
Expand All @@ -75,8 +77,6 @@ public BackstageView()
pnlMenu.BackColor = _buttonsAreaBgColor;
pnlMenu.PencilBorderColor = _buttonsAreaPencilColor;
pnlMenu.GradColor = this.BackColor;


}

public void UpdateDisplay()
Expand All @@ -86,7 +86,6 @@ public void UpdateDisplay()
if (!itemType.Show)
continue;


if (itemType.Page != null)
{
itemType.Page.Location = new Point(0, 0);
Expand Down Expand Up @@ -127,7 +126,6 @@ public Color ButtonsAreaPencilColor
}
}


[Description("Background color for the buttons region"), Category("Appearance")]
[DefaultValue(typeof(Color), "White")]
public Color ButtonsAreaBgColor
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -331,7 +327,6 @@ public void DrawMenu(BackstageViewPage CurrentPage, bool force = false)
}
continue;
}

}
else
{
Expand All @@ -355,7 +350,6 @@ private bool PageHasChildren(BackstageViewPage parent)
}
}
}

return false;
}

Expand All @@ -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'
*/
/// <summary>
/// Experimental - double clicking a button will spawn it out into a new form
/// Allows interacting with two pages simultaneously.
/// </summary>
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;
Expand All @@ -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;

Expand Down Expand Up @@ -432,6 +453,10 @@ private void ButtonClick(object sender, EventArgs e)
this.ActivatePage(associatedPage);
}

/// <summary>
/// Activates the selected page and displays it in the content panel.
/// Also handles closing any existing pop-out windows.
/// </summary>
public void ActivatePage(BackstageViewPage associatedPage)
{
if (associatedPage == null)
Expand All @@ -455,22 +480,20 @@ public void ActivatePage(BackstageViewPage associatedPage)
{
try
{
((IDeactivate) (_activePage.Page)).Deactivate();
((IDeactivate)(_activePage.Page)).Deactivate();
}
catch (Exception ex)
{
log.Error(ex);
}
}

// 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<BackstageViewButton>().Single(b => b.Tag == _activePage);
Expand All @@ -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)
{
Expand Down Expand Up @@ -544,7 +586,7 @@ protected override void OnPaint(PaintEventArgs e)
{
try
{
((IDeactivate) ((BackstageViewPage) (page)).Page).Deactivate();
((IDeactivate)((BackstageViewPage)(page)).Page).Deactivate();
}
catch (Exception ex)
{
Expand Down