@@ -154,6 +154,8 @@ extension WidgetsExt on Widget {
154154 bool translateConstraint = false ,
155155 double widthPercent = 1 ,
156156 double heightPercent = 1 ,
157+ PercentageAnchor widthPercentageAnchor = PercentageAnchor .constraint,
158+ PercentageAnchor heightPercentageAnchor = PercentageAnchor .constraint,
157159 double horizontalBias = 0.5 ,
158160 double verticalBias = 0.5 ,
159161 @_wrapperConstraint ConstraintId ? topLeftTo,
@@ -189,6 +191,8 @@ extension WidgetsExt on Widget {
189191 translateConstraint: translateConstraint,
190192 widthPercent: widthPercent,
191193 heightPercent: heightPercent,
194+ widthPercentageAnchor: widthPercentageAnchor,
195+ heightPercentageAnchor: heightPercentageAnchor,
192196 horizontalBias: horizontalBias,
193197 verticalBias: verticalBias,
194198 topLeftTo: topLeftTo,
@@ -272,6 +276,11 @@ enum BarrierDirection {
272276 bottom,
273277}
274278
279+ enum PercentageAnchor {
280+ constraint,
281+ parent,
282+ }
283+
275284class ConstraintId {
276285 String ? name;
277286
@@ -390,6 +399,10 @@ class Constraint {
390399 /// Only takes effect when height is matchConstraint
391400 final double heightPercent;
392401
402+ final PercentageAnchor widthPercentageAnchor;
403+
404+ final PercentageAnchor heightPercentageAnchor;
405+
393406 /// Only takes effect if both left and right constraints exist
394407 final double horizontalBias;
395408
@@ -439,6 +452,8 @@ class Constraint {
439452 this .translateConstraint = false ,
440453 this .widthPercent = 1 ,
441454 this .heightPercent = 1 ,
455+ this .widthPercentageAnchor = PercentageAnchor .constraint,
456+ this .heightPercentageAnchor = PercentageAnchor .constraint,
442457 this .horizontalBias = 0.5 ,
443458 this .verticalBias = 0.5 ,
444459 @_wrapperConstraint this .topLeftTo,
@@ -477,6 +492,8 @@ class Constraint {
477492 translateConstraint == other.translateConstraint &&
478493 widthPercent == other.widthPercent &&
479494 heightPercent == other.heightPercent &&
495+ widthPercentageAnchor == other.widthPercentageAnchor &&
496+ heightPercentageAnchor == other.heightPercentageAnchor &&
480497 horizontalBias == other.horizontalBias &&
481498 verticalBias == other.verticalBias &&
482499 topLeftTo == other.topLeftTo &&
@@ -511,6 +528,8 @@ class Constraint {
511528 translateConstraint.hashCode ^
512529 widthPercent.hashCode ^
513530 heightPercent.hashCode ^
531+ widthPercentageAnchor.hashCode ^
532+ heightPercentageAnchor.hashCode ^
514533 horizontalBias.hashCode ^
515534 verticalBias.hashCode ^
516535 topLeftTo.hashCode ^
@@ -759,6 +778,16 @@ class Constraint {
759778 needsLayout = true ;
760779 }
761780
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+
762791 if (parentData.horizontalBias != horizontalBias) {
763792 parentData.horizontalBias = horizontalBias;
764793 needsLayout = true ;
@@ -818,6 +847,8 @@ class _ConstraintBoxData extends ContainerBoxParentData<RenderBox> {
818847 bool ? translateConstraint;
819848 double ? widthPercent;
820849 double ? heightPercent;
850+ PercentageAnchor ? widthPercentageAnchor;
851+ PercentageAnchor ? heightPercentageAnchor;
821852 double ? horizontalBias;
822853 double ? verticalBias;
823854}
@@ -1329,29 +1360,34 @@ class _ConstraintRenderBox extends RenderBox
13291360 }());
13301361 maxWidth = minWidth;
13311362 } 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;
13511387 } else {
1352- right -= _getRightInsets (margin);
1388+ minWidth = (size.width - _getHorizontalInsets (margin)) *
1389+ element.widthPercent;
13531390 }
1354- minWidth = (right - left) * element.widthPercent;
13551391 assert (() {
13561392 if (_debugCheckConstraints) {
13571393 if (minWidth < 0 ) {
@@ -1384,29 +1420,34 @@ class _ConstraintRenderBox extends RenderBox
13841420 }());
13851421 maxHeight = minHeight;
13861422 } 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;
14061447 } else {
1407- bottom -= _getBottomInsets (margin);
1448+ minHeight = (size.height - _getVerticalInsets (margin)) *
1449+ element.heightPercent;
14081450 }
1409- minHeight = (bottom - top) * element.heightPercent;
14101451 assert (() {
14111452 if (_debugCheckConstraints) {
14121453 if (minHeight < 0 ) {
@@ -1800,6 +1841,12 @@ class _ConstrainedNode {
18001841
18011842 double get heightPercent => parentData.heightPercent! ;
18021843
1844+ PercentageAnchor get widthPercentageAnchor =>
1845+ parentData.widthPercentageAnchor! ;
1846+
1847+ PercentageAnchor get heightPercentageAnchor =>
1848+ parentData.heightPercentageAnchor! ;
1849+
18031850 set offset (Offset value) {
18041851 parentData.offset = value;
18051852 }
0 commit comments