Skip to content

Commit c39ce3a

Browse files
committed
support for margin ignore-parent with not absolute children
1 parent d33b2e8 commit c39ce3a

File tree

1 file changed

+135
-21
lines changed

1 file changed

+135
-21
lines changed

h2d/Flow.hx

Lines changed: 135 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,8 @@ class FlowProperties {
177177
**/
178178
public var lineBreak = false;
179179

180+
var calcPadding : Float;
181+
180182
/**
181183
When set, element will use the maximum size of non-autoSize elements as size constraint instead of current constraint on the parent flow.
182184
**/
@@ -1136,6 +1138,88 @@ class Flow extends Object {
11361138
return borderBottom = v;
11371139
}
11381140

1141+
inline function propAt(i: Int) {
1142+
return properties[ reverse ? children.length - i - 1 : i ];
1143+
}
1144+
1145+
function onBorderLR(p : FlowProperties, dir : FlowAlign) {
1146+
var halign = horizontalAlign ?? Left;
1147+
var align = p.horizontalAlign ?? halign;
1148+
var ok = true;
1149+
if( align == Middle ) {
1150+
// middle : should not have any on that dir
1151+
for( p2 in properties ) {
1152+
if( !p2.isAbsolute && p != p2 && (p2.horizontalAlign ?? halign) == dir ) {
1153+
ok = false;
1154+
break;
1155+
}
1156+
}
1157+
} else if( align != dir ) {
1158+
// should not have other align
1159+
for( p2 in properties ) {
1160+
if( !p2.isAbsolute && p != p2 && (p2.horizontalAlign ?? halign) != align ) {
1161+
ok = false;
1162+
break;
1163+
}
1164+
}
1165+
}
1166+
if( !ok )
1167+
return false;
1168+
// should be first/last of that align
1169+
var isLeft = dir == Left;
1170+
for( i in 0...children.length ) {
1171+
var p2 = propAt(isLeft ? i : children.length - 1 - i);
1172+
if( p2 == p )
1173+
break;
1174+
if( p2.isAbsolute ) continue;
1175+
var al = p2.horizontalAlign ?? halign;
1176+
if( al == align ) {
1177+
ok = false;
1178+
break;
1179+
}
1180+
}
1181+
return ok;
1182+
}
1183+
1184+
function onBorderTB(p : FlowProperties, dir : FlowAlign) {
1185+
var valign = verticalAlign ?? Bottom;
1186+
var align = p.verticalAlign ?? valign;
1187+
var ok = true;
1188+
if( align == Middle ) {
1189+
// middle : should not have any on that dir
1190+
for( p2 in properties ) {
1191+
if( !p2.isAbsolute && p != p2 && (p2.verticalAlign ?? valign) == dir ) {
1192+
ok = false;
1193+
break;
1194+
}
1195+
}
1196+
} else if( align != dir ) {
1197+
// should not have other align
1198+
for( p2 in properties ) {
1199+
if( !p2.isAbsolute && p != p2 && (p2.verticalAlign ?? valign) != align ) {
1200+
ok = false;
1201+
break;
1202+
}
1203+
}
1204+
}
1205+
if( !ok )
1206+
return false;
1207+
// should be first/last of that align
1208+
var isTop = dir == Top;
1209+
for( i in 0...children.length ) {
1210+
var p2 = propAt(isTop ? i : children.length - 1 - i);
1211+
if( p2 == p )
1212+
break;
1213+
if( p2.isAbsolute ) continue;
1214+
var al = p2.verticalAlign ?? valign;
1215+
if( al == align ) {
1216+
ok = false;
1217+
break;
1218+
}
1219+
}
1220+
return ok;
1221+
}
1222+
11391223
/**
11401224
Call to force all flowed elements position to be updated.
11411225
See `Flow.needReflow` for more information.
@@ -1185,9 +1269,6 @@ class Flow extends Object {
11851269
inline function childAt(i: Int) {
11861270
return children[ reverse ? children.length - i - 1 : i ];
11871271
}
1188-
inline function propAt(i: Int) {
1189-
return properties[ reverse ? children.length - i - 1 : i ];
1190-
}
11911272

11921273
inline function forChildren(func : Int->FlowProperties->h2d.Object->Void, absolute=false) {
11931274
for( i in 0...children.length ) {
@@ -1210,6 +1291,11 @@ class Flow extends Object {
12101291
if( realMinHeight >= 0 && ch < realMinHeight ) ch = realMinHeight;
12111292
}
12121293

1294+
var paddingLeft = getPad(paddingLeft,0);
1295+
var paddingRight = getPad(paddingRight,0);
1296+
var paddingTop = getPad(paddingTop,0);
1297+
var paddingBottom = getPad(paddingBottom,0);
1298+
12131299
switch(layout) {
12141300
case Horizontal:
12151301
var halign = horizontalAlign == null ? Left : horizontalAlign;
@@ -1262,20 +1348,34 @@ class Flow extends Object {
12621348
var autoWidth = maxInWidth;
12631349
var autoSum = 0.0;
12641350

1265-
inline function calcSize(p : FlowProperties, c : h2d.Object) {
1266-
var pw = getPad(p.paddingLeft,paddingLeft) + getPad(p.paddingRight,paddingRight);
1351+
inline function calcSize(p : FlowProperties, c : h2d.Object, isAbsolute=false) {
12671352
var ph = getPad(p.paddingTop,paddingTop) + getPad(p.paddingBottom,paddingBottom);
1353+
var pw;
1354+
if( isAbsolute )
1355+
pw = getPad(p.paddingLeft,paddingLeft) + getPad(p.paddingRight,paddingRight);
1356+
else {
1357+
pw = 0;
1358+
if( p.paddingLeft != PADDING_IGNORE_PARENT )
1359+
pw += p.paddingLeft;
1360+
else if( onBorderLR(p,Left) )
1361+
pw -= paddingLeft;
1362+
p.calcPadding = pw;
1363+
if( p.paddingRight != PADDING_IGNORE_PARENT )
1364+
pw += p.paddingRight;
1365+
else if( onBorderLR(p,Right) )
1366+
pw -= paddingRight;
1367+
}
12681368
inline function scaleX(v:Float) return (v - pw) / Math.abs(c.scaleX);
12691369
inline function scaleY(v:Float) return (v - ph) / Math.abs(c.scaleY);
12701370

12711371
var ccw = -1., cch = -1.;
1272-
if( p.autoSizeWidth != null && (isConstraintWidth || p.isAbsolute) )
1372+
if( p.autoSizeWidth != null && (isConstraintWidth || isAbsolute) )
12731373
ccw = scaleX(flowFloor(p.isAbsolute ? cw * p.autoSizeWidth : autoWidth * p.autoSizeWidth / autoSum));
12741374
else if( isConstraintWidth && !p.isAbsolute )
12751375
ccw = scaleX(maxInWidth);
1276-
if( p.autoSizeHeight != null && (isConstraintHeight || p.isAbsolute) )
1376+
if( p.autoSizeHeight != null && (isConstraintHeight || isAbsolute) )
12771377
cch = scaleY(p.isAbsolute ? ch * p.autoSizeHeight : hxd.Math.imax(maxLineHeight, minLineHeight) * p.autoSizeHeight);
1278-
else if( isConstraintHeight && !p.isAbsolute )
1378+
else if( isConstraintHeight && !isAbsolute )
12791379
cch = scaleY(maxInHeight);
12801380
c.constraintSize(ccw, cch);
12811381

@@ -1304,7 +1404,7 @@ class Flow extends Object {
13041404

13051405
// position all not absolute nodes
13061406
forChildren(function(i, p, c) {
1307-
if( p.autoSizeWidth != null || p.autoSizeHeight != null )
1407+
if( p.autoSizeWidth != null )
13081408
calcSize(p, c);
13091409
var br = false;
13101410
if( ((multiline && x - startX + p.calculatedWidth > maxInWidth) || p.lineBreak) && x - startX > 0 ) {
@@ -1315,7 +1415,7 @@ class Flow extends Object {
13151415
x = startX;
13161416
}
13171417
p.isBreak = br;
1318-
c.x = x + p.offsetY + getPad(p.paddingLeft,paddingLeft);
1418+
c.x = x + p.offsetY + p.calcPadding;
13191419
x += p.calculatedWidth;
13201420
if( x > cw ) cw = x;
13211421
x += horizontalSpacing;
@@ -1329,7 +1429,7 @@ class Flow extends Object {
13291429
applyMinMax();
13301430

13311431
// update size of absolute nodes before alignment
1332-
forChildren(function(i, p, c) if( p.autoSizeWidth != null || p.autoSizeHeight != null || p.horizontalAlign != null || p.verticalAlign != null ) calcSize(p, c), true);
1432+
forChildren(function(i, p, c) if( p.autoSizeWidth != null || p.autoSizeHeight != null || p.horizontalAlign != null || p.verticalAlign != null ) calcSize(p, c, true), true);
13331433

13341434
// align absolutes based on entire size
13351435
lastIndex = 0;
@@ -1392,7 +1492,7 @@ class Flow extends Object {
13921492
px = xmin;
13931493
xmin += p.calculatedWidth + horizontalSpacing;
13941494
}
1395-
c.x = px + p.offsetX + getPad(p.paddingLeft,paddingLeft);
1495+
c.x = px + p.offsetX + p.calcPadding;
13961496
}
13971497

13981498
case Vertical:
@@ -1446,20 +1546,34 @@ class Flow extends Object {
14461546
var autoHeight = maxInHeight;
14471547
var autoSum = 0.0;
14481548

1449-
inline function calcSize(p : FlowProperties, c : h2d.Object) {
1549+
inline function calcSize(p : FlowProperties, c : h2d.Object, isAbsolute=false) {
14501550
var pw = getPad(p.paddingLeft,paddingLeft) + getPad(p.paddingRight,paddingRight);
1451-
var ph = getPad(p.paddingTop,paddingTop) + getPad(p.paddingBottom,paddingBottom);
1551+
var ph;
1552+
if( isAbsolute )
1553+
ph = getPad(p.paddingTop,paddingTop) + getPad(p.paddingBottom,paddingBottom);
1554+
else {
1555+
ph = 0;
1556+
if( p.paddingTop != PADDING_IGNORE_PARENT )
1557+
ph += p.paddingTop;
1558+
else if( onBorderTB(p,Top) )
1559+
ph -= paddingTop;
1560+
p.calcPadding = ph;
1561+
if( p.paddingBottom != PADDING_IGNORE_PARENT )
1562+
ph += p.paddingBottom;
1563+
else if( onBorderTB(p,Bottom) )
1564+
ph -= paddingBottom;
1565+
}
14521566
inline function scaleX(v:Float) return (v - pw) / Math.abs(c.scaleX);
14531567
inline function scaleY(v:Float) return (v - ph) / Math.abs(c.scaleY);
14541568

14551569
var ccw = -1., cch = -1.;
14561570
if( p.autoSizeWidth != null )
1457-
ccw = scaleX(p.isAbsolute ? cw * p.autoSizeWidth : hxd.Math.imax(maxColWidth, minColWidth) * p.autoSizeWidth);
1458-
else if( isConstraintWidth && !p.isAbsolute )
1571+
ccw = scaleX(isAbsolute ? cw * p.autoSizeWidth : hxd.Math.imax(maxColWidth, minColWidth) * p.autoSizeWidth);
1572+
else if( isConstraintWidth && !isAbsolute )
14591573
ccw = scaleX(maxInWidth);
14601574
if( p.autoSizeHeight != null )
14611575
cch = scaleY(flowFloor(p.isAbsolute ? ch * p.autoSizeHeight : autoHeight * p.autoSizeHeight / autoSum));
1462-
else if( isConstraintHeight && !p.isAbsolute )
1576+
else if( isConstraintHeight && !isAbsolute )
14631577
cch = scaleY(maxInHeight);
14641578
c.constraintSize(ccw, cch);
14651579

@@ -1488,7 +1602,7 @@ class Flow extends Object {
14881602

14891603
// position all not absolute nodes
14901604
forChildren(function(i, p, c) {
1491-
if( p.autoSizeWidth != null || p.autoSizeHeight != null )
1605+
if( p.autoSizeHeight != null )
14921606
calcSize(p, c);
14931607
var br = false;
14941608
if( ((multiline && y - startY + p.calculatedHeight > maxInHeight) || p.lineBreak) && y - startY > 0 ) {
@@ -1499,7 +1613,7 @@ class Flow extends Object {
14991613
y = startY;
15001614
}
15011615
p.isBreak = br;
1502-
c.y = y + p.offsetY + getPad(p.paddingTop,paddingTop);
1616+
c.y = y + p.offsetY + p.calcPadding;
15031617
y += p.calculatedHeight;
15041618
if( y > ch ) ch = y;
15051619
y += verticalSpacing;
@@ -1513,7 +1627,7 @@ class Flow extends Object {
15131627
applyMinMax();
15141628

15151629
// update size of absolute nodes before alignment
1516-
forChildren(function(i, p, c) if( p.autoSizeWidth != null || p.autoSizeHeight != null || p.horizontalAlign != null || p.verticalAlign != null ) calcSize(p, c), true);
1630+
forChildren(function(i, p, c) if( p.autoSizeWidth != null || p.autoSizeHeight != null || p.horizontalAlign != null || p.verticalAlign != null ) calcSize(p, c, true), true);
15171631

15181632
// align absolutes based on entire size
15191633
lastIndex = 0;
@@ -1577,7 +1691,7 @@ class Flow extends Object {
15771691
py = ymin;
15781692
ymin += p.calculatedHeight + verticalSpacing;
15791693
}
1580-
c.y = py + p.offsetY + getPad(p.paddingTop,paddingTop);
1694+
c.y = py + p.offsetY + p.calcPadding;
15811695
}
15821696
case Stack:
15831697
var halign = horizontalAlign == null ? Left : horizontalAlign;

0 commit comments

Comments
 (0)