performance optimization

This commit is contained in:
NaBian committed 2020-10-29 22:50:12 +08:00
1 parent 4b7124d5c8
commit 65c2e10dc7
8 files changed
+124 -84

No files matched your search

@@ -37,9 +37,11 @@ namespace HandyControl.Controls
protected override Size MeasureOverride(Size availableSize)
{
if (Children.Count == 0) return new Size(Diameter, Diameter);
var diameter = Diameter;
var newSize = new Size(Diameter, Diameter);
if (Children.Count == 0) return new Size(diameter, diameter);
var newSize = new Size(diameter, diameter);
foreach (UIElement element in Children)
{
@@ -51,6 +53,9 @@ namespace HandyControl.Controls
protected override Size ArrangeOverride(Size finalSize)
{
var keepVertical = KeepVertical;
var offsetAngle = OffsetAngle;
var i = 0;
var perDeg = 360.0 / Children.Count;
var radius = Diameter / 2;
@@ -59,19 +64,23 @@ namespace HandyControl.Controls
{
var centerX = element.DesiredSize.Width / 2.0;
var centerY = element.DesiredSize.Height / 2.0;
var angle = perDeg * i++ + OffsetAngle;
var angle = perDeg * i++ + offsetAngle;
var transform = new RotateTransform
{
CenterX = centerX,
CenterY = centerY,
Angle = KeepVertical ? 0 : angle
Angle = keepVertical ? 0 : angle
};
element.RenderTransform = transform;
var r = Math.PI * angle / 180.0;
var x = radius * Math.Cos(r);
var y = radius * Math.Sin(r);
var rectX = x + finalSize.Width / 2 - centerX;
var rectY = y + finalSize.Height / 2 - centerY;
element.Arrange(new Rect(rectX, rectY, element.DesiredSize.Width, element.DesiredSize.Height));
}
@@ -144,9 +144,12 @@ namespace HandyControl.Controls
protected override Size MeasureOverride(Size constraint)
{
var curLineSize = new UVSize(FlexDirection);
var panelSize = new UVSize(FlexDirection);
_uvConstraint = new UVSize(FlexDirection, constraint);
var flexDirection = FlexDirection;
var flexWrap = FlexWrap;
var curLineSize = new UVSize(flexDirection);
var panelSize = new UVSize(flexDirection);
_uvConstraint = new UVSize(flexDirection, constraint);
var childConstraint = new Size(constraint.Width, constraint.Height);
_lineCount = 1;
var children = InternalChildren;
@@ -174,9 +177,9 @@ namespace HandyControl.Controls
}
child.Measure(childConstraint);
var sz = new UVSize(FlexDirection, child.DesiredSize);
var sz = new UVSize(flexDirection, child.DesiredSize);
if (FlexWrap == FlexWrap.NoWrap) //continue to accumulate a line
if (flexWrap == FlexWrap.NoWrap) //continue to accumulate a line
{
curLineSize.U += sz.U;
curLineSize.V = Math.Max(sz.V, curLineSize.V);
@@ -194,7 +197,7 @@ namespace HandyControl.Controls
{
panelSize.U = Math.Max(sz.U, panelSize.U);
panelSize.V += sz.V;
curLineSize = new UVSize(FlexDirection);
curLineSize = new UVSize(flexDirection);
_lineCount++;
}
}
@@ -216,7 +219,11 @@ namespace HandyControl.Controls
protected override Size ArrangeOverride(Size arrangeSize)
{
var uvFinalSize = new UVSize(FlexDirection, arrangeSize);
var flexDirection = FlexDirection;
var flexWrap = FlexWrap;
var alignContent = AlignContent;
var uvFinalSize = new UVSize(flexDirection, arrangeSize);
if (MathHelper.IsZero(uvFinalSize.U) || MathHelper.IsZero(uvFinalSize.V)) return arrangeSize;
// init status
@@ -224,7 +231,7 @@ namespace HandyControl.Controls
var lineIndex = 0;
var curLineSizeArr = new UVSize[_lineCount];
curLineSizeArr[0] = new UVSize(FlexDirection);
curLineSizeArr[0] = new UVSize(flexDirection);
var lastInLineArr = new int[_lineCount];
for (var i = 0; i < _lineCount; i++)
@@ -238,9 +245,9 @@ namespace HandyControl.Controls
var child = children[_orderList[i].Index];
if (child == null) continue;
var sz = new UVSize(FlexDirection, child.DesiredSize);
var sz = new UVSize(flexDirection, child.DesiredSize);
if (FlexWrap == FlexWrap.NoWrap)
if (flexWrap == FlexWrap.NoWrap)
{
curLineSizeArr[lineIndex].U += sz.U;
curLineSizeArr[lineIndex].V = Math.Max(sz.V, curLineSizeArr[lineIndex].V);
@@ -258,7 +265,7 @@ namespace HandyControl.Controls
//switch to next line which only contain one element
lastInLineArr[lineIndex] = i;
lineIndex++;
curLineSizeArr[lineIndex] = new UVSize(FlexDirection);
curLineSizeArr[lineIndex] = new UVSize(flexDirection);
}
}
else //continue to accumulate a line
@@ -273,8 +280,8 @@ namespace HandyControl.Controls
var scaleU = Math.Min(_uvConstraint.U / uvFinalSize.U, 1);
var firstInLine = 0;
var wrapReverseAdd = 0;
var wrapReverseFlag = FlexWrap == FlexWrap.WrapReverse ? -1 : 1;
var accumulatedFlag = FlexWrap == FlexWrap.WrapReverse ? 1 : 0;
var wrapReverseFlag = flexWrap == FlexWrap.WrapReverse ? -1 : 1;
var accumulatedFlag = flexWrap == FlexWrap.WrapReverse ? 1 : 0;
var itemsU = .0;
var accumulatedV = .0;
var freeV = uvFinalSize.V;
@@ -287,7 +294,7 @@ namespace HandyControl.Controls
// calculate status
var lineFreeVArr = new double[_lineCount];
switch (AlignContent)
switch (alignContent)
{
case FlexContentAlignment.Stretch:
if (_lineCount > 1)
@@ -298,15 +305,15 @@ namespace HandyControl.Controls
lineFreeVArr[i] = freeItemV;
}
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0;
accumulatedV = flexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0;
}
break;
case FlexContentAlignment.FlexStart:
wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 0 : 1;
wrapReverseAdd = flexWrap == FlexWrap.WrapReverse ? 0 : 1;
if (_lineCount > 1)
{
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0;
accumulatedV = flexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0;
}
else
{
@@ -315,10 +322,10 @@ namespace HandyControl.Controls
break;
case FlexContentAlignment.FlexEnd:
wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 1 : 0;
wrapReverseAdd = flexWrap == FlexWrap.WrapReverse ? 1 : 0;
if (_lineCount > 1)
{
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV;
accumulatedV = flexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV;
}
else
{
@@ -329,7 +336,7 @@ namespace HandyControl.Controls
case FlexContentAlignment.Center:
if (_lineCount > 1)
{
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5;
accumulatedV = flexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5;
}
break;
@@ -342,7 +349,7 @@ namespace HandyControl.Controls
lineFreeVArr[i] = freeItemV;
}
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0;
accumulatedV = flexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0;
}
break;
@@ -355,7 +362,7 @@ namespace HandyControl.Controls
lineFreeVArr[i] = freeItemV * 2;
}
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV;
accumulatedV = flexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV;
}
break;
@@ -370,9 +377,9 @@ namespace HandyControl.Controls
var child = children[_orderList[i].Index];
if (child == null) continue;
var sz = new UVSize(FlexDirection, child.DesiredSize);
var sz = new UVSize(flexDirection, child.DesiredSize);
if (FlexWrap != FlexWrap.NoWrap)
if (flexWrap != FlexWrap.NoWrap)
{
if (i >= lastInLineArr[lineIndex]) //need to switch to another line
{
@@ -392,8 +399,7 @@ namespace HandyControl.Controls
lineIndex++;
itemsU = 0;
if (i >= lastInLineArr[lineIndex]
) //the element is wider then the constraint - give it a separate line
if (i >= lastInLineArr[lineIndex]) //the element is wider then the constraint - give it a separate line
{
//switch to next line which only contain one element
ArrangeLine(new FlexLineInfo
@@ -441,8 +447,13 @@ namespace HandyControl.Controls
private void ArrangeLine(FlexLineInfo lineInfo)
{
var isHorizontal = FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse;
var isReverse = FlexDirection == FlexDirection.RowReverse || FlexDirection == FlexDirection.ColumnReverse;
var flexDirection = FlexDirection;
var flexWrap = FlexWrap;
var justifyContent = JustifyContent;
var alignItems = AlignItems;
var isHorizontal = flexDirection == FlexDirection.Row || flexDirection == FlexDirection.RowReverse;
var isReverse = flexDirection == FlexDirection.RowReverse || flexDirection == FlexDirection.ColumnReverse;
var itemCount = lineInfo.ItemEndIndex - lineInfo.ItemStartIndex;
var children = InternalChildren;
var lineFreeU = lineInfo.LineU - lineInfo.ItemsU;
@@ -452,7 +463,7 @@ namespace HandyControl.Controls
var u = .0;
if (isReverse)
{
u = JustifyContent switch
u = justifyContent switch
{
FlexContentJustify.FlexStart => lineInfo.LineU,
FlexContentJustify.SpaceBetween => lineInfo.LineU,
@@ -464,7 +475,7 @@ namespace HandyControl.Controls
}
else
{
u = JustifyContent switch
u = justifyContent switch
{
FlexContentJustify.FlexEnd => lineFreeU,
FlexContentJustify.Center => lineFreeU * 0.5,
@@ -550,7 +561,7 @@ namespace HandyControl.Controls
var offsetUArr = new double[itemCount];
if (lineFreeU > 0)
{
if (JustifyContent == FlexContentJustify.SpaceBetween)
if (justifyContent == FlexContentJustify.SpaceBetween)
{
var freeItemU = lineFreeU / (itemCount - 1);
for (var i = 1; i < itemCount; i++)
@@ -558,7 +569,7 @@ namespace HandyControl.Controls
offsetUArr[i] = freeItemU;
}
}
else if (JustifyContent == FlexContentJustify.SpaceAround)
else if (justifyContent == FlexContentJustify.SpaceAround)
{
var freeItemU = lineFreeU / itemCount * 0.5;
offsetUArr[0] = freeItemU;
@@ -575,7 +586,7 @@ namespace HandyControl.Controls
var child = children[_orderList[i].Index];
if (child == null) continue;
var childSize = new UVSize(FlexDirection, isHorizontal
var childSize = new UVSize(flexDirection, isHorizontal
? new Size(child.DesiredSize.Width * lineInfo.ScaleU, child.DesiredSize.Height)
: new Size(child.DesiredSize.Width, child.DesiredSize.Height * lineInfo.ScaleU));
@@ -593,12 +604,12 @@ namespace HandyControl.Controls
var v = lineInfo.OffsetV;
var alignSelf = GetAlignSelf(child);
var alignment = alignSelf == FlexItemAlignment.Auto ? AlignItems : (FlexItemsAlignment)alignSelf;
var alignment = alignSelf == FlexItemAlignment.Auto ? alignItems : (FlexItemsAlignment)alignSelf;
switch (alignment)
{
case FlexItemsAlignment.Stretch:
if (_lineCount == 1 && FlexWrap == FlexWrap.NoWrap)
if (_lineCount == 1 && flexWrap == FlexWrap.NoWrap)
{
childSize.V = lineInfo.LineV + lineInfo.LineFreeV;
}
@@ -32,7 +32,7 @@ namespace HandyControl.Controls
private static bool OnSpanValidate(object value)
{
var v = (int)value;
return v >= 1 || v <= 24;
return v >= 1 && v <= 24;
}
public int Span
@@ -8,7 +8,8 @@ namespace HandyControl.Controls
public class WaterfallPanel : Panel
{
public static readonly DependencyProperty GroupsProperty = DependencyProperty.Register(
"Groups", typeof(int), typeof(WaterfallPanel), new FrameworkPropertyMetadata(ValueBoxes.Int2Box, FrameworkPropertyMetadataOptions.AffectsMeasure), IsGroupsValid);
"Groups", typeof(int), typeof(WaterfallPanel), new FrameworkPropertyMetadata(
ValueBoxes.Int2Box, FrameworkPropertyMetadataOptions.AffectsMeasure), IsGroupsValid);
public int Groups
{
@@ -16,11 +17,7 @@ namespace HandyControl.Controls
set => SetValue(GroupsProperty, value);
}
private static bool IsGroupsValid(object value)
{
var v = (int)value;
return v >= 1;
}
private static bool IsGroupsValid(object value) => (int)value >= 1;
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation", typeof(Orientation), typeof(WaterfallPanel), new FrameworkPropertyMetadata(
@@ -34,14 +31,16 @@ namespace HandyControl.Controls
protected override Size MeasureOverride(Size constraint)
{
if (Groups < 1) return constraint;
var groups = Groups;
if (groups < 1) return constraint;
var children = InternalChildren;
Size panelSize;
if (Orientation == Orientation.Horizontal)
{
var heightArr = new double[Groups].ToList();
var itemWidth = constraint.Width / Groups;
var heightArr = new double[groups].ToList();
var itemWidth = constraint.Width / groups;
if (double.IsNaN(itemWidth) || double.IsInfinity(itemWidth)) return constraint;
for (int i = 0, count = children.Count; i < count; i++)
@@ -60,8 +59,8 @@ namespace HandyControl.Controls
}
else
{
var widthArr = new double[Groups].ToList();
var itemHeight = constraint.Height / Groups;
var widthArr = new double[groups].ToList();
var itemHeight = constraint.Height / groups;
if (double.IsNaN(itemHeight) || double.IsInfinity(itemHeight)) return constraint;
for (int i = 0, count = children.Count; i < count; i++)