Example #1
0
 /// <summary>This method performs the actual render operation to show a text label</summary>
 /// <param name="dc">Drawing context</param>
 /// <param name="info">Render info</param>
 /// <param name="scale">The scale.</param>
 /// <param name="offset">The offset.</param>
 public virtual void RenderHeader(DrawingContext dc, AutoHeaderTextRenderInfo info, double scale, Point offset)
 {
     dc.PushTransform(new TranslateTransform(offset.X, offset.Y));
     dc.PushTransform(new ScaleTransform(scale, scale));
     dc.PushClip(new RectangleGeometry(info.RenderRect));
     info.FormattedText.SetMaxTextWidths(new[] { info.RenderRect.Width });
     info.FormattedText.MaxLineCount = 1;
     info.FormattedText.Trimming     = TextTrimming.CharacterEllipsis;
     dc.DrawText(info.FormattedText, info.RenderRect.TopLeft);
     dc.Pop();
     dc.Pop();
     dc.Pop();
 }
 /// <summary>This method performs the actual render operation to show a text label</summary>
 /// <param name="dc">Drawing context</param>
 /// <param name="info">Render info</param>
 /// <param name="scale">The scale.</param>
 /// <param name="offset">The offset.</param>
 public virtual void RenderHeader(DrawingContext dc, AutoHeaderTextRenderInfo info, double scale, Point offset)
 {
     dc.PushTransform(new TranslateTransform(offset.X, offset.Y));
     dc.PushTransform(new ScaleTransform(scale, scale));
     dc.PushClip(new RectangleGeometry(info.RenderRect));
     info.FormattedText.SetMaxTextWidths(new[] { info.RenderRect.Width });
     info.FormattedText.MaxLineCount = 1;
     info.FormattedText.Trimming = TextTrimming.CharacterEllipsis;
     dc.DrawText(info.FormattedText, info.RenderRect.TopLeft);
     dc.Pop();
     dc.Pop();
     dc.Pop();
 }
Example #3
0
        private Size IterateChildren(Size availableSize, Action<UIElement, Rect> methodToCall)
        {
            try
            {
                var absoluteTop = ContentTopLeftPadding.Height;
                var top = absoluteTop;
                var left = ContentTopLeftPadding.Width;

                var heightUsed = top;
                var widthUsed = left;

                var horizontalSpacing = GetHorizontalTileSpacing(this);
                var verticalSpacing = GetVerticalTileSpacing(this);
                var horizontalGroupSpacing = GetHorizontalGroupSpacing(this);

                var tileWidthNormal = GetTileWidth(this);
                var tileHeight = GetTileHeight(this);
                var tileWidthDouble = tileWidthNormal*2 + horizontalSpacing;
                var tileWidthTiny = (tileWidthNormal - horizontalSpacing)/2;

                var groups = GetChildrenByGroup();

                // We figure out whether we need to leave space for headers
                if (RenderHeaders)
                {
                    _headers.Clear();
                    var titles = new List<string>();
                    var foundTitle = false;
                    foreach (var groupKey in groups.Keys)
                    {
                        var group = groups[groupKey];
                        if (group.Count > 0)
                        {
                            var groupTitle = GetGroupTitleForObject(group[0]);
                            titles.Add(groupTitle);
                            if (!string.IsNullOrEmpty(groupTitle)) foundTitle = true;
                        }
                        else titles.Add(string.Empty);
                    }
                    if (foundTitle)
                    {
                        var maxHeaderHeight = 0d;
                        foreach (var title in titles)
                        {
                            var header = new AutoHeaderTextRenderInfo
                            {
                                Text = title,
                                FormattedText = new FormattedText(title,
                                    CultureInfo.CurrentUICulture,
                                    FlowDirection.LeftToRight,
                                    new Typeface(HeaderFontFamily, HeaderFontStyle, HeaderFontWeight, FontStretches.Normal),
                                    HeaderFontSize,
                                    HeaderForegroundBrush)
                            };
                            maxHeaderHeight = Math.Max(header.FormattedText.Height, maxHeaderHeight);
                            _headers.Add(header);
                        }
                        if (maxHeaderHeight > 0)
                        {
                            absoluteTop += maxHeaderHeight + HeaderSpacing;
                            top += maxHeaderHeight + HeaderSpacing;
                            heightUsed += maxHeaderHeight + HeaderSpacing;
                        }
                    }
                }

                var groupCount = -1;
                foreach (var group in groups.Values)
                {
                    groupCount++;
                    var groupWidth = tileWidthDouble;
                    var groupLeft = left;

                    var currentTinyCount = 0;
                    var currentNormalCount = 0;

                    var currentMaxColumnWidth = 0d;

                    foreach (var child in group)
                    {
                        TileWidthModes tileWidth;
                        var contentPresenter = child as ContentPresenter;
                        if (contentPresenter != null && contentPresenter.Content != null && contentPresenter.Content is DependencyObject)
                        {
                            var dependencyContent = (DependencyObject)contentPresenter.Content;
                            tileWidth = GetTileWidthMode(dependencyContent);
                            child.Visibility = MetroTiles.GetTileVisibility(dependencyContent);
                        }
                        else
                            tileWidth = GetTileWidthMode(child);
                        if (tileWidth == TileWidthModes.Default) tileWidth = DefaultTileWidth;

                        if (child.Visibility != Visibility.Visible) continue;

                        switch (tileWidth)
                        {
                            case TileWidthModes.Tiny:
                                if (currentTinyCount == 0 && top > absoluteTop && top + tileHeight > availableSize.Height) // We are beyond the bottom and can do something about it
                                {
                                    top = absoluteTop;
                                    left += tileWidthDouble + horizontalSpacing;
                                    groupWidth += currentMaxColumnWidth + horizontalSpacing;
                                    currentMaxColumnWidth = 0d;
                                }
                                var tinyAreaLeft = left;
                                if (currentNormalCount == 1) tinyAreaLeft += tileWidthNormal + horizontalSpacing;
                                switch (currentTinyCount)
                                {
                                    case 0:
                                        var tinyTileRect0 = new Rect(tinyAreaLeft, top, tileWidthTiny, tileWidthTiny);
                                        methodToCall(child, tinyTileRect0);
                                        heightUsed = Math.Max(heightUsed, tinyTileRect0.Bottom);
                                        widthUsed = Math.Max(widthUsed, tinyTileRect0.Right);
                                        currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthTiny);
                                        break;
                                    case 1:
                                        var tinyTileRect1 = new Rect(tinyAreaLeft + horizontalSpacing + tileWidthTiny, top, tileWidthTiny, tileWidthTiny);
                                        methodToCall(child, tinyTileRect1);
                                        heightUsed = Math.Max(heightUsed, tinyTileRect1.Bottom);
                                        widthUsed = Math.Max(widthUsed, tinyTileRect1.Right);
                                        currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny + horizontalSpacing + tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthNormal);
                                        break;
                                    case 2:
                                        var tinyTileRect2 = new Rect(tinyAreaLeft, top + verticalSpacing + tileWidthTiny, tileWidthTiny, tileWidthTiny);
                                        methodToCall(child, tinyTileRect2);
                                        heightUsed = Math.Max(heightUsed, tinyTileRect2.Bottom);
                                        widthUsed = Math.Max(widthUsed, tinyTileRect2.Right);
                                        currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny + horizontalSpacing + tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthNormal);
                                        break;
                                    case 3:
                                        var tinyTileRect3 = new Rect(tinyAreaLeft + horizontalSpacing + tileWidthTiny, top + verticalSpacing + tileWidthTiny, tileWidthTiny, tileWidthTiny);
                                        methodToCall(child, tinyTileRect3);
                                        heightUsed = Math.Max(heightUsed, tinyTileRect3.Bottom);
                                        widthUsed = Math.Max(widthUsed, tinyTileRect3.Right);
                                        currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 0 ? tileWidthTiny + horizontalSpacing + tileWidthTiny : tileWidthNormal + horizontalSpacing + tileWidthNormal);
                                        break;
                                }
                                currentTinyCount++;
                                if (currentTinyCount > 3)
                                {
                                    currentNormalCount++;
                                    currentTinyCount = 0;
                                }
                                if (currentNormalCount > 1)
                                {
                                    top += tileHeight + verticalSpacing;
                                    currentNormalCount = 0;
                                }
                                break;
                            case TileWidthModes.Normal:
                                if (currentNormalCount == 1 && currentTinyCount > 0)
                                {
                                    top += tileHeight + verticalSpacing;
                                    currentNormalCount = 0;
                                }
                                if (currentNormalCount == 0 && top > absoluteTop && top + tileHeight > availableSize.Height) // We are beyond the bottom and can do something about it
                                {
                                    top = absoluteTop;
                                    left += tileWidthDouble + horizontalSpacing;
                                    groupWidth += currentMaxColumnWidth + horizontalSpacing;
                                    currentMaxColumnWidth = 0d;
                                }
                                var normalTileRect = new Rect(currentNormalCount == 1 ? left + tileWidthNormal + horizontalSpacing : left, top, tileWidthNormal, tileHeight);
                                currentTinyCount = 0;
                                currentNormalCount++;
                                methodToCall(child, normalTileRect);
                                heightUsed = Math.Max(heightUsed, normalTileRect.Bottom);
                                widthUsed = Math.Max(widthUsed, normalTileRect.Right);
                                currentMaxColumnWidth = Math.Max(currentMaxColumnWidth, currentNormalCount == 1 ? tileWidthNormal : tileWidthDouble);
                                if (currentNormalCount > 1)
                                {
                                    top += tileHeight + verticalSpacing;
                                    currentNormalCount = 0;
                                }
                                break;
                            case TileWidthModes.Double:
                                if (currentNormalCount > 0) top += tileHeight + verticalSpacing;
                                if (currentTinyCount > 0) top += tileHeight + verticalSpacing;
                                if (top > absoluteTop && top + tileHeight > availableSize.Height) // We are beyond the bottom and can do something about it
                                {
                                    top = absoluteTop;
                                    left += tileWidthDouble + horizontalSpacing;
                                    groupWidth += currentMaxColumnWidth + horizontalSpacing;
                                }
                                currentNormalCount = 0;
                                currentTinyCount = 0;
                                var dobleTileRect = new Rect(left, top, tileWidthDouble, tileHeight);
                                methodToCall(child, dobleTileRect);
                                heightUsed = Math.Max(heightUsed, dobleTileRect.Bottom);
                                widthUsed = Math.Max(widthUsed, dobleTileRect.Right);
                                currentMaxColumnWidth = tileWidthDouble;
                                top += tileHeight + verticalSpacing;
                                break;
                            case TileWidthModes.DoubleSquare:
                                if (currentNormalCount > 0) top += tileHeight + verticalSpacing;
                                if (currentTinyCount > 0) top += tileHeight + verticalSpacing;
                                if (top > absoluteTop && top + tileWidthDouble > availableSize.Height) // We are beyond the bottom and can do something about it
                                {
                                    top = absoluteTop;
                                    left += tileWidthDouble + horizontalSpacing;
                                    groupWidth += currentMaxColumnWidth + horizontalSpacing;
                                }
                                currentNormalCount = 0;
                                currentTinyCount = 0;
                                var dobleSquareTileRect = new Rect(left, top, tileWidthDouble, tileWidthDouble);
                                methodToCall(child, dobleSquareTileRect);
                                heightUsed = Math.Max(heightUsed, dobleSquareTileRect.Bottom);
                                widthUsed = Math.Max(widthUsed, dobleSquareTileRect.Right);
                                currentMaxColumnWidth = tileWidthDouble;
                                top += tileWidthDouble + verticalSpacing;
                                break;
                        }

                        // Possible headers
                        if (RenderHeaders && _headers.Count > groupCount)
                        {
                            _headers[groupCount].RenderRect = new Rect(groupLeft, 0d, groupWidth, _headers[groupCount].FormattedText.Height +4);
                            InvalidateVisual();
                        }
                    }

                    top = absoluteTop;
                    left += horizontalGroupSpacing - horizontalSpacing;
                    left += currentMaxColumnWidth;
                }
                //return new Size(left + tileWidthDouble, top + tileHeight);
                return new Size(widthUsed, heightUsed);
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
                throw;
            }
        }
Example #4
0
        /// <summary>
        /// When overridden in a derived class, measures the size in layout required for child elements and determines a size for the <see cref="T:System.Windows.FrameworkElement"/>-derived class.
        /// </summary>
        /// <param name="availableSize">The available size that this element can give to child elements. Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param>
        /// <returns>
        /// The size that this element determines it needs during layout, based on its calculations of child element sizes.
        /// </returns>
        protected override Size MeasureOverride(Size availableSize)
        {
            if (Children.Count != 2) return base.MeasureOverride(availableSize); // Not much we can do until we have exactly two elements;

            // First, we check whether we have any headers
            _headers.Clear();
            var header1 = GetCaption(Children[0]);
            var header2 = GetCaption(Children[1]);

            if (Orientation == Orientation.Vertical)
            {
                var maxHeaderHeight = 0d;
                if (!string.IsNullOrEmpty(header1) || !string.IsNullOrEmpty(header2))
                {
                    _headers.Add(new AutoHeaderTextRenderInfo { Text = header1, FormattedText = new FormattedText(header1, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush) });
                    _headers.Add(new AutoHeaderTextRenderInfo { Text = header2, FormattedText = new FormattedText(header2, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush) });
                    maxHeaderHeight = Math.Max(_headers[0].FormattedText.Height, _headers[1].FormattedText.Height);
                }

                var top = maxHeaderHeight + CaptionSpacing;
                var height = Math.Max(availableSize.Height - top, 0);
                var width = Math.Max((availableSize.Width - Spacing) / 2, 0);

                Children[0].Measure(new Size(width, height));
                Children[1].Measure(new Size(width, height));
            }
            else
            {
                var top = 0d;
                var height = Math.Max((availableSize.Height - Spacing) / 2, 0);
                var height1 = height;
                var height2 = height;

                if (!string.IsNullOrEmpty(header1))
                {
                    var text1 = new AutoHeaderTextRenderInfo { Text = header1, FormattedText = new FormattedText(header1, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush) };
                    _headers.Add(text1);
                    text1.RenderRect = new Rect(0d, 0d, availableSize.Width, text1.FormattedText.Height);
                    top += text1.FormattedText.Height + CaptionSpacing;
                    height1 -= (text1.FormattedText.Height + CaptionSpacing);
                }

                Children[0].Measure(new Size(availableSize.Width, height1));

                if (!string.IsNullOrEmpty(header2))
                {
                    var text2 = new AutoHeaderTextRenderInfo { Text = header2, FormattedText = new FormattedText(header2, CultureInfo.CurrentUICulture, FlowDirection.LeftToRight, new Typeface(CaptionFontFamily, CaptionFontStyle, CaptionFontWeight, FontStretches.Normal), CaptionFontSize, CaptionForegroundBrush) };
                    _headers.Add(text2);
                    text2.RenderRect = new Rect(0d, 0d, availableSize.Width, text2.FormattedText.Height);
                    top += text2.FormattedText.Height + CaptionSpacing;
                    height2 -= (text2.FormattedText.Height + CaptionSpacing);
                }

                Children[1].Measure(new Size(availableSize.Width, height2));
            }

            return base.MeasureOverride(availableSize);
        }