@@ -154,6 +154,8 @@ extension WidgetsExt on Widget {
154
154
bool translateConstraint = false ,
155
155
double widthPercent = 1 ,
156
156
double heightPercent = 1 ,
157
+ PercentageAnchor widthPercentageAnchor = PercentageAnchor .constraint,
158
+ PercentageAnchor heightPercentageAnchor = PercentageAnchor .constraint,
157
159
double horizontalBias = 0.5 ,
158
160
double verticalBias = 0.5 ,
159
161
@_wrapperConstraint ConstraintId ? topLeftTo,
@@ -189,6 +191,8 @@ extension WidgetsExt on Widget {
189
191
translateConstraint: translateConstraint,
190
192
widthPercent: widthPercent,
191
193
heightPercent: heightPercent,
194
+ widthPercentageAnchor: widthPercentageAnchor,
195
+ heightPercentageAnchor: heightPercentageAnchor,
192
196
horizontalBias: horizontalBias,
193
197
verticalBias: verticalBias,
194
198
topLeftTo: topLeftTo,
@@ -272,6 +276,11 @@ enum BarrierDirection {
272
276
bottom,
273
277
}
274
278
279
+ enum PercentageAnchor {
280
+ constraint,
281
+ parent,
282
+ }
283
+
275
284
class ConstraintId {
276
285
String ? name;
277
286
@@ -390,6 +399,10 @@ class Constraint {
390
399
/// Only takes effect when height is matchConstraint
391
400
final double heightPercent;
392
401
402
+ final PercentageAnchor widthPercentageAnchor;
403
+
404
+ final PercentageAnchor heightPercentageAnchor;
405
+
393
406
/// Only takes effect if both left and right constraints exist
394
407
final double horizontalBias;
395
408
@@ -439,6 +452,8 @@ class Constraint {
439
452
this .translateConstraint = false ,
440
453
this .widthPercent = 1 ,
441
454
this .heightPercent = 1 ,
455
+ this .widthPercentageAnchor = PercentageAnchor .constraint,
456
+ this .heightPercentageAnchor = PercentageAnchor .constraint,
442
457
this .horizontalBias = 0.5 ,
443
458
this .verticalBias = 0.5 ,
444
459
@_wrapperConstraint this .topLeftTo,
@@ -477,6 +492,8 @@ class Constraint {
477
492
translateConstraint == other.translateConstraint &&
478
493
widthPercent == other.widthPercent &&
479
494
heightPercent == other.heightPercent &&
495
+ widthPercentageAnchor == other.widthPercentageAnchor &&
496
+ heightPercentageAnchor == other.heightPercentageAnchor &&
480
497
horizontalBias == other.horizontalBias &&
481
498
verticalBias == other.verticalBias &&
482
499
topLeftTo == other.topLeftTo &&
@@ -511,6 +528,8 @@ class Constraint {
511
528
translateConstraint.hashCode ^
512
529
widthPercent.hashCode ^
513
530
heightPercent.hashCode ^
531
+ widthPercentageAnchor.hashCode ^
532
+ heightPercentageAnchor.hashCode ^
514
533
horizontalBias.hashCode ^
515
534
verticalBias.hashCode ^
516
535
topLeftTo.hashCode ^
@@ -759,6 +778,16 @@ class Constraint {
759
778
needsLayout = true ;
760
779
}
761
780
781
+ if (parentData.widthPercentageAnchor != widthPercentageAnchor) {
782
+ parentData.widthPercentageAnchor = widthPercentageAnchor;
783
+ needsLayout = true ;
784
+ }
785
+
786
+ if (parentData.heightPercentageAnchor != heightPercentageAnchor) {
787
+ parentData.heightPercentageAnchor = heightPercentageAnchor;
788
+ needsLayout = true ;
789
+ }
790
+
762
791
if (parentData.horizontalBias != horizontalBias) {
763
792
parentData.horizontalBias = horizontalBias;
764
793
needsLayout = true ;
@@ -818,6 +847,8 @@ class _ConstraintBoxData extends ContainerBoxParentData<RenderBox> {
818
847
bool ? translateConstraint;
819
848
double ? widthPercent;
820
849
double ? heightPercent;
850
+ PercentageAnchor ? widthPercentageAnchor;
851
+ PercentageAnchor ? heightPercentageAnchor;
821
852
double ? horizontalBias;
822
853
double ? verticalBias;
823
854
}
@@ -1329,29 +1360,34 @@ class _ConstraintRenderBox extends RenderBox
1329
1360
}());
1330
1361
maxWidth = minWidth;
1331
1362
} else if (width == matchConstraint) {
1332
- double left;
1333
- if (element.leftAlignType == _AlignType .left) {
1334
- left = element.leftConstraint! .getX ();
1335
- } else {
1336
- left = element.leftConstraint! .getRight (size);
1337
- }
1338
- if (element.leftConstraint! .isNotLaidOut ()) {
1339
- left += _getLeftInsets (goneMargin);
1340
- } else {
1341
- left += _getLeftInsets (margin);
1342
- }
1343
- double right;
1344
- if (element.rightAlignType == _AlignType .left) {
1345
- right = element.rightConstraint! .getX ();
1346
- } else {
1347
- right = element.rightConstraint! .getRight (size);
1348
- }
1349
- if (element.rightConstraint! .isNotLaidOut ()) {
1350
- right -= _getRightInsets (goneMargin);
1363
+ if (element.widthPercentageAnchor == PercentageAnchor .constraint) {
1364
+ double left;
1365
+ if (element.leftAlignType == _AlignType .left) {
1366
+ left = element.leftConstraint! .getX ();
1367
+ } else {
1368
+ left = element.leftConstraint! .getRight (size);
1369
+ }
1370
+ if (element.leftConstraint! .isNotLaidOut ()) {
1371
+ left += _getLeftInsets (goneMargin);
1372
+ } else {
1373
+ left += _getLeftInsets (margin);
1374
+ }
1375
+ double right;
1376
+ if (element.rightAlignType == _AlignType .left) {
1377
+ right = element.rightConstraint! .getX ();
1378
+ } else {
1379
+ right = element.rightConstraint! .getRight (size);
1380
+ }
1381
+ if (element.rightConstraint! .isNotLaidOut ()) {
1382
+ right -= _getRightInsets (goneMargin);
1383
+ } else {
1384
+ right -= _getRightInsets (margin);
1385
+ }
1386
+ minWidth = (right - left) * element.widthPercent;
1351
1387
} else {
1352
- right -= _getRightInsets (margin);
1388
+ minWidth = (size.width - _getHorizontalInsets (margin)) *
1389
+ element.widthPercent;
1353
1390
}
1354
- minWidth = (right - left) * element.widthPercent;
1355
1391
assert (() {
1356
1392
if (_debugCheckConstraints) {
1357
1393
if (minWidth < 0 ) {
@@ -1384,29 +1420,34 @@ class _ConstraintRenderBox extends RenderBox
1384
1420
}());
1385
1421
maxHeight = minHeight;
1386
1422
} else if (height == matchConstraint) {
1387
- double top;
1388
- if (element.topAlignType == _AlignType .top) {
1389
- top = element.topConstraint! .getY ();
1390
- } else {
1391
- top = element.topConstraint! .getBottom (size);
1392
- }
1393
- if (element.topConstraint! .isNotLaidOut ()) {
1394
- top += _getTopInsets (goneMargin);
1395
- } else {
1396
- top += _getTopInsets (margin);
1397
- }
1398
- double bottom;
1399
- if (element.bottomAlignType == _AlignType .top) {
1400
- bottom = element.bottomConstraint! .getY ();
1401
- } else {
1402
- bottom = element.bottomConstraint! .getBottom (size);
1403
- }
1404
- if (element.bottomConstraint! .isNotLaidOut ()) {
1405
- bottom -= _getBottomInsets (goneMargin);
1423
+ if (element.heightPercentageAnchor == PercentageAnchor .constraint) {
1424
+ double top;
1425
+ if (element.topAlignType == _AlignType .top) {
1426
+ top = element.topConstraint! .getY ();
1427
+ } else {
1428
+ top = element.topConstraint! .getBottom (size);
1429
+ }
1430
+ if (element.topConstraint! .isNotLaidOut ()) {
1431
+ top += _getTopInsets (goneMargin);
1432
+ } else {
1433
+ top += _getTopInsets (margin);
1434
+ }
1435
+ double bottom;
1436
+ if (element.bottomAlignType == _AlignType .top) {
1437
+ bottom = element.bottomConstraint! .getY ();
1438
+ } else {
1439
+ bottom = element.bottomConstraint! .getBottom (size);
1440
+ }
1441
+ if (element.bottomConstraint! .isNotLaidOut ()) {
1442
+ bottom -= _getBottomInsets (goneMargin);
1443
+ } else {
1444
+ bottom -= _getBottomInsets (margin);
1445
+ }
1446
+ minHeight = (bottom - top) * element.heightPercent;
1406
1447
} else {
1407
- bottom -= _getBottomInsets (margin);
1448
+ minHeight = (size.height - _getVerticalInsets (margin)) *
1449
+ element.heightPercent;
1408
1450
}
1409
- minHeight = (bottom - top) * element.heightPercent;
1410
1451
assert (() {
1411
1452
if (_debugCheckConstraints) {
1412
1453
if (minHeight < 0 ) {
@@ -1800,6 +1841,12 @@ class _ConstrainedNode {
1800
1841
1801
1842
double get heightPercent => parentData.heightPercent! ;
1802
1843
1844
+ PercentageAnchor get widthPercentageAnchor =>
1845
+ parentData.widthPercentageAnchor! ;
1846
+
1847
+ PercentageAnchor get heightPercentageAnchor =>
1848
+ parentData.heightPercentageAnchor! ;
1849
+
1803
1850
set offset (Offset value) {
1804
1851
parentData.offset = value;
1805
1852
}
0 commit comments