private void SyncChildrenToContexts() { // Find any filler child ViewBase filler = null; foreach (ViewBase child in this) { if (GetDock(child) == ViewDockStyle.Fill) { filler = child; break; } } // Remove all child elements Clear(); // Make sure we have enough cached elements if (_contextTitlesCache.Count < ViewLayoutRibbonTabs.ContextTabSets.Count) { for (int i = _contextTitlesCache.Count; i < ViewLayoutRibbonTabs.ContextTabSets.Count; i++) { // Create a new view element and an associated button controller ViewDrawRibbonContextTitle viewContextTitle = new ViewDrawRibbonContextTitle(_ribbon, _ribbon.StateContextCheckedNormal.RibbonTab) { MouseController = new ContextTitleController(_ribbon) }; _contextTitlesCache.Add(viewContextTitle); } } // Add a view element per context and update with correct reference for (int i = 0; i < ViewLayoutRibbonTabs.ContextTabSets.Count; i++) { ViewDrawRibbonContextTitle viewContext = _contextTitlesCache[i]; ContextTitleController viewController = (ContextTitleController)viewContext.MouseController; viewContext.ContextTabSet = ViewLayoutRibbonTabs.ContextTabSets[i]; viewController.ContextTabSet = viewContext.ContextTabSet; Add(viewContext); } // Put back any filler if (filler != null) { Add(filler, ViewDockStyle.Fill); } }
/// <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 children to match the current context tabs SyncChildrenToContexts(); // We take on all the available display area ClientRectangle = context.DisplayRectangle; // Find any filler child ViewBase filler = null; foreach (ViewBase child in this) { if (GetDock(child) == ViewDockStyle.Fill) { filler = child; break; } } int xLeftMost = ClientRectangle.Right; int xRightMost = ClientRectangle.Left; // Find the correct position for each child context set foreach (ViewBase child in this) { // Only interested in visible children if (child.Visible) { // We are only interested in laying out context titles if (child is ViewDrawRibbonContextTitle) { ViewDrawRibbonContextTitle childContextTitle = child as ViewDrawRibbonContextTitle; // Get the context set it is representing ContextTabSet tabContext = childContextTitle.ContextTabSet; // Get the screen position of the left and right hand positions Point leftTab = tabContext.GetLeftScreenPosition(); Point rightTab = tabContext.GetRightScreenPosition(); // If our position is above the ribbon control we must be in the chrome if (_captionArea.UsingCustomChrome && !_captionArea.KryptonForm.ApplyComposition) { int leftPadding = _captionArea.RealWindowBorders.Left; leftTab.X += leftPadding; rightTab.X += leftPadding; } // Convert the screen to our own coordinates leftTab = context.TopControl.PointToClient(leftTab); rightTab = context.TopControl.PointToClient(rightTab); // Calculate the position of the child and layout context.DisplayRectangle = new Rectangle(leftTab.X, ClientLocation.Y, rightTab.X - leftTab.X, ClientHeight); childContextTitle.Layout(context); // Track the left and right most positions xLeftMost = Math.Min(xLeftMost, leftTab.X); xRightMost = Math.Max(xRightMost, rightTab.X); } } } // Do we need to position a filler element? if (filler != null) { // How much space available on the left side int leftSpace = xLeftMost - ClientRectangle.Left; int rightSpace = ClientRectangle.Right - xRightMost; if (CenterLayout) { //TODO: test with xLeftMost/xRightMost, with ViewDrawRibbonContextTitle type leftSpace = this.Parent.ClientSize.Width - ClientRectangle.Left * 2; rightSpace = this.Parent.ClientSize.Width - xRightMost * 2; } // Use the side with the most space if (leftSpace >= rightSpace) { context.DisplayRectangle = new Rectangle(ClientLocation.X, ClientLocation.Y, leftSpace, ClientHeight); } else { context.DisplayRectangle = new Rectangle(xRightMost, ClientLocation.Y, rightSpace, ClientHeight); } filler.Layout(context); } // Put the original value back again context.DisplayRectangle = ClientRectangle; }