/// <summary> /// <see cref="FrameworkElement.ArrangeOverride"/> /// </summary> protected override Size ArrangeOverride(Size finalSize) { int firstInLine = 0; double itemWidth = ItemWidth; double itemHeight = ItemHeight; double accumulatedV = 0; double itemU = (Orientation == Orientation.Horizontal ? itemWidth : itemHeight); UVSize curLineSize = new UVSize(Orientation); UVSize uvFinalSize = new UVSize(Orientation, finalSize.Width, finalSize.Height); bool itemWidthSet = !double.IsNaN(itemWidth); bool itemHeightSet = !double.IsNaN(itemHeight); bool useItemU = (Orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet); UIElementCollection children = InternalChildren; for (int i = 0, count = children.Count; i < count; i++) { UIElement child = children[i] as UIElement; if (child == null) { continue; } UVSize sz = new UVSize( Orientation, (itemWidthSet ? itemWidth : child.DesiredSize.Width), (itemHeightSet ? itemHeight : child.DesiredSize.Height)); if (DoubleUtil.GreaterThan(curLineSize.U + sz.U, uvFinalSize.U)) //need to switch to another line { arrangeLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU); accumulatedV += curLineSize.V; curLineSize = sz; if (DoubleUtil.GreaterThan(sz.U, uvFinalSize.U)) //the element is wider then the constraint - give it a separate line { //switch to next line which only contain one element arrangeLine(accumulatedV, sz.V, i, ++i, useItemU, itemU); accumulatedV += sz.V; curLineSize = new UVSize(Orientation); } firstInLine = i; } else //continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Math.Max(sz.V, curLineSize.V); } } //arrange the last line, if any if (firstInLine < children.Count) { arrangeLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU); } return(finalSize); }
private void arrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU, UVSize desiredOverride) { double num = 0.0; bool flag = this.Orientation == Orientation.Horizontal; UIElementCollection internalChildren = base.InternalChildren; for (int i = start; i < end; i++) { int count = internalChildren.Count; UIElement element = internalChildren[i]; if (element != null) { UVSize size = new UVSize(this.Orientation, element.DesiredSize.Width, element.DesiredSize.Height); if (LastChildFill && i == count - 1) { size = new UVSize(this.Orientation, desiredOverride.U, desiredOverride.V); } double num3 = useItemU ? itemU : size.U; element.Arrange(new Rect(flag ? num : v, flag ? v : num, flag ? num3 : lineV, flag ? lineV : num3)); num += num3; } } }
private void ArrangeLineProportionally(double v, double lineV, int start, int end, double limitU) { var u = 0d; var horizontal = Orientation == Orientation.Horizontal; var children = InternalChildren; var total = 0d; for (var i = start; i < end; i++) { total += horizontal ? children[i].DesiredSize.Width : children[i].DesiredSize.Height; } var d = total / (end - start); while (limitU - total > d) { total += d; } var uMultipler = limitU / total; for (var i = start; i < end; i++) { var child = children[i]; if (child != null) { var childSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); var layoutSlotU = childSize.U * uMultipler; child.Arrange(new Rect(horizontal ? u : v, horizontal ? v : u, horizontal ? layoutSlotU : lineV, horizontal ? lineV : layoutSlotU)); u += layoutSlotU; } } }
private int ElementComparisonBySizeDesc(RadElement element1, RadElement element2) { UVSize size1 = new UVSize(this.Orientation, element1.DesiredSize.Width, element1.DesiredSize.Height); UVSize size2 = new UVSize(this.Orientation, element2.DesiredSize.Width, element2.DesiredSize.Height); return(size1.U.CompareTo(size2.U) * -1); }
private float DetermineStretchedItemU(int start, int end, RadElementCollection internalChildren, float totalU) { List <RadElement> childrenSorted = new List <RadElement>(); for (int i = start; i < end; i++) { RadElement element = internalChildren[i]; if (element != null && element.Visibility != ElementVisibility.Collapsed) { childrenSorted.Add(element); } } int itemsCount = childrenSorted.Count; float stretchedItemU = totalU / itemsCount; float totalStretchU = totalU; childrenSorted.Sort(new Comparison <RadElement>(ElementComparisonBySizeDesc)); for (int i = 0; i < childrenSorted.Count; i++) { RadElement element = childrenSorted[i]; UVSize size = new UVSize(this.Orientation, element.DesiredSize.Width, element.DesiredSize.Height); if (size.U > stretchedItemU) { totalStretchU -= size.U; itemsCount--; stretchedItemU = totalStretchU / itemsCount; } } return(stretchedItemU); }
private void arrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU, bool useRoundStep, double roundStep) { double num = 0.0; bool horizontal = this.Orientation == Orientation.Horizontal; UIElementCollection internalChildren = base.InternalChildren; for (int i = start; i < end; i++) { UIElement uIElement = internalChildren[i]; if (uIElement != null) { UVSize elementSize = new UVSize(this.Orientation, uIElement.DesiredSize.Width, uIElement.DesiredSize.Height); double num2 = elementSize.U; if (useItemU) { num2 = itemU; } else if (useRoundStep) { num2 = Math.Ceiling(elementSize.U / roundStep) * roundStep; } uIElement.Arrange(new Rect(horizontal ? num : v, horizontal ? v : num, horizontal ? num2 : lineV, horizontal ? lineV : num2)); num += num2; } } }
/// <summary> /// <see cref="FrameworkElement.MeasureOverride"/> /// </summary> protected override Size MeasureOverride(Size constraint) { UVSize curLineSize = new UVSize(Orientation); UVSize panelSize = new UVSize(Orientation); UVSize uvConstraint = new UVSize(Orientation, constraint.Width, constraint.Height); double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool itemWidthSet = !double.IsNaN(itemWidth); bool itemHeightSet = !double.IsNaN(itemHeight); Size childConstraint = new Size( (itemWidthSet ? itemWidth : constraint.Width), (itemHeightSet ? itemHeight : constraint.Height)); UIElementCollection children = InternalChildren; for (int i = 0, count = children.Count; i < count; i++) { UIElement child = children[i] as UIElement; if (child == null) { continue; } //Flow passes its own constrint to children child.Measure(childConstraint); //this is the size of the child in UV space UVSize sz = new UVSize( Orientation, (itemWidthSet ? itemWidth : child.DesiredSize.Width), (itemHeightSet ? itemHeight : child.DesiredSize.Height)); if (DoubleUtil.GreaterThan(curLineSize.U + sz.U, uvConstraint.U)) //need to switch to another line { panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; curLineSize = sz; if (DoubleUtil.GreaterThan(sz.U, uvConstraint.U)) //the element is wider then the constrint - give it a separate line { panelSize.U = Math.Max(sz.U, panelSize.U); panelSize.V += sz.V; curLineSize = new UVSize(Orientation); } } else //continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Math.Max(sz.V, curLineSize.V); } } //the last line size, if any should be added panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; //go from UV space to W/H space return(new Size(panelSize.Width, panelSize.Height)); }
/// <inheritdoc/> protected override Size ArrangeOverride(Size finalSize) { double itemWidth = ItemWidth; double itemHeight = ItemHeight; var orientation = Orientation; var children = Children; int firstInLine = 0; double accumulatedV = 0; double itemU = orientation == Orientation.Horizontal ? itemWidth : itemHeight; var curLineSize = new UVSize(orientation); var uvFinalSize = new UVSize(orientation, finalSize.Width, finalSize.Height); bool itemWidthSet = !double.IsNaN(itemWidth); bool itemHeightSet = !double.IsNaN(itemHeight); bool useItemU = orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet; for (int i = 0; i < children.Count; i++) { var child = children[i]; if (child != null) { var sz = new UVSize(orientation, itemWidthSet ? itemWidth : child.DesiredSize.Width, itemHeightSet ? itemHeight : child.DesiredSize.Height); var forceNewLine = GetForceNewLine(child); if (forceNewLine || MathUtilities.GreaterThan(curLineSize.U + sz.U, uvFinalSize.U)) // Need to switch to another line { ArrangeLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU); accumulatedV += curLineSize.V; curLineSize = sz; if (MathUtilities.GreaterThan(sz.U, uvFinalSize.U)) // The element is wider then the constraint - give it a separate line { // Switch to next line which only contain one element ArrangeLine(accumulatedV, sz.V, i, ++i, useItemU, itemU); accumulatedV += sz.V; curLineSize = new UVSize(orientation); } firstInLine = i; } else // Continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Max(sz.V, curLineSize.V); } } } // Arrange the last line, if any if (firstInLine < children.Count) { ArrangeLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU); } return(finalSize); }
/// <inheritdoc/> protected override Size MeasureOverride(Size constraint) { double itemWidth = ItemWidth; double itemHeight = ItemHeight; var orientation = Orientation; var children = Children; var curLineSize = new UVSize(orientation); var panelSize = new UVSize(orientation); var uvConstraint = new UVSize(orientation, constraint.Width, constraint.Height); bool itemWidthSet = !double.IsNaN(itemWidth); bool itemHeightSet = !double.IsNaN(itemHeight); var childConstraint = new Size( itemWidthSet ? itemWidth : constraint.Width, itemHeightSet ? itemHeight : constraint.Height); for (int i = 0, count = children.Count; i < count; i++) { var child = children[i]; if (child != null) { // Flow passes its own constraint to children child.Measure(childConstraint); // This is the size of the child in UV space var sz = new UVSize(orientation, itemWidthSet ? itemWidth : child.DesiredSize.Width, itemHeightSet ? itemHeight : child.DesiredSize.Height); var forceNewLine = GetForceNewLine(child); if (forceNewLine || MathUtilities.GreaterThan(curLineSize.U + sz.U, uvConstraint.U)) // Need to switch to another line { panelSize.U = Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; curLineSize = sz; if (MathUtilities.GreaterThan(sz.U, uvConstraint.U)) // The element is wider then the constraint - give it a separate line { panelSize.U = Max(sz.U, panelSize.U); panelSize.V += sz.V; curLineSize = new UVSize(orientation); } } else // Continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Max(sz.V, curLineSize.V); } } } // The last line size, if any should be added panelSize.U = Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; // Go from UV space to W/H space return(new Size(panelSize.Width, panelSize.Height)); }
protected override Size ArrangeOverride(Size finalSize) { int arranged = 0; double itemWidth = this.ItemWidth; double itemHeight = this.ItemHeight; double roundStep = this.RoundStep; double num2 = 0.0; double itemU = (this.Orientation == Orientation.Horizontal) ? itemWidth : itemHeight; UVSize lineSize = new UVSize(this.Orientation); UVSize thisBaseSize = new UVSize(this.Orientation, finalSize.Width, finalSize.Height); bool itemWidthDefined = !DoubleUtils.IsNaN(itemWidth); bool itemHeightDefined = !DoubleUtils.IsNaN(itemHeight); bool roundStepDefined = !DoubleUtils.IsNaN(roundStep); bool useItemU = (this.Orientation == Orientation.Horizontal) ? itemWidthDefined : itemHeightDefined; UIElementCollection internalChildren = base.InternalChildren; int i = 0; int count = internalChildren.Count; while (i < count) { UIElement uIElement = internalChildren[i]; if (uIElement != null) { UVSize elementSize = new UVSize(this.Orientation, itemWidthDefined ? itemWidth : uIElement.DesiredSize.Width, itemHeightDefined ? itemHeight : uIElement.DesiredSize.Height); if (roundStepDefined) { elementSize.U = Math.Ceiling(elementSize.U / roundStep) * roundStep; } if (DoubleUtils.GreaterThan(lineSize.U + elementSize.U, thisBaseSize.U)) { this.arrangeLine(num2, lineSize.V, arranged, i, useItemU, itemU, roundStepDefined, roundStep); num2 += lineSize.V; lineSize = elementSize; if (DoubleUtils.GreaterThan(elementSize.U, thisBaseSize.U)) { double arg_146_1 = num2; double arg_146_2 = elementSize.V; int expr_13C = i; this.arrangeLine(arg_146_1, arg_146_2, expr_13C, i = expr_13C + 1, useItemU, itemU, roundStepDefined, roundStep); num2 += elementSize.V; lineSize = new UVSize(this.Orientation); } arranged = i; } else { lineSize.U += elementSize.U; lineSize.V = Math.Max(elementSize.V, lineSize.V); } } i++; } if (arranged < internalChildren.Count) { this.arrangeLine(num2, lineSize.V, arranged, internalChildren.Count, useItemU, itemU, roundStepDefined, roundStep); } return(finalSize); }
/// <summary> /// <see cref="FrameworkElement.ArrangeOverride"/> /// </summary> protected override Size ArrangeOverride(Size finalSize) { int firstInLine = 0; double itemWidth = ItemWidth; double itemHeight = ItemHeight; double accumulatedV = 0; double itemU = (IsHorizontal() ? itemWidth : itemHeight); UVSize curLineSize = new UVSize(Orientation); bool itemWidthSet = !Double.IsNaN(itemWidth); bool itemHeightSet = !Double.IsNaN(itemHeight); bool useItemU = (IsHorizontal() ? itemWidthSet : itemHeightSet); int lineCount = 0; UIElementCollection children = InternalChildren; for (int i = 0, count = children.Count; i < count; i++) { UIElement child = children[i] as UIElement; if (child == null) { continue; } UVSize sz = new UVSize( Orientation, (itemWidthSet ? itemWidth : child.DesiredSize.Width), (itemHeightSet ? itemHeight : child.DesiredSize.Height)); if (lineCount < WrapCount) //同じ行に追加 { curLineSize.U += sz.U; curLineSize.V = Math.Max(sz.V, curLineSize.V); } else //新しい行に移行 { lineCount = 0; arrangeLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU); accumulatedV += curLineSize.V; curLineSize = sz; firstInLine = i; } lineCount++; } //arrange the last line, if any if (firstInLine < children.Count) { arrangeLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU); } return(finalSize); }
protected override System.Drawing.SizeF MeasureOverride(System.Drawing.SizeF constraint) { UVSize size = new UVSize(this.Orientation); UVSize size2 = new UVSize(this.Orientation); UVSize size3 = new UVSize(this.Orientation, constraint.Width, constraint.Height); float itemWidth = this.ItemWidth; float itemHeight = this.ItemHeight; bool flag = !float.IsNaN(itemWidth); bool flag2 = !float.IsNaN(itemHeight); SizeF availableSize = new SizeF(flag ? itemWidth : constraint.Width, flag2 ? itemHeight : constraint.Height); RadElementCollection internalChildren = base.Children; int num3 = 0; int count = internalChildren.Count; while (num3 < count) { RadCommandBarBaseItem element = internalChildren[num3] as RadCommandBarBaseItem; if (element != null) { if (!element.VisibleInStrip) { element.Measure(SizeF.Empty); } else { element.Measure(availableSize); } UVSize size5 = new UVSize(this.Orientation, flag ? itemWidth : element.DesiredSize.Width, flag2 ? itemHeight : element.DesiredSize.Height); if (DoubleUtil.GreaterThan(size.U + size5.U, size3.U)) { size2.U = Math.Max(size.U, size2.U); size2.V += size.V; size = size5; if (DoubleUtil.GreaterThan(size5.U, size3.U)) { size2.U = Math.Max(size5.U, size2.U); size2.V += size5.V; size = new UVSize(this.Orientation); } } else { size.U += size5.U; size.V = Math.Max(size5.V, size.V); } } num3++; } size2.U = Math.Max(size.U, size2.U); size2.V += size.V; return(new SizeF(size2.Width, size2.Height)); }
/// <summary> /// <see cref="FrameworkElement.MeasureOverride"/> /// </summary> protected override Size MeasureOverride(Size constraint) { UVSize curLineSize = new UVSize(Orientation); UVSize panelSize = new UVSize(Orientation); UVSize uvConstraint = new UVSize(Orientation, constraint.Width, constraint.Height); double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool itemWidthSet = !Double.IsNaN(itemWidth); bool itemHeightSet = !Double.IsNaN(itemHeight); int lineCount = 0; Size childConstraint = new Size( (itemWidthSet ? itemWidth : constraint.Width), (itemHeightSet ? itemHeight : constraint.Height)); foreach (UIElement child in InternalChildren) { if (child == null) { continue; } //Flow passes its own constrint to children child.Measure(childConstraint); //this is the size of the child in UV space UVSize sz = new UVSize( Orientation, (itemWidthSet ? itemWidth : child.DesiredSize.Width), (itemHeightSet ? itemHeight : child.DesiredSize.Height)); if (lineCount < WrapCount) //同じ行に追加 { curLineSize.U += sz.U; curLineSize.V = Math.Max(sz.V, curLineSize.V); } else //新しい行に移行 { lineCount = 0; panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; curLineSize = sz; } lineCount++; } //the last line size, if any should be added panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; //go from UV space to W/H space return(new Size(panelSize.Width, panelSize.Height)); }
protected override void MeasureOverride(int availableWidth, int availableHeight, out int desiredWidth, out int desiredHeight) { UVSize desiredSize = new UVSize(orientation); UVSize availableSize = new UVSize(orientation, availableWidth, availableHeight); UVSize currentLineSize = new UVSize(orientation); bool itemWidthSet = itemWidth != 0; bool itemHeightSet = itemHeight != 0; int availableChildWidth = itemWidthSet ? itemWidth : availableWidth; int availableChildHeight = itemHeightSet ? itemHeight : availableHeight; int count = Children.Count; for (int i = 0; i < count; i++) { UIElement child = Children[i]; if (child == null) { continue; } child.Measure(availableChildWidth, availableChildHeight); int desiredChildWidth, desiredChildHeight; child.GetDesiredSize(out desiredChildWidth, out desiredChildHeight); UVSize childSize = new UVSize(orientation, itemWidthSet ? itemWidth : desiredChildWidth, itemHeightSet ? itemHeight : desiredChildHeight); if (currentLineSize.U + childSize.U > availableSize.U) { desiredSize.U = System.Math.Max(currentLineSize.U, desiredSize.U); desiredSize.V += currentLineSize.V; currentLineSize = childSize; if (childSize.U > availableSize.U) { desiredSize.U = System.Math.Max(childSize.U, desiredSize.U); desiredSize.V = childSize.V; currentLineSize = new UVSize(orientation); } } else { currentLineSize.U += childSize.U; currentLineSize.V = System.Math.Max(childSize.V, currentLineSize.V); } } desiredWidth = System.Math.Max(currentLineSize.U, desiredSize.U); desiredHeight = desiredSize.V + currentLineSize.V; }
protected override Size ArrangeOverride(Size finalSize) { int start = 0; double itemWidth = this.ItemWidth; double itemHeight = this.ItemHeight; double v = 0.0; double itemU = (this.Orientation == Orientation.Horizontal) ? itemWidth : itemHeight; UVSize size = new UVSize(this.Orientation); UVSize size2 = new UVSize(this.Orientation, finalSize.Width, finalSize.Height); bool flag = !Double.IsNaN(itemWidth); bool flag2 = !Double.IsNaN(itemHeight); bool useItemU = (this.Orientation == Orientation.Horizontal) ? flag : flag2; UIElementCollection internalChildren = base.InternalChildren; int end = 0; int count = internalChildren.Count; UVSize size3 = new UVSize(this.Orientation); while (end < count) { UIElement element = internalChildren[end]; if (element != null) { size3 = new UVSize(this.Orientation, flag ? itemWidth : element.DesiredSize.Width, flag2 ? itemHeight : element.DesiredSize.Height); if (LastChildFill && end == count - 1) { size3 = new UVSize(this.Orientation, flag ? itemWidth : size2.U - size.U, flag2 ? itemHeight : size2.V - size.V); } if (GreaterThan(size.U + size3.U, size2.U)) { this.arrangeLine(v, size.V, start, end, useItemU, itemU, size3); v += size.V; size = size3; if (GreaterThan(size3.U, size2.U)) { this.arrangeLine(v, size3.V, end, ++end, useItemU, itemU, new UVSize(this.Orientation)); v += size3.V; size = new UVSize(this.Orientation); } start = end; } else { size.U += size3.U; size.V = Math.Max(size3.V, size.V); } } end++; } if (start < internalChildren.Count) { this.arrangeLine(v, size.V, start, internalChildren.Count, useItemU, itemU, size3); } return(finalSize); }
private static bool NeedsAnotherLine(UVSize curLineSize, UVSize uvFinalSize, UVSize sz, UVSize prev, double heightSoFar) { if (heightSoFar + sz.V > curLineSize.V) { // dock on the right return(curLineSize.U + sz.U > uvFinalSize.U); } else { // dock at the bottom return(curLineSize.U - prev.U + sz.U > uvFinalSize.U); } }
private void ArrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU) { double num = 0.0; bool flag = this.Orientation == Orientation.Horizontal; UIElementCollection internalChildren = Children; for (int i = start; i < end; i++) { UIElement element = internalChildren[i]; if (element != null) { UVSize size = new UVSize(this.Orientation, element.DesiredSize.Width, element.DesiredSize.Height); double num3 = useItemU ? itemU : size.U; Rect finalRect = new Rect(flag ? num : v, flag ? v : num, flag ? num3 : lineV, flag ? lineV : num3); Point previousTopLeft = this.previousTopLeftArrangePoint[element]; Point newTopLeft = new Point(finalRect.Left, finalRect.Top); int index = -1; TranslateTransform tt = GetTranslateTransform(element, ref index); if (element.Visibility == Visibility.Visible && this.IsAnimated) { if (tt != null && tt.X != previousTopLeft.X && tt.Y != previousTopLeft.Y) { previousTopLeft.X = -tt.X; previousTopLeft.Y = -tt.Y; } if (newTopLeft != previousTopLeft) { this.AnimateLocation(element, previousTopLeft, newTopLeft); } } else { if (tt != null) { tt.X = tt.Y = 0; } } this.previousTopLeftArrangePoint[element] = newTopLeft; element.Arrange(finalRect); if (element.Visibility == Visibility.Visible) { num += num3; } } } }
protected override Size MeasureOverride(Size constraint) { UVSize thisBaseSize = new UVSize(this.Orientation, constraint.Width, constraint.Height); UVSize lineSize = new UVSize(this.Orientation); UVSize usedSize = new UVSize(this.Orientation); double itemWidth = this.ItemWidth; double itemHeight = this.ItemHeight; double roundStep = this.RoundStep; bool itemWidthDefined = !DoubleUtils.IsNaN(itemWidth); bool itemHeightDefined = !DoubleUtils.IsNaN(itemHeight); bool roundStepDefined = !DoubleUtils.IsNaN(roundStep); Size availableSize = new Size(itemWidthDefined ? itemWidth : constraint.Width, itemHeightDefined ? itemHeight : constraint.Height); UIElementCollection internalChildren = base.InternalChildren; int i = 0; int count = internalChildren.Count; while (i < count) { UIElement uIElement = internalChildren[i]; if (uIElement != null) { uIElement.Measure(availableSize); UVSize elementSize = new UVSize(this.Orientation, itemWidthDefined ? itemWidth : uIElement.DesiredSize.Width, itemHeightDefined ? itemHeight : uIElement.DesiredSize.Height); if (roundStepDefined) { elementSize.U = Math.Ceiling(elementSize.U / roundStep) * roundStep; } if (DoubleUtils.GreaterThan(lineSize.U + elementSize.U, thisBaseSize.U)) { usedSize.U = Math.Max(lineSize.U, usedSize.U); usedSize.V += lineSize.V; lineSize = elementSize; if (DoubleUtils.GreaterThan(elementSize.U, thisBaseSize.U)) { usedSize.U = Math.Max(elementSize.U, usedSize.U); usedSize.V += elementSize.V; lineSize = new UVSize(this.Orientation); } } else { lineSize.U += elementSize.U; lineSize.V = Math.Max(elementSize.V, lineSize.V); } } i++; } usedSize.U = Math.Max(lineSize.U, usedSize.U); usedSize.V += lineSize.V; return(new Size(usedSize.Width, usedSize.Height)); }
protected override SizeF ArrangeOverride(SizeF finalSize) { int start = 0; float itemWidth = this.ItemWidth; float itemHeight = this.ItemHeight; float v = 0; float itemU = (this.Orientation == Orientation.Horizontal) ? itemWidth : itemHeight; float totalSize = (this.Orientation == Orientation.Horizontal) ? finalSize.Width : finalSize.Height; UVSize size = new UVSize(this.Orientation); UVSize size2 = new UVSize(this.Orientation, finalSize.Width, finalSize.Height); bool flag = !float.IsNaN(itemWidth); bool flag2 = !float.IsNaN(itemHeight); bool useItemU = (this.Orientation == Orientation.Horizontal) ? flag : flag2; RadElementCollection internalChildren = base.Children; int end = 0; int count = internalChildren.Count; while (end < count) { RadElement element = internalChildren[end]; if (element != null) { UVSize size3 = new UVSize(this.Orientation, flag ? itemWidth : element.DesiredSize.Width, flag2 ? itemHeight : element.DesiredSize.Height); if (DoubleUtil.GreaterThan(size.U + size3.U, size2.U)) { this.ArrangeLine(v, size.V, start, end, useItemU, itemU, totalSize); v += size.V; size = size3; if (DoubleUtil.GreaterThan(size3.U, size2.U)) { this.ArrangeLine(v, size3.V, end, ++end, useItemU, itemU, totalSize); v += size3.V; size = new UVSize(this.Orientation); } start = end; } else { size.U += size3.U; size.V = Math.Max(size3.V, size.V); } } end++; } if (start < internalChildren.Count) { this.ArrangeLine(v, size.V, start, internalChildren.Count, useItemU, itemU, totalSize); } return(finalSize); }
/// <inheritdoc/> protected override Size ArrangeOverride(Size finalSize) { int firstInLine = 0; double accumulatedV = 0; UVSize curLineSize = new UVSize(Orientation); UVSize uvFinalSize = new UVSize(Orientation, finalSize.Width, finalSize.Height); for (int i = 0; i < Children.Count; i++) { var child = Children[i]; if (child == null) { continue; } var sz = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); if (MathUtilities.GreaterThan(curLineSize.U + sz.U, uvFinalSize.U)) //need to switch to another line { arrangeLine(accumulatedV, curLineSize.V, firstInLine, i); accumulatedV += curLineSize.V; curLineSize = sz; if (MathUtilities.GreaterThan(sz.U, uvFinalSize.U)) //the element is wider then the constraint - give it a separate line { //switch to next line which only contain one element arrangeLine(accumulatedV, sz.V, i, ++i); accumulatedV += sz.V; curLineSize = new UVSize(Orientation); } firstInLine = i; } else //continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Max(sz.V, curLineSize.V); } } //arrange the last line, if any if (firstInLine < Children.Count) { arrangeLine(accumulatedV, curLineSize.V, firstInLine, Children.Count); } return(finalSize); }
/// <summary> /// Arranges the content of a <see cref="T:System.Windows.Controls.WrapPanel"/> element. /// </summary> /// <returns> /// The <see cref="T:System.Windows.Size"/> that represents the arranged size of this <see cref="T:System.Windows.Controls.WrapPanel"/> element and its children. /// </returns> /// <param name="finalSize">The <see cref="T:System.Windows.Size"/> that this element should use to arrange its child elements. /// </param> protected override Size ArrangeOverride(Size finalSize) { int start = 0; double itemWidth = ItemWidth; double itemHeight = ItemHeight; double v = 0.0; double itemU = (Orientation == Orientation.Horizontal) ? itemWidth : itemHeight; var size = new UVSize(Orientation); var size2 = new UVSize(Orientation, finalSize.Width, finalSize.Height); bool flag = !DoubleUtil.IsNaN(itemWidth); bool flag2 = !DoubleUtil.IsNaN(itemHeight); bool useItemU = (Orientation == Orientation.Horizontal) ? flag : flag2; var internalChildren = base.InternalChildren; int end = 0; int count = internalChildren.Count; while (end < count) { var element = internalChildren[end]; if (element != null) { var size3 = new UVSize(Orientation, flag ? itemWidth : element.DesiredSize.Width, flag2 ? itemHeight : element.DesiredSize.Height); if (DoubleUtil.GreaterThan(size.U + size3.U, size2.U)) { arrangeLine(v, size.V, start, end, useItemU, itemU); v += size.V; size = size3; if (DoubleUtil.GreaterThan(size3.U, size2.U)) { arrangeLine(v, size3.V, end, ++end, useItemU, itemU); v += size3.V; size = new UVSize(Orientation); } start = end; } else { size.U += size3.U; size.V = Math.Max(size3.V, size.V); } } end++; } if (start < internalChildren.Count) { arrangeLine(v, size.V, start, internalChildren.Count, useItemU, itemU); } return(finalSize); }
/// <summary> /// Provides the behavior for the "measure" pass of Silverlight layout. Classes can override this method to define their own measure pass behavior. /// </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) { UVSize size = new UVSize(this.Orientation); UVSize size2 = new UVSize(this.Orientation); UVSize size3 = new UVSize(this.Orientation, availableSize.Width, availableSize.Height); double itemWidth = this.ItemWidth; double itemHeight = this.ItemHeight; bool flag = !Double.IsNaN(itemWidth); bool flag2 = !Double.IsNaN(itemHeight); Size remainingSize = new Size(flag ? itemWidth : availableSize.Width, flag2 ? itemHeight : availableSize.Height); UIElementCollection internalChildren = Children; int num3 = 0; int count = internalChildren.Count; while (num3 < count) { UIElement element = internalChildren[num3]; if (!this.previousTopLeftArrangePoint.ContainsKey(element)) { this.previousTopLeftArrangePoint.Add(element, new Point()); } if (element != null) { element.Measure(remainingSize); UVSize size5 = new UVSize(this.Orientation, flag ? itemWidth : element.DesiredSize.Width, flag2 ? itemHeight : element.DesiredSize.Height); if ((size.U + size5.U) > size3.U) { size2.U = Math.Max(size.U, size2.U); size2.V += size.V; size = size5; if (size5.U > size3.U) { size2.U = Math.Max(size5.U, size2.U); size2.V += size5.V; size = new UVSize(this.Orientation); } } else { size.U += size5.U; size.V = Math.Max(size5.V, size.V); } } num3++; } size2.U = Math.Max(size.U, size2.U); size2.V += size.V; return(new Size(size2.Width, size2.Height)); }
/// <inheritdoc/> protected override Size MeasureOverride(Size constraint) { var curLineSize = new UVSize(Orientation); var panelSize = new UVSize(Orientation); var uvConstraint = new UVSize(Orientation, constraint.Width, constraint.Height); var childConstraint = new Size(constraint.Width, constraint.Height); for (int i = 0, count = Children.Count; i < count; i++) { var child = Children[i]; if (child == null) { continue; } //Flow passes its own constrint to children child.Measure(childConstraint); //this is the size of the child in UV space var sz = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); if (MathUtilities.GreaterThan(curLineSize.U + sz.U, uvConstraint.U)) //need to switch to another line { panelSize.U = Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; curLineSize = sz; if (MathUtilities.GreaterThan(sz.U, uvConstraint.U)) //the element is wider then the constrint - give it a separate line { panelSize.U = Max(sz.U, panelSize.U); panelSize.V += sz.V; curLineSize = new UVSize(Orientation); } } else //continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Max(sz.V, curLineSize.V); } } //the last line size, if any should be added panelSize.U = Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; //go from UV space to W/H space return(new Size(panelSize.Width, panelSize.Height)); }
// ************************************************************************ private void arrangeLine(int lineIndex, double v, double lineV, int start, int end, bool useItemU, double itemU, UVSize uvFinalSize) { double u = 0; bool isHorizontal = (Orientation == Orientation.Horizontal); Debug.Assert(lineIndex < _lineInfos.Count); LineInfo lineInfo = _lineInfos[lineIndex]; double lineSpaceAvailableForCorrection = Math.Max(uvFinalSize.U - lineInfo.Size.U, 0); double perControlCorrection = 0; if (lineSpaceAvailableForCorrection > 0 && lineInfo.Size.U > 0) { perControlCorrection = lineSpaceAvailableForCorrection / lineInfo.ElementsWithNoWidthSet.Count; if (double.IsInfinity(perControlCorrection)) { perControlCorrection = 0; } } int indexOfControlToAdjustSizeToFill = 0; UIElement uIElementToAdjustNext = indexOfControlToAdjustSizeToFill < lineInfo.ElementsWithNoWidthSet.Count ? lineInfo.ElementsWithNoWidthSet[indexOfControlToAdjustSizeToFill] : null; UIElementCollection children = InternalChildren; for (int i = start; i < end; i++) { UIElement child = children[i] as UIElement; if (child != null) { UVSize childSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); double layoutSlotU = (useItemU ? itemU : childSize.U); if (perControlCorrection > 0 && child == uIElementToAdjustNext) { layoutSlotU += perControlCorrection; indexOfControlToAdjustSizeToFill++; uIElementToAdjustNext = indexOfControlToAdjustSizeToFill < lineInfo.ElementsWithNoWidthSet.Count ? lineInfo.ElementsWithNoWidthSet[indexOfControlToAdjustSizeToFill] : null; } child.Arrange(new Rect( (isHorizontal ? u : v), (isHorizontal ? v : u), (isHorizontal ? layoutSlotU : lineV), (isHorizontal ? lineV : layoutSlotU))); u += layoutSlotU; } } }
private void arrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU) { double accV = 0; var origV = v; double u = 0; bool isHorizontal = (Orientation == Orientation.Horizontal); UIElementCollection children = InternalChildren; UVSize prev = new UVSize(); for (int i = start; i < end; i++) { UIElement child = children[i] as UIElement; if (child != null) { UVSize childSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); double layoutSlotU = (useItemU ? itemU : childSize.U); if (i == start || accV + childSize.V > lineV) { v = origV; // dock on the right var r = new Rect( (isHorizontal ? u : v), (isHorizontal ? v : u), (isHorizontal ? layoutSlotU : lineV), (isHorizontal ? childSize.V : layoutSlotU)); Debug.WriteLine(r); child.Arrange(r); u += layoutSlotU; accV = childSize.V; } else { v += prev.V; // dock on the bottom var r = new Rect(u - prev.U, v, layoutSlotU, childSize.V); Debug.WriteLine(r); child.Arrange(r); u += Math.Max(0, layoutSlotU - prev.U); accV += childSize.V; } prev = childSize; } } }
private void ArrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU) { var u = 0d; var horizontal = Orientation == Orientation.Horizontal; var children = InternalChildren; for (var i = start; i < end; i++) { var child = children[i]; if (child != null) { var childSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); var layoutSlotU = useItemU ? itemU : childSize.U; child.Arrange(new Rect(horizontal ? u : v, horizontal ? v : u, horizontal ? layoutSlotU : lineV, horizontal ? lineV : layoutSlotU)); u += layoutSlotU; } } }
private void ArrangeLine(float VPosition, float lineV, int start, int end, bool useItemU, float itemU, float totalU) { float currentUPosition = 0; bool isHorizontal = this.Orientation == Orientation.Horizontal; RadElementCollection internalChildren = base.Children; float stretchedItemU = 0; if (this.stretchItems) { stretchedItemU = DetermineStretchedItemU(start, end, internalChildren, totalU); } for (int i = start; i < end; i++) { RadElement element = internalChildren[i]; if (element != null) { UVSize size = new UVSize(this.Orientation, element.DesiredSize.Width, element.DesiredSize.Height); float actualItemU = useItemU ? itemU : size.U; if (this.stretchItems && element.Visibility != ElementVisibility.Collapsed && actualItemU < stretchedItemU) { actualItemU = stretchedItemU; } RectangleF rect = new RectangleF(isHorizontal ? currentUPosition : VPosition, isHorizontal ? VPosition : currentUPosition, isHorizontal ? actualItemU : lineV, isHorizontal ? lineV : actualItemU); if (this.RightToLeft) { if (isHorizontal) { rect.X = totalU - rect.X - rect.Width; } } element.Arrange(rect); currentUPosition += actualItemU; } } }
private void arrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU) { double num = 0.0; bool horizontal = Orientation == Orientation.Horizontal; var duration = Duration; var internalChildren = base.InternalChildren; for (int i = start; i < end; i++) { var element = internalChildren[i]; if (element != null) { var size = new UVSize(Orientation, element.DesiredSize.Width, element.DesiredSize.Height); double u = useItemU ? itemU : size.U; AnimatedPanelHelper.ArrangeChild(this, element, new Rect(horizontal ? num : v, horizontal ? v : num, horizontal ? u : lineV, horizontal ? lineV : u), duration); num += u; } } }
private void arrangeLine(double v, double lineV, int start, int end) { double u = 0; bool isHorizontal = (Orientation == Orientation.Horizontal); for (int i = start; i < end; i++) { var child = Children[i]; if (child != null) { UVSize childSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); double layoutSlotU = childSize.U; child.Arrange(new Rect( (isHorizontal ? u : v), (isHorizontal ? v : u), (isHorizontal ? layoutSlotU : lineV), (isHorizontal ? lineV : layoutSlotU))); u += layoutSlotU; } } }
private void ArrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU) { var orientation = Orientation; var children = Children; double u = 0; bool isHorizontal = orientation == Orientation.Horizontal; for (int i = start; i < end; i++) { var child = children[i]; if (child != null) { var childSize = new UVSize(orientation, child.DesiredSize.Width, child.DesiredSize.Height); double layoutSlotU = useItemU ? itemU : childSize.U; child.Arrange(new Rect( isHorizontal ? u : v, isHorizontal ? v : u, isHorizontal ? layoutSlotU : lineV, isHorizontal ? lineV : layoutSlotU)); u += layoutSlotU; } } }
protected override void MeasureOverride(int availableWidth, int availableHeight, out int desiredWidth, out int desiredHeight) { UVSize desiredSize = new UVSize(orientation); UVSize availableSize = new UVSize(orientation, availableWidth, availableHeight); UVSize currentLineSize = new UVSize(orientation); bool itemWidthSet = itemWidth != 0; bool itemHeightSet = itemHeight != 0; int availableChildWidth = itemWidthSet ? itemWidth : availableWidth; int availableChildHeight = itemHeightSet ? itemHeight : availableHeight; int count = Children.Count; for (int i = 0; i < count; i++) { UIElement child = Children[i]; if (child == null) continue; child.Measure(availableChildWidth, availableChildHeight); int desiredChildWidth, desiredChildHeight; child.GetDesiredSize(out desiredChildWidth, out desiredChildHeight); UVSize childSize = new UVSize(orientation, itemWidthSet ? itemWidth : desiredChildWidth, itemHeightSet ? itemHeight : desiredChildHeight); if (currentLineSize.U + childSize.U > availableSize.U) { desiredSize.U = System.Math.Max(currentLineSize.U, desiredSize.U); desiredSize.V += currentLineSize.V; currentLineSize = childSize; if (childSize.U > availableSize.U) { desiredSize.U = System.Math.Max(childSize.U, desiredSize.U); desiredSize.V = childSize.V; currentLineSize = new UVSize(orientation); } } else { currentLineSize.U += childSize.U; currentLineSize.V = System.Math.Max(childSize.V, currentLineSize.V); } } desiredWidth = System.Math.Max(currentLineSize.U, desiredSize.U); desiredHeight = desiredSize.V + currentLineSize.V; }
private void ArrangeLine(int v, int lineV, int indexStart, int indexEnd, bool useSetU, int itemSetU) { int u = 0; bool isHorizontal = orientation == Orientation.Horizontal; for (int i = indexStart; i < indexEnd; i++) { UIElement child = Children[i]; if (child == null) continue; UVSize childSize = new UVSize(orientation); if (isHorizontal) child.GetDesiredSize(out childSize.U, out childSize.V); else child.GetDesiredSize(out childSize.V, out childSize.U); int layoutSlotU = useSetU ? itemSetU : childSize.U; if (isHorizontal) child.Arrange(u, v, layoutSlotU, lineV); else child.Arrange(v, u, lineV, layoutSlotU); u += layoutSlotU; } }
private void ArrangeLine(int lineStart, int lineEnd, double? directDelta, double directMaximum, double indirectOffset, double indirectGrowth) { bool isHorizontal = this.Orientation == Orientation.Horizontal; UIElementCollection children = base.InternalChildren; 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]; UVSize elementSize = new UVSize(this.Orientation, 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.U; // 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]; UVSize elementSize = new UVSize(this.Orientation, 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.U; // 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; } }
protected override void ArrangeOverride(int arrangeWidth, int arrangeHeight) { UVSize arrangeSize = new UVSize(orientation, arrangeWidth, arrangeHeight); UVSize currentLineSize = new UVSize(orientation); int accumulatedV = 0; bool itemWidthSet = itemWidth != 0; bool itemHeightSet = itemHeight != 0; bool useSetU = orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet; int itemSetU = orientation == Orientation.Horizontal ? itemWidth : itemHeight; int firstInLineIndex = 0; int count = Children.Count; for (int i = 0; i < count; i++) { UIElement child = Children[i]; if (child == null) continue; int desiredWidth, desiredHeight; child.GetDesiredSize(out desiredWidth, out desiredHeight); UVSize childSize = new UVSize(orientation, itemWidthSet ? itemWidth : desiredWidth, itemHeightSet ? itemHeight : desiredHeight); // does not fit on line if (currentLineSize.U + childSize.U > arrangeSize.U) { // arrange previous line ArrangeLine(accumulatedV, currentLineSize.V, firstInLineIndex, i /* exclusive */, useSetU, itemSetU); accumulatedV += currentLineSize.V; // this child is on new line currentLineSize = childSize; // child is bigger than available size if (childSize.U > arrangeSize.U) { ArrangeLine(accumulatedV, childSize.V, i, i + 1, useSetU, itemSetU); i++; // order of parameters evaluation is not guaranted // this is the only child on line accumulatedV += childSize.V; currentLineSize = new UVSize(orientation); } firstInLineIndex = i; } else { currentLineSize.U += childSize.U; currentLineSize.V = System.Math.Max(childSize.V, currentLineSize.V); } } if (firstInLineIndex < count) ArrangeLine(accumulatedV, currentLineSize.V, firstInLineIndex, count, useSetU, itemSetU); }
private void arrangeLine(double v, double lineV, int start, int end, bool useItemU, double itemU) { double u = 0; bool isHorizontal = (Orientation == Orientation.Horizontal); UIElementCollection children = InternalChildren; for(int i = start; i < end; i++) { UIElement child = children[i] as UIElement; if(child != null) { UVSize childSize = new UVSize(Orientation, child.DesiredSize.Width, child.DesiredSize.Height); double layoutSlotU = (useItemU ? itemU : childSize.U); child.Arrange(new Rect( (isHorizontal ? u : v), (isHorizontal ? v : u), (isHorizontal ? layoutSlotU : lineV), (isHorizontal ? lineV : layoutSlotU))); u += layoutSlotU; } } }
/// <summary> /// <see cref="FrameworkElement.ArrangeOverride"/> /// </summary> protected override Size ArrangeOverride(Size finalSize) { int firstInLine = 0; double itemWidth = ItemWidth; double itemHeight = ItemHeight; double accumulatedV = 0; double itemU = (Orientation == Orientation.Horizontal ? itemWidth : itemHeight); UVSize curLineSize = new UVSize(Orientation); UVSize uvFinalSize = new UVSize(Orientation, finalSize.Width, finalSize.Height); bool itemWidthSet = !DoubleUtil.IsNaN(itemWidth); bool itemHeightSet = !DoubleUtil.IsNaN(itemHeight); bool useItemU = (Orientation == Orientation.Horizontal ? itemWidthSet : itemHeightSet); UIElementCollection children = InternalChildren; for(int i=0, count = children.Count; i<count; i++) { UIElement child = children[i] as UIElement; if(child == null) continue; UVSize sz = new UVSize( Orientation, (itemWidthSet ? itemWidth : child.DesiredSize.Width), (itemHeightSet ? itemHeight : child.DesiredSize.Height)); if (DoubleUtil.GreaterThan(curLineSize.U + sz.U, uvFinalSize.U)) //need to switch to another line { arrangeLine(accumulatedV, curLineSize.V, firstInLine, i, useItemU, itemU); accumulatedV += curLineSize.V; curLineSize = sz; if(DoubleUtil.GreaterThan(sz.U, uvFinalSize.U)) //the element is wider then the constraint - give it a separate line { //switch to next line which only contain one element arrangeLine(accumulatedV, sz.V, i, ++i, useItemU, itemU); accumulatedV += sz.V; curLineSize = new UVSize(Orientation); } firstInLine= i; } else //continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Math.Max(sz.V, curLineSize.V); } } //arrange the last line, if any if(firstInLine < children.Count) { arrangeLine(accumulatedV, curLineSize.V, firstInLine, children.Count, useItemU, itemU); } return finalSize; }
/// <summary> /// Positions child elements based on the size of the panel.</summary> /// <param name="finalSize">The final area within the parent that this element /// should use to arrange itself and its children.</param> /// <returns>Returns the original finalSize</returns> protected override Size ArrangeOverride(Size finalSize) { // Variables tracking the size of the current line, and the maximum size available to fill. UVSize lineSize = new UVSize(this.Orientation); UVSize maximumSize = new UVSize(this.Orientation, finalSize.Width, finalSize.Height); double itemWidth = this.ItemWidth; double itemHeight = this.ItemHeight; double indirectOffset = 0.0; double itemU = (this.Orientation == Orientation.Horizontal) ? itemWidth : itemHeight; bool hasFixedWidth = !itemWidth.IsNaN(); bool hasFixedHeight = !itemHeight.IsNaN(); bool useItemU = (this.Orientation == Orientation.Horizontal) ? hasFixedWidth : hasFixedHeight; double? directDelta = (this.Orientation == 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 internalChildren = base.InternalChildren; int count = internalChildren.Count; int lineStart = 0; for (int lineEnd = 0; lineEnd < count; lineEnd++) { UIElement element = internalChildren[lineEnd]; if (element != null) { // Get the size of the element UVSize elementSize = new UVSize( this.Orientation, hasFixedWidth ? itemWidth : element.DesiredSize.Width, hasFixedHeight ? itemHeight : element.DesiredSize.Height); // If this element falls off the edge of the line if (NumericUtil.IsGreaterThan(lineSize.U + elementSize.U, maximumSize.U)) { // Then we just completed a line and we should arrange it ArrangeLine(lineStart, lineEnd, directDelta, maximumSize.U, indirectOffset, lineSize.V); indirectOffset += lineSize.V; lineSize = elementSize; // If the current element is larger than the maximum size if (NumericUtil.IsGreaterThan(elementSize.U, maximumSize.U)) { // Arrange the element as a single line ArrangeLine(lineEnd, ++lineEnd, directDelta, maximumSize.U, indirectOffset, elementSize.V); indirectOffset += elementSize.V; lineSize = new UVSize(this.Orientation); } // 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.U += elementSize.U; lineSize.V = Math.Max(elementSize.V, lineSize.V); } } } if (lineStart < internalChildren.Count) { ArrangeLine(lineStart, count, directDelta, maximumSize.U, indirectOffset, lineSize.V); } return finalSize; }
/// <summary> /// <see cref="FrameworkElement.MeasureOverride"/> /// </summary> protected override Size MeasureOverride(Size constraint) { UVSize curLineSize = new UVSize(Orientation); UVSize panelSize = new UVSize(Orientation); UVSize uvConstraint = new UVSize(Orientation, constraint.Width, constraint.Height); double itemWidth = ItemWidth; double itemHeight = ItemHeight; bool itemWidthSet = !DoubleUtil.IsNaN(itemWidth); bool itemHeightSet = !DoubleUtil.IsNaN(itemHeight); Size childConstraint = new Size( (itemWidthSet ? itemWidth : constraint.Width), (itemHeightSet ? itemHeight : constraint.Height)); UIElementCollection children = InternalChildren; for(int i=0, count = children.Count; i<count; i++) { UIElement child = children[i] as UIElement; if(child == null) continue; //Flow passes its own constrint to children child.Measure(childConstraint); //this is the size of the child in UV space UVSize sz = new UVSize( Orientation, (itemWidthSet ? itemWidth : child.DesiredSize.Width), (itemHeightSet ? itemHeight : child.DesiredSize.Height)); if (DoubleUtil.GreaterThan(curLineSize.U + sz.U, uvConstraint.U)) //need to switch to another line { panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; curLineSize = sz; if(DoubleUtil.GreaterThan(sz.U, uvConstraint.U)) //the element is wider then the constrint - give it a separate line { panelSize.U = Math.Max(sz.U, panelSize.U); panelSize.V += sz.V; curLineSize = new UVSize(Orientation); } } else //continue to accumulate a line { curLineSize.U += sz.U; curLineSize.V = Math.Max(sz.V, curLineSize.V); } } //the last line size, if any should be added panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; //go from UV space to W/H space return new Size(panelSize.Width, panelSize.Height); }