Пример #1
0
        protected override Size MeasureOverride(Size availableSize)
        {
            // Measure each child with the same available size as the parent, in the direction of the panel.
            foreach (var element in Elements)
                element.Measure(CreateSize(GetStackLength(availableSize), GetStretchLength(availableSize)));

            var groups = GetGroups(availableSize);

            // Find the tallest and longest group lengths.
            double stackLength = 0, stretchLength = 0;
            foreach (var group in groups)
            {
                double groupStackLength = 0, groupStretchLength = 0;
                foreach (var child in group.Elements)
                {
                    groupStackLength += GetStackLength(child.DesiredSize);
                    groupStretchLength = Math.Max(groupStretchLength, GetStretchLength(child.DesiredSize));
                    // Group with largest child.
                }
                stackLength = Math.Max(stackLength, groupStackLength); // Largest group based on total size.
                stretchLength += groupStretchLength;
            }

            return CreateSize(stackLength, stretchLength);
        }
Пример #2
0
        protected override Size ArrangeOverride(Size finalSize)
        {
            double maxStackLength = 0;
            double stretchLength = 0;
            var groups = GetGroups(finalSize);

            foreach (var group in groups)
            {
                // Find max size of child to be the max width/height of the row/column.
                var groupMaxLength = group.Elements.Select(child => GetStretchLength(child.DesiredSize)).Max();
                double groupLength = 0;

                foreach (var child in group.Elements)
                {
                    var childStackLength = GetStackLength(child.DesiredSize);

                    var rect = Orientation == Orientation.Horizontal
                        ? new Rectangle(groupLength, stretchLength, childStackLength, groupMaxLength)
                        : new Rectangle(stretchLength, groupLength, groupMaxLength, childStackLength);
                    child.Arrange(rect);

                    groupLength += childStackLength; //The next element will be position below/to the right of this one.
                }

                maxStackLength = Math.Max(maxStackLength, groupLength);
                // Move the x/y over by the max length to start a new row or column.
                stretchLength += groupMaxLength;
            }

            return finalSize;
        }
Пример #3
0
        protected override Size ArrangeOverride(Size finalSize)
        {
            var stretchLength = GetStretchSize(finalSize);

            double stackLength = 0;
            for (var i = 0; i < Elements.Count; i++)
            {
                var child = Elements[i];
                // Get the size in the stacking direction of the child.
                var childStackLength = GetStackSize(child.DesiredSize);

                var point = CreatePoint(stackLength, 0);

                // Create a rectangle from the point and length of the stretch and stack lengths.
                var rect = Orientation == Orientation.Vertical
                    ? new Rectangle(point, stretchLength, childStackLength)
                    : new Rectangle(point, childStackLength, stretchLength);

                child.Arrange(rect);

                stackLength += childStackLength;
            }

            return CreateSize(GetStackSize(finalSize), stretchLength);
        }
Пример #4
0
        protected override Size ArrangeOverride(Size finalSize)
        {
            var remainingWidth = finalSize.Width;
            var remainingHeight = finalSize.Height;

            double left = 0, top = 0;

            for (var i = 0; i < Elements.Count; i++)
            {
                var child = Elements[i];
                var dock = GetDock(child);
                var orientation = GetOrientation(dock);

                // If this is the last child and LastChildFill is true, fill the child to the available size.
                var fill = LastChildFill && i == Elements.Count - 1;

                // If the orientation is vertical, fill the width, and if it is horizontal, will the height.
                var cellWidth = orientation == Orientation.Vertical || fill
                    ? remainingWidth
                    : child.DesiredSize.Width;
                var cellHeight = orientation == Orientation.Horizontal || fill
                    ? remainingHeight
                    : child.DesiredSize.Height;

                // If to the right or bottom, use the remaining size - the cell size.
                double cellLeft = 0, cellTop = 0;
                if (dock == Dock.Right)
                    cellLeft = remainingWidth - cellWidth;
                else if (dock == Dock.Bottom)
                    cellTop = remainingHeight - cellHeight;

                child.Arrange(new Rectangle(left + cellLeft, top + cellTop, cellWidth, cellHeight));

                // Add to the left or top if from the left or top.
                if (orientation == Orientation.Horizontal)
                {
                    remainingWidth -= cellWidth;
                    if (dock == Dock.Left)
                        left += cellWidth;
                }
                else
                {
                    remainingHeight -= cellHeight;
                    if (dock == Dock.Top)
                        top += cellHeight;
                }
            }

            return finalSize;
        }
Пример #5
0
        protected override Size MeasureOverride(Size availableSize)
        {
            double stackLength = 0, stretchLength = 0;

            for (var i = 0; i < Elements.Count; i++)
            {
                var child = Elements[i];

                // Measure each child with the container size in the stack direction and an infinite size in the other.
                child.Measure(CreateSize(double.PositiveInfinity, GetStretchSize(availableSize)));

                // Add to the stack length so far, and use the largest size in the stretch directorion to set the size of the stack panel.
                stackLength += GetStackSize(child.DesiredSize);
                stretchLength = Math.Max(stretchLength, GetStretchSize(child.DesiredSize));
            }

            return CreateSize(stackLength, stretchLength);
        }
Пример #6
0
        protected override Size ArrangeOverride(Size finalSize)
        {
            foreach (var child in Elements)
            {
                // By default, position them in the top left corner.
                var x = 0d;
                var y = 0d;
                var left = GetLeft(child);
                var top = GetTop(child);

                // X axis
                if (!double.IsNaN(left))
                    x = left; // If left is defined, use that for the x position.
                else // If it is not, use the right position.
                {
                    // Arrange with right.
                    var right = GetRight(child);
                    if (!double.IsNaN(right))
                        x = finalSize.Width - child.DesiredSize.Width - right;
                }

                // Y axis
                if (!double.IsNaN(top))
                    y = top;
                else
                {
                    var elementBottom = GetBottom(child);
                    if (!double.IsNaN(elementBottom))
                        y = finalSize.Height - child.DesiredSize.Height - elementBottom;
                }

                child.Arrange(new Rectangle(new Point(x, y), child.DesiredSize));
            }

            return finalSize;
        }
Пример #7
0
        /// <summary>
        /// Clamp the size between a lower and upper bound.
        /// </summary>
        public Size Clamp(Size min, Size max)
        {
            if (min.Width > max.Width || min.Height > max.Height)
                throw new ArgumentException("Minimum must be less than maximum.");

            return Max(min).Min(max);
        }
Пример #8
0
        /// <summary>
        /// Retuns an offset to the elements position according to its size, container size, and alignment.
        /// </summary>
        private Point Align(Rectangle container, Size size)
        {
            if (!double.IsInfinity(size.Width)) // Infinite sizes will be handled elsewhere.
            {
                switch (HorizontalAlignment)
                {
                    case HorizontalAlignment.Stretch:
                    case HorizontalAlignment.Center:
                        container.X = container.Left + (container.Width - size.Width) / 2;
                        break;
                    case HorizontalAlignment.Right:
                        container.X = container.Left + container.Width - size.Width;
                        break;
                }
            }

            if (!double.IsInfinity(size.Height))
            {
                switch (VerticalAlignment)
                {
                    case VerticalAlignment.Stretch:
                    case VerticalAlignment.Center:
                        container.Y = container.Top + (container.Height - size.Height) / 2;
                        break;
                    case VerticalAlignment.Bottom:
                        container.Y = container.Top + container.Height - size.Height;
                        break;
                }
            }

            return container.Point;
        }
Пример #9
0
        protected override Size MeasureOverride(Size availableSize)
        {
            var remainingWidth = availableSize.Width;
            var remainingHeight = availableSize.Height;

            foreach (var child in Elements)
            {
                // Measure the child with the remaining area.
                child.Measure(new Size(remainingWidth, remainingHeight));

                // Subtract from the remaining area depending on the orientation.
                if (GetOrientation(GetDock(child)) == Orientation.Horizontal)
                    remainingWidth -= child.DesiredSize.Width;
                else
                    remainingHeight -= child.DesiredSize.Height;
            }

            double totalWidth = 0;
            double totalHeight = 0;

            foreach (var child in Elements)
            {
                if (GetOrientation(GetDock(child)) == Orientation.Horizontal)
                {
                    totalWidth += child.DesiredSize.Width;
                    totalHeight = Math.Max(totalHeight, child.DesiredSize.Height);
                }
                else
                {
                    totalHeight += child.DesiredSize.Height;
                    totalWidth = Math.Max(totalWidth, child.DesiredSize.Width);
                }
            }

            return new Size(totalWidth, totalHeight);
        }
Пример #10
0
        public override void Measure(Size availableSize)
        {
            // If visibility is collapsed, do not account for the element's size.
            if (Visibility == Visibility.Collapsed)
            {
                Manager.Layout.RemoveMeasure(this);
                DesiredSize = Size.Zero;
                return;
            }

            base.Measure(availableSize);
        }
Пример #11
0
        /// <summary>
        /// Measures the size of all child elements in a specific layout pattern.
        /// By default, returns the size of the largest child element.
        /// </summary>
        protected virtual Size MeasureOverride(Size availableSize)
        {
            // By default, return the size of the largest child element.
            var desired = Size.Zero;

            foreach (var child in Elements)
            {
                child.Measure(availableSize);
                desired = desired.Max(child.DesiredSize);
            }

            return desired;
        }
Пример #12
0
 private double GetStretchLength(Size size)
 {
     return Orientation == Orientation.Horizontal ? size.Height : size.Width;
 }
Пример #13
0
 /// <summary>
 /// Determines if the size is equal to another size within margin of error (because of floating point precision).
 /// </summary>
 public bool IsClose(Size size) => Width.IsClose(size.Width) && Height.IsClose(size.Height);
Пример #14
0
 // Force derived panels to implement their own layout logic.
 protected abstract override Size ArrangeOverride(Size finalSize);
Пример #15
0
 public Rectangle(Size size) : this(Point.Zero, size)
 {
 }
Пример #16
0
 public Rectangle(Point location, Size size) : this(location.X, location.Y, size.Width, size.Height)
 {
 }
Пример #17
0
 /// <summary>
 /// Extend the rectangle dimensions by the specified size.
 /// </summary>
 /// <param name="size"></param>
 /// <returns></returns>
 public Rectangle Extend(Size size) => new Rectangle(X, Y, Width + size.Width, Height + size.Height);
Пример #18
0
        protected override Size MeasureOverride(Size availableSize)
        {
            // Give each child infinite size.
            foreach (var child in Elements)
            {
                // Idea: Give each child the available size of the container, minus their position?
                //child.Measure(availableSize - new Size(child.Position.X, child.Position.Y));
                child.Measure(Size.Infinity);
            }

            return Size.Zero;
        }
Пример #19
0
        /// <summary>
        /// Return the larger size of this size and the specified size.
        /// </summary>
        public Size Max(Size size)
        {
            var width = size.IsWidthEmpty ? Width : Math.Max(Width, size.Width);
            var height = size.IsHeightEmpty ? Height : Math.Max(Height, size.Height);

            return new Size(width, height);
        }
Пример #20
0
 private Point AlignText(Size textsize)
 {
     // Calculate center for each axis.
     var center = new Point((Bounds.Width / 2) - (textsize.Width / 2),
         (Bounds.Height / 2) - (textsize.Height / 2));
     var x = 0d;
     var y = 0d;
     switch (TextAlignment)
     {
         // Top.
         case Alignment.TopLeft:
             break;
         case Alignment.TopRight:
             x = Bounds.Width - textsize.Width;
             break;
         // Bottom.
         case Alignment.BottomLeft:
             y = Bounds.Height - textsize.Height;
             break;
         case Alignment.BottomRight:
             y = Bounds.Height - textsize.Height;
             x = Bounds.Width - textsize.Width;
             break;
         // Center.
         case Alignment.TopCenter:
             x = center.X;
             break;
         case Alignment.BottomCenter:
             y = Bounds.Height - textsize.Height;
             x = center.X;
             break;
         case Alignment.LeftCenter:
             y = center.Y;
             break;
         case Alignment.RightCenter:
             y = center.Y;
             x = Bounds.Width - textsize.Width;
             break;
         case Alignment.Center:
             y = center.Y;
             x = center.X;
             break;
     }
     return new Point(x, y);
 }
Пример #21
0
 public bool Equals(Size other) => Width.Equals(other.Width) && Height.Equals(other.Height);
Пример #22
0
        protected override Size ArrangeOverride(Size finalSize)
        {
            Child?.Arrange(new Rectangle(BorderThickness + Padding, finalSize.Remove(BorderThickness).Remove(Padding)));

            return finalSize;
        }
Пример #23
0
 /// <summary>
 /// If the width or height is NaN or 0, fall back to another value.
 /// </summary>
 public Size Fallback(Size fallback)
 {
     return new Size(
         double.IsNaN(Width) || Width.IsClose(0) ? fallback.Width : Width,
         double.IsNaN(Height) || Height.IsClose(0) ? fallback.Height : Height);
 }
Пример #24
0
        /// <summary>
        /// Create or gets the groups of elements that will form rows/colums.
        /// </summary>
        // ReSharper disable once ReturnTypeCanBeEnumerable.Local
        private List<WrapGroup> GetGroups(Size size)
        {
            if (!groupsInvalidated)
                return groupCache;
            var maxLength = GetStackLength(size); // Size of one row/column

            var groups = new List<WrapGroup>();
            var group = new WrapGroup();

            for (var i = 0; i < Elements.Count; i++)
            {
                var child = Elements[i];
                var childSize = GetStackLength(child.DesiredSize);

                // If the group length + this child is more than the column/row length, start a new group.
                if (group.Length + childSize > maxLength)
                {
                    groups.Add(group);
                    group = new WrapGroup();
                }

                group.AddElement(child);
                group.Length += childSize;
            }

            groups.Add(group);
            groupsInvalidated = false;
            groupCache = groups;
            return groups;
        }
Пример #25
0
 protected abstract override Size MeasureOverride(Size availableSize);
Пример #26
0
 private double GetStackSize(Size size) => Orientation == Orientation.Vertical ? size.Height : size.Width;
Пример #27
0
 protected override Size MeasureCore(Size availableSize)
 {
     if (textSizeInvalidated)
     {
         textSize = Manager.Renderer.MeasureText(Text, FontSize, FontStyle);
         textSizeInvalidated = false;
     }
     return textSize.Max(Size);
 }
Пример #28
0
 private double GetStretchSize(Size size) => Orientation == Orientation.Vertical ? size.Width : size.Height;
Пример #29
0
 protected override Size MeasureOverride(Size availableSize)
 {
     // Remove the border and padding, measure the element, and then add them back, as they must be ignored.
     availableSize = availableSize.Remove(BorderThickness).Remove(Padding);
     var size = base.MeasureOverride(availableSize) + BorderThickness + Padding;
     return size;
 }
Пример #30
0
        /// <summary>
        /// Measures the element.
        /// </summary>
        protected virtual Size MeasureCore(Size availableSize)
        {
            // Remove the margin from the size, as it should be ignored for now.
            availableSize = availableSize.Remove(Margin);

            // If the width or height is NaN or 0, fall back to the available size, and clamp it within the min and max sizes.
            availableSize = Size.Fallback(availableSize).Clamp(MinSize, MaxSize);

            // Measure the size of child elements.
            var measuredSize = MeasureOverride(availableSize);

            measuredSize = Size.Fallback(measuredSize).Clamp(MinSize, MaxSize);

            measuredSize = measuredSize.Add(Margin);

            return measuredSize;
        }