/// <summary>
/// Perform a layout of the elements.
/// </summary>
/// <param name="context">Layout context.</param>
public override void Layout(ViewLayoutContext context)
{
Debug.Assert(context != null);
// Sync child elements to represent the current ribbon tabs collection setup
SyncChildrenToRibbonTabs();
// We take on all the available display area
ClientRectangle = context.DisplayRectangle;
int x = ClientLocation.X;
// Are there any children to layout?
if (this.Count > 0)
{
// Modify the cached sizes so they are ideally sized for actual space
Size[] layoutSizes = AdjustSizesToFit();
int y = ClientRectangle.Y;
int bottom = ClientRectangle.Bottom;
int height = ClientHeight;
// Position each item from left to right taking up entire height
for (int i = 0; i < this.Count; i++)
{
// Only interested in visible items
if (layoutSizes[i].Width > 0)
{
// Separators are made the full height, others are aligned on the bottom edge
if (this[i] is ViewDrawRibbonTabSep)
{
// Update separator with latest calculated need to draw
ViewDrawRibbonTabSep tabSep = this[i] as ViewDrawRibbonTabSep;
tabSep.Draw = _showSeparators;
context.DisplayRectangle = new Rectangle(x, y, layoutSizes[i].Width, height);
}
else if (this[i] is ViewDrawRibbonTab)
{
// Update checked state of the tab
ViewDrawRibbonTab tab = this[i] as ViewDrawRibbonTab;
tab.Checked = (_ribbon.SelectedTab == tab.RibbonTab);
context.DisplayRectangle = new Rectangle(x, bottom - layoutSizes[i].Height, layoutSizes[i].Width, layoutSizes[i].Height);
}
else if (this[i] is ViewDrawRibbonDesignTab)
{
context.DisplayRectangle = new Rectangle(x, bottom - layoutSizes[i].Height, layoutSizes[i].Width, layoutSizes[i].Height);
}
// Position the element
this[i].Layout(context);
// Move across to next position
x += layoutSizes[i].Width;
}
}
}
// Fill remainder space with the tabs spare element
Rectangle customCaptionRect = Rectangle.Empty;
if (_tabsSpare != null)
{
_tabsSpare.Visible = false;
if (x < ClientRectangle.Right)
{
if (_ribbon.GetRedirector().GetMetricBool(PaletteState.Normal, PaletteMetricBool.RibbonTabsSpareCaption) == InheritBool.True)
{
customCaptionRect = new Rectangle(x, ClientRectangle.Y, ClientRectangle.Right - x, ClientHeight);
context.DisplayRectangle = customCaptionRect;
_tabsSpare.Visible = true;
_tabsSpare.Layout(context);
x = ClientRectangle.Right;
}
}
}
// We have an owning form we need to update the custom area it treats as a caption
if (_ribbon.CaptionArea.KryptonForm != null)
{
if (!customCaptionRect.IsEmpty)
{
// Convert the rectangle to the owning form coordinates
customCaptionRect = _parentControl.RectangleToScreen(customCaptionRect);
customCaptionRect = _ribbon.CaptionArea.KryptonForm.RectangleToClient(customCaptionRect);
}
_ribbon.CaptionArea.KryptonForm.CustomCaptionArea = customCaptionRect;
}
// Update our own size to reflect how wide we actually need to be for all the children
ClientRectangle = new Rectangle(ClientLocation, new Size(x - ClientLocation.X, ClientHeight));
// Update the display rectangle we allocated for use by parent
context.DisplayRectangle = new Rectangle(ClientLocation, new Size(x - ClientLocation.X, ClientHeight));
}