コード例 #1
0
        /// <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;
        }
コード例 #2
0
        /// <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));
        }
コード例 #3
0
 /// <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);
 }
コード例 #4
0
 /// <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));
 }
コード例 #5
0
        /// <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);
            }
        }
コード例 #6
0
 /// <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);
 }
コード例 #7
0
 /// <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;
 }
コード例 #8
0
        /// <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;
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
 /// <summary>
 /// Perform a layout of the elements.
 /// </summary>
 /// <param name="context">Layout context.</param>
 public override void Layout(ViewLayoutContext context)
 {
     UpdateSeparatorSize();
     base.Layout(context);
 }
コード例 #11
0
        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);
        }
コード例 #12
0
 /// <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));
 }
コード例 #13
0
        /// <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);
            }
        }
コード例 #14
0
        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++;
                }
            }
        }
コード例 #15
0
        /// <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;
        }
コード例 #16
0
        /// <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);
        }
コード例 #17
0
 /// <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);
 }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        /// <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);
 }
コード例 #23
0
        /// <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) });
            }
        }
コード例 #24
0
        /// <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());
        }
コード例 #25
0
 /// <summary>
 /// Discover the preferred size of the element.
 /// </summary>
 /// <param name="context">Layout context.</param>
 public override Size GetPreferredSize(ViewLayoutContext context)
 {
     return(_viewSize);
 }
コード例 #26
0
        /// <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);
        }
コード例 #27
0
 /// <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));
 }
コード例 #28
0
        /// <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;
        }
コード例 #29
0
 /// <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));
 }
コード例 #30
0
 /// <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);
 }