#region Disclaimer / License
// Copyright (C) 2010, Jackie Ng
// http://trac.osgeo.org/mapguide/wiki/maestro, jumpinjackie@gmail.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion Disclaimer / License
using System;
using System.Collections.Generic;
using System.Windows.Forms;
using WeifenLuo.WinFormsUI.Docking;
namespace Maestro.Shared.UI
{
///
/// The Workbench base class
///
public partial class WorkbenchBase : Form
{
private MenuStrip menu;
private ToolStripContainer toolStripContainer;
private ToolStrip toolbar;
private StatusStrip status;
private ToolStripStatusLabel statusLabel;
private readonly DockPanel contentPanel;
private ContextMenuStrip ctxToolbar;
private IWorkbenchInitializer _workbenchInitializer;
private WorkbenchBase()
{
InitializeComponent();
}
///
/// Initializes a new instance of the WorkbenchBase class
///
///
protected WorkbenchBase(IWorkbenchInitializer init)
: this()
{
_workbenchInitializer = init;
_toolstrips = new Dictionary();
_toolstripRegions = new Dictionary();
this.Icon = _workbenchInitializer.GetIcon();
this.WindowState = init.StartMaximized ? FormWindowState.Maximized : FormWindowState.Normal;
contentPanel = new DockPanel();
contentPanel.ActiveDocumentChanged += OnActiveDocumentChanged;
contentPanel.DocumentStyle = DocumentStyle.DockingWindow;
contentPanel.ShowDocumentIcon = true;
contentPanel.Dock = DockStyle.Fill;
contentPanel.DockLeftPortion = 250;
contentPanel.DockBottomPortion = 150;
contentPanel.DockRightPortion = 250;
menu = _workbenchInitializer.GetMainMenu(this);
toolStripContainer = new ToolStripContainer();
toolStripContainer.ContentPanel.Controls.Add(contentPanel);
toolStripContainer.Dock = DockStyle.Fill;
this.Controls.Add(toolStripContainer);
ctxToolbar = new ContextMenuStrip();
menu.ContextMenuStrip = ctxToolbar;
toolStripContainer.TopToolStripPanel.ContextMenuStrip = ctxToolbar;
toolStripContainer.BottomToolStripPanel.ContextMenuStrip = ctxToolbar;
toolStripContainer.LeftToolStripPanel.ContextMenuStrip = ctxToolbar;
toolStripContainer.RightToolStripPanel.ContextMenuStrip = ctxToolbar;
toolbar = _workbenchInitializer.GetMainToolStrip(this);
toolbar.Stretch = true;
toolbar.Tag = BASE_TOOLSTRIP;
AddToolbar(toolbar.Tag.ToString(), toolbar, ToolbarRegion.Top, true); //NOXLATE
status = new StatusStrip();
statusLabel = new ToolStripStatusLabel();
status.Items.Add(statusLabel);
this.Controls.Add(menu);
this.Controls.Add(status);
// Use the Idle event to update the status of menu and toolbar items.
Application.Idle += OnApplicationIdle;
}
private void OnActiveDocumentChanged(object sender, EventArgs e)
{
var doc = contentPanel.ActiveDocument as DockContent;
if (doc != null)
{
var vc = doc.Tag as IViewContent;
if (vc != null)
OnViewActivated(this, vc);
}
}
private const string BASE_TOOLSTRIP = "Base"; //NOXLATE
///
/// Called when a view content has been activated
///
///
///
protected virtual void OnViewActivated(object sender, IViewContent content)
{
}
private Dictionary _toolstrips;
private Dictionary _toolstripRegions;
///
/// Adds the toolbar.
///
/// The name.
/// The toolbar.
/// The region.
/// if set to true [can toggle visibility].
public void AddToolbar(string name, ToolStrip toolbar, ToolbarRegion region, bool canToggleVisibility)
{
_toolstrips.Add(name, toolbar);
_toolstripRegions.Add(name, region);
if (canToggleVisibility)
{
ToolStripMenuItem item = new ToolStripMenuItem();
item.Text = name;
item.Tag = name;
item.Checked = true;
item.CheckOnClick = true;
item.Click += delegate
{
SetToolbarVisibility(name, item.Checked);
};
ctxToolbar.Items.Add(item);
}
switch (region)
{
case ToolbarRegion.Top:
AddTopToolStrip(toolbar);
break;
case ToolbarRegion.Bottom:
toolStripContainer.BottomToolStripPanel.Controls.Add(toolbar);
break;
case ToolbarRegion.Left:
toolStripContainer.LeftToolStripPanel.Controls.Add(toolbar);
break;
case ToolbarRegion.Right:
toolStripContainer.RightToolStripPanel.Controls.Add(toolbar);
break;
}
}
///
/// Sets the toolbar visibility.
///
/// Name of the toolbar.
/// if set to true [visible].
public void SetToolbarVisibility(string toolbarName, bool visible)
{
ToolStrip strip = GetToolbar(toolbarName);
if (strip != null)
{
ToolbarRegion region = _toolstripRegions[toolbarName];
if (visible)
{
switch (region)
{
case ToolbarRegion.Bottom:
toolStripContainer.BottomToolStripPanel.Controls.Add(strip);
break;
case ToolbarRegion.Left:
toolStripContainer.LeftToolStripPanel.Controls.Add(strip);
break;
case ToolbarRegion.Right:
toolStripContainer.RightToolStripPanel.Controls.Add(strip);
break;
case ToolbarRegion.Top:
AddTopToolStrip(strip);
break;
}
}
else
{
switch (region)
{
case ToolbarRegion.Bottom:
toolStripContainer.BottomToolStripPanel.Controls.Remove(strip);
break;
case ToolbarRegion.Left:
toolStripContainer.LeftToolStripPanel.Controls.Remove(strip);
break;
case ToolbarRegion.Right:
toolStripContainer.RightToolStripPanel.Controls.Remove(strip);
break;
case ToolbarRegion.Top:
toolStripContainer.TopToolStripPanel.Controls.Remove(strip);
break;
}
}
}
}
//SUPER-DUPER HACK: ToolStrip objects are added in the most unintuitive manner when ordering is a concern
//
//You'd think first one added will be the top-most tool strip. Nope! Not at all!
//So we need this hacky method to ensure the base toolstrip will always be the top-most one
private void AddTopToolStrip(ToolStrip strip)
{
var panel = toolStripContainer.TopToolStripPanel;
if ((string)strip.Tag == BASE_TOOLSTRIP)
panel.Controls.Add(strip);
else
{
var controls = new List();
panel.SuspendLayout();
Control baseTs = null;
for (int i = 0; i < panel.Controls.Count; i++)
{
if ((string)panel.Controls[i].Tag == BASE_TOOLSTRIP)
baseTs = panel.Controls[i];
else
controls.Add(panel.Controls[i]);
}
panel.Controls.Clear();
foreach (var cnt in controls)
{
panel.Controls.Add(cnt);
}
panel.Controls.Add(baseTs);
panel.Controls.Add(strip);
panel.ResumeLayout();
}
}
///
/// Gets the toolbar.
///
/// The name.
///
public ToolStrip GetToolbar(string name)
{
if (_toolstrips.ContainsKey(name))
return _toolstrips[name];
return null;
}
///
/// Gets the toolbar names.
///
/// The toolbar names.
public ICollection ToolbarNames => _toolstrips.Keys;
///
/// Sets the status label.
///
/// The text.
public void SetStatusLabel(string text) => statusLabel.Text = text;
///
/// Sets the title.
///
/// The title.
public void SetTitle(string title) => this.Text = title;
///
/// Gets the active view in the document region
///
public IViewContent ActiveDocumentView
{
get
{
var doc = contentPanel.ActiveDocument as DockContent;
if (doc != null)
return doc.Tag as IViewContent;
return null;
}
}
///
/// Shows the content.
///
/// The vc.
internal void ShowContent(IViewContent vc)
{
DockContent content = new DockContent();
content.TabText = vc.Title;
content.Text = vc.Title;
content.ToolTipText = vc.Description;
content.CloseButton = vc.AllowUserClose;
content.CloseButtonVisible = vc.AllowUserClose;
content.Tag = vc;
var icon = vc.ViewIcon;
if (icon != null)
{
content.Icon = icon;
content.ShowIcon = true;
}
if (vc.IsExclusiveToDocumentRegion)
{
content.DockAreas = DockAreas.Document;
}
else
{
content.DockAreas = (DockAreas)(vc.DefaultRegion);
}
vc.SetParentForm(content);
vc.ViewContentActivating += (sender, e) =>
{
content.Activate();
};
vc.TitleChanged += (sender, e) =>
{
content.TabText = vc.Title;
content.Text = vc.Title;
};
vc.DescriptionChanged += (sender, e) =>
{
content.ToolTipText = vc.Description;
};
if (vc.AllowUserClose && vc.IsExclusiveToDocumentRegion)
content.TabPageContextMenuStrip = documentTabContextMenu;
content.ClientSize = vc.ContentControl.Size;
vc.ContentControl.Dock = DockStyle.Fill;
content.Controls.Add(vc.ContentControl);
if (vc.IsModalWindow && vc.DefaultRegion == ViewRegion.Floating)
{
content.StartPosition = FormStartPosition.CenterParent;
content.ShowDialog();
}
else
{
content.Show(contentPanel);
}
}
// Use the Idle event to update the status of menu and toolbar.
// Depending on your application and the number of menu items with complex conditions,
// you might want to update the status less frequently.
private void OnApplicationIdle(object sender, EventArgs e) => _workbenchInitializer.UpdateMenuItemStatus(menu, _toolstrips.Values);
private void closeToolStripMenuItem_Click(object sender, EventArgs e)
{
var doc = contentPanel.ActiveDocument as DockContent;
if (doc != null)
{
var view = doc.Tag as IViewContent;
view.Close();
}
}
private void closeAllToolStripMenuItem_Click(object sender, EventArgs e)
{
var closeMe = new List();
foreach (var doc in contentPanel.Documents)
{
var cnt = doc as DockContent;
if (cnt != null)
{
var view = cnt.Tag as IViewContent;
if (view != null)
closeMe.Add(view);
}
}
foreach (var view in closeMe)
view.Close();
}
private void closeAllButThisToolStripMenuItem_Click(object sender, EventArgs e)
{
var closeMe = new List();
foreach (var doc in contentPanel.Documents)
{
if (doc == contentPanel.ActiveDocument)
continue;
var cnt = doc as DockContent;
if (cnt != null)
{
var view = cnt.Tag as IViewContent;
if (view != null)
closeMe.Add(view);
}
}
foreach (var view in closeMe)
view.Close();
}
}
///
/// Defines the valid regions a toolbar can reside on a workbench
///
public enum ToolbarRegion
{
///
/// On the top
///
Top,
///
/// On the left
///
Left,
///
/// On the right
///
Right,
///
/// On the bottom
///
Bottom
}
}