コード例 #1
0
        /// <summary>
        /// Arrange a sequence of elements in a single line.
        /// </summary>
        /// <param name="lineStart">
        /// Index of the first element in the sequence to arrange.
        /// </param>
        /// <param name="lineEnd">
        /// Index of the last element in the sequence to arrange.
        /// </param>
        /// <param name="directDelta">
        /// Optional fixed growth in the primary direction.
        /// </param>
        /// <param name="indirectOffset">
        /// Offset of the line in the indirect direction.
        /// </param>
        /// <param name="indirectGrowth">
        /// Shared indirect growth of the elements on this line.
        /// </param>
        /// <param name="maxDirect">
        /// MaxSize of WrapPanel to be used in right to left orentation scenarios
        /// </param>
        private void ArrangeLine(int lineStart, int lineEnd, double?directDelta, double indirectOffset, double indirectGrowth
                                 // Added by lepipele
                                 , double maxDirect)
        {
            Orientation o            = Orientation;
            bool        isHorizontal = o == Orientation.Horizontal;

            FlowDirection f             = FlowDirection;
            bool          isLeftToRight = f == FlowDirection.LeftToRight;

            double directOffset = 0.0;

            if (!isLeftToRight)
            {
                directOffset = maxDirect;
            }

            UIElementCollection children = Children;

            for (int index = lineStart; index < lineEnd; index++)
            {
                // Get the size of the element
                UIElement    element     = children[index];
                OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                // Determine if we should use the element's desired size or the
                // fixed item width or height
                double directGrowth = directDelta != null ?
                                      directDelta.Value :
                                      elementSize.Direct;

                // Arrange the element
                Rect bounds = Rect.Empty;

                if (isLeftToRight)
                {
                    bounds = isHorizontal ?
                             new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) :
                             new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth);

                    directOffset += directGrowth;
                }
                else
                {
                    bounds = isHorizontal ?
                             new Rect(directOffset - directGrowth, indirectOffset, directGrowth, indirectGrowth) :
                             new Rect(indirectOffset, directOffset - directGrowth, indirectGrowth, directGrowth);

                    directOffset -= directGrowth;
                }

                element.Arrange(bounds);
            }
        }
コード例 #2
0
        /// <summary>
        /// Arrange a sequence of elements in a single line.
        /// </summary>
        /// <param name="lineStart">
        /// Index of the first element in the sequence to arrange.
        /// </param>
        /// <param name="lineEnd">
        /// Index of the last element in the sequence to arrange.
        /// </param>
        /// <param name="directDelta">
        /// Optional fixed growth in the primary direction.
        /// </param>
        /// <param name="indirectOffset">
        /// Offset of the line in the indirect direction.
        /// </param>
        /// <param name="indirectGrowth">
        /// Shared indirect growth of the elements on this line.
        /// </param>
        private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double indirectOffset, double indirectGrowth)
        {
            double directOffset = 0.0;

            Orientation o = Orientation;
            bool isHorizontal = o == Orientation.Horizontal;

            UIElementCollection children = Children;
            for (int index = lineStart; index < lineEnd; index++)
            {
                // Get the size of the element
                UIElement element = children[index];
                OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                // Determine if we should use the element's desired size or the
                // fixed item width or height
                double directGrowth = directDelta != null ?
                    directDelta.Value :
                    elementSize.Direct;

                // Arrange the element
                Rect bounds = isHorizontal ?
                    new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) :
                    new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth);
                element.Arrange(bounds);

                directOffset += directGrowth;
            }
        }
コード例 #3
0
        /// <summary>
        /// Arranges and sizes the
        /// <see cref="T:System.Windows.Controls.WrapPanel" /> control and its
        /// child elements.
        /// </summary>
        /// <param name="finalSize">
        /// The area within the parent that the
        /// <see cref="T:System.Windows.Controls.WrapPanel" /> should use 
        /// arrange itself and its children.
        /// </param>
        /// <returns>
        /// The actual size used by the
        /// <see cref="T:System.Windows.Controls.WrapPanel" />.
        /// </returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // Variables tracking the size of the current line, and the maximum
            // size available to fill.  Note that the line might represent a row
            // or a column depending on the orientation.
            Orientation o = Orientation;
            OrientedSize lineSize = new OrientedSize(o);
            OrientedSize maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height);

            // Determine the constraints for individual items
            double itemWidth = ItemWidth;
            double itemHeight = ItemHeight;
            bool hasFixedWidth = !itemWidth.IsNaN();
            bool hasFixedHeight = !itemHeight.IsNaN();
            double indirectOffset = 0;
            double? directDelta = (o == Orientation.Horizontal) ?
                (hasFixedWidth ? (double?)itemWidth : null) :
                (hasFixedHeight ? (double?)itemHeight : null);

            // Measure each of the Children.  We will process the elements one
            // line at a time, just like during measure, but we will wait until
            // we've completed an entire line of elements before arranging them.
            // The lineStart and lineEnd variables track the size of the
            // currently arranged line.
            UIElementCollection children = Children;
            int count = children.Count;
            int lineStart = 0;
            for (int lineEnd = 0; lineEnd < count; lineEnd++)
            {
                UIElement element = children[lineEnd];

                // Get the size of the element
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height);

                // If this element falls of the edge of the line
                if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
                {
                    // Then we just completed a line and we should arrange it
                    ArrangeLine(lineStart, lineEnd, directDelta, indirectOffset, lineSize.Indirect);

                    // Move the current element to a new line
                    indirectOffset += lineSize.Indirect;
                    lineSize = elementSize;

                    // If the current element is larger than the maximum size
                    if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
                    {
                        // Arrange the element as a single line
                        ArrangeLine(lineEnd, ++lineEnd, directDelta, indirectOffset, elementSize.Indirect);

                        // Move to a new line
                        indirectOffset += lineSize.Indirect;
                        lineSize = new OrientedSize(o);
                    }

                    // Advance the start index to a new line after arranging
                    lineStart = lineEnd;
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            // Arrange any elements on the last line
            if (lineStart < count)
            {
                ArrangeLine(lineStart, count, directDelta, indirectOffset, lineSize.Indirect);
            }

            return finalSize;
        }
コード例 #4
0
        protected override Size MeasureOverride(Size constraint)
        {
            // Variables tracking the size of the current line, the total size
            // measured so far, and the maximum size available to fill.  Note
            // that the line might represent a row or a column depending on the
            // orientation.
            Orientation o = Orientation;
            OrientedSize lineSize = new OrientedSize(o);
            OrientedSize totalSize = new OrientedSize(o);
            OrientedSize maximumSize = new OrientedSize(o, constraint.Width, constraint.Height);

            // Determine the constraints for individual items
            double itemWidth = ItemWidth;
            double itemHeight = ItemHeight;
            bool hasFixedWidth = !itemWidth.IsNaN();
            bool hasFixedHeight = !itemHeight.IsNaN();
            Size itemSize = new Size(
                hasFixedWidth ? itemWidth : constraint.Width,
                hasFixedHeight ? itemHeight : constraint.Height);

            // Measure each of the Children
            foreach (UIElement element in Children)
            {
                // Determine the size of the element
                element.Measure(itemSize);
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height);

                // If this element falls of the edge of the line
                if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
                {
                    // Update the total size with the direct and indirect growth
                    // for the current line
                    totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct);
                    totalSize.Indirect += lineSize.Indirect;

                    // Move the element to a new line
                    lineSize = elementSize;

                    // If the current element is larger than the maximum size,
                    // place it on a line by itself
                    if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
                    {
                        // Update the total size for the line occupied by this
                        // single element
                        totalSize.Direct = Math.Max(elementSize.Direct, totalSize.Direct);
                        totalSize.Indirect += elementSize.Indirect;

                        // Move to a new line
                        lineSize = new OrientedSize(o);
                    }
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            // Update the total size with the elements on the last line
            totalSize.Direct = Math.Max(lineSize.Direct, totalSize.Direct);
            totalSize.Indirect += lineSize.Indirect;

            // Return the total size required as an un-oriented quantity
            return new Size(totalSize.Width, totalSize.Height);
        }
コード例 #5
0
        /// <summary>
        /// Arranges and sizes the
        /// <see cref="T:System.Windows.Controls.WrapPanel" /> control and its
        /// child elements.
        /// </summary>
        /// <param name="finalSize">
        /// The area within the parent that the
        /// <see cref="T:System.Windows.Controls.WrapPanel" /> should use
        /// arrange itself and its children.
        /// </param>
        /// <returns>
        /// The actual size used by the
        /// <see cref="T:System.Windows.Controls.WrapPanel" />.
        /// </returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            // Variables tracking the size of the current line, and the maximum
            // size available to fill.  Note that the line might represent a row
            // or a column depending on the orientation.
            Orientation  o           = Orientation;
            OrientedSize lineSize    = new OrientedSize(o);
            OrientedSize maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height);

            // Determine the constraints for individual items
            double itemWidth      = ItemWidth;
            double itemHeight     = ItemHeight;
            bool   hasFixedWidth  = !itemWidth.IsNaN();
            bool   hasFixedHeight = !itemHeight.IsNaN();
            double indirectOffset = 0;
            double?directDelta    = (o == Orientation.Horizontal) ?
                                    (hasFixedWidth ? (double?)itemWidth : null) :
                                    (hasFixedHeight ? (double?)itemHeight : null);

            // Measure each of the Children.  We will process the elements one
            // line at a time, just like during measure, but we will wait until
            // we've completed an entire line of elements before arranging them.
            // The lineStart and lineEnd variables track the size of the
            // currently arranged line.
            UIElementCollection children = Children;
            int count     = children.Count;
            int lineStart = 0;

            for (int lineEnd = 0; lineEnd < count; lineEnd++)
            {
                UIElement element = children[lineEnd];

                // Get the size of the element
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height);

                // If this element falls of the edge of the line
                if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
                {
                    // Then we just completed a line and we should arrange it
                    ArrangeLine(lineStart, lineEnd, directDelta, indirectOffset, lineSize.Indirect);

                    // Move the current element to a new line
                    indirectOffset += lineSize.Indirect;
                    lineSize        = elementSize;

                    // If the current element is larger than the maximum size
                    if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
                    {
                        // Arrange the element as a single line
                        ArrangeLine(lineEnd, ++lineEnd, directDelta, indirectOffset, elementSize.Indirect);

                        // Move to a new line
                        indirectOffset += lineSize.Indirect;
                        lineSize        = new OrientedSize(o);
                    }

                    // Advance the start index to a new line after arranging
                    lineStart = lineEnd;
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct  += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            // Arrange any elements on the last line
            if (lineStart < count)
            {
                ArrangeLine(lineStart, count, directDelta, indirectOffset, lineSize.Indirect);
            }

            return(finalSize);
        }
コード例 #6
0
        protected override Size MeasureOverride(Size constraint)
        {
            // Variables tracking the size of the current line, the total size
            // measured so far, and the maximum size available to fill.  Note
            // that the line might represent a row or a column depending on the
            // orientation.
            Orientation  o           = Orientation;
            OrientedSize lineSize    = new OrientedSize(o);
            OrientedSize totalSize   = new OrientedSize(o);
            OrientedSize maximumSize = new OrientedSize(o, constraint.Width, constraint.Height);

            // Determine the constraints for individual items
            double itemWidth      = ItemWidth;
            double itemHeight     = ItemHeight;
            bool   hasFixedWidth  = !itemWidth.IsNaN();
            bool   hasFixedHeight = !itemHeight.IsNaN();
            Size   itemSize       = new Size(
                hasFixedWidth ? itemWidth : constraint.Width,
                hasFixedHeight ? itemHeight : constraint.Height);

            // Measure each of the Children
            foreach (UIElement element in Children)
            {
                // Determine the size of the element
                element.Measure(itemSize);
                OrientedSize elementSize = new OrientedSize(
                    o,
                    hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                    hasFixedHeight ? itemHeight : element.DesiredSize.Height);

                // If this element falls of the edge of the line
                if (NumericExtensions.IsGreaterThan(lineSize.Direct + elementSize.Direct, maximumSize.Direct))
                {
                    // Update the total size with the direct and indirect growth
                    // for the current line
                    totalSize.Direct    = Math.Max(lineSize.Direct, totalSize.Direct);
                    totalSize.Indirect += lineSize.Indirect;

                    // Move the element to a new line
                    lineSize = elementSize;

                    // If the current element is larger than the maximum size,
                    // place it on a line by itself
                    if (NumericExtensions.IsGreaterThan(elementSize.Direct, maximumSize.Direct))
                    {
                        // Update the total size for the line occupied by this
                        // single element
                        totalSize.Direct    = Math.Max(elementSize.Direct, totalSize.Direct);
                        totalSize.Indirect += elementSize.Indirect;

                        // Move to a new line
                        lineSize = new OrientedSize(o);
                    }
                }
                else
                {
                    // Otherwise just add the element to the end of the line
                    lineSize.Direct  += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            // Update the total size with the elements on the last line
            totalSize.Direct    = Math.Max(lineSize.Direct, totalSize.Direct);
            totalSize.Indirect += lineSize.Indirect;

            // Return the total size required as an un-oriented quantity
            return(new Size(totalSize.Width, totalSize.Height));
        }
コード例 #7
0
ファイル: BalancedWrapPanel.cs プロジェクト: Chesire/myManga
        /// <summary>
        /// Arrange a sequence of elements in a single line.
        /// </summary>
        /// <param name="lineStart">
        /// Index of the first element in the sequence to arrange.
        /// </param>
        /// <param name="lineEnd">
        /// Index of the last+1 element in the sequence to arrange.
        /// </param>
        /// <param name="directDelta">
        /// Optional fixed growth in the primary direction.
        /// </param>
        /// <param name="directMaximum">
        /// Maximum length in the direct direction.
        /// </param>
        /// <param name="indirectOffset">
        /// Offset of the line in the indirect direction.
        /// </param>
        /// <param name="indirectGrowth">
        /// Shared indirect growth of the elements on this line.
        /// </param>
        private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double directMaximum, double indirectOffset, double indirectGrowth)
        {
            Orientation o = Orientation;
            bool isHorizontal = o == Orientation.Horizontal;
            UIElementCollection children = Children;
            double directLength = 0.0;
            double itemCount = 0.0;
            double itemLength = isHorizontal ? ItemWidth : ItemHeight;

            if (AlignLastItems && !itemLength.IsNaN())
            {
                // Length is easy to calculate in this case
                itemCount = Math.Floor(directMaximum / itemLength);
                directLength = itemCount * itemLength;
            }
            else
            {
                // Make first pass to calculate the slack space
                itemCount = lineEnd - lineStart;
                for (int index = lineStart; index < lineEnd; index++)
                {
                    // Get the size of the element
                    UIElement element = children[index];
                    OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                    // Determine if we should use the element's desired size or the
                    // fixed item width or height
                    double directGrowth = directDelta != null ?
                        directDelta.Value :
                        elementSize.Direct;

                    // Update total length
                    directLength += directGrowth;
                }
            }

            // Determine slack
            double directSlack = directMaximum - directLength;
            double directSlackSlice = directSlack / (itemCount + 1.0);
            double directOffset = directSlackSlice;

            // Make second pass to arrange items
            for (int index = lineStart; index < lineEnd; index++)
            {
                // Get the size of the element
                UIElement element = children[index];
                OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                // Determine if we should use the element's desired size or the
                // fixed item width or height
                double directGrowth = directDelta != null ?
                    directDelta.Value :
                    elementSize.Direct;

                // Arrange the element
                Rect bounds = isHorizontal ?
                    new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) :
                    new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth);
                element.Arrange(bounds);

                // Update offset for next time
                directOffset += directGrowth + directSlackSlice;
            }
        }
コード例 #8
0
        /// <summary>
        /// Arrange a sequence of elements in a single line.
        /// </summary>
        /// <param name="lineStart">
        /// Index of the first element in the sequence to arrange.
        /// </param>
        /// <param name="lineEnd">
        /// Index of the last element in the sequence to arrange.
        /// </param>
        /// <param name="directDelta">
        /// Optional fixed growth in the primary direction.
        /// </param>
        /// <param name="indirectOffset">
        /// Offset of the line in the indirect direction.
        /// </param>
        /// <param name="indirectGrowth">
        /// Shared indirect growth of the elements on this line.
        /// </param>
        /// <param name="maxDirect">
        /// MaxSize of WrapPanel to be used in right to left orentation scenarios
        /// </param>
        private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double indirectOffset, double indirectGrowth
            // Added by lepipele
            , double maxDirect)
        {
            Orientation o = Orientation;
            bool isHorizontal = o == Orientation.Horizontal;

            FlowDirection f = FlowDirection;
            bool isLeftToRight = f == FlowDirection.LeftToRight;

            double directOffset = 0.0;
            if (!isLeftToRight)
            {
                directOffset = maxDirect;
            }

            UIElementCollection children = Children;
            for (int index = lineStart; index < lineEnd; index++)
            {
                // Get the size of the element
                UIElement element = children[index];
                OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                // Determine if we should use the element's desired size or the
                // fixed item width or height
                double directGrowth = directDelta != null ?
                    directDelta.Value :
                    elementSize.Direct;

                // Arrange the element
                Rect bounds = Rect.Empty;

                if (isLeftToRight)
                {
                    bounds = isHorizontal ?
                        new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) :
                        new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth);

                    directOffset += directGrowth;
                }
                else
                {
                    bounds = isHorizontal ?
                        new Rect(directOffset - directGrowth, indirectOffset, directGrowth, indirectGrowth) :
                        new Rect(indirectOffset, directOffset - directGrowth, indirectGrowth, directGrowth);

                    directOffset -= directGrowth;
                }

                element.Arrange(bounds);
            }
        }
コード例 #9
0
        /// <summary>
        /// Arrange a sequence of elements in a single line.
        /// </summary>
        /// <param name="lineStart">
        /// Index of the first element in the sequence to arrange.
        /// </param>
        /// <param name="lineEnd">
        /// Index of the last+1 element in the sequence to arrange.
        /// </param>
        /// <param name="directDelta">
        /// Optional fixed growth in the primary direction.
        /// </param>
        /// <param name="directMaximum">
        /// Maximum length in the direct direction.
        /// </param>
        /// <param name="indirectOffset">
        /// Offset of the line in the indirect direction.
        /// </param>
        /// <param name="indirectGrowth">
        /// Shared indirect growth of the elements on this line.
        /// </param>
        private void ArrangeLine(int lineStart, int lineEnd, double?directDelta, double directMaximum, double indirectOffset, double indirectGrowth)
        {
            Orientation         o            = Orientation;
            bool                isHorizontal = o == Orientation.Horizontal;
            UIElementCollection children     = Children;
            double              directLength = 0.0;
            double              itemCount    = 0.0;
            double              itemLength   = isHorizontal ? ItemWidth : ItemHeight;

            if (AlignLastItems && !itemLength.IsNaN())
            {
                // Length is easy to calculate in this case
                itemCount    = Math.Floor(directMaximum / itemLength);
                directLength = itemCount * itemLength;
            }
            else
            {
                // Make first pass to calculate the slack space
                itemCount = lineEnd - lineStart;
                for (int index = lineStart; index < lineEnd; index++)
                {
                    // Get the size of the element
                    UIElement    element     = children[index];
                    OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                    // Determine if we should use the element's desired size or the
                    // fixed item width or height
                    double directGrowth = directDelta != null ?
                                          directDelta.Value :
                                          elementSize.Direct;

                    // Update total length
                    directLength += directGrowth;
                }
            }

            // Determine slack
            double directSlack      = directMaximum - directLength;
            double directSlackSlice = directSlack / (itemCount + 1.0);
            double directOffset     = directSlackSlice;

            // Make second pass to arrange items
            for (int index = lineStart; index < lineEnd; index++)
            {
                // Get the size of the element
                UIElement    element     = children[index];
                OrientedSize elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                // Determine if we should use the element's desired size or the
                // fixed item width or height
                double directGrowth = directDelta != null ?
                                      directDelta.Value :
                                      elementSize.Direct;

                // Arrange the element
                Rect bounds = isHorizontal ?
                              new Rect(directOffset, indirectOffset, directGrowth, indirectGrowth) :
                              new Rect(indirectOffset, directOffset, indirectGrowth, directGrowth);
                element.Arrange(bounds);

                // Update offset for next time
                directOffset += directGrowth + directSlackSlice;
            }
        }
コード例 #10
0
        /// <summary>
        /// Arrange a sequence of elements in a single line.
        /// </summary>
        /// <param name="lineStart">
        /// Index of the first element in the sequence to arrange.
        /// </param>
        /// <param name="lineEnd">
        /// Index of the last element in the sequence to arrange.
        /// </param>
        /// <param name="directDelta">
        /// Optional fixed growth in the primary direction.
        /// </param>
        /// <param name="colWidth">
        /// Offset of the line in the indirect direction.
        /// </param>
        /// <param name="colCount">
        /// Shared indirect growth of the elements on this line.
        /// </param>
        private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double colWidth, int colCount)
        {
            var directOffset = 0.0;
            var o = Orientation;
            var isHorizontal = o == Orientation.Horizontal;
            var offset = colCount * colWidth;
            var children = Children;
            for (var index = lineStart; index < lineEnd; index++)
            {
                if (index >= children.Count) continue;
                // Get the size of the element
                var element = children[index];
                var elementSize = new OrientedSize(o, element.DesiredSize.Width, element.DesiredSize.Height);

                // Determine if we should use the element's desired size or the
                // fixed item width or height
                var directGrowth = directDelta != null
                                       ? directDelta.Value
                                       : elementSize.Direct;
                // Arrange the element
                var bounds = isHorizontal ? new Rect(directOffset, offset, directGrowth, colWidth) : new Rect(offset, directOffset, colWidth, directGrowth);
                element.Arrange(bounds);

                directOffset += directGrowth;
            }
        }
コード例 #11
0
        /// <summary>
        /// Arranges and sizes the
        /// <see cref="DynamicallySizedWrapPanel" /> control and its
        /// child elements.
        /// </summary>
        /// <param name="finalSize">
        /// The area within the parent that the
        /// <see cref="DynamicallySizedWrapPanel" /> should use 
        /// arrange itself and its children.
        /// </param>
        /// <returns>
        /// The actual size used by the
        /// <see cref="DynamicallySizedWrapPanel" />.
        /// </returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            #region Initialize Variables

            // Variables tracking the size of the current line, and the maximum
            // size available to fill.  Note that the line might represent a row
            // or a column depending on the orientation.
            var o = Orientation;
            var lineSize = new OrientedSize(o);
            var maximumSize = new OrientedSize(o, finalSize.Width, finalSize.Height);
            var numCols = NumberOfColumns;

            // Determine the constraints for individual items
            var itemWidth = ItemWidth;
            var itemHeight = ItemHeight;
            var hasFixedWidth = !itemWidth.IsNaN();
            var hasFixedHeight = !itemHeight.IsNaN();
            var indirectOffset = 0.0;
            var directDelta = (o == Orientation.Horizontal) ?
                (hasFixedWidth ? (double?)itemWidth : null) :
                (hasFixedHeight ? (double?)itemHeight : null);



            // Measure each of the Children.  We will process the elements one
            // line at a time, just like during measure, but we will wait until
            // we've completed an entire line of elements before arranging them.
            // The lineStart and lineEnd variables track the size of the
            // currently arranged line.
            var children = Children;
            var numberOfElements = children.Count;

            #endregion

            //TODO: Measure all of the children and save those numbers into an array

            var sizeArray = new int[(children.Where(c => c.DesiredSize.Height > 0)).Count()];
            var count = 0;

            //Iterates through the children to find the height for each and saves them to an arrays
            foreach (var child in Children)
            {
                if ((int)child.DesiredSize.Height != 0)
                {
                    sizeArray[count] = (int)child.DesiredSize.Height;
                    count++;
                }
            }

            //TODO: Figure out mean and standard deviation for the set
            //Had to specify double for the division that occurs below
            var totalChildHeight = sizeArray.Sum();
            double averageChildHeight = 0;
            if (sizeArray.Length > 0)
                averageChildHeight = sizeArray.Average();

            #region Standard Deviation Calculator

            double totalVariance = 0;

            var lengthOfArray = sizeArray.Length;

            var dataAverage = averageChildHeight;

            totalVariance += sizeArray.Sum(childHeight => Math.Pow(childHeight - dataAverage, 2));

            var stDev = lengthOfArray != 0 ? Math.Sqrt(totalVariance / lengthOfArray) : 0;

            #endregion

            //TODO: Put objects in each column until it surpasses any of the requirements

            //The average number of items each column should have
            var averageElementsPerColumn = numberOfElements / numCols;

            //Average height for a column
            var averageColumnHeight = totalChildHeight / numCols;

            var startOfColumnElementIndex = new int[numCols];

            var endOfColumnElementIndex = new int[numCols];

            startOfColumnElementIndex[0] = 0;
            //Set to negative 1 so that when the loop exits, the tracker will still be in the right position
            var positionTracker = -1;
            var maxHeight = 0;
            var tallestColumn = 0;

            for (var i = 0; i < numCols; i++)
            {
                var thisColHeight = 0;

                startOfColumnElementIndex[i] = (positionTracker + 1);

                var minHeightForColumn = (averageColumnHeight - (.5 * stDev));

                while (thisColHeight < minHeightForColumn && positionTracker < (children.Count - 1)) //(c => c.DesiredSize.Height > 0)
                {
                    positionTracker++;
                    thisColHeight += (int)children[positionTracker].DesiredSize.Height;
                }

                //if (thisColHeight > maxHeightForColumn || startOfColumnElementIndex[i] == positionTracker)
                //    positionTracker--;

                endOfColumnElementIndex[i] = positionTracker;

                if (i == (numCols - 1))
                {
                    endOfColumnElementIndex[i] = positionTracker - 1;
                    //thisColHeight -= (int)children[positionTracker].DesiredSize.Height;
                }
                if (thisColHeight > maxHeight)
                {
                    tallestColumn = i;
                    maxHeight = thisColHeight;
                }
            }
            //TODO: Print to the screen
            var colWidth = finalSize.Width / numCols;

            #region Print Elements to the screen
            var tallestChild = 0;

            if (children.Count(c => c.DesiredSize.Height > 0) == numCols)
            {
                var i = 0;
                for (var counter = 0; counter < children.Count; counter++)
                {
                    if (children[counter].DesiredSize.Height > 0)
                    {
                        startOfColumnElementIndex[i] = counter;
                        endOfColumnElementIndex[i] = counter;
                        i++;

                        if (children[counter].DesiredSize.Height > tallestChild)
                        {
                            tallestChild = (int) children[counter].DesiredSize.Height;
                            tallestColumn = i - 1;                        
                        }
                    }
                }
            }
            var lineStart = 0;
            var colCount = 0;

            var firstCol = true;
            //Iterate through each column
            for (var colIndex = 0; colIndex < numCols; colIndex++)
            {
                //Iterate through each element in the column
                for (var elementIndexToPrint = startOfColumnElementIndex[colIndex]; elementIndexToPrint <= endOfColumnElementIndex[colIndex]; elementIndexToPrint++)
                {
                    var element = children[elementIndexToPrint];

                    if (Math.Abs(element.DesiredSize.Height - 0.0) <= 0)
                        continue;

                    // Get the size of the element
                    var elementSize = new OrientedSize(
                        o,
                        hasFixedWidth ? itemWidth : element.DesiredSize.Width,
                        hasFixedHeight ? itemHeight : element.DesiredSize.Height);


                    // If this element falls off the edge of the line
                    if (elementIndexToPrint == endOfColumnElementIndex[colIndex])
                    {
                        #region use this to print things

                        // Then we just completed a line and we should arrange it
                        ArrangeLine(lineStart, ++elementIndexToPrint, directDelta, colWidth, colCount);
                        colCount++;

                        // Advance the start index to a new line after arranging
                        lineStart = elementIndexToPrint;

                        if (firstCol)
                        {
                            lineSize.Indirect = elementSize.Indirect;
                        }

                        firstCol = false;

                        // Move the current element to a new line
                        indirectOffset += lineSize.Indirect;
                        lineSize = elementSize;

                        #endregion

                        lineSize.Indirect = 0;
                        continue;
                    }

                    // Otherwise just add the element to the end of the line
                    lineSize.Direct += elementSize.Direct;
                    lineSize.Indirect = Math.Max(lineSize.Indirect, elementSize.Indirect);
                }
            }

            #endregion

            var tallestHeight = 0;

            for (var i = startOfColumnElementIndex[tallestColumn]; i <= endOfColumnElementIndex[tallestColumn]; i++)
            {
                tallestHeight += (int)children[i].DesiredSize.Height;
            }

            var test = maxHeight;
             
            return new Size(finalSize.Width, tallestHeight);
        }
コード例 #12
0
        protected override Size MeasureOverride(Size constraint)
        {
            // Variables tracking the size of the current line, the total size
            // measured so far, and the maximum size available to fill.  Note
            // that the line might represent a row or a column depending on the
            // orientation.
            var o = Orientation;
            //var lineSize = new OrientedSize(o);
            var totalSize = new OrientedSize(o);
            //var maximumSize = new OrientedSize(o, constraint.Width, constraint.Height);

            // Determine the constraints for individual items
            var itemWidth = ItemWidth;
            var itemHeight = ItemHeight;
            var hasFixedWidth = !itemWidth.IsNaN();
            var hasFixedHeight = !itemHeight.IsNaN();
            var itemSize = new Size(
                hasFixedWidth ? itemWidth : constraint.Width,
                hasFixedHeight ? itemHeight : constraint.Height);

            var numCols = NumberOfColumns;
            var children = Children;
            var numberOfElements = children.Count;

            // Measure each of the Children
            foreach (var element in Children)
            {
                // Determine the size of the element
                element.Measure(itemSize);
            }


            #region Copied From ArrangeOverride

            var startOfColumnElementIndex = new int[numCols];

            var endOfColumnElementIndex = new int[numCols];

            var tallestHeight = 0;

            //if (children.Count(c => c.DesiredSize.Height > 0) == numCols)
            //{
            //    var i = 0;
            //    for (var counter = 0; counter < children.Count; counter++)
            //    {
            //        if (children[counter].DesiredSize.Height > 0)
            //        {
            //            startOfColumnElementIndex[i] = counter;
            //            endOfColumnElementIndex[i] = counter;
            //            i++;
            //        }
            //    }

            //    foreach (var child in children.Where(child => child.DesiredSize.Height > tallestHeight))
            //        tallestHeight = (int)child.DesiredSize.Height;
                
                
            //    // Return the total size required as an un-oriented quantity
            //    return new Size(totalSize.Width, tallestHeight); 
            //}

            var sizeArray = new int[(children.Where(c => c.DesiredSize.Height > 0)).Count()];
            var count = 0;

            //Iterates through the children to find the height for each and saves them to an arrays
            foreach (var child in Children)
            {
                if ((int)child.DesiredSize.Height != 0)
                {
                    sizeArray[count] = (int)child.DesiredSize.Height;
                    count++;
                }
            }

            //TODO: Figure out mean and standard deviation for the set
            //Had to specify double for the division that occurs below
            var totalChildHeight = sizeArray.Sum();
            double averageChildHeight = 0;
            if (sizeArray.Length > 0)
                averageChildHeight = sizeArray.Average();

            #region Standard Deviation Calculator

            double totalVariance = 0;

            var lengthOfArray = sizeArray.Length;

            var dataAverage = averageChildHeight;

            totalVariance += sizeArray.Sum(childHeight => Math.Pow(childHeight - dataAverage, 2));

            var stDev = lengthOfArray != 0 ? Math.Sqrt(totalVariance / lengthOfArray) : 0;

            #endregion

            //TODO: Put objects in each column until it surpasses any of the requirements

            //The average number of items each column should have
            var averageElementsPerColumn = numberOfElements / numCols;

            //Average height for a column
            var averageColumnHeight = totalChildHeight / numCols;

            startOfColumnElementIndex[0] = 0;
            //Set to negative 1 so that when the loop exits, the tracker will still be in the right position
            var positionTracker = -1;
            var maxHeight = 0;
            var tallestColumn = 0;

            for (var i = 0; i < numCols; i++)
            {
                var thisColHeight = 0;

                startOfColumnElementIndex[i] = (positionTracker + 1);

                var minHeightForColumn = (averageColumnHeight - (.5 * stDev));

                while (thisColHeight < minHeightForColumn && positionTracker < (children.Count - 1)) //(c => c.DesiredSize.Height > 0)
                {
                    positionTracker++;
                    thisColHeight += (int)children[positionTracker].DesiredSize.Height;
                }

                //if (thisColHeight > maxHeightForColumn || startOfColumnElementIndex[i] == positionTracker)
                //    positionTracker--;

                endOfColumnElementIndex[i] = positionTracker;

                if (i == (numCols - 1))
                {
                    endOfColumnElementIndex[i] = positionTracker - 1;
                    //thisColHeight -= (int)children[positionTracker].DesiredSize.Height;
                }
                if (thisColHeight > maxHeight)
                {
                    tallestColumn = i;
                    maxHeight = thisColHeight;
                }
            }
            #endregion

            for (var i = startOfColumnElementIndex[tallestColumn]; i <= endOfColumnElementIndex[tallestColumn]; i++)
            {
                tallestHeight += (int)children[i].DesiredSize.Height;
            }

            // Return the total size required as an un-oriented quantity
            return new Size(totalSize.Width, tallestHeight);
        }