From a34a0a9662d31d72af440a6d508baa513e31cf13 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Tue, 21 Jul 2020 00:43:03 +0800 Subject: [PATCH 1/6] init branch --- .../Controls/Panel/FlexPanel.cs | 99 +++++++++++++++++++ .../Data/Flex/FlexContentAlignment.cs | 12 +++ .../Data/Flex/FlexContentJustify.cs | 11 +++ .../Data/Flex/FlexItemAlignment.cs | 12 +++ .../Data/Flex/FlexItemsAlignment.cs | 11 +++ .../Data/Flex/FlexOrientation.cs | 10 ++ .../Data/Flex/FlexWrapping.cs | 9 ++ .../HandyControl_Shared.projitems | 7 ++ 8 files changed, 171 insertions(+) create mode 100644 src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Flex/FlexContentJustify.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Flex/FlexItemAlignment.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs create mode 100644 src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs new file mode 100644 index 000000000..2f91936b6 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs @@ -0,0 +1,99 @@ +using System.Windows; +using System.Windows.Controls; +using HandyControl.Data; + +namespace HandyControl.Controls +{ + public class FlexPanel : Panel + { + public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached( + "Order", typeof(int), typeof(FlexPanel), new PropertyMetadata(ValueBoxes.Int0Box)); + + public static void SetOrder(DependencyObject element, int value) + => element.SetValue(OrderProperty, value); + + public static int GetOrder(DependencyObject element) + => (int) element.GetValue(OrderProperty); + + public static readonly DependencyProperty FlexGrowProperty = DependencyProperty.RegisterAttached( + "FlexGrow", typeof(double), typeof(FlexPanel), new PropertyMetadata(ValueBoxes.Double0Box)); + + public static void SetFlexGrow(DependencyObject element, double value) + => element.SetValue(FlexGrowProperty, value); + + public static double GetFlexGrow(DependencyObject element) + => (double) element.GetValue(FlexGrowProperty); + + public static readonly DependencyProperty FlexShrinkProperty = DependencyProperty.RegisterAttached( + "FlexShrink", typeof(double), typeof(FlexPanel), new PropertyMetadata(ValueBoxes.Double1Box)); + + public static void SetFlexShrink(DependencyObject element, double value) + => element.SetValue(FlexShrinkProperty, value); + + public static double GetFlexShrink(DependencyObject element) + => (double) element.GetValue(FlexShrinkProperty); + + public static readonly DependencyProperty FlexBasisProperty = DependencyProperty.RegisterAttached( + "FlexBasis", typeof(double), typeof(FlexPanel), new PropertyMetadata(double.NaN)); + + public static void SetFlexBasis(DependencyObject element, double value) + => element.SetValue(FlexBasisProperty, value); + + public static double GetFlexBasis(DependencyObject element) + => (double) element.GetValue(FlexBasisProperty); + + public static readonly DependencyProperty AlignSelfProperty = DependencyProperty.RegisterAttached( + "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new PropertyMetadata(default(FlexItemAlignment))); + + public static void SetAlignSelf(DependencyObject element, FlexItemAlignment value) + => element.SetValue(AlignSelfProperty, value); + + public static FlexItemAlignment GetAlignSelf(DependencyObject element) + => (FlexItemAlignment) element.GetValue(AlignSelfProperty); + + public static readonly DependencyProperty FlexDirectionProperty = DependencyProperty.Register( + "FlexDirection", typeof(FlexOrientation), typeof(FlexPanel), new PropertyMetadata(default(FlexOrientation))); + + public FlexOrientation FlexDirection + { + get => (FlexOrientation) GetValue(FlexDirectionProperty); + set => SetValue(FlexDirectionProperty, value); + } + + public static readonly DependencyProperty FlexWrapProperty = DependencyProperty.Register( + "FlexWrap", typeof(FlexWrapping), typeof(FlexPanel), new PropertyMetadata(default(FlexWrapping))); + + public FlexWrapping FlexWrap + { + get => (FlexWrapping) GetValue(FlexWrapProperty); + set => SetValue(FlexWrapProperty, value); + } + + public static readonly DependencyProperty JustifyContentProperty = DependencyProperty.Register( + "JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel), new PropertyMetadata(default(FlexContentJustify))); + + public FlexContentJustify JustifyContent + { + get => (FlexContentJustify) GetValue(JustifyContentProperty); + set => SetValue(JustifyContentProperty, value); + } + + public static readonly DependencyProperty AlignItemsProperty = DependencyProperty.Register( + "AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel), new PropertyMetadata(default(FlexItemsAlignment))); + + public FlexItemsAlignment AlignItems + { + get => (FlexItemsAlignment) GetValue(AlignItemsProperty); + set => SetValue(AlignItemsProperty, value); + } + + public static readonly DependencyProperty AlignContentProperty = DependencyProperty.Register( + "AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel), new PropertyMetadata(default(FlexContentAlignment))); + + public FlexContentAlignment AlignContent + { + get => (FlexContentAlignment) GetValue(AlignContentProperty); + set => SetValue(AlignContentProperty, value); + } + } +} diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs new file mode 100644 index 000000000..e6ec5f0b5 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs @@ -0,0 +1,12 @@ +namespace HandyControl.Data +{ + public enum FlexContentAlignment + { + FlexStart, + FlexEnd, + Center, + SpaceBetween, + SpaceAround, + Stretch + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexContentJustify.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexContentJustify.cs new file mode 100644 index 000000000..5402f93ee --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexContentJustify.cs @@ -0,0 +1,11 @@ +namespace HandyControl.Data +{ + public enum FlexContentJustify + { + FlexStart, + FlexEnd, + Center, + SpaceBetween, + SpaceAround + } +} \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexItemAlignment.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexItemAlignment.cs new file mode 100644 index 000000000..0f9e3c2b4 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexItemAlignment.cs @@ -0,0 +1,12 @@ +namespace HandyControl.Data +{ + public enum FlexItemAlignment + { + Auto, + FlexStart, + FlexEnd, + Center, + Baseline, + Stretch + } +} diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs new file mode 100644 index 000000000..6c0549e63 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs @@ -0,0 +1,11 @@ +namespace HandyControl.Data +{ + public enum FlexItemsAlignment + { + FlexStart, + FlexEnd, + Center, + Baseline, + Stretch + } +} diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs new file mode 100644 index 000000000..6f22ed487 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs @@ -0,0 +1,10 @@ +namespace HandyControl.Data +{ + public enum FlexOrientation + { + Row, + RowReverse, + Column, + ColumnReverse + } +} diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs new file mode 100644 index 000000000..471448494 --- /dev/null +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs @@ -0,0 +1,9 @@ +namespace HandyControl.Data +{ + public enum FlexWrapping + { + NoWrap, + Wrap, + WrapReverse + } +} diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 43a2d51c7..17ffb4baa 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -44,6 +44,7 @@ + @@ -73,6 +74,12 @@ + + + + + + From d5caa4243057e0156ece701db4ba2d2f6ca3166f Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Thu, 3 Sep 2020 00:55:09 +0800 Subject: [PATCH 2/6] implemented axis layout --- .../Controls/Panel/FlexPanel.cs | 461 +++++++++++++++++- .../Data/Flex/FlexContentAlignment.cs | 4 +- .../{FlexOrientation.cs => FlexDirection.cs} | 2 +- .../Data/Flex/FlexItemsAlignment.cs | 4 +- .../Flex/{FlexWrapping.cs => FlexWrap.cs} | 2 +- .../HandyControl_Shared.projitems | 4 +- 6 files changed, 446 insertions(+), 31 deletions(-) rename src/Shared/HandyControl_Shared/Data/Flex/{FlexOrientation.cs => FlexDirection.cs} (78%) rename src/Shared/HandyControl_Shared/Data/Flex/{FlexWrapping.cs => FlexWrap.cs} (76%) diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs index 2f91936b6..f4f3b0f61 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs @@ -1,99 +1,514 @@ -using System.Windows; +using System; +using System.Windows; using System.Windows.Controls; using HandyControl.Data; +using HandyControl.Expression.Drawing; namespace HandyControl.Controls { public class FlexPanel : Panel { + private UVSize _uvConstraint; + + private int _lineCount; + public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached( - "Order", typeof(int), typeof(FlexPanel), new PropertyMetadata(ValueBoxes.Int0Box)); + "Order", typeof(int), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); public static void SetOrder(DependencyObject element, int value) => element.SetValue(OrderProperty, value); public static int GetOrder(DependencyObject element) - => (int) element.GetValue(OrderProperty); + => (int)element.GetValue(OrderProperty); public static readonly DependencyProperty FlexGrowProperty = DependencyProperty.RegisterAttached( - "FlexGrow", typeof(double), typeof(FlexPanel), new PropertyMetadata(ValueBoxes.Double0Box)); + "FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); public static void SetFlexGrow(DependencyObject element, double value) => element.SetValue(FlexGrowProperty, value); public static double GetFlexGrow(DependencyObject element) - => (double) element.GetValue(FlexGrowProperty); + => (double)element.GetValue(FlexGrowProperty); public static readonly DependencyProperty FlexShrinkProperty = DependencyProperty.RegisterAttached( - "FlexShrink", typeof(double), typeof(FlexPanel), new PropertyMetadata(ValueBoxes.Double1Box)); + "FlexShrink", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double1Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); public static void SetFlexShrink(DependencyObject element, double value) => element.SetValue(FlexShrinkProperty, value); public static double GetFlexShrink(DependencyObject element) - => (double) element.GetValue(FlexShrinkProperty); + => (double)element.GetValue(FlexShrinkProperty); public static readonly DependencyProperty FlexBasisProperty = DependencyProperty.RegisterAttached( - "FlexBasis", typeof(double), typeof(FlexPanel), new PropertyMetadata(double.NaN)); + "FlexBasis", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure)); public static void SetFlexBasis(DependencyObject element, double value) => element.SetValue(FlexBasisProperty, value); public static double GetFlexBasis(DependencyObject element) - => (double) element.GetValue(FlexBasisProperty); + => (double)element.GetValue(FlexBasisProperty); public static readonly DependencyProperty AlignSelfProperty = DependencyProperty.RegisterAttached( - "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new PropertyMetadata(default(FlexItemAlignment))); + "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure)); public static void SetAlignSelf(DependencyObject element, FlexItemAlignment value) => element.SetValue(AlignSelfProperty, value); public static FlexItemAlignment GetAlignSelf(DependencyObject element) - => (FlexItemAlignment) element.GetValue(AlignSelfProperty); + => (FlexItemAlignment)element.GetValue(AlignSelfProperty); public static readonly DependencyProperty FlexDirectionProperty = DependencyProperty.Register( - "FlexDirection", typeof(FlexOrientation), typeof(FlexPanel), new PropertyMetadata(default(FlexOrientation))); + "FlexDirection", typeof(FlexDirection), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexDirection), FrameworkPropertyMetadataOptions.AffectsMeasure)); - public FlexOrientation FlexDirection + public FlexDirection FlexDirection { - get => (FlexOrientation) GetValue(FlexDirectionProperty); + get => (FlexDirection)GetValue(FlexDirectionProperty); set => SetValue(FlexDirectionProperty, value); } public static readonly DependencyProperty FlexWrapProperty = DependencyProperty.Register( - "FlexWrap", typeof(FlexWrapping), typeof(FlexPanel), new PropertyMetadata(default(FlexWrapping))); + "FlexWrap", typeof(FlexWrap), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexWrap), FrameworkPropertyMetadataOptions.AffectsMeasure)); - public FlexWrapping FlexWrap + public FlexWrap FlexWrap { - get => (FlexWrapping) GetValue(FlexWrapProperty); + get => (FlexWrap)GetValue(FlexWrapProperty); set => SetValue(FlexWrapProperty, value); } public static readonly DependencyProperty JustifyContentProperty = DependencyProperty.Register( - "JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel), new PropertyMetadata(default(FlexContentJustify))); + "JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexContentJustify), FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexContentJustify JustifyContent { - get => (FlexContentJustify) GetValue(JustifyContentProperty); + get => (FlexContentJustify)GetValue(JustifyContentProperty); set => SetValue(JustifyContentProperty, value); } public static readonly DependencyProperty AlignItemsProperty = DependencyProperty.Register( - "AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel), new PropertyMetadata(default(FlexItemsAlignment))); + "AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemsAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexItemsAlignment AlignItems { - get => (FlexItemsAlignment) GetValue(AlignItemsProperty); + get => (FlexItemsAlignment)GetValue(AlignItemsProperty); set => SetValue(AlignItemsProperty, value); } public static readonly DependencyProperty AlignContentProperty = DependencyProperty.Register( - "AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel), new PropertyMetadata(default(FlexContentAlignment))); + "AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexContentAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexContentAlignment AlignContent { - get => (FlexContentAlignment) GetValue(AlignContentProperty); + get => (FlexContentAlignment)GetValue(AlignContentProperty); set => SetValue(AlignContentProperty, value); } + + protected override Size MeasureOverride(Size constraint) + { + 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; + + foreach (UIElement child in InternalChildren) + { + if (child == null) continue; + child.Measure(childConstraint); + + var sz = new UVSize(FlexDirection, child.DesiredSize); + + if (FlexWrap == FlexWrap.NoWrap) //continue to accumulate a line + { + curLineSize.U += sz.U; + curLineSize.V = Math.Max(sz.V, curLineSize.V); + } + else + { + if (MathHelper.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; + _lineCount++; + + if (MathHelper.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(FlexDirection); + _lineCount++; + } + } + 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); + } + + protected override Size ArrangeOverride(Size arrangeSize) + { + var uvFinalSize = new UVSize(FlexDirection, arrangeSize); + if (MathHelper.IsZero(uvFinalSize.U) || MathHelper.IsZero(uvFinalSize.V)) return arrangeSize; + + // init status + var children = InternalChildren; + var lineIndex = 0; + + var curLineSizeArr = new UVSize[_lineCount]; + curLineSizeArr[0] = new UVSize(FlexDirection); + + var lastInLineArr = new int[_lineCount]; + for (var i = 0; i < _lineCount; i++) + { + lastInLineArr[i] = int.MaxValue; + } + + // calculate line max U space + for (var i = 0; i < children.Count; i++) + { + var child = children[i]; + if (child == null) continue; + + var sz = new UVSize(FlexDirection, child.DesiredSize); + + if (FlexWrap == FlexWrap.NoWrap) + { + curLineSizeArr[lineIndex].U += sz.U; + curLineSizeArr[lineIndex].V = uvFinalSize.V; + } + else + { + if (MathHelper.GreaterThan(curLineSizeArr[lineIndex].U + sz.U, uvFinalSize.U)) //need to switch to another line + { + lastInLineArr[lineIndex] = i; + lineIndex++; + curLineSizeArr[lineIndex] = sz; + + if (MathHelper.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 + lastInLineArr[lineIndex] = i; + lineIndex++; + curLineSizeArr[lineIndex] = new UVSize(FlexDirection); + } + } + else //continue to accumulate a line + { + curLineSizeArr[lineIndex].U += sz.U; + curLineSizeArr[lineIndex].V = Math.Max(sz.V, curLineSizeArr[lineIndex].V); + } + } + } + + // init status + var scaleU = Math.Min(_uvConstraint.U / uvFinalSize.U, 1); + var firstInLine = 0; + var wrapReverseFlag = FlexWrap == FlexWrap.WrapReverse ? -1 : 1; + var wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 1 : 0; + var itemsU = .0; + var accumulatedV = .0; + + // calculate free V space + var freeV = uvFinalSize.V; + foreach (var flexSize in curLineSizeArr) + { + freeV -= flexSize.V; + } + + var lineFreeVArr = new double[_lineCount]; + switch (AlignContent) + { + case FlexContentAlignment.Stretch: + { + var freeItemV = freeV / _lineCount; + for (var i = 0; i < _lineCount; i++) + { + lineFreeVArr[i] = freeItemV; + } + + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + } + break; + case FlexContentAlignment.FlexStart: + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + break; + case FlexContentAlignment.FlexEnd: + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV; + break; + case FlexContentAlignment.Center: + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5; + break; + case FlexContentAlignment.SpaceBetween: + { + var freeItemV = freeV / (_lineCount - 1); + for (var i = 0; i < _lineCount - 1; i++) + { + lineFreeVArr[i] = freeItemV; + } + + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + } + break; + case FlexContentAlignment.SpaceAround: + { + var freeItemV = freeV / _lineCount * 0.5; + for (var i = 0; i < _lineCount - 1; i++) + { + lineFreeVArr[i] = freeItemV * 2; + } + + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV; + } + break; + } + + // clear status + lineIndex = 0; + + //arrange line + for (var i = 0; i < children.Count; i++) + { + var child = children[i]; + if (child == null) continue; + + var sz = new UVSize(FlexDirection, child.DesiredSize); + + if (FlexWrap != FlexWrap.NoWrap) + { + if (i >= lastInLineArr[lineIndex]) //need to switch to another line + { + ArrangeLine(new FlexLineInfo + { + ItemsU = itemsU, + OffsetV = accumulatedV, + LineV = curLineSizeArr[lineIndex].V, + LineU = uvFinalSize.U, + ItemStartIndex = firstInLine, + ItemEndIndex = i, + ScaleU = scaleU + }); + + accumulatedV += (lineFreeVArr[lineIndex] + curLineSizeArr[lineIndex + wrapReverseAdd].V) * wrapReverseFlag; + lineIndex++; + itemsU = 0; + + 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 + { + ItemsU = itemsU, + OffsetV = accumulatedV, + LineV = curLineSizeArr[lineIndex].V, + LineU = uvFinalSize.U, + ItemStartIndex = i, + ItemEndIndex = ++i, + ScaleU = scaleU + }); + + accumulatedV += (lineFreeVArr[lineIndex] + curLineSizeArr[lineIndex + wrapReverseAdd].V) * wrapReverseFlag; + lineIndex++; + itemsU = 0; + } + firstInLine = i; + } + } + + itemsU += sz.U; + } + + //arrange the last line, if any + if (firstInLine < children.Count) + { + ArrangeLine(new FlexLineInfo + { + ItemsU = itemsU, + OffsetV = accumulatedV, + LineV = curLineSizeArr[lineIndex].V, + LineU = uvFinalSize.U, + ItemStartIndex = firstInLine, + ItemEndIndex = children.Count, + ScaleU = scaleU + }); + } + + return arrangeSize; + } + + private void ArrangeLine(FlexLineInfo lineInfo) + { + var isHorizontal = FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse; + var isReverse = FlexDirection == FlexDirection.RowReverse || FlexDirection == FlexDirection.ColumnReverse; + + //calculate initial u + var u = .0; + if (isReverse) + { + u = JustifyContent switch + { + FlexContentJustify.FlexStart => lineInfo.LineU, + FlexContentJustify.SpaceBetween => lineInfo.LineU, + FlexContentJustify.SpaceAround => lineInfo.LineU, + FlexContentJustify.FlexEnd => lineInfo.ItemsU, + FlexContentJustify.Center => (lineInfo.LineU + lineInfo.ItemsU) * 0.5, + _ => u + }; + } + else + { + u = JustifyContent switch + { + FlexContentJustify.FlexEnd => lineInfo.LineU - lineInfo.ItemsU, + FlexContentJustify.Center => (lineInfo.LineU - lineInfo.ItemsU) * 0.5, + _ => u + }; + } + u *= lineInfo.ScaleU; + + // calculate offset u + var itemCount = lineInfo.ItemEndIndex - lineInfo.ItemStartIndex; + var offsetUArr = new double[itemCount]; + if (JustifyContent == FlexContentJustify.SpaceBetween) + { + var freeItemU = (lineInfo.LineU - lineInfo.ItemsU) / (itemCount - 1); + for (var i = 1; i < itemCount; i++) + { + offsetUArr[i] = freeItemU; + } + } + else if (JustifyContent == FlexContentJustify.SpaceAround) + { + var freeItemU = (lineInfo.LineU - lineInfo.ItemsU) / itemCount * 0.5; + offsetUArr[0] = freeItemU; + for (var i = 1; i < itemCount; i++) + { + offsetUArr[i] = freeItemU * 2; + } + } + + var children = InternalChildren; + for (int i = lineInfo.ItemStartIndex, j = 0; i < lineInfo.ItemEndIndex; i++, j++) + { + var child = children[i]; + if (child == null) continue; + + 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)); + + if (isReverse) + { + u -= childSize.U; + u -= offsetUArr[j]; + } + else + { + u += offsetUArr[j]; + } + + var v = lineInfo.OffsetV; + switch (AlignItems) + { + case FlexItemsAlignment.Stretch: + childSize.V = lineInfo.LineV; + break; + case FlexItemsAlignment.FlexEnd: + v += lineInfo.LineV - childSize.V; + break; + case FlexItemsAlignment.Center: + v += (lineInfo.LineV - childSize.V) * 0.5; + break; + } + + child.Arrange(isHorizontal ? new Rect(u, v, childSize.U, childSize.V) : new Rect(v, u, childSize.V, childSize.U)); + + if (!isReverse) + { + u += childSize.U; + } + } + } + + private struct FlexLineInfo + { + public double ItemsU { get; set; } + + public double OffsetV { get; set; } + + public double LineU { get; set; } + + public double LineV { get; set; } + + public int ItemStartIndex { get; set; } + + public int ItemEndIndex { get; set; } + + public double ScaleU { get; set; } + } + + private struct UVSize + { + public UVSize(FlexDirection direction, Size size) + { + U = V = 0d; + FlexDirection = direction; + Width = size.Width; + Height = size.Height; + } + + public UVSize(FlexDirection direction) + { + U = V = 0d; + FlexDirection = direction; + } + + public double U { get; set; } + + public double V { get; set; } + + private FlexDirection FlexDirection { get; } + + public double Width + { + get => FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse ? U : V; + private set + { + if (FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse) + { + U = value; + } + else + { + V = value; + } + } + } + + public double Height + { + get => FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse ? V : U; + private set + { + if (FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse) + { + V = value; + } + else + { + U = value; + } + } + } + } } } diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs index e6ec5f0b5..965ce360e 100644 --- a/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexContentAlignment.cs @@ -2,11 +2,11 @@ { public enum FlexContentAlignment { + Stretch, FlexStart, FlexEnd, Center, SpaceBetween, - SpaceAround, - Stretch + SpaceAround } } \ No newline at end of file diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexDirection.cs similarity index 78% rename from src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs rename to src/Shared/HandyControl_Shared/Data/Flex/FlexDirection.cs index 6f22ed487..6d3b0d859 100644 --- a/src/Shared/HandyControl_Shared/Data/Flex/FlexOrientation.cs +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexDirection.cs @@ -1,6 +1,6 @@ namespace HandyControl.Data { - public enum FlexOrientation + public enum FlexDirection { Row, RowReverse, diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs index 6c0549e63..c51b62d32 100644 --- a/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexItemsAlignment.cs @@ -2,10 +2,10 @@ { public enum FlexItemsAlignment { + Stretch, FlexStart, FlexEnd, Center, - Baseline, - Stretch + Baseline } } diff --git a/src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs b/src/Shared/HandyControl_Shared/Data/Flex/FlexWrap.cs similarity index 76% rename from src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs rename to src/Shared/HandyControl_Shared/Data/Flex/FlexWrap.cs index 471448494..de1cfc9bb 100644 --- a/src/Shared/HandyControl_Shared/Data/Flex/FlexWrapping.cs +++ b/src/Shared/HandyControl_Shared/Data/Flex/FlexWrap.cs @@ -1,6 +1,6 @@ namespace HandyControl.Data { - public enum FlexWrapping + public enum FlexWrap { NoWrap, Wrap, diff --git a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems index 17ffb4baa..f84010643 100644 --- a/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems +++ b/src/Shared/HandyControl_Shared/HandyControl_Shared.projitems @@ -78,8 +78,8 @@ - - + + From 0d486653e6b1fe241049cf17984b586b390926a3 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sat, 5 Sep 2020 00:36:24 +0800 Subject: [PATCH 3/6] Update FlexPanel.cs --- .../Controls/Panel/FlexPanel.cs | 137 ++++++++++++++---- 1 file changed, 106 insertions(+), 31 deletions(-) diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs index f4f3b0f61..a0cdb2186 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs @@ -12,6 +12,8 @@ public class FlexPanel : Panel private int _lineCount; + #region Item + public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached( "Order", typeof(int), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); @@ -54,6 +56,10 @@ public static double GetFlexBasis(DependencyObject element) public static void SetAlignSelf(DependencyObject element, FlexItemAlignment value) => element.SetValue(AlignSelfProperty, value); + #endregion + + #region Panel + public static FlexItemAlignment GetAlignSelf(DependencyObject element) => (FlexItemAlignment)element.GetValue(AlignSelfProperty); @@ -102,6 +108,8 @@ public FlexContentAlignment AlignContent set => SetValue(AlignContentProperty, value); } + #endregion + protected override Size MeasureOverride(Size constraint) { var curLineSize = new UVSize(FlexDirection); @@ -184,7 +192,7 @@ protected override Size ArrangeOverride(Size arrangeSize) if (FlexWrap == FlexWrap.NoWrap) { curLineSizeArr[lineIndex].U += sz.U; - curLineSizeArr[lineIndex].V = uvFinalSize.V; + curLineSizeArr[lineIndex].V = Math.Max(sz.V, curLineSizeArr[lineIndex].V); } else { @@ -213,61 +221,116 @@ protected override Size ArrangeOverride(Size arrangeSize) // init status var scaleU = Math.Min(_uvConstraint.U / uvFinalSize.U, 1); var firstInLine = 0; + var wrapReverseAdd = 0; var wrapReverseFlag = FlexWrap == FlexWrap.WrapReverse ? -1 : 1; - var wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 1 : 0; + var accumulatedFlag = FlexWrap == FlexWrap.WrapReverse ? 1 : 0; var itemsU = .0; var accumulatedV = .0; - - // calculate free V space + var freeItemV = .0; var freeV = uvFinalSize.V; foreach (var flexSize in curLineSizeArr) { freeV -= flexSize.V; } + // calculate status var lineFreeVArr = new double[_lineCount]; switch (AlignContent) { case FlexContentAlignment.Stretch: { - var freeItemV = freeV / _lineCount; - for (var i = 0; i < _lineCount; i++) + if (_lineCount > 1) { - lineFreeVArr[i] = freeItemV; - } + freeItemV = freeV / _lineCount; + for (var i = 0; i < _lineCount; i++) + { + lineFreeVArr[i] = freeItemV; + } - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0; + } + else + { + freeItemV = freeV; + } } break; case FlexContentAlignment.FlexStart: - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + if (FlexWrap == FlexWrap.WrapReverse) + { + wrapReverseAdd = 1; + } + + if (_lineCount > 1) + { + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + } + else + { + wrapReverseAdd = 0; + freeItemV = freeV; + } break; case FlexContentAlignment.FlexEnd: - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV; + if (FlexWrap != FlexWrap.WrapReverse) + { + wrapReverseAdd = 1; + } + + if (_lineCount > 1) + { + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV; + } + else + { + wrapReverseAdd = 0; + freeItemV = freeV; + } break; case FlexContentAlignment.Center: - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5; + if (_lineCount > 1) + { + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5; + } + else + { + freeItemV = freeV; + } break; case FlexContentAlignment.SpaceBetween: { - var freeItemV = freeV / (_lineCount - 1); - for (var i = 0; i < _lineCount - 1; i++) + if (_lineCount > 1) { - lineFreeVArr[i] = freeItemV; - } + freeItemV = freeV / (_lineCount - 1); + for (var i = 0; i < _lineCount - 1; i++) + { + lineFreeVArr[i] = freeItemV; + } - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; + } + else + { + freeItemV = freeV; + } } break; case FlexContentAlignment.SpaceAround: { - var freeItemV = freeV / _lineCount * 0.5; - for (var i = 0; i < _lineCount - 1; i++) + if (_lineCount > 1) { - lineFreeVArr[i] = freeItemV * 2; - } + freeItemV = freeV / _lineCount * 0.5; + for (var i = 0; i < _lineCount - 1; i++) + { + 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; + } + else + { + freeItemV = freeV; + } } break; } @@ -275,7 +338,7 @@ protected override Size ArrangeOverride(Size arrangeSize) // clear status lineIndex = 0; - //arrange line + // arrange line for (var i = 0; i < children.Count; i++) { var child = children[i]; @@ -290,15 +353,16 @@ protected override Size ArrangeOverride(Size arrangeSize) ArrangeLine(new FlexLineInfo { ItemsU = itemsU, - OffsetV = accumulatedV, + OffsetV = accumulatedV + freeItemV * wrapReverseAdd, LineV = curLineSizeArr[lineIndex].V, + LineFreeV = freeItemV, LineU = uvFinalSize.U, ItemStartIndex = firstInLine, ItemEndIndex = i, ScaleU = scaleU }); - accumulatedV += (lineFreeVArr[lineIndex] + curLineSizeArr[lineIndex + wrapReverseAdd].V) * wrapReverseFlag; + accumulatedV += (lineFreeVArr[lineIndex] + curLineSizeArr[lineIndex + accumulatedFlag].V) * wrapReverseFlag; lineIndex++; itemsU = 0; @@ -308,15 +372,16 @@ protected override Size ArrangeOverride(Size arrangeSize) ArrangeLine(new FlexLineInfo { ItemsU = itemsU, - OffsetV = accumulatedV, + OffsetV = accumulatedV + freeItemV * wrapReverseAdd, LineV = curLineSizeArr[lineIndex].V, + LineFreeV = freeItemV, LineU = uvFinalSize.U, ItemStartIndex = i, ItemEndIndex = ++i, ScaleU = scaleU }); - accumulatedV += (lineFreeVArr[lineIndex] + curLineSizeArr[lineIndex + wrapReverseAdd].V) * wrapReverseFlag; + accumulatedV += (lineFreeVArr[lineIndex] + curLineSizeArr[lineIndex + accumulatedFlag].V) * wrapReverseFlag; lineIndex++; itemsU = 0; } @@ -327,14 +392,15 @@ protected override Size ArrangeOverride(Size arrangeSize) itemsU += sz.U; } - //arrange the last line, if any + // arrange the last line, if any if (firstInLine < children.Count) { ArrangeLine(new FlexLineInfo { ItemsU = itemsU, - OffsetV = accumulatedV, + OffsetV = accumulatedV + freeItemV * wrapReverseAdd, LineV = curLineSizeArr[lineIndex].V, + LineFreeV = freeItemV, LineU = uvFinalSize.U, ItemStartIndex = firstInLine, ItemEndIndex = children.Count, @@ -350,7 +416,7 @@ private void ArrangeLine(FlexLineInfo lineInfo) var isHorizontal = FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse; var isReverse = FlexDirection == FlexDirection.RowReverse || FlexDirection == FlexDirection.ColumnReverse; - //calculate initial u + // calculate initial u var u = .0; if (isReverse) { @@ -420,7 +486,14 @@ private void ArrangeLine(FlexLineInfo lineInfo) switch (AlignItems) { case FlexItemsAlignment.Stretch: - childSize.V = lineInfo.LineV; + if (_lineCount == 1 && FlexWrap == FlexWrap.NoWrap) + { + childSize.V = lineInfo.LineV + lineInfo.LineFreeV; + } + else + { + childSize.V = lineInfo.LineV; + } break; case FlexItemsAlignment.FlexEnd: v += lineInfo.LineV - childSize.V; @@ -449,6 +522,8 @@ private struct FlexLineInfo public double LineV { get; set; } + public double LineFreeV { get; set; } + public int ItemStartIndex { get; set; } public int ItemEndIndex { get; set; } From 8fb493049877e731a2ab4ecdaacbb585837d6d18 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sat, 5 Sep 2020 01:15:09 +0800 Subject: [PATCH 4/6] implemented order prop --- .../Controls/Panel/FlexPanel.cs | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs index a0cdb2186..20056e1eb 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Controls; +using System.Windows.Media; using HandyControl.Data; using HandyControl.Expression.Drawing; @@ -12,10 +14,12 @@ public class FlexPanel : Panel private int _lineCount; + private readonly List _orderList = new List(); + #region Item public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached( - "Order", typeof(int), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); + "Order", typeof(int), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, OnItemPropertyChanged)); public static void SetOrder(DependencyObject element, int value) => element.SetValue(OrderProperty, value); @@ -24,7 +28,7 @@ public static int GetOrder(DependencyObject element) => (int)element.GetValue(OrderProperty); public static readonly DependencyProperty FlexGrowProperty = DependencyProperty.RegisterAttached( - "FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); + "FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged)); public static void SetFlexGrow(DependencyObject element, double value) => element.SetValue(FlexGrowProperty, value); @@ -33,7 +37,7 @@ public static double GetFlexGrow(DependencyObject element) => (double)element.GetValue(FlexGrowProperty); public static readonly DependencyProperty FlexShrinkProperty = DependencyProperty.RegisterAttached( - "FlexShrink", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double1Box, FrameworkPropertyMetadataOptions.AffectsMeasure)); + "FlexShrink", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double1Box, OnItemPropertyChanged)); public static void SetFlexShrink(DependencyObject element, double value) => element.SetValue(FlexShrinkProperty, value); @@ -42,7 +46,7 @@ public static double GetFlexShrink(DependencyObject element) => (double)element.GetValue(FlexShrinkProperty); public static readonly DependencyProperty FlexBasisProperty = DependencyProperty.RegisterAttached( - "FlexBasis", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(double.NaN, FrameworkPropertyMetadataOptions.AffectsMeasure)); + "FlexBasis", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(double.NaN, OnItemPropertyChanged)); public static void SetFlexBasis(DependencyObject element, double value) => element.SetValue(FlexBasisProperty, value); @@ -51,7 +55,7 @@ public static double GetFlexBasis(DependencyObject element) => (double)element.GetValue(FlexBasisProperty); public static readonly DependencyProperty AlignSelfProperty = DependencyProperty.RegisterAttached( - "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure)); + "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemAlignment), OnItemPropertyChanged)); public static void SetAlignSelf(DependencyObject element, FlexItemAlignment value) => element.SetValue(AlignSelfProperty, value); @@ -110,17 +114,33 @@ public FlexContentAlignment AlignContent #endregion + private static void OnItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is UIElement element) + { + if (VisualTreeHelper.GetParent(element) is FlexPanel p) + { + p.InvalidateMeasure(); + } + } + } + protected override Size MeasureOverride(Size constraint) { + _orderList.Clear(); 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; - foreach (UIElement child in InternalChildren) + for (var i = 0; i < children.Count; i++) { + var child = children[i]; if (child == null) continue; + + _orderList.Add(new FlexItemInfo(i, GetOrder(child))); child.Measure(childConstraint); var sz = new UVSize(FlexDirection, child.DesiredSize); @@ -155,6 +175,8 @@ protected override Size MeasureOverride(Size constraint) } } + _orderList.Sort(); + //the last line size, if any should be added panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; @@ -184,7 +206,7 @@ protected override Size ArrangeOverride(Size arrangeSize) // calculate line max U space for (var i = 0; i < children.Count; i++) { - var child = children[i]; + var child = children[_orderList[i].Index]; if (child == null) continue; var sz = new UVSize(FlexDirection, child.DesiredSize); @@ -341,7 +363,7 @@ protected override Size ArrangeOverride(Size arrangeSize) // arrange line for (var i = 0; i < children.Count; i++) { - var child = children[i]; + var child = children[_orderList[i].Index]; if (child == null) continue; var sz = new UVSize(FlexDirection, child.DesiredSize); @@ -465,7 +487,7 @@ private void ArrangeLine(FlexLineInfo lineInfo) var children = InternalChildren; for (int i = lineInfo.ItemStartIndex, j = 0; i < lineInfo.ItemEndIndex; i++, j++) { - var child = children[i]; + var child = children[_orderList[i].Index]; if (child == null) continue; var childSize = new UVSize(FlexDirection, isHorizontal ? @@ -512,6 +534,21 @@ private void ArrangeLine(FlexLineInfo lineInfo) } } + private readonly struct FlexItemInfo : IComparable + { + public FlexItemInfo(int index, int order) + { + Index = index; + Order = order; + } + + private int Order { get; } + + public int Index { get; } + + public int CompareTo(FlexItemInfo other) => Order.CompareTo(other.Order); + } + private struct FlexLineInfo { public double ItemsU { get; set; } From 0cc7c097da793f43acd2488e10b6258fb084d681 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sat, 5 Sep 2020 12:34:09 +0800 Subject: [PATCH 5/6] implemented AlignSelf prop --- .../Controls/Panel/FlexPanel.cs | 90 +++++++++---------- 1 file changed, 42 insertions(+), 48 deletions(-) diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs index 20056e1eb..996c56223 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs @@ -5,6 +5,7 @@ using System.Windows.Media; using HandyControl.Data; using HandyControl.Expression.Drawing; +using HandyControl.Tools; namespace HandyControl.Controls { @@ -28,7 +29,7 @@ public static int GetOrder(DependencyObject element) => (int)element.GetValue(OrderProperty); public static readonly DependencyProperty FlexGrowProperty = DependencyProperty.RegisterAttached( - "FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged)); + "FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged), ValidateHelper.IsInRangeOfPosDoubleIncludeZero); public static void SetFlexGrow(DependencyObject element, double value) => element.SetValue(FlexGrowProperty, value); @@ -127,7 +128,6 @@ private static void OnItemPropertyChanged(DependencyObject d, DependencyProperty protected override Size MeasureOverride(Size constraint) { - _orderList.Clear(); var curLineSize = new UVSize(FlexDirection); var panelSize = new UVSize(FlexDirection); _uvConstraint = new UVSize(FlexDirection, constraint); @@ -135,12 +135,21 @@ protected override Size MeasureOverride(Size constraint) _lineCount = 1; var children = InternalChildren; + _orderList.Clear(); for (var i = 0; i < children.Count; i++) { var child = children[i]; if (child == null) continue; _orderList.Add(new FlexItemInfo(i, GetOrder(child))); + } + _orderList.Sort(); + + for (var i = 0; i < children.Count; i++) + { + var child = children[_orderList[i].Index]; + if (child == null) continue; + child.Measure(childConstraint); var sz = new UVSize(FlexDirection, child.DesiredSize); @@ -175,8 +184,6 @@ protected override Size MeasureOverride(Size constraint) } } - _orderList.Sort(); - //the last line size, if any should be added panelSize.U = Math.Max(curLineSize.U, panelSize.U); panelSize.V += curLineSize.V; @@ -248,33 +255,27 @@ protected override Size ArrangeOverride(Size arrangeSize) var accumulatedFlag = FlexWrap == FlexWrap.WrapReverse ? 1 : 0; var itemsU = .0; var accumulatedV = .0; - var freeItemV = .0; var freeV = uvFinalSize.V; foreach (var flexSize in curLineSizeArr) { freeV -= flexSize.V; } + var freeItemV = freeV; // calculate status var lineFreeVArr = new double[_lineCount]; switch (AlignContent) { case FlexContentAlignment.Stretch: + if (_lineCount > 1) { - if (_lineCount > 1) + freeItemV = freeV / _lineCount; + for (var i = 0; i < _lineCount; i++) { - freeItemV = freeV / _lineCount; - for (var i = 0; i < _lineCount; i++) - { - lineFreeVArr[i] = freeItemV; - } - - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0; - } - else - { - freeItemV = freeV; + lineFreeVArr[i] = freeItemV; } + + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0; } break; case FlexContentAlignment.FlexStart: @@ -290,7 +291,6 @@ protected override Size ArrangeOverride(Size arrangeSize) else { wrapReverseAdd = 0; - freeItemV = freeV; } break; case FlexContentAlignment.FlexEnd: @@ -306,7 +306,6 @@ protected override Size ArrangeOverride(Size arrangeSize) else { wrapReverseAdd = 0; - freeItemV = freeV; } break; case FlexContentAlignment.Center: @@ -314,45 +313,29 @@ protected override Size ArrangeOverride(Size arrangeSize) { accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5; } - else - { - freeItemV = freeV; - } break; case FlexContentAlignment.SpaceBetween: + if (_lineCount > 1) { - if (_lineCount > 1) - { - freeItemV = freeV / (_lineCount - 1); - for (var i = 0; i < _lineCount - 1; i++) - { - lineFreeVArr[i] = freeItemV; - } - - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; - } - else + freeItemV = freeV / (_lineCount - 1); + for (var i = 0; i < _lineCount - 1; i++) { - freeItemV = freeV; + lineFreeVArr[i] = freeItemV; } + + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; } break; case FlexContentAlignment.SpaceAround: + if (_lineCount > 1) { - if (_lineCount > 1) + freeItemV = freeV / _lineCount * 0.5; + for (var i = 0; i < _lineCount - 1; i++) { - freeItemV = freeV / _lineCount * 0.5; - for (var i = 0; i < _lineCount - 1; i++) - { - lineFreeVArr[i] = freeItemV * 2; - } - - accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV; - } - else - { - freeItemV = freeV; + lineFreeVArr[i] = freeItemV * 2; } + + accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV; } break; } @@ -505,7 +488,18 @@ private void ArrangeLine(FlexLineInfo lineInfo) } var v = lineInfo.OffsetV; - switch (AlignItems) + var alignSelf = GetAlignSelf(child); + FlexItemsAlignment alignment; + if (alignSelf == FlexItemAlignment.Auto) + { + alignment = AlignItems; + } + else + { + alignment = (FlexItemsAlignment)alignSelf; + } + + switch (alignment) { case FlexItemsAlignment.Stretch: if (_lineCount == 1 && FlexWrap == FlexWrap.NoWrap) From d07e1a3d874b6f189972f0a3a6782688a2813193 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sat, 5 Sep 2020 14:51:27 +0800 Subject: [PATCH 6/6] completed the branch --- .../Controls/Panel/FlexPanel.cs | 193 +++++++++++++----- 1 file changed, 145 insertions(+), 48 deletions(-) diff --git a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs index 996c56223..dd4b60b31 100644 --- a/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs +++ b/src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs @@ -6,6 +6,7 @@ using HandyControl.Data; using HandyControl.Expression.Drawing; using HandyControl.Tools; +using HandyControl.Tools.Extension; namespace HandyControl.Controls { @@ -20,7 +21,8 @@ public class FlexPanel : Panel #region Item public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached( - "Order", typeof(int), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, OnItemPropertyChanged)); + "Order", typeof(int), typeof(FlexPanel), + new FrameworkPropertyMetadata(ValueBoxes.Int0Box, OnItemPropertyChanged)); public static void SetOrder(DependencyObject element, int value) => element.SetValue(OrderProperty, value); @@ -29,7 +31,9 @@ public static int GetOrder(DependencyObject element) => (int)element.GetValue(OrderProperty); public static readonly DependencyProperty FlexGrowProperty = DependencyProperty.RegisterAttached( - "FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged), ValidateHelper.IsInRangeOfPosDoubleIncludeZero); + "FlexGrow", typeof(double), typeof(FlexPanel), + new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged), + ValidateHelper.IsInRangeOfPosDoubleIncludeZero); public static void SetFlexGrow(DependencyObject element, double value) => element.SetValue(FlexGrowProperty, value); @@ -38,7 +42,9 @@ public static double GetFlexGrow(DependencyObject element) => (double)element.GetValue(FlexGrowProperty); public static readonly DependencyProperty FlexShrinkProperty = DependencyProperty.RegisterAttached( - "FlexShrink", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double1Box, OnItemPropertyChanged)); + "FlexShrink", typeof(double), typeof(FlexPanel), + new FrameworkPropertyMetadata(ValueBoxes.Double1Box, OnItemPropertyChanged), + ValidateHelper.IsInRangeOfPosDoubleIncludeZero); public static void SetFlexShrink(DependencyObject element, double value) => element.SetValue(FlexShrinkProperty, value); @@ -47,7 +53,8 @@ public static double GetFlexShrink(DependencyObject element) => (double)element.GetValue(FlexShrinkProperty); public static readonly DependencyProperty FlexBasisProperty = DependencyProperty.RegisterAttached( - "FlexBasis", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(double.NaN, OnItemPropertyChanged)); + "FlexBasis", typeof(double), typeof(FlexPanel), + new FrameworkPropertyMetadata(double.NaN, OnItemPropertyChanged)); public static void SetFlexBasis(DependencyObject element, double value) => element.SetValue(FlexBasisProperty, value); @@ -56,7 +63,8 @@ public static double GetFlexBasis(DependencyObject element) => (double)element.GetValue(FlexBasisProperty); public static readonly DependencyProperty AlignSelfProperty = DependencyProperty.RegisterAttached( - "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemAlignment), OnItemPropertyChanged)); + "AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), + new FrameworkPropertyMetadata(default(FlexItemAlignment), OnItemPropertyChanged)); public static void SetAlignSelf(DependencyObject element, FlexItemAlignment value) => element.SetValue(AlignSelfProperty, value); @@ -69,7 +77,8 @@ public static FlexItemAlignment GetAlignSelf(DependencyObject element) => (FlexItemAlignment)element.GetValue(AlignSelfProperty); public static readonly DependencyProperty FlexDirectionProperty = DependencyProperty.Register( - "FlexDirection", typeof(FlexDirection), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexDirection), FrameworkPropertyMetadataOptions.AffectsMeasure)); + "FlexDirection", typeof(FlexDirection), typeof(FlexPanel), + new FrameworkPropertyMetadata(default(FlexDirection), FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexDirection FlexDirection { @@ -78,7 +87,8 @@ public FlexDirection FlexDirection } public static readonly DependencyProperty FlexWrapProperty = DependencyProperty.Register( - "FlexWrap", typeof(FlexWrap), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexWrap), FrameworkPropertyMetadataOptions.AffectsMeasure)); + "FlexWrap", typeof(FlexWrap), typeof(FlexPanel), + new FrameworkPropertyMetadata(default(FlexWrap), FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexWrap FlexWrap { @@ -87,7 +97,9 @@ public FlexWrap FlexWrap } public static readonly DependencyProperty JustifyContentProperty = DependencyProperty.Register( - "JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexContentJustify), FrameworkPropertyMetadataOptions.AffectsMeasure)); + "JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel), + new FrameworkPropertyMetadata(default(FlexContentJustify), + FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexContentJustify JustifyContent { @@ -96,7 +108,9 @@ public FlexContentJustify JustifyContent } public static readonly DependencyProperty AlignItemsProperty = DependencyProperty.Register( - "AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemsAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure)); + "AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel), + new FrameworkPropertyMetadata(default(FlexItemsAlignment), + FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexItemsAlignment AlignItems { @@ -105,7 +119,9 @@ public FlexItemsAlignment AlignItems } public static readonly DependencyProperty AlignContentProperty = DependencyProperty.Register( - "AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexContentAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure)); + "AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel), + new FrameworkPropertyMetadata(default(FlexContentAlignment), + FrameworkPropertyMetadataOptions.AffectsMeasure)); public FlexContentAlignment AlignContent { @@ -143,6 +159,7 @@ protected override Size MeasureOverride(Size constraint) _orderList.Add(new FlexItemInfo(i, GetOrder(child))); } + _orderList.Sort(); for (var i = 0; i < children.Count; i++) @@ -150,6 +167,11 @@ protected override Size MeasureOverride(Size constraint) var child = children[_orderList[i].Index]; if (child == null) continue; + var flexBasis = GetFlexBasis(child); + if (!flexBasis.IsNaN()) + { + child.SetCurrentValue(WidthProperty, flexBasis); + } child.Measure(childConstraint); var sz = new UVSize(FlexDirection, child.DesiredSize); @@ -260,6 +282,7 @@ protected override Size ArrangeOverride(Size arrangeSize) { freeV -= flexSize.V; } + var freeItemV = freeV; // calculate status @@ -277,13 +300,10 @@ protected override Size ArrangeOverride(Size arrangeSize) accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0; } + break; case FlexContentAlignment.FlexStart: - if (FlexWrap == FlexWrap.WrapReverse) - { - wrapReverseAdd = 1; - } - + wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 0 : 1; if (_lineCount > 1) { accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; @@ -292,13 +312,10 @@ protected override Size ArrangeOverride(Size arrangeSize) { wrapReverseAdd = 0; } + break; case FlexContentAlignment.FlexEnd: - if (FlexWrap != FlexWrap.WrapReverse) - { - wrapReverseAdd = 1; - } - + wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 1 : 0; if (_lineCount > 1) { accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV; @@ -307,12 +324,14 @@ protected override Size ArrangeOverride(Size arrangeSize) { wrapReverseAdd = 0; } + break; case FlexContentAlignment.Center: if (_lineCount > 1) { accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5; } + break; case FlexContentAlignment.SpaceBetween: if (_lineCount > 1) @@ -325,6 +344,7 @@ protected override Size ArrangeOverride(Size arrangeSize) accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0; } + break; case FlexContentAlignment.SpaceAround: if (_lineCount > 1) @@ -337,6 +357,7 @@ protected override Size ArrangeOverride(Size arrangeSize) accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV; } + break; } @@ -371,7 +392,8 @@ protected override Size ArrangeOverride(Size arrangeSize) 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 @@ -390,6 +412,7 @@ protected override Size ArrangeOverride(Size arrangeSize) lineIndex++; itemsU = 0; } + firstInLine = i; } } @@ -420,6 +443,10 @@ private void ArrangeLine(FlexLineInfo lineInfo) { 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; + var constraintFreeU = _uvConstraint.U - lineInfo.ItemsU; // calculate initial u var u = .0; @@ -439,43 +466,120 @@ private void ArrangeLine(FlexLineInfo lineInfo) { u = JustifyContent switch { - FlexContentJustify.FlexEnd => lineInfo.LineU - lineInfo.ItemsU, - FlexContentJustify.Center => (lineInfo.LineU - lineInfo.ItemsU) * 0.5, + FlexContentJustify.FlexEnd => lineFreeU, + FlexContentJustify.Center => lineFreeU * 0.5, _ => u }; } + u *= lineInfo.ScaleU; - // calculate offset u - var itemCount = lineInfo.ItemEndIndex - lineInfo.ItemStartIndex; - var offsetUArr = new double[itemCount]; - if (JustifyContent == FlexContentJustify.SpaceBetween) + // apply FlexGrow + var flexGrowUArr = new double[itemCount]; + if (constraintFreeU > 0) { - var freeItemU = (lineInfo.LineU - lineInfo.ItemsU) / (itemCount - 1); - for (var i = 1; i < itemCount; i++) + var ignoreFlexGrow = true; + var flexGrowSum = .0; + + for (var i = 0; i < itemCount; i++) + { + var flexGrow = GetFlexGrow(children[_orderList[i].Index]); + ignoreFlexGrow &= MathHelper.IsVerySmall(flexGrow); + flexGrowUArr[i] = flexGrow; + flexGrowSum += flexGrow; + } + + if (!ignoreFlexGrow) + { + var flexGrowItem = .0; + if (flexGrowSum > 0) + { + flexGrowItem = constraintFreeU / flexGrowSum; + lineInfo.ScaleU = 1; + lineFreeU = 0; //line free U was used up + } + + for (var i = 0; i < itemCount; i++) + { + flexGrowUArr[i] *= flexGrowItem; + } + } + else { - offsetUArr[i] = freeItemU; + flexGrowUArr = new double[itemCount]; } } - else if (JustifyContent == FlexContentJustify.SpaceAround) + + // apply FlexShrink + var flexShrinkUArr = new double[itemCount]; + if (constraintFreeU < 0) { - var freeItemU = (lineInfo.LineU - lineInfo.ItemsU) / itemCount * 0.5; - offsetUArr[0] = freeItemU; - for (var i = 1; i < itemCount; i++) + var ignoreFlexShrink = true; + var flexShrinkSum = .0; + + for (var i = 0; i < itemCount; i++) { - offsetUArr[i] = freeItemU * 2; + var flexShrink = GetFlexShrink(children[_orderList[i].Index]); + ignoreFlexShrink &= MathHelper.IsVerySmall(flexShrink - 1); + flexShrinkUArr[i] = flexShrink; + flexShrinkSum += flexShrink; + } + + if (!ignoreFlexShrink) + { + var flexShrinkItem = .0; + if (flexShrinkSum > 0) + { + flexShrinkItem = constraintFreeU / flexShrinkSum; + lineInfo.ScaleU = 1; + lineFreeU = 0; //line free U was used up + } + + for (var i = 0; i < itemCount; i++) + { + flexShrinkUArr[i] *= flexShrinkItem; + } + } + else + { + flexShrinkUArr = new double[itemCount]; } } - var children = InternalChildren; + // calculate offset u + var offsetUArr = new double[itemCount]; + if (lineFreeU > 0) + { + if (JustifyContent == FlexContentJustify.SpaceBetween) + { + var freeItemU = lineFreeU / (itemCount - 1); + for (var i = 1; i < itemCount; i++) + { + offsetUArr[i] = freeItemU; + } + } + else if (JustifyContent == FlexContentJustify.SpaceAround) + { + var freeItemU = lineFreeU / itemCount * 0.5; + offsetUArr[0] = freeItemU; + for (var i = 1; i < itemCount; i++) + { + offsetUArr[i] = freeItemU * 2; + } + } + } + + // arrange item for (int i = lineInfo.ItemStartIndex, j = 0; i < lineInfo.ItemEndIndex; i++, j++) { var child = children[_orderList[i].Index]; if (child == null) continue; - 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)); + 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)); + + childSize.U += flexGrowUArr[j] + flexShrinkUArr[j]; if (isReverse) { @@ -489,15 +593,7 @@ private void ArrangeLine(FlexLineInfo lineInfo) var v = lineInfo.OffsetV; var alignSelf = GetAlignSelf(child); - FlexItemsAlignment alignment; - if (alignSelf == FlexItemAlignment.Auto) - { - alignment = AlignItems; - } - else - { - alignment = (FlexItemsAlignment)alignSelf; - } + var alignment = alignSelf == FlexItemAlignment.Auto ? AlignItems : (FlexItemsAlignment)alignSelf; switch (alignment) { @@ -510,6 +606,7 @@ private void ArrangeLine(FlexLineInfo lineInfo) { childSize.V = lineInfo.LineV; } + break; case FlexItemsAlignment.FlexEnd: v += lineInfo.LineV - childSize.V;