Skip to content

Commit d07e1a3

Browse files
committed
completed the branch
1 parent 0cc7c09 commit d07e1a3

1 file changed

Lines changed: 145 additions & 48 deletions

File tree

src/Shared/HandyControl_Shared/Controls/Panel/FlexPanel.cs

Lines changed: 145 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using HandyControl.Data;
77
using HandyControl.Expression.Drawing;
88
using HandyControl.Tools;
9+
using HandyControl.Tools.Extension;
910

1011
namespace HandyControl.Controls
1112
{
@@ -20,7 +21,8 @@ public class FlexPanel : Panel
2021
#region Item
2122

2223
public static readonly DependencyProperty OrderProperty = DependencyProperty.RegisterAttached(
23-
"Order", typeof(int), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Int0Box, OnItemPropertyChanged));
24+
"Order", typeof(int), typeof(FlexPanel),
25+
new FrameworkPropertyMetadata(ValueBoxes.Int0Box, OnItemPropertyChanged));
2426

2527
public static void SetOrder(DependencyObject element, int value)
2628
=> element.SetValue(OrderProperty, value);
@@ -29,7 +31,9 @@ public static int GetOrder(DependencyObject element)
2931
=> (int)element.GetValue(OrderProperty);
3032

3133
public static readonly DependencyProperty FlexGrowProperty = DependencyProperty.RegisterAttached(
32-
"FlexGrow", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged), ValidateHelper.IsInRangeOfPosDoubleIncludeZero);
34+
"FlexGrow", typeof(double), typeof(FlexPanel),
35+
new FrameworkPropertyMetadata(ValueBoxes.Double0Box, OnItemPropertyChanged),
36+
ValidateHelper.IsInRangeOfPosDoubleIncludeZero);
3337

3438
public static void SetFlexGrow(DependencyObject element, double value)
3539
=> element.SetValue(FlexGrowProperty, value);
@@ -38,7 +42,9 @@ public static double GetFlexGrow(DependencyObject element)
3842
=> (double)element.GetValue(FlexGrowProperty);
3943

4044
public static readonly DependencyProperty FlexShrinkProperty = DependencyProperty.RegisterAttached(
41-
"FlexShrink", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(ValueBoxes.Double1Box, OnItemPropertyChanged));
45+
"FlexShrink", typeof(double), typeof(FlexPanel),
46+
new FrameworkPropertyMetadata(ValueBoxes.Double1Box, OnItemPropertyChanged),
47+
ValidateHelper.IsInRangeOfPosDoubleIncludeZero);
4248

4349
public static void SetFlexShrink(DependencyObject element, double value)
4450
=> element.SetValue(FlexShrinkProperty, value);
@@ -47,7 +53,8 @@ public static double GetFlexShrink(DependencyObject element)
4753
=> (double)element.GetValue(FlexShrinkProperty);
4854

4955
public static readonly DependencyProperty FlexBasisProperty = DependencyProperty.RegisterAttached(
50-
"FlexBasis", typeof(double), typeof(FlexPanel), new FrameworkPropertyMetadata(double.NaN, OnItemPropertyChanged));
56+
"FlexBasis", typeof(double), typeof(FlexPanel),
57+
new FrameworkPropertyMetadata(double.NaN, OnItemPropertyChanged));
5158

5259
public static void SetFlexBasis(DependencyObject element, double value)
5360
=> element.SetValue(FlexBasisProperty, value);
@@ -56,7 +63,8 @@ public static double GetFlexBasis(DependencyObject element)
5663
=> (double)element.GetValue(FlexBasisProperty);
5764

5865
public static readonly DependencyProperty AlignSelfProperty = DependencyProperty.RegisterAttached(
59-
"AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemAlignment), OnItemPropertyChanged));
66+
"AlignSelf", typeof(FlexItemAlignment), typeof(FlexPanel),
67+
new FrameworkPropertyMetadata(default(FlexItemAlignment), OnItemPropertyChanged));
6068

6169
public static void SetAlignSelf(DependencyObject element, FlexItemAlignment value)
6270
=> element.SetValue(AlignSelfProperty, value);
@@ -69,7 +77,8 @@ public static FlexItemAlignment GetAlignSelf(DependencyObject element)
6977
=> (FlexItemAlignment)element.GetValue(AlignSelfProperty);
7078

7179
public static readonly DependencyProperty FlexDirectionProperty = DependencyProperty.Register(
72-
"FlexDirection", typeof(FlexDirection), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexDirection), FrameworkPropertyMetadataOptions.AffectsMeasure));
80+
"FlexDirection", typeof(FlexDirection), typeof(FlexPanel),
81+
new FrameworkPropertyMetadata(default(FlexDirection), FrameworkPropertyMetadataOptions.AffectsMeasure));
7382

7483
public FlexDirection FlexDirection
7584
{
@@ -78,7 +87,8 @@ public FlexDirection FlexDirection
7887
}
7988

8089
public static readonly DependencyProperty FlexWrapProperty = DependencyProperty.Register(
81-
"FlexWrap", typeof(FlexWrap), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexWrap), FrameworkPropertyMetadataOptions.AffectsMeasure));
90+
"FlexWrap", typeof(FlexWrap), typeof(FlexPanel),
91+
new FrameworkPropertyMetadata(default(FlexWrap), FrameworkPropertyMetadataOptions.AffectsMeasure));
8292

8393
public FlexWrap FlexWrap
8494
{
@@ -87,7 +97,9 @@ public FlexWrap FlexWrap
8797
}
8898

8999
public static readonly DependencyProperty JustifyContentProperty = DependencyProperty.Register(
90-
"JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexContentJustify), FrameworkPropertyMetadataOptions.AffectsMeasure));
100+
"JustifyContent", typeof(FlexContentJustify), typeof(FlexPanel),
101+
new FrameworkPropertyMetadata(default(FlexContentJustify),
102+
FrameworkPropertyMetadataOptions.AffectsMeasure));
91103

92104
public FlexContentJustify JustifyContent
93105
{
@@ -96,7 +108,9 @@ public FlexContentJustify JustifyContent
96108
}
97109

98110
public static readonly DependencyProperty AlignItemsProperty = DependencyProperty.Register(
99-
"AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexItemsAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure));
111+
"AlignItems", typeof(FlexItemsAlignment), typeof(FlexPanel),
112+
new FrameworkPropertyMetadata(default(FlexItemsAlignment),
113+
FrameworkPropertyMetadataOptions.AffectsMeasure));
100114

101115
public FlexItemsAlignment AlignItems
102116
{
@@ -105,7 +119,9 @@ public FlexItemsAlignment AlignItems
105119
}
106120

107121
public static readonly DependencyProperty AlignContentProperty = DependencyProperty.Register(
108-
"AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel), new FrameworkPropertyMetadata(default(FlexContentAlignment), FrameworkPropertyMetadataOptions.AffectsMeasure));
122+
"AlignContent", typeof(FlexContentAlignment), typeof(FlexPanel),
123+
new FrameworkPropertyMetadata(default(FlexContentAlignment),
124+
FrameworkPropertyMetadataOptions.AffectsMeasure));
109125

110126
public FlexContentAlignment AlignContent
111127
{
@@ -143,13 +159,19 @@ protected override Size MeasureOverride(Size constraint)
143159

144160
_orderList.Add(new FlexItemInfo(i, GetOrder(child)));
145161
}
162+
146163
_orderList.Sort();
147164

148165
for (var i = 0; i < children.Count; i++)
149166
{
150167
var child = children[_orderList[i].Index];
151168
if (child == null) continue;
152169

170+
var flexBasis = GetFlexBasis(child);
171+
if (!flexBasis.IsNaN())
172+
{
173+
child.SetCurrentValue(WidthProperty, flexBasis);
174+
}
153175
child.Measure(childConstraint);
154176

155177
var sz = new UVSize(FlexDirection, child.DesiredSize);
@@ -260,6 +282,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
260282
{
261283
freeV -= flexSize.V;
262284
}
285+
263286
var freeItemV = freeV;
264287

265288
// calculate status
@@ -277,13 +300,10 @@ protected override Size ArrangeOverride(Size arrangeSize)
277300

278301
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - lineFreeVArr[0] : 0;
279302
}
303+
280304
break;
281305
case FlexContentAlignment.FlexStart:
282-
if (FlexWrap == FlexWrap.WrapReverse)
283-
{
284-
wrapReverseAdd = 1;
285-
}
286-
306+
wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 0 : 1;
287307
if (_lineCount > 1)
288308
{
289309
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0;
@@ -292,13 +312,10 @@ protected override Size ArrangeOverride(Size arrangeSize)
292312
{
293313
wrapReverseAdd = 0;
294314
}
315+
295316
break;
296317
case FlexContentAlignment.FlexEnd:
297-
if (FlexWrap != FlexWrap.WrapReverse)
298-
{
299-
wrapReverseAdd = 1;
300-
}
301-
318+
wrapReverseAdd = FlexWrap == FlexWrap.WrapReverse ? 1 : 0;
302319
if (_lineCount > 1)
303320
{
304321
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV : freeV;
@@ -307,12 +324,14 @@ protected override Size ArrangeOverride(Size arrangeSize)
307324
{
308325
wrapReverseAdd = 0;
309326
}
327+
310328
break;
311329
case FlexContentAlignment.Center:
312330
if (_lineCount > 1)
313331
{
314332
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeV * 0.5 : freeV * 0.5;
315333
}
334+
316335
break;
317336
case FlexContentAlignment.SpaceBetween:
318337
if (_lineCount > 1)
@@ -325,6 +344,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
325344

326345
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V : 0;
327346
}
347+
328348
break;
329349
case FlexContentAlignment.SpaceAround:
330350
if (_lineCount > 1)
@@ -337,6 +357,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
337357

338358
accumulatedV = FlexWrap == FlexWrap.WrapReverse ? uvFinalSize.V - curLineSizeArr[0].V - freeItemV : freeItemV;
339359
}
360+
340361
break;
341362
}
342363

@@ -371,7 +392,8 @@ protected override Size ArrangeOverride(Size arrangeSize)
371392
lineIndex++;
372393
itemsU = 0;
373394

374-
if (i >= lastInLineArr[lineIndex]) //the element is wider then the constraint - give it a separate line
395+
if (i >= lastInLineArr[lineIndex]
396+
) //the element is wider then the constraint - give it a separate line
375397
{
376398
//switch to next line which only contain one element
377399
ArrangeLine(new FlexLineInfo
@@ -390,6 +412,7 @@ protected override Size ArrangeOverride(Size arrangeSize)
390412
lineIndex++;
391413
itemsU = 0;
392414
}
415+
393416
firstInLine = i;
394417
}
395418
}
@@ -420,6 +443,10 @@ private void ArrangeLine(FlexLineInfo lineInfo)
420443
{
421444
var isHorizontal = FlexDirection == FlexDirection.Row || FlexDirection == FlexDirection.RowReverse;
422445
var isReverse = FlexDirection == FlexDirection.RowReverse || FlexDirection == FlexDirection.ColumnReverse;
446+
var itemCount = lineInfo.ItemEndIndex - lineInfo.ItemStartIndex;
447+
var children = InternalChildren;
448+
var lineFreeU = lineInfo.LineU - lineInfo.ItemsU;
449+
var constraintFreeU = _uvConstraint.U - lineInfo.ItemsU;
423450

424451
// calculate initial u
425452
var u = .0;
@@ -439,43 +466,120 @@ private void ArrangeLine(FlexLineInfo lineInfo)
439466
{
440467
u = JustifyContent switch
441468
{
442-
FlexContentJustify.FlexEnd => lineInfo.LineU - lineInfo.ItemsU,
443-
FlexContentJustify.Center => (lineInfo.LineU - lineInfo.ItemsU) * 0.5,
469+
FlexContentJustify.FlexEnd => lineFreeU,
470+
FlexContentJustify.Center => lineFreeU * 0.5,
444471
_ => u
445472
};
446473
}
474+
447475
u *= lineInfo.ScaleU;
448476

449-
// calculate offset u
450-
var itemCount = lineInfo.ItemEndIndex - lineInfo.ItemStartIndex;
451-
var offsetUArr = new double[itemCount];
452-
if (JustifyContent == FlexContentJustify.SpaceBetween)
477+
// apply FlexGrow
478+
var flexGrowUArr = new double[itemCount];
479+
if (constraintFreeU > 0)
453480
{
454-
var freeItemU = (lineInfo.LineU - lineInfo.ItemsU) / (itemCount - 1);
455-
for (var i = 1; i < itemCount; i++)
481+
var ignoreFlexGrow = true;
482+
var flexGrowSum = .0;
483+
484+
for (var i = 0; i < itemCount; i++)
485+
{
486+
var flexGrow = GetFlexGrow(children[_orderList[i].Index]);
487+
ignoreFlexGrow &= MathHelper.IsVerySmall(flexGrow);
488+
flexGrowUArr[i] = flexGrow;
489+
flexGrowSum += flexGrow;
490+
}
491+
492+
if (!ignoreFlexGrow)
493+
{
494+
var flexGrowItem = .0;
495+
if (flexGrowSum > 0)
496+
{
497+
flexGrowItem = constraintFreeU / flexGrowSum;
498+
lineInfo.ScaleU = 1;
499+
lineFreeU = 0; //line free U was used up
500+
}
501+
502+
for (var i = 0; i < itemCount; i++)
503+
{
504+
flexGrowUArr[i] *= flexGrowItem;
505+
}
506+
}
507+
else
456508
{
457-
offsetUArr[i] = freeItemU;
509+
flexGrowUArr = new double[itemCount];
458510
}
459511
}
460-
else if (JustifyContent == FlexContentJustify.SpaceAround)
512+
513+
// apply FlexShrink
514+
var flexShrinkUArr = new double[itemCount];
515+
if (constraintFreeU < 0)
461516
{
462-
var freeItemU = (lineInfo.LineU - lineInfo.ItemsU) / itemCount * 0.5;
463-
offsetUArr[0] = freeItemU;
464-
for (var i = 1; i < itemCount; i++)
517+
var ignoreFlexShrink = true;
518+
var flexShrinkSum = .0;
519+
520+
for (var i = 0; i < itemCount; i++)
465521
{
466-
offsetUArr[i] = freeItemU * 2;
522+
var flexShrink = GetFlexShrink(children[_orderList[i].Index]);
523+
ignoreFlexShrink &= MathHelper.IsVerySmall(flexShrink - 1);
524+
flexShrinkUArr[i] = flexShrink;
525+
flexShrinkSum += flexShrink;
526+
}
527+
528+
if (!ignoreFlexShrink)
529+
{
530+
var flexShrinkItem = .0;
531+
if (flexShrinkSum > 0)
532+
{
533+
flexShrinkItem = constraintFreeU / flexShrinkSum;
534+
lineInfo.ScaleU = 1;
535+
lineFreeU = 0; //line free U was used up
536+
}
537+
538+
for (var i = 0; i < itemCount; i++)
539+
{
540+
flexShrinkUArr[i] *= flexShrinkItem;
541+
}
542+
}
543+
else
544+
{
545+
flexShrinkUArr = new double[itemCount];
467546
}
468547
}
469548

470-
var children = InternalChildren;
549+
// calculate offset u
550+
var offsetUArr = new double[itemCount];
551+
if (lineFreeU > 0)
552+
{
553+
if (JustifyContent == FlexContentJustify.SpaceBetween)
554+
{
555+
var freeItemU = lineFreeU / (itemCount - 1);
556+
for (var i = 1; i < itemCount; i++)
557+
{
558+
offsetUArr[i] = freeItemU;
559+
}
560+
}
561+
else if (JustifyContent == FlexContentJustify.SpaceAround)
562+
{
563+
var freeItemU = lineFreeU / itemCount * 0.5;
564+
offsetUArr[0] = freeItemU;
565+
for (var i = 1; i < itemCount; i++)
566+
{
567+
offsetUArr[i] = freeItemU * 2;
568+
}
569+
}
570+
}
571+
572+
// arrange item
471573
for (int i = lineInfo.ItemStartIndex, j = 0; i < lineInfo.ItemEndIndex; i++, j++)
472574
{
473575
var child = children[_orderList[i].Index];
474576
if (child == null) continue;
475577

476-
var childSize = new UVSize(FlexDirection, isHorizontal ?
477-
new Size(child.DesiredSize.Width * lineInfo.ScaleU, child.DesiredSize.Height) :
478-
new Size(child.DesiredSize.Width, child.DesiredSize.Height * lineInfo.ScaleU));
578+
var childSize = new UVSize(FlexDirection, isHorizontal
579+
? new Size(child.DesiredSize.Width * lineInfo.ScaleU, child.DesiredSize.Height)
580+
: new Size(child.DesiredSize.Width, child.DesiredSize.Height * lineInfo.ScaleU));
581+
582+
childSize.U += flexGrowUArr[j] + flexShrinkUArr[j];
479583

480584
if (isReverse)
481585
{
@@ -489,15 +593,7 @@ private void ArrangeLine(FlexLineInfo lineInfo)
489593

490594
var v = lineInfo.OffsetV;
491595
var alignSelf = GetAlignSelf(child);
492-
FlexItemsAlignment alignment;
493-
if (alignSelf == FlexItemAlignment.Auto)
494-
{
495-
alignment = AlignItems;
496-
}
497-
else
498-
{
499-
alignment = (FlexItemsAlignment)alignSelf;
500-
}
596+
var alignment = alignSelf == FlexItemAlignment.Auto ? AlignItems : (FlexItemsAlignment)alignSelf;
501597

502598
switch (alignment)
503599
{
@@ -510,6 +606,7 @@ private void ArrangeLine(FlexLineInfo lineInfo)
510606
{
511607
childSize.V = lineInfo.LineV;
512608
}
609+
513610
break;
514611
case FlexItemsAlignment.FlexEnd:
515612
v += lineInfo.LineV - childSize.V;

0 commit comments

Comments
 (0)