예제 #1
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);
            }
        }
예제 #2
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++;
                }
            }
        }