/// <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)); }