/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); ClientRectangle = context.DisplayRectangle; // We always extend an extra pixel downwards to draw over the containers border Rectangle adjustRect = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientWidth, ClientHeight + 1); // Get the client rect of the parent Rectangle parentRect = Parent.ClientRectangle; // If we are only partially visible on the right hand side if ((adjustRect.X < parentRect.Right) && (adjustRect.Right >= parentRect.Right)) { // Truncate on the right hand side to the parent adjustRect.Width = parentRect.Right - adjustRect.X; } // If we are only partially visible on the left hand side if ((adjustRect.Right > parentRect.X) && (adjustRect.X < parentRect.X)) { // Truncate on the left hand side to the parent adjustRect.Width = adjustRect.Right - parentRect.X; adjustRect.X = parentRect.X; } // Use adjusted rectangle as our client rectangle ClientRectangle = adjustRect; // Use the font height to decide on the text rectangle int fontHeight = _ribbon.CalculatedValues.DrawFontHeight; _textRect = new Rectangle(ClientLocation.X + TEXT_SIDE_GAP, ClientLocation.Y + (ClientHeight - fontHeight - TEXT_BOTTOM_GAP), ClientWidth - (TEXT_SIDE_GAP * 2), fontHeight); // Remember to dispose of old memento if (_mementoContentText != null) { _mementoContentText.Dispose(); _mementoContentText = null; } if (_mementoContentShadow1 != null) { _mementoContentShadow1.Dispose(); _mementoContentShadow1 = null; } if (_mementoContentShadow2 != null) { _mementoContentShadow2.Dispose(); _mementoContentShadow2 = null; } // Office 2010 draws a shadow effect of the text if (_ribbon.RibbonShape == PaletteRibbonShape.Office2010) { Rectangle shadowTextRect1 = new Rectangle(_textRect.X - 1, _textRect.Y + 1, _textRect.Width, _textRect.Height); Rectangle shadowTextRect2 = new Rectangle(_textRect.X + 1, _textRect.Y + 1, _textRect.Width, _textRect.Height); _contentProvider.OverrideTextColor = Color.FromArgb(128, ControlPaint.Dark(GetRibbonBackColor1(PaletteState.Normal))); if (DrawOnComposition) { _contentProvider.OverrideTextHint = PaletteTextHint.SingleBitPerPixelGridFit; } _mementoContentShadow1 = context.Renderer.RenderStandardContent.LayoutContent(context, shadowTextRect1, _contentProvider, this, VisualOrientation.Top, false, PaletteState.Normal, false); _mementoContentShadow2 = context.Renderer.RenderStandardContent.LayoutContent(context, shadowTextRect2, _contentProvider, this, VisualOrientation.Top, false, PaletteState.Normal, false); _contentProvider.OverrideTextColor = Color.Empty; } // Use the renderer to layout the text _mementoContentText = context.Renderer.RenderStandardContent.LayoutContent(context, _textRect, _contentProvider, this, VisualOrientation.Top, false, PaletteState.Normal, false); _contentProvider.OverrideTextHint = PaletteTextHint.Inherit; }
/// <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 to represent the current ribbon QAT buttons SyncChildren(true); // We take on all the available display area ClientRectangle = context.DisplayRectangle; int x = ClientLocation.X; int right = ClientRectangle.Right; // If we need to show the extra button if (_extraButton != null) { // Find size of the extra button Size childSize = _extraButton.GetPreferredSize(context); // Make sure there is always enough room for it at the right hand side right -= childSize.Width; } int y = ClientLocation.Y; int height = ClientHeight; Overflow = false; // Are there any children to layout? if (Count > 0) { // Position each item from left to right taking up entire height for (int i = 0; i < Count; i++) { ViewBase child = this[i]; // We only position visible items and we always ignore the extra button if (child != _extraButton) { if (child.Visible) { // Cache preferred size of the child Size childSize = this[i].GetPreferredSize(context); // Is there enough width for this item to be displayed if ((childSize.Width + x) <= right) { // Define display rectangle for the group context.DisplayRectangle = new Rectangle(x, y, childSize.Width, height); // Position the element this[i].Layout(context); // Move across to next position x += childSize.Width; } else { // Hide the child, not enough for it child.Visible = false; // Need to use the extra button as an overflow button Overflow = true; } } else { // Cast child to correct type ViewDrawRibbonQATButton view = (ViewDrawRibbonQATButton)child; // If the quick access toolbar button wants to be visible if (view.QATButton.GetVisible() || Ribbon.InDesignHelperMode) { Overflow = true; } } } } } // Do we need to position the extra button? if (_extraButton != null) { // Cache preferred size of the child Size childSize = _extraButton.GetPreferredSize(context); // Is there enough width for this item to be displayed if ((childSize.Width + x) <= ClientRectangle.Right) { // Define display rectangle for the group context.DisplayRectangle = new Rectangle(x, y, childSize.Width, height); // Position the element _extraButton.Layout(context); // Move across to next position x += childSize.Width; } // Should button show as overflow or customization _extraButton.Overflow = Overflow; } // 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)); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { // Sync to represent a groups view per tab SyncChildrenToRibbonTabs(); base.Layout(context); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { return(new Size(0, _height)); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { bool relayout; bool canScrollV; bool canScrollH; // Update the enabled state of the scrollbars and contained control ViewControl.Enabled = Enabled; ScrollbarV.Enabled = Enabled; ScrollbarH.Enabled = Enabled; BorderEdgeV.Enabled = Enabled; BorderEdgeH.Enabled = Enabled; // Cache the starting viewport offsets Point originalOffset = Viewport.Offset; // Hide both scrollbars, in case having them both hidden // always enough content to be seen that none or only one // of them is required. BorderEdgeV.Visible = ScrollbarV.Visible = false; BorderEdgeH.Visible = ScrollbarH.Visible = false; // Get the the visible state before processing string beforeOverflowState = ViewBuilder.GetOverflowButtonStates(); // Make all stacking items visible so all that can be shown will be ViewBuilder.UnshrinkAppropriatePages(); // Do not actually change the layout of any child controls context.ViewManager.DoNotLayoutControls = true; do { // Do we need to layout again? relayout = false; // Always reinstate the cached offset, so that if one of the cycles // limits the offset to a different value then subsequent cycles // will not remember that artificial limitation Viewport.Offset = originalOffset; // Make sure the viewport has extents calculated Viewport.GetPreferredSize(context); // Let base class perform a layout calculation DockerLayout(context); // Find the latest scrolling requirement canScrollV = Viewport.CanScrollV; canScrollH = Viewport.CanScrollH; // If we need to use vertical scrolling... if (canScrollV) { // Ask the view builder to try and hide stacking items to free up some vertical // space. We provide the amount of space required to remove the vertical scroll // bar from view, so only the minimum number of stacking items are removed. relayout = ViewBuilder.ShrinkVertical(Viewport.ScrollExtent.Height - Viewport.ClientSize.Height); } // Is there a change in vertical scrolling? if (canScrollV != ScrollbarV.Visible) { // Update the view elements ScrollbarV.Visible = canScrollV; BorderEdgeV.Visible = canScrollV; relayout = true; } // Is there a change in horizontally scrolling? if (canScrollH != ScrollbarH.Visible) { // Update the view elements ScrollbarH.Visible = canScrollH; BorderEdgeH.Visible = canScrollH; relayout = true; } // We short size the horizontal scrollbar if both bars are showing bool needShortSize = (ScrollbarV.Visible && ScrollbarH.Visible); if (ScrollbarH.ShortSize != needShortSize) { // Update the scrollbar view and need layout to reflect resizing ScrollbarH.ShortSize = needShortSize; relayout = true; } } while (relayout); // Now all layouts have occured we can actually move child controls context.ViewManager.DoNotLayoutControls = false; // Perform actual layout of child controls foreach (ViewBase child in this) { context.DisplayRectangle = child.ClientRectangle; child.Layout(context); } // Do we need to update the vertical scrolling values? if (canScrollV) { ScrollbarV.SetScrollValues(0, Viewport.ScrollExtent.Height - 1, 1, Viewport.ClientSize.Height, Viewport.ScrollOffset.Y); } // Do we need to update the horizontal scrolling values? if (canScrollH) { ScrollbarH.SetScrollValues(0, Viewport.ScrollExtent.Width - 1, 1, Viewport.ClientSize.Width, Viewport.ScrollOffset.X); } // If visible state of an overflow button has changed, need to relayout if (!beforeOverflowState.Equals(ViewBuilder.GetOverflowButtonStates())) { NeedPaint(true); } }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { // Preferred size is calculated by parent for us return(Size.Empty); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { // Take on all the provided area ClientRectangle = context.DisplayRectangle; }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); // Validate incoming reference if (context == null) { throw new ArgumentNullException(nameof(context)); } // We take on all the available display area ClientRectangle = context.DisplayRectangle; Size preferredSize = Size.Empty; // Cache the size for the current item switch (CurrentSize) { case GroupItemSize.Small: preferredSize = _preferredSizeSmall; break; case GroupItemSize.Medium: preferredSize = _preferredSizeMedium; break; case GroupItemSize.Large: preferredSize = _preferredSizeLarge; break; } // Starting left offset is half the difference between the client width and the total child widths int xOffset = (ClientWidth - preferredSize.Width) / 2; // Layout each child centered within this space foreach (ViewBase child in this) { // Only layout visible children if (child.Visible) { // Get the cached size of the child Size childPreferred = Size.Empty; switch (CurrentSize) { case GroupItemSize.Small: childPreferred = _viewToSmall.ContainsKey(child) ? _viewToSmall[child] : child.GetPreferredSize(context); break; case GroupItemSize.Medium: childPreferred = _viewToMedium.ContainsKey(child) ? _viewToMedium[child] : child.GetPreferredSize(context); break; case GroupItemSize.Large: childPreferred = _viewToLarge.ContainsKey(child) ? _viewToLarge[child] : child.GetPreferredSize(context); break; } // Find vertical offset for centering int yOffset = (ClientHeight - childPreferred.Height) / 2; // Create the rectangle that centers the child in our space context.DisplayRectangle = new Rectangle(ClientRectangle.X + xOffset, ClientRectangle.Y + yOffset, childPreferred.Width, childPreferred.Height); // Finally ask the child to layout child.Layout(context); // Move across to next horizontal position xOffset += childPreferred.Width; } } // Put back the original display value now we have finished context.DisplayRectangle = ClientRectangle; }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Debug.Assert(context != null); switch (CurrentSize) { case GroupItemSize.Small: _viewToSmall.Clear(); break; case GroupItemSize.Medium: _viewToMedium.Clear(); break; case GroupItemSize.Large: _viewToLarge.Clear(); break; default: // Should never happen! Debug.Assert(false); break; } Size preferredSize = Size.Empty; foreach (ViewBase child in this) { // Only investigate visible children if (child.Visible) { // Ask child for it's own preferred size Size childPreferred = child.GetPreferredSize(context); // Cache the child preferred size for use in layout switch (CurrentSize) { case GroupItemSize.Small: _viewToSmall.Add(child, childPreferred); break; case GroupItemSize.Medium: _viewToMedium.Add(child, childPreferred); break; case GroupItemSize.Large: _viewToLarge.Add(child, childPreferred); break; } // Always add on the width of the child preferredSize.Width += childPreferred.Width; // Find the tallest of the children preferredSize.Height = Math.Max(preferredSize.Height, childPreferred.Height); } } // Cache the size for the current item switch (CurrentSize) { case GroupItemSize.Small: _preferredSizeSmall = preferredSize; break; case GroupItemSize.Medium: _preferredSizeMedium = preferredSize; break; case GroupItemSize.Large: _preferredSizeLarge = preferredSize; break; } return(preferredSize); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { UpdateSeparatorSize(); base.Layout(context); }
private int AdjustGroupStateToMatchSpace(ViewLayoutContext context) { List <GroupSizeWidth[]> listWidths = new List <GroupSizeWidth[]>(); List <IRibbonViewGroupSize> listGroups = new List <IRibbonViewGroupSize>(); // Scan all groups int pixelGaps = 0; int maxEntries = 0; foreach (ViewBase child in this) { if (child.Visible) { // Only interested in children that are actually groups if (child is IRibbonViewGroupSize) { // Cast child view to correct interface IRibbonViewGroupSize childSize = (IRibbonViewGroupSize)child; // Find list of possible sizes for this group GroupSizeWidth[] widths = childSize.GetPossibleSizes(context); // Track how many extra pixels are needed for inter group gaps pixelGaps += SEP_LENGTH_2007; // Add into list of all container values listWidths.Add(widths); listGroups.Add(childSize); // Track the longest list found maxEntries = Math.Max(maxEntries, widths.Length); } } } int bestWidth = 0; int availableWidth = context.DisplayRectangle.Width; int[] bestIndexes = null; List <int> permIndexes = new List <int>(); // Scan each horizontal slice of the 2D array of values for (int i = 0; i < maxEntries; i++) { // Move from right to left creating a permutation each time for (int j = listWidths.Count - 1; j >= 0; j--) { // Does this cell actually exist? if (listWidths[j].Length > i) { // Starting width is the pixel gaps int permTotalWidth = pixelGaps; permIndexes.Clear(); // Generate permutation by taking cell values for (int k = listWidths.Count - 1; k >= 0; k--) { // If we are on the left of the 'j' cell then move up a level int index = i + (k > j ? 1 : 0); // Limit check the index to available height index = Math.Min(index, listWidths[k].Length - 1); permIndexes.Insert(0, index); // Find width and size of the entry int width = listWidths[k][index].Width; // Track the total width of this permutation permTotalWidth += width; } // We record this as the best match so far, if either it is the first permutation // tried or if closest to filling the entire available width of the client area if ((permTotalWidth > bestWidth) && (permTotalWidth <= availableWidth)) { bestWidth = permTotalWidth; bestIndexes = permIndexes.ToArray(); } } } } // If we have a best fit solution if (bestWidth > 0) { // Use the best discovered solution and push it back to the groups _groupWidths = new int[listGroups.Count]; for (int i = 0; i < listGroups.Count; i++) { _groupWidths[i] = (listWidths[i][bestIndexes[i]].Width); listGroups[i].SetSolutionSize(listWidths[i][bestIndexes[i]].Sizing); } } else { // Use the smallest solution and push it back to the groups _groupWidths = new int[listGroups.Count]; for (int i = 0; i < listGroups.Count; i++) { _groupWidths[i] = (listWidths[i][listWidths[i].Length - 1].Width); listGroups[i].SetSolutionSize(listWidths[i][listWidths[i].Length - 1].Sizing); } } return(bestWidth); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { UpdateSeparatorSize(); return(base.GetPreferredSize(context)); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { // Sync child elements to the current group items SyncChildrenToRibbonGroupItems(); // Clear down the cache of item sizes _sizeList.Clear(); _viewList.Clear(); _viewToGap.Clear(); int totalWidth = 0; ViewBase previousChild = null; // Find the size of each individual visible child item for (int i = 0; i < this.Count; i++) { ViewBase child = this[i]; // Only interested in visible items if (child.Visible) { // Are we positioning a cluster? if (child is ViewLayoutRibbonGroupCluster) { // Inform cluster if it is immediatley after another cluster (and so potentially needs a separator) ViewLayoutRibbonGroupCluster clusterChild = (ViewLayoutRibbonGroupCluster)child; clusterChild.StartSeparator = (previousChild != null) && !(previousChild is ViewLayoutRibbonGroupCluster); clusterChild.EndSeparator = true; } // Can we calculate the spacing gap between the previous and this item if (previousChild != null) { if (_viewToItem.ContainsKey(child) && _viewToItem.ContainsKey(previousChild)) { // Cast to correct type IRibbonGroupItem childItem = _viewToItem[child] as IRibbonGroupItem; IRibbonGroupItem previousItem = _viewToItem[previousChild] as IRibbonGroupItem; // Find the requested gap between them _viewToGap.Add(child, childItem.ItemGap(previousItem)); } else { // Default the gap _viewToGap.Add(child, DEFAULT_GAP); } } // Get requested size of the child Size childSize = child.GetPreferredSize(context); // Add to list of visible child sizes _sizeList.Add(childSize); _viewList.Add(child); // Cache total visible width for later totalWidth += childSize.Width; // This is now the previous child previousChild = child; } } // Find the item size specific preferred calculation switch (_currentSize) { case GroupItemSize.Large: return(LargeMediumPreferredSize(totalWidth, ref _split1Large)); case GroupItemSize.Medium: return(LargeMediumPreferredSize(totalWidth, ref _split1Medium)); case GroupItemSize.Small: return(SmallPreferredSize(totalWidth)); default: // Should never happen! Debug.Assert(false); return(Size.Empty); } }
private void SmallLayout(ViewLayoutContext context) { int x = ClientLocation.X; int y = ClientLocation.Y; // At design time we reserve space at the left side for the selection flap if (_ribbon.InDesignHelperMode) { x += DesignTimeDraw.FlapWidth; } ViewBase previousChild = null; // Position the visible items in turn for (int i = 0, visibleIndex = 0; i < this.Count; i++) { ViewBase child = this[i]; // We only position visible items if (child.Visible) { // Are we positioning a cluster? if (child is ViewLayoutRibbonGroupCluster) { // Inform cluster if it is immediatley after another item and so needs a start separator ViewLayoutRibbonGroupCluster clusterChild = (ViewLayoutRibbonGroupCluster)child; clusterChild.StartSeparator = (previousChild != null) && !(previousChild is ViewLayoutRibbonGroupCluster); clusterChild.EndSeparator = false; } if ((previousChild != null) && (previousChild is ViewLayoutRibbonGroupCluster)) { // Inform cluster if it is before another item and so needs an end separator ViewLayoutRibbonGroupCluster clusterChild = (ViewLayoutRibbonGroupCluster)previousChild; clusterChild.EndSeparator = true; // Need to layout the item again with the new setting context.DisplayRectangle = new Rectangle(previousChild.ClientLocation.X, previousChild.ClientLocation.Y, previousChild.ClientWidth, previousChild.ClientHeight); previousChild.Layout(context); } // If not the first item on the line, then get the pixel gap between them if ((previousChild != null) && _viewToGap.ContainsKey(child)) { x += _viewToGap[child]; } // Get the size of the child item Size childSize = _sizeList[visibleIndex]; // Define display rectangle for the group context.DisplayRectangle = new Rectangle(x, y, childSize.Width, childSize.Height); // Position the element this[i].Layout(context); // Do we need to split after this item if ((_split1Small == visibleIndex) || (_split2Small == visibleIndex)) { // Move back to start of line and downwards to next line x = ClientLocation.X; // At design time we reserve space at the left side for the selection flap if (_ribbon.InDesignHelperMode) { x += DesignTimeDraw.FlapWidth; } y += _ribbon.CalculatedValues.GroupLineHeight; // As last item on the line, there is no previous item on next line previousChild = null; } else { // Move across to next position x += childSize.Width; // We have become the previous child previousChild = child; } // Not all child items are visible, so track separately visibleIndex++; } } }
/// <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; // Use the side with the most space context.DisplayRectangle = leftSpace >= rightSpace ? new Rectangle(ClientLocation.X, ClientLocation.Y, leftSpace, ClientHeight) : new Rectangle(xRightMost, ClientLocation.Y, rightSpace, ClientHeight); filler.Layout(context); } // Put the original value back again context.DisplayRectangle = ClientRectangle; }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Size preferredSize = Size.Empty; // We need an owning form to perform calculations if (CompOwnerForm != null) { // We only have size if custom chrome is being used with composition if (CompOwnerForm.ApplyCustomChrome && CompOwnerForm.ApplyComposition) { try { // Create structure that will be populated by call to WM_GETTITLEBARINFOEX PI.TITLEBARINFOEX tbi = new PI.TITLEBARINFOEX(); tbi.cbSize = (uint)Marshal.SizeOf(tbi); // Ask the window for the title bar information PI.SendMessage(CompOwnerForm.Handle, PI.WM_.GETTITLEBARINFOEX, IntPtr.Zero, ref tbi); // Find width of the button rectangle int closeWidth = tbi.rcCloseButton.right - tbi.rcCloseButton.left; int helpWidth = tbi.rcHelpButton.right - tbi.rcHelpButton.left; int minWidth = tbi.rcMinimizeButton.right - tbi.rcMinimizeButton.left; int maxWidth = tbi.rcMaximizeButton.right - tbi.rcMaximizeButton.left; int clientWidth = CompOwnerForm.ClientSize.Width; int clientScreenRight = CompOwnerForm.RectangleToScreen(CompOwnerForm.ClientRectangle).Right; int leftMost = clientScreenRight; // Find the left most button edge (start with right side of client area) if ((closeWidth > 0) && (closeWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcCloseButton.left); } if ((helpWidth > 0) && (helpWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcHelpButton.left); } if ((minWidth > 0) && (minWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcMinimizeButton.left); } if ((maxWidth > 0) && (maxWidth < clientWidth)) { leftMost = Math.Min(leftMost, tbi.rcMaximizeButton.left); } // Our width is the distance between the left most button edge and the right // side of the client area (this space the buttons are taking up). Plus a small // extra gap between the first button and the caption elements to its left. _width = (clientScreenRight - leftMost) + SPACING_GAP; preferredSize.Width = _width; } catch (ObjectDisposedException) { // Asking for the WM_GETTITLEBARINFOEX can cause exception if the form level // Icon has already been disposed. This happens in rare circumstances. } } } return(preferredSize); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { // We have no preferred size, we take all we are given return(Size.Empty); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Debug.Assert(context != null); // Reset the largest child size to empty _maximumItem = Size.Empty; // Keep track of the total preferred size Size preferredSize = Size.Empty; // Nothing to calculate if there are no children if (Count > 0) { // Default to no space between each child item int gap = 0; // If we have a metric provider then get the child gap to use if (_paletteMetric != null) { gap = _paletteMetric.GetMetricInt(State, _metricGap); } else { gap = context.Renderer.RenderTabBorder.GetTabBorderSpacingGap(_tabBorderStyle); } // Line spacing gap can never be less than zero int lineGap = (gap < 0 ? 0 : gap); bool reversed = false; // Do we need to apply right to left by positioning children in reverse order? if (IsOneLine && !BarVertical && (context.Control.RightToLeft == RightToLeft.Yes)) { reversed = true; } // Allocate caching for size of each child element _childSizes = new Size[Count]; // Find the child index of the selected page int selectedChildIndex = -1; // Find the size of each child in turn for (int i = 0; i < Count; i++) { // Get access to the indexed child ViewBase child = this[reversed ? (Count - i - 1) : i]; INavCheckItem checkItem = (INavCheckItem)child; // Only examine visible children if (child.Visible) { // Cache child index of the selected page if (checkItem.Navigator.SelectedPage == checkItem.Page) { selectedChildIndex = i; } // Ask child for it's own preferred size _childSizes[i] = child.GetPreferredSize(context); // Enfore the minimum and maximum sizes if (ItemVertical) { _childSizes[i].Width = Math.Max(Math.Min(_childSizes[i].Width, _itemMaximumSize.Height), _itemMinimumSize.Height); _childSizes[i].Height = Math.Max(Math.Min(_childSizes[i].Height, _itemMaximumSize.Width), _itemMinimumSize.Width); } else { _childSizes[i].Width = Math.Max(Math.Min(_childSizes[i].Width, _itemMaximumSize.Width), _itemMinimumSize.Width); _childSizes[i].Height = Math.Max(Math.Min(_childSizes[i].Height, _itemMaximumSize.Height), _itemMinimumSize.Height); } // Remember the largest child encountered _maximumItem.Width = Math.Max(_childSizes[i].Width, _maximumItem.Width); _maximumItem.Height = Math.Max(_childSizes[i].Height, _maximumItem.Height); } } // Apply the item sizing method switch (BarItemSizing) { case BarItemSizing.Individual: // Do nothing, each item can be its own size break; case BarItemSizing.SameHeight: if (!BarVertical) { for (int i = 0; i < _childSizes.Length; i++) { if (!_childSizes[i].IsEmpty) { _childSizes[i].Height = _maximumItem.Height; } } } else { for (int i = 0; i < _childSizes.Length; i++) { if (!_childSizes[i].IsEmpty) { _childSizes[i].Width = _maximumItem.Width; } } } break; case BarItemSizing.SameWidth: if (!BarVertical) { for (int i = 0; i < _childSizes.Length; i++) { if (!_childSizes[i].IsEmpty) { _childSizes[i].Width = _maximumItem.Width; } } } else { for (int i = 0; i < _childSizes.Length; i++) { if (!_childSizes[i].IsEmpty) { _childSizes[i].Height = _maximumItem.Height; } } } break; case BarItemSizing.SameWidthAndHeight: for (int i = 0; i < _childSizes.Length; i++) { if (!_childSizes[i].IsEmpty) { _childSizes[i] = _maximumItem; } } break; default: // Should never happen! Debug.Assert(false); break; } // Store a list of the individual line vectors (height or width depending on orientation) _lineDetails = new List <LineDetails>(); int itemCount = 0; int startIndex = 0; int visibleItems = 0; if (BarVertical) { int yPos = 0; int yMaxPos = 0; int lineWidth = 0; _preferredOrientLength = 0; for (int i = 0; i < _childSizes.Length; i++) { // Ignore invisible items, which are zero sized if (!_childSizes[i].IsEmpty) { // If not the first visible item on line, then need a spacing gap int yAdd = (visibleItems > 0) ? gap : 0; // Add on the heght of the child yAdd += _childSizes[i].Height; // Does this item extend beyond visible line? // (unless first item, we always have at least one item on a line) if (!IsOneLine && (yPos > 0) && ((yPos + yAdd) > context.DisplayRectangle.Height)) { // Remember the line metrics _lineDetails.Add(new LineDetails(yPos, lineWidth, startIndex, itemCount)); // Track the widest line encountered yMaxPos = Math.Max(yPos, yMaxPos); // Reset back to start of the next line yPos = 0; itemCount = 0; startIndex = i; _preferredOrientLength += (lineGap + lineWidth); lineWidth = 0; // First item on new line does not need a spacing gap yAdd = _childSizes[i].Height; } // Add on to the current line yPos += yAdd; visibleItems++; // Track the tallest item on this line if (lineWidth < _childSizes[i].Width) { lineWidth = _childSizes[i].Width; } } // Visible and Invisible items are added to the item count itemCount++; } // Add the last line to the height _preferredOrientLength += lineWidth; // Check if the last line is the tallest line yMaxPos = Math.Max(yPos, yMaxPos); // If we extended past end of the line if (yMaxPos > context.DisplayRectangle.Height) { // If the mode requires we do not extend over the line if ((BarMultiline == BarMultiline.Shrinkline) || (BarMultiline == BarMultiline.Exactline)) { bool changed; // Keep looping to reduce item sizes until all are zero sized or finished removing extra space do { changed = false; // Are there any items avaiable for reducing? if (visibleItems > 0) { // How much do we need to shrink each item by? int shrink = Math.Max(1, (yMaxPos - context.DisplayRectangle.Height) / visibleItems); // Reduce size of each item for (int i = 0; i < _childSizes.Length; i++) { // Cannot make smaller then zero height if (_childSizes[i].Height > 0) { // Reduce size int tempHeight = _childSizes[i].Height; _childSizes[i].Height -= shrink; // Prevent going smaller then zero if (_childSizes[i].Height <= 0) { _childSizes[i].Height = 0; visibleItems--; } // Reduce total width by the height removed from item yMaxPos -= (tempHeight - _childSizes[i].Height); // All reduction made, exit the loop if (yMaxPos <= context.DisplayRectangle.Height) { break; } changed = true; } } } } while (changed && (yMaxPos > context.DisplayRectangle.Height)); } } // If we are shorter than the available height if (yMaxPos < context.DisplayRectangle.Height) { // If the mode requires we extend to the end of the line if ((BarMultiline == BarMultiline.Expandline) || (BarMultiline == BarMultiline.Exactline)) { bool changed; // Keep looping to expand item sizes until all extra space is allocated do { changed = false; // Are there any items avaiable for expanding? if (visibleItems > 0) { // How much do we need to expand each item by? int expand = Math.Max(1, (context.DisplayRectangle.Height - yMaxPos) / visibleItems); // Expand size of each item for (int i = 0; i < _childSizes.Length; i++) { // Expand size _childSizes[i].Height += expand; // Reduce free space by that allocated yMaxPos += expand; changed = true; // All expansion made, exit the loop if (yMaxPos >= context.DisplayRectangle.Height) { break; } } } } while (changed && (yMaxPos < context.DisplayRectangle.Height)); } } // Remember the line metrics _lineDetails.Add(new LineDetails(yMaxPos, lineWidth, startIndex, itemCount)); // Our preferred size is tall enough to show the longest line and total width preferredSize.Width = _preferredOrientLength; preferredSize.Height = yMaxPos; } else { int xPos = 0; int xMaxPos = 0; int lineHeight = 0; _preferredOrientLength = 0; for (int i = 0; i < _childSizes.Length; i++) { // Ignore invisible items, which are zero sized if (!_childSizes[i].IsEmpty) { // If not the first item on line, then need a spacing gap int xAdd = (visibleItems > 0) ? gap : 0; // Add on the width of the child xAdd += _childSizes[i].Width; // Does this item extend beyond visible line? // (unless first item, we always have at least one item on a line) if (!IsOneLine && (xPos > 0) && ((xPos + xAdd) > context.DisplayRectangle.Width)) { // Remember the line metrics _lineDetails.Add(new LineDetails(xPos, lineHeight, startIndex, itemCount)); // Track the widest line encountered xMaxPos = Math.Max(xPos, xMaxPos); // Reset back to start of the next line xPos = 0; itemCount = 0; startIndex = i; _preferredOrientLength += (lineGap + lineHeight); lineHeight = 0; // First item on new line does not need a spacing gap xAdd = _childSizes[i].Width; } // Add on to the current line xPos += xAdd; visibleItems++; // Track the tallest item on this line if (lineHeight < _childSizes[i].Height) { lineHeight = _childSizes[i].Height; } } // Visible and Invisible items are added to the item count itemCount++; } // Add the last line to the height _preferredOrientLength += lineHeight; // Check if the last line is the widest line xMaxPos = Math.Max(xPos, xMaxPos); // If we extended past end of the line if (xMaxPos > context.DisplayRectangle.Width) { // If the mode requires we do not extend over the line if ((BarMultiline == BarMultiline.Shrinkline) || (BarMultiline == BarMultiline.Exactline)) { bool changed; // Keep looping to reduce item sizes until all are zero sized or finished removing extra space do { changed = false; // Are there any items avaiable for reducing? if (visibleItems > 0) { // How much do we need to shrink each item by? int shrink = Math.Max(1, (xMaxPos - context.DisplayRectangle.Width) / visibleItems); // Reduce size of each item for (int i = 0; i < _childSizes.Length; i++) { // Cannot make smaller then zero width if (_childSizes[i].Width > 0) { // Reduce size int tempWidth = _childSizes[i].Width; _childSizes[i].Width -= shrink; // Prevent going smaller then zero if (_childSizes[i].Width <= 0) { _childSizes[i].Width = 0; visibleItems--; } // Reduce total width by the width removed from item xMaxPos -= (tempWidth - _childSizes[i].Width); // All reduction made, exit the loop if (xMaxPos <= context.DisplayRectangle.Width) { break; } changed = true; } } } } while (changed && (xMaxPos > context.DisplayRectangle.Width)); } } // If we are shorter than the line width if (xMaxPos < context.DisplayRectangle.Width) { // If the mode requires we extend to the end of the line if ((BarMultiline == BarMultiline.Expandline) || (BarMultiline == BarMultiline.Exactline)) { bool changed; // Keep looping to expand item sizes until all the extra space is removed do { changed = false; // Are there any items avaiable for reducing? if (visibleItems > 0) { // How much do we need to expand each item by? int expand = Math.Max(1, (context.DisplayRectangle.Width - xMaxPos) / visibleItems); // Expand size of each item for (int i = 0; i < _childSizes.Length; i++) { // Expand size _childSizes[i].Width += expand; // Increase total width taken up by items xMaxPos += expand; changed = true; // All expansion made, exit the loop if (xMaxPos >= context.DisplayRectangle.Width) { break; } } } } while (changed && (xMaxPos < context.DisplayRectangle.Width)); } } // Remember the line metrics _lineDetails.Add(new LineDetails(xMaxPos, lineHeight, startIndex, itemCount)); // Our preferred size is tall enough to show the widest line and total height preferredSize.Width = xMaxPos; preferredSize.Height = _preferredOrientLength; } // Reverse the order of the lines when at top or left edge, as the // items should be positioned from the inside edge moving outwards if ((Orientation == VisualOrientation.Top) || (Orientation == VisualOrientation.Left)) { _lineDetails.Reverse(); } // If we are using tabs then we need to move the line with the selection if (ReorderSelectedLine) { // Did we find a selected child index? if (selectedChildIndex >= 0) { // Find the line details that contains this child index for (int i = 0; i < _lineDetails.Count; i++) { // Is the selected item in the range of items for this line? if ((selectedChildIndex >= _lineDetails[i].StartIndex) && (selectedChildIndex < (_lineDetails[i].StartIndex + _lineDetails[i].ItemCount))) { // Remove the line details LineDetails ld = _lineDetails[i]; _lineDetails.RemoveAt(i); if ((Orientation == VisualOrientation.Top) || (Orientation == VisualOrientation.Left)) { // Move to end of the list _lineDetails.Add(ld); } else { // Move to start of the list _lineDetails.Insert(0, ld); } } } } } } // Enfore the minimum height of the bar if (BarVertical) { preferredSize.Width = Math.Max(preferredSize.Width, _barMinimumHeight); } else { preferredSize.Height = Math.Max(preferredSize.Height, _barMinimumHeight); } return(preferredSize); }
private Rectangle CalculatePopupRect(ViewLayoutRibbonTabsArea tabsArea, ViewDrawPanel drawMinimizedPanel) { Size popupSize; // Get the preferred size of the groups area, we only really want the height using (ViewLayoutContext context = new ViewLayoutContext(_ribbon, Renderer)) { popupSize = drawMinimizedPanel.GetPreferredSize(context); } // The width should default to being the same width as the ribbon control popupSize.Width = _ribbon.Width; // Get the screen rectangles for the ribbon and the tabs area of the ribbon Rectangle parentRibbonRect = _ribbon.RectangleToScreen(_ribbon.ClientRectangle); Rectangle parentTabsRect = _ribbon.RectangleToScreen(tabsArea.ClientRectangle); // Default popup is placed below the ribbon Rectangle popupRect = new Rectangle(parentRibbonRect.X, parentTabsRect.Bottom - 1, popupSize.Width, popupSize.Height); // Get the view element for the currently selected tab ViewDrawRibbonTab viewTab = tabsArea.LayoutTabs.GetViewForRibbonTab(_ribbon.SelectedTab); // Convert the view tab client area to screen coordinates Rectangle viewTabRect = _ribbon.RectangleToScreen(viewTab.ClientRectangle); // Get the screen that the tab is mostly within Screen screen = Screen.FromRectangle(viewTabRect); Rectangle workingArea = screen.WorkingArea; workingArea.Width -= BOTTOMRIGHT_GAP; workingArea.Height -= BOTTOMRIGHT_GAP; // Is the right side of the popup extending over the right edge of the screen... if (popupRect.Right > workingArea.Right) { // Reduce width to bring it back onto the screen popupRect.Width -= (popupRect.Right - workingArea.Right); // Enforce a minimum useful width for the popup if (popupRect.Width < MINIMUM_WIDTH) { popupRect.X -= (MINIMUM_WIDTH - popupRect.Width); popupRect.Width = MINIMUM_WIDTH; } } else { // Is the left side of the popup extending over left edge of screen... if (popupRect.Left < workingArea.Left) { // Reduce left side of popup to start at screen left edge int reduce = (workingArea.Left - popupRect.Left); popupRect.Width -= reduce; popupRect.X += reduce; // Enforce a minimum useful width for the popup if (popupRect.Width < MINIMUM_WIDTH) { popupRect.Width = MINIMUM_WIDTH; } } } // If there is not enough room to place the popup below the tabs area if (popupRect.Bottom > workingArea.Bottom) { // Is there enough room above the parent for the entire popup height? if ((parentTabsRect.Top - popupRect.Height) >= workingArea.Top) { // Place the popup above the parent popupRect.Y = parentTabsRect.Top - popupSize.Height; } else { // Cannot show entire popup above or below, find which has most space int spareAbove = parentTabsRect.Top - workingArea.Top; int spareBelow = workingArea.Bottom - parentTabsRect.Bottom; // Place it in the area with the most space if (spareAbove > spareBelow) { popupRect.Y = workingArea.Top; } else { popupRect.Y = parentTabsRect.Bottom; } } } return(popupRect); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); // We take on all the available display area ClientRectangle = context.DisplayRectangle; // Start laying out children from the top left Point pt = ClientLocation; // Nothing to calculate if there are no children if (Count > 0) { // Default to no space between each child item int gap = 0; // If we have a metric provider then get the child gap to use if (_paletteMetric != null) { gap = _paletteMetric.GetMetricInt(State, _metricGap); } else { gap = context.Renderer.RenderTabBorder.GetTabBorderSpacingGap(_tabBorderStyle); } // Line spacing gap can never be less than zero int lineGap = (gap < 0 ? 0 : gap); bool reverseAccess = false; bool reversePosition = false; // Do we need to apply right to left by positioning children in reverse order? if (!BarVertical && (context.Control.RightToLeft == RightToLeft.Yes)) { if (IsOneLine) { reverseAccess = true; } else { reversePosition = true; } } if (BarVertical) { int xPos; // Ensure the left orientation is aligned towards right of bar area if (Orientation == VisualOrientation.Left) { xPos = ClientLocation.X + Math.Max(0, ClientWidth - _preferredOrientLength); } else { xPos = ClientLocation.X; } // Layout each line of buttons in turn foreach (LineDetails lineDetails in _lineDetails) { // Get starting position for first button on the line int yPos = FindStartingYPosition(context, lineDetails, reversePosition); // Layout each button on the line for (int i = 0; i < lineDetails.ItemCount; i++) { // Get the actual child index to use int itemIndex = lineDetails.StartIndex + i; // Ignore invisible items, which are zero sized if (!_childSizes[itemIndex].IsEmpty) { // Get access to the indexed child ViewBase child = this[(reverseAccess ? lineDetails.StartIndex + lineDetails.ItemCount - 1 - i : lineDetails.StartIndex + i)]; // Add on the height of the child int yAdd = _childSizes[itemIndex].Height; int xPosition = xPos; int yPosition = (reversePosition ? yPos - _childSizes[itemIndex].Height : yPos); // At the left edge, we need to ensure buttons are align by there right edges if (Orientation == VisualOrientation.Left) { xPosition = xPos + lineDetails.CrossLength - _childSizes[itemIndex].Width; } // Create the rectangle that shows all of the check button context.DisplayRectangle = new Rectangle(new Point(xPosition, yPosition), _childSizes[itemIndex]); // Ask the child to layout child.Layout(context); // Move to next child position if (reversePosition) { yPos -= (yAdd + gap); } else { yPos += (yAdd + gap); } } } // Move across to the next line xPos += (lineGap + lineDetails.CrossLength); } } else { int yPos; // Ensure the top orientation is aligned towards bottom of bar area if (Orientation == VisualOrientation.Top) { yPos = ClientLocation.Y + Math.Max(0, ClientHeight - _preferredOrientLength); } else { yPos = ClientLocation.Y; } // Layout each line of buttons in turn foreach (LineDetails lineDetails in _lineDetails) { // Get starting position for first button on the line int xPos = FindStartingXPosition(context, lineDetails, reversePosition); // Layout each button on the line for (int i = 0; i < lineDetails.ItemCount; i++) { // Get the actual child index to use int itemIndex = lineDetails.StartIndex + i; // Ignore invisible items, which are zero sized if (!_childSizes[itemIndex].IsEmpty) { // Get access to the indexed child ViewBase child = this[(reverseAccess ? lineDetails.StartIndex + lineDetails.ItemCount - 1 - i : lineDetails.StartIndex + i)]; // Add on the width of the child int xAdd = _childSizes[itemIndex].Width; int yPosition = yPos; int xPosition = (reversePosition ? xPos - _childSizes[itemIndex].Width : xPos); // At the top edge, we need to ensure buttons are align by there bottom edges if (Orientation == VisualOrientation.Top) { yPosition = yPos + lineDetails.CrossLength - _childSizes[itemIndex].Height; } // Create the rectangle that shows all of the check button context.DisplayRectangle = new Rectangle(new Point(xPosition, yPosition), _childSizes[itemIndex]); // Ask the child to layout child.Layout(context); // Move to next child position if (reversePosition) { xPos -= (xAdd + gap); } else { xPos += (xAdd + gap); } } } // Move down to the next line yPos += (lineGap + lineDetails.CrossLength); } } } // Put back the original display value now we have finished context.DisplayRectangle = ClientRectangle; }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) => _large ? _largeSize : _smallSize;
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { Debug.Assert(context != null); return(Size.Empty); }
/// <summary> /// Gets an array of the allowed possible sizes of the container. /// </summary> /// <param name="context">Context used to calculate the sizes.</param> /// <returns>Array of size values.</returns> public ItemSizeWidth[] GetPossibleSizes(ViewLayoutContext context) { // Ensure the control has the correct parent UpdateParent(context.Control); if (LastGallery != null) { Size originalItemSize = LastGallery.PreferredItemSize; GroupItemSize originalSize = _currentSize; // Create a list of results List <ItemSizeWidth> results = new List <ItemSizeWidth>(); // Are we allowed to be in the large size? if (GroupGallery.ItemSizeMaximum == GroupItemSize.Large) { // Allow a maximum of 39 steps between the large and medium values (with a minimum of 1) int step = Math.Max(1, (GroupGallery.LargeItemCount - GroupGallery.MediumItemCount) / 20); // Process each step from large to medium int itemCount = GroupGallery.LargeItemCount; while (itemCount > GroupGallery.MediumItemCount) { LastGallery.InternalPreferredItemSize = new Size(itemCount, 1); results.Add(new ItemSizeWidth(GroupItemSize.Large, GetPreferredSize(context).Width, itemCount)); itemCount -= step; } } // Are we allowed to be in the medium size? if (((int)GroupGallery.ItemSizeMaximum >= (int)GroupItemSize.Medium) && ((int)GroupGallery.ItemSizeMinimum <= (int)GroupItemSize.Medium)) { LastGallery.InternalPreferredItemSize = new Size(GroupGallery.MediumItemCount, 1); ItemSizeWidth mediumWidth = new ItemSizeWidth(GroupItemSize.Medium, GetPreferredSize(context).Width); if (_ribbon.InDesignHelperMode) { // Only add if we are the first calculation, as in design mode we // always provide a single possible size which is the largest item if (results.Count == 0) { results.Add(mediumWidth); } } else { // Only add the medium size if there is no other entry or we are // smaller than the existing size and so represent a useful shrinkage if ((results.Count == 0) || (results[results.Count - 1].Width > mediumWidth.Width)) { results.Add(mediumWidth); } } } // Are we allowed to be in the small size? if ((int)GroupGallery.ItemSizeMinimum == (int)GroupItemSize.Small) { // Temporary set the item size to be size _viewLarge.Visible = true; _currentSize = GroupItemSize.Small; // Get the width of the large button view ItemSizeWidth smallWidth = new ItemSizeWidth(GroupItemSize.Small, GetPreferredSize(context).Width); if (_ribbon.InDesignHelperMode) { // Only add if we are the first calculation, as in design mode we // always provide a single possible size which is the largest item if (results.Count == 0) { results.Add(smallWidth); } } else { // Only add the medium size if there is no other entry or we are // smaller than the existing size and so represent a useful shrinkage if ((results.Count == 0) || (results[results.Count - 1].Width > smallWidth.Width)) { results.Add(smallWidth); } } } // Ensure original value is put back LastGallery.InternalPreferredItemSize = originalItemSize; _currentSize = originalSize; return(results.ToArray()); } else { return(new ItemSizeWidth[] { new ItemSizeWidth(GroupItemSize.Large, NULL_CONTROL_WIDTH) }); } }
/// <summary> /// Gets an array of the allowed possible sizes of the container. /// </summary> /// <param name="context">Context used to calculate the sizes.</param> /// <returns>Array of size values.</returns> public ItemSizeWidth[] GetPossibleSizes(ViewLayoutContext context) { // Sync child elements to the current group items SyncChildrenToRibbonGroupItems(); // Create a list of results List <ItemSizeWidth> results = new List <ItemSizeWidth>(); // Are we allowed to be in the large size? if (_ribbonTriple.ItemSizeMaximum == GroupItemSize.Large) { ApplySize(GroupItemSize.Large); results.Add(new ItemSizeWidth(GroupItemSize.Large, GetPreferredSize(context).Width)); } // Are we allowed to be in the medium size? if (((int)_ribbonTriple.ItemSizeMaximum >= (int)GroupItemSize.Medium) && ((int)_ribbonTriple.ItemSizeMinimum <= (int)GroupItemSize.Medium)) { ApplySize(GroupItemSize.Medium); ItemSizeWidth mediumWidth = new ItemSizeWidth(GroupItemSize.Medium, GetPreferredSize(context).Width); if (_ribbon.InDesignHelperMode) { // Only add if we are the first calculation, as in design mode we // always provide a single possible size which is the largest item if (results.Count == 0) { results.Add(mediumWidth); } } else { // Only add the medium size if there is no other entry or we are // smaller than the existing size and so represent a useful shrinkage if ((results.Count == 0) || (results[0].Width > mediumWidth.Width)) { results.Add(mediumWidth); } } } // Are we allowed to be in the small size? if (_ribbonTriple.ItemSizeMinimum == GroupItemSize.Small) { ApplySize(GroupItemSize.Small); ItemSizeWidth smallWidth = new ItemSizeWidth(GroupItemSize.Small, GetPreferredSize(context).Width); if (_ribbon.InDesignHelperMode) { // Only add if we are the first calculation, as in design mode we // always provide a single possible size which is the largest item if (results.Count == 0) { results.Add(smallWidth); } } else { // Only add the small size if there is no other entry or we are // smaller than the existing size and so represent a useful shrinkage if ((results.Count == 0) || (results[results.Count - 1].Width > smallWidth.Width)) { results.Add(smallWidth); } } } // Ensure original value is put back ResetSize(); return(results.ToArray()); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { return(_viewSize); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { // Clear down the preferred size caches switch (_currentSize) { case GroupItemSize.Small: _smallCache.Clear(); _smallWidest = 0; break; case GroupItemSize.Medium: _mediumCache.Clear(); _mediumWidest = 0; break; case GroupItemSize.Large: _largeCache.Clear(); break; } // Sync child elements to the current group items SyncChildrenToRibbonGroupItems(); Size preferredSize = Size.Empty; // Are we sizing horizontal or vertical? bool horizontal = (_currentSize == GroupItemSize.Large); // Find total width and maximum height across all child elements for (int i = 0; i < this.Count; i++) { ViewBase child = this[i]; // Only interested in visible items if (child.Visible) { // Cache preferred size of the child Size childSize = child.GetPreferredSize(context); // Add into the size cache for use in layout code switch (_currentSize) { case GroupItemSize.Small: _smallCache.Add(child, childSize); _smallWidest = Math.Max(_smallWidest, childSize.Width); break; case GroupItemSize.Medium: _mediumCache.Add(child, childSize); _mediumWidest = Math.Max(_mediumWidest, childSize.Width); break; case GroupItemSize.Large: _largeCache.Add(child, childSize); break; } if (horizontal) { // If not the first item positioned if (preferredSize.Width > 0) { // Add on a single pixel spacing gap preferredSize.Width++; } // Always add on to the width preferredSize.Width += childSize.Width; // Find maximum height encountered preferredSize.Height = Math.Max(preferredSize.Height, childSize.Height); } else { // Always add on to the width preferredSize.Height += childSize.Height; // Find maximum height encountered preferredSize.Width = Math.Max(preferredSize.Width, childSize.Width); } } } // At design time we add space for the selection flap if (_ribbon.InDesignHelperMode) { preferredSize.Width += DesignTimeDraw.FlapWidth + DesignTimeDraw.SepWidth; } return(preferredSize); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { // Sync to represent a groups view per tab SyncChildrenToRibbonTabs(); return(base.GetPreferredSize(context)); }
/// <summary> /// Perform a layout of the elements. /// </summary> /// <param name="context">Layout context.</param> public override void Layout(ViewLayoutContext context) { Debug.Assert(context != null); // Store the provided client area ClientRectangle = context.DisplayRectangle; // Are we sizing horizontal or vertical? bool horizontal = (_currentSize == GroupItemSize.Large); int widest = (_currentSize == GroupItemSize.Small ? _smallWidest : _mediumWidest); // Are there any children to layout? if (this.Count > 0) { int x = ClientLocation.X; int y = ClientLocation.Y; // At design time we reserve space at the left side for the selection flap if (_ribbon.InDesignHelperMode) { x += DesignTimeDraw.FlapWidth; } // Position each item from left/top to right/bottom int width = ClientRectangle.Right - x; for (int i = 0; i < this.Count; i++) { ViewBase child = this[i]; // We only position visible items if (child.Visible) { // Get the cached size of this view Size childSize = Size.Empty; switch (_currentSize) { case GroupItemSize.Small: childSize = _smallCache[child]; break; case GroupItemSize.Medium: childSize = _mediumCache[child]; break; case GroupItemSize.Large: childSize = _largeCache[child]; break; } if (horizontal) { // Define display rectangle for the group context.DisplayRectangle = new Rectangle(x, y, childSize.Width, ClientHeight); // Position the element this[i].Layout(context); // Move across to next position (add 1 extra as the spacing gap) x += childSize.Width + 1; } else { // Define display rectangle for the group switch (_ribbonTriple.ItemAlignment) { case RibbonItemAlignment.Near: context.DisplayRectangle = new Rectangle(x, y, childSize.Width, childSize.Height); break; case RibbonItemAlignment.Center: context.DisplayRectangle = new Rectangle(x + (widest - childSize.Width) / 2, y, childSize.Width, childSize.Height); break; case RibbonItemAlignment.Far: context.DisplayRectangle = new Rectangle(x + widest - childSize.Width, y, childSize.Width, childSize.Height); break; } // Position the element this[i].Layout(context); // Move down to next position y += childSize.Height; } } } } // Update the display rectangle we allocated for use by parent context.DisplayRectangle = ClientRectangle; }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { return(context.Renderer.RenderStandardContent.GetContentPreferredSize(context, _contentProvider, this, VisualOrientation.Top, PaletteState.Normal, false, false)); }
/// <summary> /// Discover the preferred size of the element. /// </summary> /// <param name="context">Layout context.</param> public override Size GetPreferredSize(ViewLayoutContext context) { // We have no preference, just set our size to whatever is needed return(Size.Empty); }