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;