// *********************************
// Message from Original Author:
//
// 2008 Jose Menendez Poo
// Please give me credit if you use this code. It's all I ask.
// Contact me for more info: menendezpoo@gmail.com
// *********************************
//
// Original project from http://ribbon.codeplex.com/
// Continue to support and maintain by http://officeribbon.codeplex.com/
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Security.Permissions;
using System.Windows.Forms.RibbonHelpers;
namespace System.Windows.Forms
{
///
/// Provides a Ribbon toolbar
///
[Designer(typeof(RibbonDesigner))]
public class Ribbon
: Control, IMessageFilter
{
private delegate void HandlerCallbackMethode();
#region Const
public const string Version = "5.0";
private const int DefaultTabSpacing = 6;
private const int DefaultPanelSpacing = 3;
#endregion
#region Static
public static int CaptionBarHeight = 24;
#endregion
#region Fields
private int _contextspace = 0;
private bool? _isopeninvisualstudiodesigner;
internal bool ForceOrbMenu;
private Size _lastSizeMeasured;
private Padding _tabsMargin;
internal bool _minimized = true;//is the ribbon minimized?
internal bool _expanded; //is the ribbon currently expanded when in minimize mode
internal bool _expanding; //is the ribbon expanding. Flag used to prevent calling methods multiple time while the size changes
//private int _minimizedHeight;//height when minimized
private int _expandedHeight; //height when expanded
private RibbonRenderer _renderer;
private bool _useAlwaysStandardTheme;
private Theme _theme;
private Padding _panelMargin;
private RibbonTab _activeTab;
private RibbonTab _lastSelectedTab;
//private float _tabSum;
private bool _updatingSuspended;
private bool _orbSelected;
private bool _orbPressed;
private bool _orbVisible;
private Image _orbImage;
private string _orbText;
private Size _orbTextSize = Size.Empty;
//private bool _quickAcessVisible;
private RibbonWindowMode _borderMode;
private GlobalHook _mouseHook;
private GlobalHook _keyboardHook;
private Font _RibbonItemFont = new Font("Trebuchet MS", 9);
private Font _RibbonTabFont = new Font("Trebuchet MS", 9);
private bool _CaptionBarVisible;
private bool _enabled;
internal RibbonItem ActiveTextBox; //tracks the current active textbox so we can hide it when you click off it
#endregion
#region Events
///
/// Occours when the Orb is clicked
///
public event EventHandler OrbClicked;
///
/// Occours when the Orb is double-clicked
///
public event EventHandler OrbDoubleClick;
///
/// Occours when the property value has changed
///
public event EventHandler ActiveTabChanged;
///
/// Occours when the property has changed
///
public event EventHandler ActualBorderModeChanged;
///
/// Occours when the property value has changed
///
public event EventHandler CaptionButtonsVisibleChanged;
/////
///// Occours when the Ribbon changes its miminized state
/////
public event EventHandler ExpandedChanged;
#endregion
#region Ctor
///
/// Creates a new Ribbon control
///
public Ribbon()
{
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.Selectable, false);
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
Dock = DockStyle.Top;
Tabs = new RibbonTabCollection(this);
Contexts = new RibbonContextCollection(this);
OrbsPadding = new Padding(8, 5, 8, 3);
TabsPadding = new Padding(8, 5, 8, 3);
_tabsMargin = new Padding(12, 24 + 2, 20, 0);
TabTextMargin = new Padding(4, 2, 4, 2);
TabContentMargin = new Padding(1, 0, 1, 2);
PanelPadding = new Padding(3);
_panelMargin = new Padding(3, 2, 3, 15);
PanelMoreMargin = new Padding(0, 0, 1, 1);
PanelSpacing = DefaultPanelSpacing;
ItemPadding = new Padding(1, 0, 1, 0);
ItemMargin = new Padding(4, 2, 4, 2);
ItemImageToTextSpacing = 3;
TabSpacing = DefaultTabSpacing;
DropDownMargin = new Padding(2);
_renderer = new RibbonProfessionalRenderer(this);
_orbVisible = true;
OrbDropDown = new RibbonOrbDropDown(this);
QuickAccessToolbar = new RibbonQuickAccessToolbar(this);
//_quickAcessVisible = true;
MinimizeButton = new RibbonCaptionButton(RibbonCaptionButton.CaptionButton.Minimize);
MaximizeRestoreButton = new RibbonCaptionButton(RibbonCaptionButton.CaptionButton.Maximize);
CloseButton = new RibbonCaptionButton(RibbonCaptionButton.CaptionButton.Close);
LayoutHelper = new LayoutHelper(this);
MinimizeButton.SetOwner(this);
MaximizeRestoreButton.SetOwner(this);
CloseButton.SetOwner(this);
_CaptionBarVisible = true;
Font = SystemFonts.CaptionFont;
BorderMode = RibbonWindowMode.NonClientAreaGlass;
_minimized = false;
_expanded = true;
_enabled = true;
RibbonPopupManager.PopupRegistered += OnPopupRegistered;
RibbonPopupManager.PopupUnRegistered += OnPopupUnregistered;
Control parent = null;
ParentChanged += (o1, e1) =>
{
if (parent != null)
{
parent.KeyUp -= Ribbon_KeyUp;
parent.KeyDown -= parent_KeyDown;
}
parent = Parent;
Application.AddMessageFilter(this);
if (parent is Form)
{
var form = parent as Form;
form.KeyPreview = true;
form.FormClosing += (o, e) =>
{
Application.RemoveMessageFilter(this);
};
}
if (parent != null)
{
parent.KeyDown += parent_KeyDown;
parent.KeyUp += Ribbon_KeyUp;
}
};
}
public bool PreFilterMessage(ref Message m)
{
// Handle Alt - KeyUp
const int WM_SYSKEYUP = 261;
if (m.Msg == WM_SYSKEYUP)
{
AltPressed = false;
Invalidate();
}
return false;
}
internal bool AltPressed;
private void parent_KeyDown(object sender, KeyEventArgs e)
{
//var reDraw = false;
//if (AltPressed != e.Alt)
//{
// reDraw = true;
//}
AltPressed = e.Alt;
//if (reDraw)
Invalidate();
}
// Function to check if item was targeted by AltKey
private bool IsTargetedAltKey(string key, string altKey)
{
if (!String.IsNullOrEmpty(key) && String.Equals(key, altKey, StringComparison.InvariantCultureIgnoreCase))
return true;
return false;
}
// Choose an action for the selected item
private void ParseItem(RibbonItem item)
{
//if (item is RibbonDropDown)
// (item as RibbonDropDown).Focus();
//else
if (item is RibbonButton)
(item as RibbonButton).PerformClick();
else if (item is RibbonCheckBox)
(item as RibbonCheckBox).Checked = !(item as RibbonCheckBox).Checked;
else if (item is RibbonTextBox)
(item as RibbonTextBox).SetSelected(true);
}
public void Ribbon_KeyUp(object sender, KeyEventArgs e)
{
// character on key up
var char1 = (new KeysConverter().ConvertToString(e.KeyValue));
if (e.Alt && e.KeyValue > 0)
{
var ribbon1 = this;
if (ribbon1.OrbPressed)
{
#region Check in Orb Menus
foreach (var item in ribbon1.OrbDropDown.MenuItems)
{
if (IsTargetedAltKey(item.AltKey, char1))
{
ParseItem(item);
goto done;
}
}
#endregion
}
if (ribbon1.ActiveTab != null)
{
#region Check in Selected Tab
foreach (var panel in ribbon1.ActiveTab.Panels)
{
foreach (var item in panel.GetItems())
{
if (IsTargetedAltKey(item.AltKey, char1))
{
ParseItem(item);
goto done;
}
}
}
#endregion
}
if (IsTargetedAltKey(ribbon1.AltKey, char1))
{
ribbon1.ShowOrbDropDown();
goto done;
}
#region Check Tabs
foreach (var tab in ribbon1.Tabs)
{
if (IsTargetedAltKey(tab.AltKey, char1))
{
ribbon1.ActiveTab = tab;
goto done;
}
}
#endregion
done:;
}
//AltPressed = false;
//Invalidate();
}
///
/// Ribbon is open in Visual Studio Designer
///
protected bool IsOpenInVisualStudioDesigner()
{
if (!_isopeninvisualstudiodesigner.HasValue)
{
_isopeninvisualstudiodesigner = LicenseManager.UsageMode == LicenseUsageMode.Designtime ||
this.DesignMode;
if (!_isopeninvisualstudiodesigner.Value)
{
try
{
using (var process = System.Diagnostics.Process.GetCurrentProcess())
{
_isopeninvisualstudiodesigner = process.ProcessName.ToLowerInvariant().Contains("devenv");
}
}
catch
{
}
}
}
return _isopeninvisualstudiodesigner.Value;
}
///
/// Clean up any resources being used.
///
/// true if managed resources should be disposed; otherwise, false.
protected override void Dispose(bool disposing)
{
if (disposing && RibbonDesigner.Current == null)
{
try
{
foreach (RibbonTab tab in Tabs)
tab.Dispose();
}
catch (InvalidOperationException)
{
if (!IsOpenInVisualStudioDesigner())
{
throw;
}
}
OrbDropDown.Dispose();
QuickAccessToolbar.Dispose();
MinimizeButton.Dispose();
MaximizeRestoreButton.Dispose();
if (_RibbonItemFont != null)
{
_RibbonItemFont.Dispose();
}
if (_RibbonTabFont != null)
{
_RibbonTabFont.Dispose();
}
CloseButton.Dispose();
RibbonPopupManager.PopupRegistered -= OnPopupRegistered;
RibbonPopupManager.PopupUnRegistered -= OnPopupUnregistered;
//GC.SuppressFinalize(this); //not necessary, it is called in base class
}
DisposeHooks();
base.Dispose(disposing);
}
//Finalize is called by base class "System.ComponentModel.Component"
//~Ribbon()
//{
// Dispose(false);
//}
private void DisposeHooks()
{
if (_mouseHook != null)
{
_mouseHook.MouseWheel -= _mouseHook_MouseWheel;
_mouseHook.MouseDown -= _mouseHook_MouseDown;
_mouseHook.Dispose();
_mouseHook = null;
}
if (_keyboardHook != null)
{
_keyboardHook.KeyDown -= _keyboardHook_KeyDown;
_keyboardHook.Dispose();
_keyboardHook = null;
}
}
#endregion
#region Props
[RefreshProperties(RefreshProperties.All)]
[DefaultValue(0)]
[Category("Behavior")]
public int ContextSpace
{
get => _contextspace;
set
{
_contextspace = value;
OrbStyle = OrbStyle;
}
}
///
/// Gets or sets the key combination that activates this element when the Alt key was pressed
///
[DefaultValue(null)]
[Category("Behavior")]
public string AltKey { get; set; }
///
/// Gets or sets the tabs expanded state when in minimize mode
///
[DefaultValue(true)]
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool Expanded
{
get => _expanded;
set
{
_expanded = value;
if (!IsDesignMode() && Minimized)
{
_expanding = true;
if (_expanded)
Height = _expandedHeight;
else
Height = MinimizedHeight;
OnExpandedChanged(EventArgs.Empty);
if (_expanded)
SetUpHooks();
else if (!_expanded && RibbonPopupManager.PopupCount == 0)
DisposeHooks();
//UpdateRegions();
Invalidate();
_expanding = false;
}
}
}
[DefaultValue(true)]
[Category("Behavior")]
[Description("Sets if the Ribbon should be enabled")]
public new bool Enabled
{
get => _enabled;
set
{
_enabled = value;
Invalidate();
UpdateRegions();
}
}
///
/// Gets the height of the ribbon when collapsed
///
//[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false)]
[Description("Gets the height of the ribbon when collapsed")]
public int MinimizedHeight
{
get
{
int tabBottom = Tabs.Count > 0 ? Tabs[0].Bounds.Bottom : 0;
return Math.Max(OrbBounds.Bottom, tabBottom) + 1;
}
}
//[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new Size Size
{
get => base.Size;
set
{
base.Size = value;
Height = value.Height;
if (!Minimized || (!_expanding && Expanded))
_expandedHeight = Height;
}
}
internal Rectangle CaptionTextBounds
{
get
{
if (RightToLeft == RightToLeft.No)
{
int left = 0;
int right = Width - 100;
int contextLeft = right;
int contextRight = left;
if (OrbVisible) left = OrbBounds.Right;
if (QuickAccessToolbar.Visible) left = QuickAccessToolbar.Bounds.Right + 20;
if (QuickAccessToolbar.Visible && QuickAccessToolbar.DropDownButtonVisible) left = QuickAccessToolbar.DropDownButton.Bounds.Right;
// Determine the limits of the visible contexts
foreach (RibbonContext context in Contexts)
{
if (context.Visible)
{
contextLeft = Math.Min(contextLeft, context.Bounds.Left);
contextRight = Math.Max(contextRight, context.Bounds.Right);
}
}
/* Determine which side of the context is bigger to display the caption bar.
* In Word/Excel, there are always enough tabs that the left side is always big enough, but this
* may not be the case in the user's app. If no context is displayed, both will be the same size. */
Rectangle r;
if (contextLeft - left > right - contextRight)
{
r = Rectangle.FromLTRB(left, 0, contextLeft, CaptionBarSize);
}
else
{
r = Rectangle.FromLTRB(contextRight, 0, right, CaptionBarSize);
}
return r;
}
else
{
int right = ClientRectangle.Right;
int left = 100;
int contextLeft = right;
int contextRight = left;
if (OrbVisible) right = OrbBounds.Left;
if (QuickAccessToolbar.Visible) right = QuickAccessToolbar.Bounds.Left - 20;
if (QuickAccessToolbar.Visible && QuickAccessToolbar.DropDownButtonVisible) right = QuickAccessToolbar.DropDownButton.Bounds.Left;
// Determine the limits of the visible contexts
foreach (RibbonContext context in Contexts)
{
if (context.Visible)
{
contextLeft = Math.Min(contextLeft, context.Bounds.Left);
contextRight = Math.Max(contextRight, context.Bounds.Right);
}
}
/* Determine which side of the context is bigger to display the caption bar.
* In Word/Excel, there are always enough tabs that the left side is always big enough, but this
* may not be the case in the user's app. If no context is displayed, both will be the same size. */
Rectangle r;
if (contextLeft - left > right - contextRight)
{
r = Rectangle.FromLTRB(left, 0, contextLeft, CaptionBarSize);
}
else
{
r = Rectangle.FromLTRB(contextRight, 0, right, CaptionBarSize);
}
return r;
}
}
}
///
/// Gets if the caption buttons are currently visible, according to the value specified in
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool CaptionButtonsVisible { get; private set; }
///
/// Gets the Ribbon's close button
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonCaptionButton CloseButton { get; }
///
/// Gets the Ribbon's maximize-restore button
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonCaptionButton MaximizeRestoreButton { get; }
///
/// Gets the Ribbon's minimize button
///
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonCaptionButton MinimizeButton { get; }
///
/// Gets or sets the RibbonFormHelper object if the parent form is IRibbonForm
///
[Browsable(false)]
public RibbonFormHelper FormHelper
{
get
{
IRibbonForm irf = Parent as IRibbonForm;
if (irf != null)
{
return irf.Helper;
}
return null;
}
}
///
/// Gets the Layout Helper
///
[Browsable(false)]
public LayoutHelper LayoutHelper { get; }
///
/// Gets the actual that the ribbon has.
/// It's value may vary from
/// because of computer and operative system capabilities.
///
[Browsable(false)]
public RibbonWindowMode ActualBorderMode { get; private set; }
///
/// Gets or sets the border mode of the ribbon relative to the window where it is contained
///
[DefaultValue(RibbonWindowMode.NonClientAreaGlass)]
[Category("Appearance")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Description("Specifies how the Ribbon is placed on the window border and the non-client area")]
public RibbonWindowMode BorderMode
{
get => _borderMode;
set
{
_borderMode = value;
RibbonWindowMode actual = value;
if (value == RibbonWindowMode.NonClientAreaGlass && !WinApi.IsGlassEnabled)
{
actual = RibbonWindowMode.NonClientAreaCustomDrawn;
}
if (FormHelper == null || (value == RibbonWindowMode.NonClientAreaCustomDrawn && Environment.OSVersion.Platform != PlatformID.Win32NT))
{
actual = RibbonWindowMode.InsideWindow;
}
SetActualBorderMode(actual);
}
}
///
/// Gets the Orb's DropDown
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[Category("Orb")]
[Browsable(true)]
public RibbonOrbDropDown OrbDropDown { get; }
///
/// Gets or sets the height of the Panel Caption area.
///
[DefaultValue(15)]
[Category("Appearance")]
[Description("Gets or sets the height of the Panel Caption area")]
public int PanelCaptionHeight
{
get => _panelMargin.Bottom;
set
{
_panelMargin.Bottom = value;
UpdateRegions();
Invalidate();
}
}
///
/// Gets the QuickAcessToolbar
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public RibbonQuickAccessToolbar QuickAccessToolbar { get; }
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Theme Theme => _theme == null ? Theme.Standard : _theme;
///
/// Gets or sets the Style of the orb
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Orb")]
[DefaultValue(RibbonOrbStyle.Office_2007)]
public RibbonOrbStyle OrbStyle
{
get => Theme.Style;
set
{
var changed = value != Theme.Style;
EnsureCustomThemeCreated(value, ThemeColor);
Theme.Style = value;
if (value == RibbonOrbStyle.Office_2007)
{
TabsPadding = new Padding(8, 4, 8, 4);
OrbsPadding = new Padding(8, 4, 8, 4);
if (CaptionBarVisible)
{
_tabsMargin = new Padding(12, CaptionBarHeight + 2 + ContextSpace, 20, 0);
}
else
{
_tabsMargin = new Padding(12, 2 + ContextSpace, 20, 0);
}
TabContentMargin = new Padding(1, 0, 2, 2);
TabContentPadding = new Padding(0);
TabSpacing = 6;
PanelSpacing = 4;
PanelPadding = new Padding(3);
_panelMargin = new Padding(3, 2, 3, 15);
PanelMoreSize = new Size(6, 6);
PanelMoreMargin = new Padding(0, 0, 1, 1);
ItemMargin = new Padding(4, 2, 4, 2);
ItemPadding = new Padding(1, 0, 1, 0);
ItemImageToTextSpacing = 4;
}
else if ((value == RibbonOrbStyle.Office_2010) ||
(value == RibbonOrbStyle.Office_2010_Extended))
{
TabsPadding = new Padding(10, 3, 7, 2);
OrbsPadding = new Padding(17, 4, 15, 4);
if (CaptionBarVisible)
{
TabsMargin = new Padding(6, CaptionBarHeight + 2 + ContextSpace, 20, 0);
}
else
{
TabsMargin = new Padding(6, 2 + ContextSpace, 20, 0);
}
TabContentMargin = new Padding(0, 0, 0, 2);
TabContentPadding = new Padding(0);
TabSpacing = 3;
PanelSpacing = 0;
PanelPadding = new Padding(0, 1, 1, 1);
_panelMargin = new Padding(2, 2, 2, 15);
PanelMoreSize = new Size(6, 6);
PanelMoreMargin = new Padding(0, 0, 2, 0);
ItemMargin = new Padding(3, 2, 0, 2);
ItemPadding = new Padding(1, 0, 1, 0);
ItemImageToTextSpacing = 11;
}
else if (value == RibbonOrbStyle.Office_2013)
{
TabsPadding = new Padding(8, 4, 8, 1);
OrbsPadding = new Padding(15, 3, 15, 3);
if (CaptionBarVisible)
{
_tabsMargin = new Padding(5, CaptionBarHeight + 2 + ContextSpace, 20, 0);
}
else
{
_tabsMargin = new Padding(5, 2 + ContextSpace, 20, 0);
}
TabContentMargin = new Padding(0, 0, 0, 2);
TabContentPadding = new Padding(0);
TabSpacing = 4;
PanelSpacing = 0;
PanelPadding = new Padding(3);
_panelMargin = new Padding(3, 2, 3, 15);
PanelMoreSize = new Size(6, 6);
PanelMoreMargin = new Padding(0, 0, 1, 0);
ItemMargin = new Padding(2, 2, 0, 2);
ItemPadding = new Padding(1, 0, 1, 0);
ItemImageToTextSpacing = 11;
}
UpdateRegions();
Invalidate();
if (changed)
{
OrbStyleChanged?.Invoke(this, EventArgs.Empty);
}
}
}
public event EventHandler OrbStyleChanged;
///
/// Gets or sets the theme of the ribbon control
///
//Michael Spradlin 07/05/2013
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
[Category("Appearance")]
[DefaultValue(RibbonTheme.Normal)]
public RibbonTheme ThemeColor
{
get => Theme.RibbonTheme;
set
{
EnsureCustomThemeCreated(OrbStyle, value);
Theme.RibbonTheme = value;
OnRegionsChanged();
Invalidate();
}
}
///
/// If this value is set, you can still link a Ribbon fixed to the Standard Theme.
/// E.g. used to statically link the theme builder form to the Standard theme which is
/// used in the .
///
[DefaultValue(false)]
[Category("Appearance")]
[Description("If this value is set, you can still link a Ribbon fixed to the Standard Theme.")]
public bool UseAlwaysStandardTheme
{
get => _useAlwaysStandardTheme;
set
{
_useAlwaysStandardTheme = value;
if (value)
{
_theme = null;
}
}
}
///
/// Gets or sets the Text in the orb. Only available when the OrbStyle is set to Office2010
///
[DefaultValue(null)]
[Category("Orb")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string OrbText
{
get => _orbText;
set
{
_orbText = value;
RecalculateOrbTextSize();
OnRegionsChanged();
Invalidate();
}
}
///
/// Gets or sets the Image of the orb
///
[DefaultValue(null)]
[Category("Orb")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Image OrbImage
{
get => _orbImage;
set { _orbImage = value; OnRegionsChanged(); Invalidate(OrbBounds); }
}
///
/// Gets or sets if the Ribbon should show an orb on the corner
///
[DefaultValue(true)]
[Category("Orb")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool OrbVisible
{
get => _orbVisible;
set { _orbVisible = value; OnRegionsChanged(); }
}
///
/// Gets or sets if the Orb is currently selected
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool OrbSelected
{
get => _orbSelected;
set { _orbSelected = value; Invalidate(OrbBounds); }
}
///
/// Gets or sets if the Orb is currently pressed
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool OrbPressed
{
get => _orbPressed;
set { _orbPressed = value; Invalidate(OrbBounds); }
}
///
/// Gets the Height of the caption bar
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int CaptionBarSize => CaptionBarHeight;
///
/// Gets the bounds of the orb
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Rectangle OrbBounds
{
get
{
if (OrbStyle == RibbonOrbStyle.Office_2007)
{
if (OrbVisible && RightToLeft == RightToLeft.No && CaptionBarVisible)
{
return new Rectangle(4, 4, 36, 36);
}
if (OrbVisible && RightToLeft == RightToLeft.Yes && CaptionBarVisible)
{
return new Rectangle(Width - 36 - 4, 4, 36, 36);
}
if (RightToLeft == RightToLeft.No)
{
return new Rectangle(4, 4, 0, 0);
}
return new Rectangle(Width - 4, 4, 0, 0);
}
if ((OrbStyle == RibbonOrbStyle.Office_2010) || (OrbStyle == RibbonOrbStyle.Office_2010_Extended)) //Kevin Carbis - office 2010 style orb
{
//Measure the string size of the button text so we know how big to make the button
Size contentSize = _orbTextSize;
//If we are using an image adjust the size
if (OrbImage != null)
{
contentSize.Width = Math.Max(contentSize.Width, OrbImage.Size.Width);
contentSize.Height = Math.Max(contentSize.Height, OrbImage.Size.Height);
}
if (OrbVisible && RightToLeft == RightToLeft.No)
{
return new Rectangle(1, TabsMargin.Top, contentSize.Width + OrbsPadding.Left + OrbsPadding.Right, OrbsPadding.Top + contentSize.Height + OrbsPadding.Bottom);
}
if (OrbVisible && RightToLeft == RightToLeft.Yes && CaptionBarVisible)
{
return new Rectangle(Width - contentSize.Width - OrbsPadding.Left - OrbsPadding.Right - 1, TabsMargin.Top, contentSize.Width + OrbsPadding.Left + OrbsPadding.Right, OrbsPadding.Top + contentSize.Height + OrbsPadding.Bottom);
}
if (RightToLeft == RightToLeft.No)
{
return new Rectangle(4, 4, 0, 0);
}
return new Rectangle(Width - 4, 4, 0, 0);
}
else //Michael Spradlin - 05/03/2013 Office 2013 Style Changes
{
//Measure the string size of the button text so we know how big to make the button
Size contentSize = _orbTextSize;
//If we are using an image adjust the size
if (OrbImage != null)
{
contentSize.Width = Math.Max(contentSize.Width, OrbImage.Size.Width);
contentSize.Height = Math.Max(contentSize.Height, OrbImage.Size.Height);
}
if (OrbVisible && RightToLeft == RightToLeft.No)
{
//Steve
//return new Rectangle(0, TabsMargin.Top, contentSize.Width + OrbsPadding.Left + OrbsPadding.Right, OrbsPadding.Top + contentSize.Height + OrbsPadding.Bottom);
return new Rectangle(0, TabsMargin.Top, contentSize.Width + OrbsPadding.Left + OrbsPadding.Right, OrbsPadding.Top + contentSize.Height + OrbsPadding.Bottom + 1);
}
if (OrbVisible && RightToLeft == RightToLeft.Yes && CaptionBarVisible)
{
return new Rectangle(Width - contentSize.Width - OrbsPadding.Left - OrbsPadding.Right - 4, TabsMargin.Top, contentSize.Width + OrbsPadding.Left + OrbsPadding.Right, OrbsPadding.Top + contentSize.Height + OrbsPadding.Bottom);
}
if (RightToLeft == RightToLeft.No)
{
return new Rectangle(4, 4, 0, 0);
}
return new Rectangle(Width - 4, 4, 0, 0);
}
}
}
///
/// Gets the next tab to be activated
///
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonTab NextTab
{
get
{
if (ActiveTab == null || Tabs.Count == 0)
{
if (Tabs.Count == 0)
return null;
return Tabs[0];
}
int index = Tabs.IndexOf(ActiveTab);
if (index == Tabs.Count - 1)
{
return ActiveTab;
}
return Tabs[index + 1];
}
}
///
/// Gets the next tab to be activated
///
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonTab PreviousTab
{
get
{
if (ActiveTab == null || Tabs.Count == 0)
{
if (Tabs.Count == 0)
return null;
return Tabs[0];
}
int index = Tabs.IndexOf(ActiveTab);
if (index == 0)
{
return ActiveTab;
}
return Tabs[index - 1];
}
}
///
/// Gets or sets the internal spacing between the tab and its text
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding TabTextMargin { get; set; }
///
/// Gets or sets the margis of the DropDowns shown by the Ribbon
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding DropDownMargin { get; set; }
///
/// Gets or sets the external spacing of items on panels
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding ItemPadding { get; set; }
///
/// Gets or sets the padding between the image and text on a drop down RibbonItem.
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int ItemImageToTextSpacing { get; set; }
///
/// Gets or sets the internal spacing of items
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding ItemMargin { get; set; }
///
/// Gets or sets the tab that is currently active
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonTab ActiveTab
{
get => _activeTab;
set
{
RibbonTab NewTab = _activeTab;
foreach (RibbonTab tab in Tabs)
{
if (tab != value)
{
tab.SetActive(false);
}
else
{
NewTab = tab;
}
}
NewTab.SetActive(true);
_activeTab = value;
RemoveHelperControls();
value.UpdatePanelsRegions();
Invalidate();
RenewSensor();
OnActiveTabChanged(EventArgs.Empty);
}
}
///
/// Gets or sets the spacing leaded between panels
///
[DefaultValue(DefaultPanelSpacing)]
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int PanelSpacing { get; set; }
///
/// Gets or sets the size of the panel More glyph
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Size PanelMoreSize { get; set; } = new Size(7, 7);
///
/// Gets or sets the external spacing of panels inside of tabs
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding PanelPadding { get; set; }
///
/// Gets or sets the internal spacing of panels inside of tabs
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding PanelMargin
{
get => _panelMargin;
set => _panelMargin = value;
}
///
/// Gets or sets the external spacing of the More glyph
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding PanelMoreMargin { get; set; }
///
/// Gets or sets the spacing between tabs
///
[Browsable(false)]
[DefaultValue(DefaultTabSpacing)]
public int TabSpacing { get; set; }
///
/// Gets the collection of RibbonTab tabs
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public RibbonTabCollection Tabs { get; }
///
/// Gets or sets a value indicating if the Ribbon supports being minimized
///
[Category("Appearance")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool Minimized
{
get => _minimized;
set
{
_minimized = value;
if (!IsDesignMode())
{
if (_minimized)
{
Height = MinimizedHeight;
}
else
{
Height = _expandedHeight;
}
Expanded = !Minimized;
UpdateRegions();
Invalidate();
}
}
}
///
/// Gets the collection of Contexts of this Ribbon
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public RibbonContextCollection Contexts { get; }
///
/// Gets or sets the Renderer for this Ribbon control
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public RibbonRenderer Renderer
{
get => _renderer;
set
{
_renderer = value ?? throw new ArgumentNullException(nameof(Renderer), "Null renderer!");
Invalidate();
}
}
///
/// Gets or sets the internal spacing of the tab content pane
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding TabContentMargin { get; set; }
///
/// Gets or sets the external spacing of the tabs content pane
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding TabContentPadding { get; set; }
///
/// Gets a value indicating the external spacing of tabs
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding TabsMargin
{
get => _tabsMargin;
set
{
_tabsMargin = value;
UpdateRegions();
Invalidate();
}
}
///
/// Gets a value indicating the internal spacing of tabs
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding TabsPadding { get; set; }
///
/// Gets a value indicating the internal spacing of the orb
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Padding OrbsPadding { get; set; }
///
/// Overriden. The maximum size is fixed
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Size MaximumSize
{
get => new Size(0, 200);
set
{
//not supported
}
}
///
/// Overriden. The minimum size is fixed
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public override Size MinimumSize
{
get => new Size(0, 27);
set
{
//not supported
}
}
///
/// Overriden. The default dock of the ribbon is top
///
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[DefaultValue(DockStyle.Top)]
public override DockStyle Dock
{
get => base.Dock;
set => base.Dock = value;
}
///
/// Gets or sets the current panel sensor for this ribbon
///
[Browsable(false)]
public RibbonMouseSensor Sensor { get; private set; }
[DefaultValue(RightToLeft.No)]
public override RightToLeft RightToLeft
{
get => base.RightToLeft;
set
{
base.RightToLeft = value;
OnRegionsChanged();
}
}
///
/// sets or gets the visibility of the caption bar
///
[Category("Appearance")]
[DefaultValue(true)]
public bool CaptionBarVisible
{
get => _CaptionBarVisible;
set
{
_CaptionBarVisible = value;
OrbStyle = OrbStyle;
}
}
public override void Refresh()
{
try
{
if (IsDisposed == false)
{
if (InvokeRequired)
{
HandlerCallbackMethode del = Refresh;
Invoke(del);
}
else
{
base.Refresh();
}
}
}
catch (Exception)
{
}
}
#region cr
private string cr => "Professional Ribbon\n\n2009 Jos?Manuel Menéndez Poo\nwww.menendezpoo.com";
#endregion
/////
///// Gets or sets the Font associated with Ribbon Items.
/////
//[DefaultValue(null)]
//[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
//public Font RibbonItemFont
//{
// get { return _RibbonItemFont; }
// set { _RibbonItemFont = value;}
//}
///
/// Gets or sets the Font associated with Ribbon tabs and the ORB.
///
[DefaultValue(null)]
[Category("Appearance")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Font RibbonTabFont
{
get => _RibbonTabFont;
set { _RibbonTabFont = value; RecalculateOrbTextSize(); }
}
///
/// Specifies if a Tab is invisible in case it is the only one and the text is set to string.Empty.
///
[Category("Appearance")]
[Description("Specifies if a Tab is invisible in case it is the only one and the text is set to string.Empty.")]
[DefaultValue(true)]
public bool HideSingleTabIfTextEmpty { get; set; } = true;
#endregion
#region Handler Methods
///
/// Resends the mousedown to PopupManager
///
///
///
private void _mouseHook_MouseDown(object sender, MouseEventArgs e)
{
bool handled = false;
if (!RectangleToScreen(OrbBounds).Contains(e.Location))
{
handled = RibbonPopupManager.FeedHookClick(e);
}
if (RectangleToScreen(Bounds).Contains(e.Location))
{
//they clicked inside the ribbon
handled = true;
}
if (Minimized && !handled)
Expanded = false;
}
///
/// Checks if MouseWheel should be raised
///
///
///
private void _mouseHook_MouseWheel(object sender, MouseEventArgs e)
{
if (!RibbonPopupManager.FeedMouseWheel(e))
{
if (RectangleToScreen(
new Rectangle(Point.Empty, Size)
).Contains(e.Location))
{
OnMouseWheel(e);
}
}
}
///
/// Raises the OrbClicked event
///
/// event data
internal virtual void OnOrbClicked(EventArgs e)
{
if (OrbPressed)
{
RibbonPopupManager.Dismiss(RibbonPopupManager.DismissReason.ItemClicked);
}
else
{
ShowOrbDropDown();
}
if (OrbClicked != null)
{
OrbClicked(this, e);
}
}
///
/// Raises the OrbDoubleClicked
///
///
internal virtual void OnOrbDoubleClicked(EventArgs e)
{
if (OrbDoubleClick != null)
{
OrbDoubleClick(this, e);
}
}
#endregion
#region Methods
///
/// Initializes hooks
///
private void SetUpHooks()
{
if (RibbonDesigner.Current == null)
{
if (_mouseHook == null)
{
_mouseHook = new GlobalHook(GlobalHook.HookTypes.Mouse);
_mouseHook.MouseWheel += _mouseHook_MouseWheel;
_mouseHook.MouseDown += _mouseHook_MouseDown;
}
if (_keyboardHook == null)
{
_keyboardHook = new GlobalHook(GlobalHook.HookTypes.Keyboard);
_keyboardHook.KeyDown += _keyboardHook_KeyDown;
}
}
}
private void _keyboardHook_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
RibbonPopupManager.Dismiss(RibbonPopupManager.DismissReason.EscapePressed);
}
}
///
/// Shows the Orb's dropdown
///
public void ShowOrbDropDown()
{
OrbPressed = true;
if (RightToLeft == RightToLeft.No)
if (OrbStyle == RibbonOrbStyle.Office_2007)
OrbDropDown.Show(PointToScreen(new Point(OrbBounds.X - 4, OrbBounds.Bottom - OrbDropDown.ContentMargin.Top + 2)));
else if (OrbStyle == RibbonOrbStyle.Office_2010 || OrbStyle == RibbonOrbStyle.Office_2010_Extended || OrbStyle == RibbonOrbStyle.Office_2013)//Michael Spradlin - 05/03/2013 Office 2013 Style Changes
OrbDropDown.Show(PointToScreen(new Point(OrbBounds.X - 4, OrbBounds.Bottom)));
else
if (OrbStyle == RibbonOrbStyle.Office_2007)
OrbDropDown.Show(PointToScreen(new Point(OrbBounds.Right + 4 - OrbDropDown.Width, OrbBounds.Bottom - OrbDropDown.ContentMargin.Top + 2)));
else if (OrbStyle == RibbonOrbStyle.Office_2010 || OrbStyle == RibbonOrbStyle.Office_2010_Extended || OrbStyle == RibbonOrbStyle.Office_2013) //Michael Spradlin - 05/03/2013 Office 2013 Style Changes
OrbDropDown.Show(PointToScreen(new Point(OrbBounds.Right + 4 - OrbDropDown.Width, OrbBounds.Bottom)));
}
///
/// Shows the Orb's dropdown at the specified point.
///
public void ShowOrbDropDown(Point pt)
{
OrbPressed = true;
OrbDropDown.Show(PointToScreen(pt));
}
///
/// Drops out the old sensor and creates a new one
///
private void RenewSensor()
{
if (ActiveTab == null)
{
return;
}
if (Sensor != null) Sensor.Dispose();
Sensor = new RibbonMouseSensor(this, this, ActiveTab);
if (CaptionButtonsVisible)
{
Sensor.Items.AddRange(new RibbonItem[] { CloseButton, MaximizeRestoreButton, MinimizeButton });
}
}
///
/// Sets the value of the property
///
/// Actual border mode accquired
private void SetActualBorderMode(RibbonWindowMode borderMode)
{
bool trigger = ActualBorderMode != borderMode;
ActualBorderMode = borderMode;
if (trigger)
OnActualBorderModeChanged(EventArgs.Empty);
SetCaptionButtonsVisible(borderMode == RibbonWindowMode.NonClientAreaCustomDrawn);
}
///
/// Sets the value of the property
///
/// Value to set to the caption buttons
private void SetCaptionButtonsVisible(bool visible)
{
bool trigger = CaptionButtonsVisible != visible;
CaptionButtonsVisible = visible;
if (trigger)
OnCaptionButtonsVisibleChanged(EventArgs.Empty);
}
///
/// Suspends any drawing/regions update operation
///
public void SuspendUpdating()
{
_updatingSuspended = true;
}
///
/// Resumes any drawing/regions update operation
///
/////
public void ResumeUpdating()
{
ResumeUpdating(true);
}
///
/// Resumes any drawing/regions update operation
///
///
public void ResumeUpdating(bool update)
{
_updatingSuspended = false;
if (update)
{
OnRegionsChanged();
}
}
///
/// Removes all helper controls placed by any reason.
/// Contol's visibility is set to false before removed.
///
private void RemoveHelperControls()
{
RibbonPopupManager.Dismiss(RibbonPopupManager.DismissReason.AppClicked);
while (Controls.Count > 0)
{
Control ctl = Controls[0];
ctl.Visible = false;
Controls.Remove(ctl);
}
}
///
/// Hittest on tab
///
///
///
/// true if a tab has been clicked
internal bool TabHitTest(int x, int y)
{
//if (Rectangle.FromLTRB(Right - 10, Bottom - 10, Right, Bottom).Contains(x, y))
//{
// MessageBox.Show(cr);
//}
//look for mouse on tabs
foreach (RibbonTab tab in Tabs)
{
if (tab.TabBounds.Contains(x, y))
{
ActiveTab = tab;
Expanded = true;
return true;
}
}
return false;
}
///
/// Hittest on context
///
///
///
/// true if a tab has been clicked
internal bool ContextHitTest(int x, int y)
{
//look for mouse on context
foreach (RibbonContext context in Contexts)
{
if (context.Bounds.Contains(x, y))
{
return true;
}
}
return false;
}
///
/// Updates the regions of the tabs and the tab content bounds of the active tab
///
internal void UpdateRegions()
{
UpdateRegions(null);
}
///
/// Updates the regions of the tabs and the tab content bounds of the active tab
///
internal void UpdateRegions(Graphics g)
{
bool graphicsCreated = false;
if (IsDisposed || _updatingSuspended) return;
//Graphics for measurement
if (g == null)
{
g = CreateGraphics();
graphicsCreated = true;
}
UpdateRegionsTabsConsiderRTL(g);
if (RightToLeft == RightToLeft.No)
{
#region Update QuickAccess bounds
QuickAccessToolbar.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.Compact));
if (OrbStyle == RibbonOrbStyle.Office_2007)
QuickAccessToolbar.SetBounds(new Rectangle(new Point(OrbBounds.Right + QuickAccessToolbar.Margin.Left, OrbBounds.Top - 2), QuickAccessToolbar.LastMeasuredSize));
else if ((OrbStyle == RibbonOrbStyle.Office_2010) || (OrbStyle == RibbonOrbStyle.Office_2010_Extended)) //2010 - no need to offset for the orb
QuickAccessToolbar.SetBounds(new Rectangle(new Point(QuickAccessToolbar.Margin.Left, 0), QuickAccessToolbar.LastMeasuredSize));
else if (OrbStyle == RibbonOrbStyle.Office_2013) //Michael Spradlin - 05/03/2013 Office 2013 Style Changes : no need to offset for the orb
QuickAccessToolbar.SetBounds(new Rectangle(new Point(QuickAccessToolbar.Margin.Left, 0), QuickAccessToolbar.LastMeasuredSize));
#endregion
#region Update Caption Buttons bounds
if (CaptionButtonsVisible)
{
Size cbs = new Size(20, 20);
int cbg = 2;
CloseButton.SetBounds(new Rectangle(new Point(ClientRectangle.Right - cbs.Width - cbg, cbg), cbs));
MaximizeRestoreButton.SetBounds(new Rectangle(new Point(CloseButton.Bounds.Left - cbs.Width, cbg), cbs));
MinimizeButton.SetBounds(new Rectangle(new Point(MaximizeRestoreButton.Bounds.Left - cbs.Width, cbg), cbs));
}
#endregion
}
else // RightToLeft.Yes
{
#region Update QuickAccess bounds
QuickAccessToolbar.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.Compact));
if (OrbStyle == RibbonOrbStyle.Office_2007)
QuickAccessToolbar.SetBounds(new Rectangle(new Point(OrbBounds.Left - QuickAccessToolbar.Margin.Right - QuickAccessToolbar.LastMeasuredSize.Width, OrbBounds.Top - 2), QuickAccessToolbar.LastMeasuredSize));
else if ((OrbStyle == RibbonOrbStyle.Office_2010) || (OrbStyle == RibbonOrbStyle.Office_2010_Extended)) //2010 - no need to offset for the orb
QuickAccessToolbar.SetBounds(new Rectangle(new Point(ClientRectangle.Right - QuickAccessToolbar.Margin.Right - QuickAccessToolbar.LastMeasuredSize.Width, 0), QuickAccessToolbar.LastMeasuredSize));
else if (OrbStyle == RibbonOrbStyle.Office_2013) //Michael Spradlin - 05/03/2013 Office 2013 Style Changes: no need to offset for the orb
QuickAccessToolbar.SetBounds(new Rectangle(new Point(ClientRectangle.Right - QuickAccessToolbar.Margin.Right - QuickAccessToolbar.LastMeasuredSize.Width, 0), QuickAccessToolbar.LastMeasuredSize));
#endregion
#region Update Caption Buttons bounds
if (CaptionButtonsVisible)
{
Size cbs = new Size(20, 20);
int cbg = 2;
CloseButton.SetBounds(new Rectangle(new Point(ClientRectangle.Left, cbg), cbs));
MaximizeRestoreButton.SetBounds(new Rectangle(new Point(CloseButton.Bounds.Right, cbg), cbs));
MinimizeButton.SetBounds(new Rectangle(new Point(MaximizeRestoreButton.Bounds.Right, cbg), cbs));
}
#endregion
}
//Update the minimize settings
//_minimizedHeight = tabsBottom;
if (graphicsCreated)
g.Dispose();
_lastSizeMeasured = Size;
RenewSensor();
}
private void UpdateRegionsTabsConsiderRTL(Graphics g)
{
// Saves the bottom of the tabs
int tabsBottom = 0;
// X coordinate reminder
Point curXPos = new Point((RightToLeft == RightToLeft.No) ? OrbBounds.Width + TabsMargin.Left : OrbBounds.Left - TabsMargin.Left + 4, 0);
// Saves the width of the larger tab
int maxWidth = 0;
int tabTop = 0;
#region Assign default tab and unused context bounds (best case)
foreach (RibbonTab tab in Tabs)
{
if (tab.Visible || IsDesignMode())
{
Size tabSize = tab.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.None));
if (tab.Contextual && tab.Context.ContextualTabsCount == 1)
{
//Only if the context covers one tab do we need to be concerned that the context text maybe longer than the tab text.
Size contextSize = tab.Context.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.None));
tabSize.Width = Math.Max(tabSize.Width, contextSize.Width);
}
tabTop = (tab.Invisible == false || OrbVisible)
? TabsMargin.Top
: TabsMargin.Top - tabSize.Height - 8 + (OrbStyle == RibbonOrbStyle.Office_2013 ? 2 : 0);
Rectangle bounds = new Rectangle(0, tabTop,
TabsPadding.Left + tabSize.Width + TabsPadding.Right,
TabsPadding.Top + tabSize.Height + TabsPadding.Bottom);
bounds = LayoutHelper.CalcNewPosition(curXPos, bounds, LayoutHelper.RTLLayoutPosition.Far, TabSpacing);
tab.SetTabBounds(bounds);
curXPos = LayoutHelper.CalcNewPosition(bounds, curXPos, LayoutHelper.RTLLayoutPosition.Far, 0);
maxWidth = Math.Max(bounds.Width, maxWidth);
tabsBottom = Math.Max(bounds.Bottom, tabsBottom);
tab.SetTabContentBounds(Rectangle.FromLTRB(
TabContentMargin.Left, tabsBottom + TabContentMargin.Top,
ClientSize.Width - TabContentMargin.Right, ClientSize.Height - TabContentMargin.Bottom));
if (tab.Active)
{
tab.UpdatePanelsRegions();
}
}
else
{
tab.SetTabBounds(Rectangle.Empty);
tab.SetTabContentBounds(Rectangle.Empty);
if (tab.Contextual)
{
tab.Context.SetBounds(Rectangle.Empty);
tab.Context.SetHeaderBounds(Rectangle.Empty);
}
}
}
foreach (RibbonContext context in Contexts)
{
//Include unused RibbonContexts that need to be displayed
if ((context.ContextualTabsCount == 0) && IsDesignMode())
{
Size contextSize = context.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.None));
tabTop = (context.Visible || OrbVisible)
? TabsMargin.Top
: TabsMargin.Top - contextSize.Height - 8 + (OrbStyle == RibbonOrbStyle.Office_2013 ? 2 : 0);
Rectangle contextBounds = new Rectangle(0, tabTop - CaptionBarHeight,
TabsPadding.Left + contextSize.Width + TabsPadding.Right,
TabsPadding.Top + contextSize.Height + TabsPadding.Bottom + CaptionBarHeight);
Rectangle contextHeaderBounds = new Rectangle(contextBounds.Left, contextBounds.Top,
contextBounds.Width, CaptionBarHeight);
contextBounds = LayoutHelper.CalcNewPosition(curXPos, contextBounds, LayoutHelper.RTLLayoutPosition.Far, TabSpacing);
contextHeaderBounds = LayoutHelper.CalcNewPosition(curXPos, contextHeaderBounds, LayoutHelper.RTLLayoutPosition.Far, TabSpacing);
context.SetBounds(contextBounds);
context.SetHeaderBounds(contextHeaderBounds);
curXPos = LayoutHelper.CalcNewPosition(contextBounds, curXPos, LayoutHelper.RTLLayoutPosition.Far, 0);
maxWidth = Math.Max(contextBounds.Width, maxWidth);
tabsBottom = Math.Max(contextBounds.Bottom, tabsBottom);
}
}
#endregion
#region Reduce bounds of tabs if needed
while ((RightToLeft == RightToLeft.No ? curXPos.X > ClientRectangle.Right : curXPos.X < ClientRectangle.Left)
&& maxWidth > 0)
{
curXPos = new Point((RightToLeft == RightToLeft.No) ? OrbBounds.Width + TabsMargin.Left : OrbBounds.Left - TabsMargin.Left + 4, 0);
maxWidth--;
// Shrink each tab
foreach (RibbonTab tab in Tabs)
{
if (tab.Visible)
{
Size tabSize = tab.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.None));
if (tabSize.Width >= maxWidth)
{
tabSize.Width = maxWidth;
}
if (tab.Contextual && tab.Context.ContextualTabsCount == 1)
{
//Only if the context covers one tab do we need to be concerned that the context text maybe longer than the tab text.
Size contextSize = tab.Context.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.None));
tabSize.Width = Math.Max(tabSize.Width, contextSize.Width);
}
tabTop = (tab.Invisible == false || OrbVisible)
? TabsMargin.Top
: TabsMargin.Top - tabSize.Height - 8 + (OrbStyle == RibbonOrbStyle.Office_2013 ? 2 : 0);
Rectangle bounds = new Rectangle(0, tabTop,
TabsPadding.Left + tabSize.Width + TabsPadding.Right,
TabsPadding.Top + tabSize.Height + TabsPadding.Bottom);
bounds = LayoutHelper.CalcNewPosition(curXPos, bounds, LayoutHelper.RTLLayoutPosition.Far, TabSpacing);
tab.SetTabBounds(bounds);
curXPos = LayoutHelper.CalcNewPosition(bounds, curXPos, LayoutHelper.RTLLayoutPosition.Far, 0);
}
}
// Shrink each context
foreach (RibbonContext context in Contexts)
{
//Include unused RibbonContexts that need to be displayed
if ((context.ContextualTabsCount == 0) && IsDesignMode())
{
Size contextSize = context.MeasureSize(this, new RibbonElementMeasureSizeEventArgs(g, RibbonElementSizeMode.None));
if (contextSize.Width >= maxWidth)
{
contextSize.Width = maxWidth;
}
tabTop = (context.Visible || OrbVisible)
? TabsMargin.Top
: TabsMargin.Top - contextSize.Height - 8 + (OrbStyle == RibbonOrbStyle.Office_2013 ? 2 : 0);
Rectangle contextBounds = new Rectangle(0, tabTop - CaptionBarHeight,
TabsPadding.Left + contextSize.Width + TabsPadding.Right,
TabsPadding.Top + contextSize.Height + TabsPadding.Bottom + CaptionBarHeight);
Rectangle contextHeaderBounds = new Rectangle(contextBounds.Left, contextBounds.Top,
contextBounds.Width, CaptionBarHeight);
contextBounds = LayoutHelper.CalcNewPosition(curXPos, contextBounds, LayoutHelper.RTLLayoutPosition.Far, TabSpacing);
contextHeaderBounds = LayoutHelper.CalcNewPosition(curXPos, contextHeaderBounds, LayoutHelper.RTLLayoutPosition.Far, TabSpacing);
context.SetBounds(contextBounds);
context.SetHeaderBounds(contextHeaderBounds);
curXPos = LayoutHelper.CalcNewPosition(contextBounds, curXPos, LayoutHelper.RTLLayoutPosition.Far, 0);
}
}
}
#endregion
#region Fix the width of contexts that contain tabs
foreach (RibbonContext context in Contexts)
{
//Define bounds for contexts
if (context.ContextualTabsCount > 0)
{
foreach (RibbonTab tab in context.ContextualTabs)
{
Rectangle firstTabBounds = context.ContextualTabs[context.ContextualTabs.Count - 1].Bounds;
Rectangle lastTabBounds = context.ContextualTabs[0].Bounds;
int maxRight = Math.Max(firstTabBounds.Right, lastTabBounds.Right);
int maxLeft = Math.Min(firstTabBounds.Left, lastTabBounds.Left);
Rectangle contextBounds = new Rectangle(maxLeft, tabTop - CaptionBarHeight,
(maxRight - maxLeft),
TabsPadding.Top + firstTabBounds.Height + TabsPadding.Bottom + CaptionBarHeight);
Rectangle contextHeaderBounds = new Rectangle(contextBounds.Left, contextBounds.Top,
contextBounds.Width, CaptionBarHeight);
tab.Context.SetBounds(contextBounds);
tab.Context.SetHeaderBounds(contextHeaderBounds);
}
}
}
#endregion
}
///
/// Forces a size recalculation on the entire control
///
internal void OnRegionsChanged()
{
if (_updatingSuspended) return;
//Kevin - Fix when only one tab present and there is a textbox on it. It will loose focus after each char is entered
//if (Tabs.Count == 1)
if (Tabs.Count == 1 && ActiveTab != Tabs[0])
{
ActiveTab = Tabs[0];
}
_lastSizeMeasured = Size.Empty;
Refresh();
}
///
/// Redraws the specified tab
///
///
internal void RedrawTab(RibbonTab tab)
{
using (Graphics g = CreateGraphics())
{
Rectangle clip = Rectangle.FromLTRB(
tab.TabBounds.Left,
tab.TabBounds.Top,
tab.TabBounds.Right,
tab.TabBounds.Bottom);
g.SetClip(clip);
SmoothingMode sm = g.SmoothingMode;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.AntiAlias;
tab.OnPaint(this, new RibbonElementPaintEventArgs(tab.TabBounds, g, RibbonElementSizeMode.None));
g.SmoothingMode = sm;
g.TextRenderingHint = TextRenderingHint.SystemDefault;
}
}
///
/// Sets the currently selected tab
///
///
private void SetSelectedTab(RibbonTab tab)
{
if (tab == _lastSelectedTab) return;
if (_lastSelectedTab != null)
{
_lastSelectedTab.SetSelected(false);
RedrawTab(_lastSelectedTab);
}
if (tab != null)
{
tab.SetSelected(true);
RedrawTab(tab);
}
_lastSelectedTab = tab;
}
///
/// Suspends the sensor activity
///
internal void SuspendSensor()
{
if (Sensor != null)
Sensor.Suspend();
}
///
/// Resumes the sensor activity
///
internal void ResumeSensor()
{
Sensor.Resume();
}
///
/// Redraws the specified area on the sensor's control
///
///
public void RedrawArea(Rectangle area)
{
Sensor.Control.Invalidate(area);
}
///
/// Activates the next tab available
///
public void ActivateNextTab()
{
RibbonTab tab = NextTab;
if (tab != null)
{
ActiveTab = tab;
}
}
///
/// Activates the previous tab available
///
public void ActivatePreviousTab()
{
RibbonTab tab = PreviousTab;
if (tab != null)
{
ActiveTab = tab;
}
}
///
/// Handles the mouse down on the orb area
///
internal void OrbMouseDown()
{
OnOrbClicked(EventArgs.Empty);
}
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
protected override void WndProc(ref Message m)
{
bool bypassed = false;
if (WinApi.IsWindows && (ActualBorderMode == RibbonWindowMode.NonClientAreaGlass || ActualBorderMode == RibbonWindowMode.NonClientAreaCustomDrawn))
{
if (m.Msg == WinApi.WM_NCHITTEST) //0x84
{
Form f = FindForm();
Rectangle caption;
if (RightToLeft == RightToLeft.No)
{
int captionLeft = QuickAccessToolbar.Visible ? QuickAccessToolbar.Bounds.Right : OrbBounds.Right;
if (QuickAccessToolbar.Visible && QuickAccessToolbar.DropDownButtonVisible) captionLeft = QuickAccessToolbar.DropDownButton.Bounds.Right;
caption = Rectangle.FromLTRB(captionLeft, 0, Width, CaptionBarSize);
}
else
{
int captionRight = QuickAccessToolbar.Visible ? QuickAccessToolbar.Bounds.Left : OrbBounds.Left;
if (QuickAccessToolbar.Visible && QuickAccessToolbar.DropDownButtonVisible) captionRight = QuickAccessToolbar.DropDownButton.Bounds.Left;
caption = Rectangle.FromLTRB(0, 0, captionRight, CaptionBarSize);
}
Point screenPoint = new Point(WinApi.LoWord((int)m.LParam), WinApi.HiWord((int)m.LParam));
Point ribbonPoint = PointToClient(screenPoint);
bool onCaptionButtons = false;
if (CaptionButtonsVisible)
{
onCaptionButtons = CloseButton.Bounds.Contains(ribbonPoint) ||
MinimizeButton.Bounds.Contains(ribbonPoint) ||
MaximizeRestoreButton.Bounds.Contains(ribbonPoint);
}
if (RectangleToScreen(caption).Contains(screenPoint) && !onCaptionButtons)
{
//on the caption bar area
Point p = PointToScreen(screenPoint);
WinApi.SendMessage(f.Handle, WinApi.WM_NCHITTEST, m.WParam, WinApi.MakeLParam(p.X, p.Y));
m.Result = new IntPtr(-1);
bypassed = true;
//Kevin - fix so when you mouse off the caption buttons onto the caption area
//the buttons will clear the selection. same with the QAT buttons
CloseButton.SetSelected(false);
MinimizeButton.SetSelected(false);
MaximizeRestoreButton.SetSelected(false);
OrbSelected = false;
QuickAccessToolbar.DropDownButton.SetSelected(false);
}
}
}
if (!bypassed)
{
base.WndProc(ref m);
}
}
///
/// Paints the Ribbon on the specified device
///
/// Device where to paint on
/// Clip rectangle
private void PaintOn(Graphics g, Rectangle clip)
{
try
{
if (WinApi.IsWindows && Environment.OSVersion.Platform == PlatformID.Win32NT)
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
}
//Caption Background
Renderer.OnRenderRibbonBackground(new RibbonRenderEventArgs(this, g, clip));
//Caption Bar
Renderer.OnRenderRibbonCaptionBar(new RibbonRenderEventArgs(this, g, clip));
//Caption Buttons
if (CaptionButtonsVisible)
{
MinimizeButton.OnPaint(this, new RibbonElementPaintEventArgs(clip, g, RibbonElementSizeMode.Medium));
MaximizeRestoreButton.OnPaint(this, new RibbonElementPaintEventArgs(clip, g, RibbonElementSizeMode.Medium));
CloseButton.OnPaint(this, new RibbonElementPaintEventArgs(clip, g, RibbonElementSizeMode.Medium));
}
//Orb
Renderer.OnRenderRibbonOrb(new RibbonRenderEventArgs(this, g, clip));
//QuickAccess toolbar
QuickAccessToolbar.OnPaint(this, new RibbonElementPaintEventArgs(clip, g, RibbonElementSizeMode.Compact));
//Render Contexts
foreach (RibbonContext context in Contexts)
{
if (context.Visible || IsDesignMode())
{
context.OnPaint(this, new RibbonElementPaintEventArgs(context.Bounds, g, RibbonElementSizeMode.None, this));
}
}
//Render Tabs
foreach (RibbonTab tab in Tabs)
{
if (tab.Visible || IsDesignMode())
{
tab.OnPaint(this, new RibbonElementPaintEventArgs(tab.TabBounds, g, RibbonElementSizeMode.None, this));
}
}
if (OrbVisible && !_expanded && !string.IsNullOrEmpty(OrbText))
{
if ((OrbStyle == RibbonOrbStyle.Office_2010) ||
(OrbStyle == RibbonOrbStyle.Office_2010_Extended))
{
//draw the divider line at the bottom of the ribbon
Pen p = new Pen(Theme.RendererColorTable.TabBorder);
g.DrawLine(p, OrbBounds.Left, OrbBounds.Bottom, Bounds.Right, OrbBounds.Bottom);
}
else if (OrbStyle == RibbonOrbStyle.Office_2013)
{
//There is no line at the bottom of the Ribbon in Office 2013
}
}
}
catch
{
}
}
private void PaintDoubleBuffered(Graphics wndGraphics, Rectangle clip)
{
using (Bitmap bmp = new Bitmap(Width, Height))
{
using (Graphics g = Graphics.FromImage(bmp))
{
g.Clear(Color.Black);
PaintOn(g, clip);
g.Flush();
WinApi.BitBlt(wndGraphics.GetHdc(), clip.X, clip.Y, clip.Width, clip.Height, g.GetHdc(), clip.X, clip.Y, WinApi.SRCCOPY);
//WinApi.BitBlt(wndGraphics.GetHdc(), 0, 0, Width, Height, g.GetHdc(), 0, 0, WinApi.SRCCOPY);
}
//wndGraphics.DrawImage(bmp, Point.Empty);
}
}
internal bool IsDesignMode()
{
return Site != null && Site.DesignMode;
}
private void EnsureCustomThemeCreated(RibbonOrbStyle orbStyle, RibbonTheme theme)
{
if (_theme == null && Theme.StandardThemeIsGlobal == false && UseAlwaysStandardTheme == false)
{
_theme = new Theme(orbStyle, theme);
}
}
private void RecalculateOrbTextSize()
{
if (string.IsNullOrEmpty(OrbText))
{
_orbTextSize = Size.Empty;
}
else
{
try
{
using (Graphics g = CreateGraphics())
{
_orbTextSize = Size.Ceiling(g.MeasureString(OrbText, RibbonTabFont));
}
}
catch { }
}
}
#endregion
#region Event Overrides
///
/// Raises the event
///
/// Event data
protected virtual void OnActiveTabChanged(EventArgs e)
{
if (ActiveTabChanged != null)
{
ActiveTabChanged(this, e);
}
}
///
/// Raises the event
///
///
protected virtual void OnActualBorderModeChanged(EventArgs e)
{
if (ActualBorderModeChanged != null)
{
ActualBorderModeChanged(this, e);
}
}
///
/// Raises the event
///
///
protected virtual void OnCaptionButtonsVisibleChanged(EventArgs e)
{
if (CaptionButtonsVisibleChanged != null)
{
CaptionButtonsVisibleChanged(this, e);
}
}
///
/// Raises the event
///
///
protected virtual void OnExpandedChanged(EventArgs e)
{
if (ExpandedChanged != null)
{
ExpandedChanged(this, e);
}
}
protected override void OnMouseDoubleClick(MouseEventArgs e)
{
base.OnMouseDoubleClick(e);
if (OrbBounds.Contains(e.Location))
{
OnOrbDoubleClicked(EventArgs.Empty);
}
if (Tabs.Count != 1 || Tabs[0].Invisible == false)
{
foreach (RibbonTab tab in Tabs)
{
if (tab.Bounds.Contains(e.Location))
{
Minimized = !Minimized;
break;
}
}
}
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
//base.OnPaintBackground(pevent);
}
///
/// Overriden. Raises the Paint event and draws all the Ribbon content
///
/// A that contains the event data.
protected override void OnPaint(PaintEventArgs e)
{
if (_updatingSuspended) return;
if (Size != _lastSizeMeasured)
UpdateRegions(e.Graphics);
PaintOn(e.Graphics, e.ClipRectangle);
}
///
/// Overriden. Raises the Click event and tunnels the message to child elements
///
/// An that contains the event data.
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
}
///
/// Overriden. Riases the MouseEnter event and tunnels the message to child elements
///
/// An that contains the event data.
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
}
///
/// Overriden. Raises the MouseLeave event and tunnels the message to child elements
///
/// An that contains the event data.
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
//Console.WriteLine("Ribbon Mouse Leave");
SetSelectedTab(null);
if (!Expanded)
foreach (RibbonTab tab in Tabs)
{
tab.SetSelected(false);
}
Invalidate();
}
///
/// Overriden. Raises the MouseMove event and tunnels the message to child elements
///
/// A that contains the event data.
protected override void OnMouseMove(MouseEventArgs e)
{
//Console.WriteLine("Ribbon: " + e.Location.ToString());
// Kevin Carbis's new code, edited by adriancs, on behave of Carbis
// The below fix some minor bug. The cursor is not displayed properly
// when cursor is entering CheckBound of CheckBox and TextBox.
// The cursor keep changing from Cursors.Default to Cursors.Hand a few times
// within a second.
// The below code is obtain from Kcarbis's website
#region Kevin Carbis's new code, edited by adriancs
base.OnMouseMove(e);
if (ActiveTab == null) return;
bool someTabHitted = false;
//Check if mouse on tab
if (ActiveTab.TabContentBounds.Contains(e.X, e.Y))
{
//Do nothing, everything is on the sensor
}
//Check if mouse on orb
else if (OrbVisible && OrbBounds.Contains(e.Location) && !OrbSelected)
{
OrbSelected = true;
Invalidate(OrbBounds);
}
//Check if mouse on QuickAccess toolbar
else if (QuickAccessToolbar.Visible && QuickAccessToolbar.Bounds.Contains(e.Location))
{
}
else
{
//look for mouse on tabs
foreach (RibbonTab tab in Tabs)
{
if (tab.TabBounds.Contains(e.X, e.Y))
{
SetSelectedTab(tab);
someTabHitted = true;
tab.OnMouseMove(e);
}
}
}
if (!someTabHitted)
SetSelectedTab(null);
if (OrbSelected && !OrbBounds.Contains(e.Location))
{
OrbSelected = false;
Invalidate(OrbBounds);
}
#endregion
#region Kevin Carbis's old code, commented out by adriancs
//base.OnMouseMove(e);
////Kevin Carbis - Need to reset the curor here so we can pickup the cursor when it moves off of an active textbox. If we don't we will
////have the IBeam cursor over the entire ribbon.
//Cursor.Current = Cursors.Default;
//if (ActiveTab == null) return;
//bool someTabHitted = false;
////Check if mouse on tab
//if (ActiveTab.TabContentBounds.Contains(e.X, e.Y))
//{
// //Do nothing, everything is on the sensor
//}
////Check if mouse on orb
//else if (OrbVisible && OrbBounds.Contains(e.Location) && !OrbSelected)
//{
// OrbSelected = true;
// Invalidate(OrbBounds);
//}
////Check if mouse on QuickAccess toolbar
//else if (QuickAcessToolbar.Visible && QuickAcessToolbar.Bounds.Contains(e.Location))
//{
//}
//else
//{
// //look for mouse on tabs
// foreach (RibbonTab tab in Tabs)
// {
// if (tab.TabBounds.Contains(e.X, e.Y))
// {
// SetSelectedTab(tab);
// someTabHitted = true;
// tab.OnMouseMove(e);
// }
// }
//}
//if (!someTabHitted)
// SetSelectedTab(null);
////Clear the orb highlight
//if (OrbSelected && !OrbBounds.Contains(e.Location))
//{
// OrbSelected = false;
// Invalidate(OrbBounds);
//}
#endregion
}
///
/// Overriden. Raises the MouseUp event and tunnels the message to child elements
///
/// A that contains the event data.
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
}
///
/// Overriden. Raises the MouseDown event and tunnels the message to child elements
///
protected override void OnMouseDown(MouseEventArgs e)
{
//Kevin Carbis - this fixes the focus problem with textboxes when a different item is clicked
//and the edit box is still visible. This will now close the edit box for the textbox that previously
//had the focus. Otherwise the first click on a button would close the textbox and you would have to click twice.
//Control.Focus();
if (ActiveTextBox != null)
(ActiveTextBox as RibbonTextBox).EndEdit();
base.OnMouseDown(e);
if (OrbBounds.Contains(e.Location))
{
OrbMouseDown();
}
else
{
TabHitTest(e.X, e.Y);
}
}
///
/// Handles the mouse wheel
///
///
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
//if (Tabs.Count == 0 || ActiveTab == null) return;
//int index = Tabs.IndexOf(ActiveTab);
//if (e.Delta < 0)
//{
// _tabSum += 0.4f;
//}
//else
//{
// _tabSum -= 0.4f;
//}
//int tabRounded = Convert.ToInt16(Math.Round(_tabSum));
//if (tabRounded != 0)
//{
// index += tabRounded;
// if (index < 0)
// {
// index = 0;
// }
// else if (index >= Tabs.Count - 1)
// {
// index = Tabs.Count - 1;
// }
// ActiveTab = Tabs[index];
// _tabSum = 0f;
//}
}
///
/// Handles the MouseMove on a RibbonHost control. Not the best solution, but there
/// is no simple method to hook into the host controls.
///
///
internal void OnRibbonHostMouseMove(MouseEventArgs e)
{
OnMouseMove(e);
}
///
/// Overriden. Raises the OnSizeChanged event and performs layout calculations
///
/// An that contains the event data.
protected override void OnSizeChanged(EventArgs e)
{
UpdateRegions();
RemoveHelperControls();
base.OnSizeChanged(e);
}
///
/// Handles when its parent has changed
///
///
protected override void OnParentChanged(EventArgs e)
{
base.OnParentChanged(e);
if (!(Site != null && Site.DesignMode))
{
BorderMode = BorderMode;
if (Parent is IRibbonForm)
{
FormHelper.Ribbon = this;
}
}
if (Parent != null)
{
Control p = Parent;
while (p.Parent != null)
p = p.Parent;
Form parentForm = p as Form;
if (parentForm != null)
parentForm.Deactivate += parentForm_Deactivate;
}
}
private void parentForm_Deactivate(object sender, EventArgs e)
{
if (Form.ActiveForm == null) // check for ActiveForm, because Click in Orb Menu causes the Form as well to fire the Deactivate Event
{
RibbonPopupManager.Dismiss(RibbonPopupManager.DismissReason.AppFocusChanged);
}
}
private void OnPopupRegistered(object sender, EventArgs args)
{
if (RibbonPopupManager.PopupCount == 1)
SetUpHooks();
}
private void OnPopupUnregistered(object sender, EventArgs args)
{
if (RibbonPopupManager.PopupCount == 0 && (Minimized == false || (Minimized && Expanded == false)))
DisposeHooks();
}
protected override void OnVisibleChanged(EventArgs e)
{
base.OnVisibleChanged(e);
// Because the RibbonItem, RibbonPanel and RibbonTab return "Visible == false" if any of
// their parents is not visible, a redraw is required when the Ribbon becomes visible finally!
if (Visible)
{
UpdateRegions();
Invalidate();
}
}
#endregion
}
}