Commit d81ec90c authored by Hixie's avatar Hixie

Reimplement 'stretch' for flexible items correctly.

Fixes #698 to actually work.
Also, adds some debugging aids around Flex.
And a test to check this fix.
parent ca42e886
...@@ -396,6 +396,7 @@ abstract class RenderBox extends RenderObject { ...@@ -396,6 +396,7 @@ abstract class RenderBox extends RenderObject {
assert(value._owner.parent == this); assert(value._owner.parent == this);
} }
_size = inDebugBuild ? new _DebugSize(value, this, debugCanParentUseSize) : value; _size = inDebugBuild ? new _DebugSize(value, this, debugCanParentUseSize) : value;
assert(debugDoesMeetConstraints());
} }
void applyPaintTransform(Matrix4 transform) { void applyPaintTransform(Matrix4 transform) {
......
...@@ -85,7 +85,6 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -85,7 +85,6 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
} }
} }
// Set during layout if overflow occurred on the main axis
TextBaseline _textBaseline; TextBaseline _textBaseline;
TextBaseline get textBaseline => _textBaseline; TextBaseline get textBaseline => _textBaseline;
void set textBaseline (TextBaseline value) { void set textBaseline (TextBaseline value) {
...@@ -95,6 +94,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -95,6 +94,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
} }
} }
// Set during layout if overflow occurred on the main axis
double _overflow; double _overflow;
void setupParentData(RenderBox child) { void setupParentData(RenderBox child) {
...@@ -344,29 +344,29 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -344,29 +344,29 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
if (alignItems == FlexAlignItems.stretch) { if (alignItems == FlexAlignItems.stretch) {
switch (_direction) { switch (_direction) {
case FlexDirection.horizontal: case FlexDirection.horizontal:
innerConstraints = new BoxConstraints(minWidth: constraints.maxWidth, innerConstraints = new BoxConstraints(minWidth: spaceForChild,
maxWidth: constraints.maxWidth, maxWidth: spaceForChild,
minHeight: constraints.minHeight, minHeight: constraints.maxHeight,
maxHeight: constraints.maxHeight); maxHeight: constraints.maxHeight);
break; break;
case FlexDirection.vertical: case FlexDirection.vertical:
innerConstraints = new BoxConstraints(minWidth: constraints.minWidth, innerConstraints = new BoxConstraints(minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth, maxWidth: constraints.maxWidth,
minHeight: constraints.maxHeight, minHeight: spaceForChild,
maxHeight: constraints.maxHeight); maxHeight: spaceForChild);
break; break;
} }
} else { } else {
switch (_direction) { switch (_direction) {
case FlexDirection.horizontal: case FlexDirection.horizontal:
innerConstraints = new BoxConstraints(maxHeight: constraints.maxHeight, innerConstraints = new BoxConstraints(minWidth: spaceForChild,
minWidth: spaceForChild, maxWidth: spaceForChild,
maxWidth: spaceForChild); maxHeight: constraints.maxHeight);
break; break;
case FlexDirection.vertical: case FlexDirection.vertical:
innerConstraints = new BoxConstraints(minHeight: spaceForChild, innerConstraints = new BoxConstraints(maxWidth: constraints.maxWidth,
maxHeight: spaceForChild, minHeight: spaceForChild,
maxWidth: constraints.maxWidth); maxHeight: spaceForChild);
break; break;
} }
} }
...@@ -467,35 +467,54 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl ...@@ -467,35 +467,54 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin<RenderBox, Fl
} }
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (_overflow > 0) { if (_overflow <= 0.0) {
defaultPaint(context, offset);
return;
}
// We have overflow. Clip it.
context.canvas.save(); context.canvas.save();
context.canvas.clipRect(offset & size); context.canvas.clipRect(offset & size);
defaultPaint(context, offset); defaultPaint(context, offset);
context.canvas.restore(); context.canvas.restore();
} else { assert(() {
defaultPaint(context, offset); // In debug mode, if you have overflow, we highlight where the
} // overflow would be by painting that area red. Since that is
} // likely to be clipped by an ancestor, we also draw a thick red
// line at the edge that's overflowing.
void debugPaintSize(PaintingContext context, Offset offset) {
super.debugPaintSize(context, offset); // If you do want clipping, use a RenderClip (Clip in the
if (_overflow <= 0) // Widgets library).
return;
Paint markerPaint = new Paint()..color = const Color(0xE0FF0000);
// Draw a red rectangle over the overflow area in debug mode Paint highlightPaint = new Paint()..color = const Color(0x7FFF0000);
// You should be using a Clip if you want to clip your children const kMarkerSize = 0.1;
Paint paint = new Paint()..color = const Color(0x7FFF0000); Rect markerRect, overflowRect;
Rect overflowRect;
switch(direction) { switch(direction) {
case FlexDirection.horizontal: case FlexDirection.horizontal:
markerRect = offset + new Offset(size.width * (1.0 - kMarkerSize), 0.0) &
new Size(size.width * kMarkerSize, size.height);
overflowRect = offset + new Offset(size.width, 0.0) & overflowRect = offset + new Offset(size.width, 0.0) &
new Size(_overflow, size.height); new Size(_overflow, size.height);
break; break;
case FlexDirection.vertical: case FlexDirection.vertical:
markerRect = offset + new Offset(0.0, size.height * (1.0 - kMarkerSize)) &
new Size(size.width, size.height * kMarkerSize);
overflowRect = offset + new Offset(0.0, size.height) & overflowRect = offset + new Offset(0.0, size.height) &
new Size(size.width, _overflow); new Size(size.width, _overflow);
break; break;
} }
context.canvas.drawRect(overflowRect, paint); context.canvas.drawRect(markerRect, markerPaint);
context.canvas.drawRect(overflowRect, highlightPaint);
return true;
});
} }
String toStringName() {
String header = super.toStringName();
if (_overflow > 0.0)
header += ' OVERFLOWING';
return header;
}
} }
...@@ -738,6 +738,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -738,6 +738,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
String toString([String prefix = '']) { String toString([String prefix = '']) {
RenderObject debugPreviousActiveLayout = _debugActiveLayout; RenderObject debugPreviousActiveLayout = _debugActiveLayout;
_debugActiveLayout = null; _debugActiveLayout = null;
String header = toStringName();
prefix += ' ';
String result = '${header}\n${debugDescribeSettings(prefix)}${debugDescribeChildren(prefix)}';
_debugActiveLayout = debugPreviousActiveLayout;
return result;
}
String toStringName() {
String header = '${runtimeType}'; String header = '${runtimeType}';
if (_relayoutSubtreeRoot != null && _relayoutSubtreeRoot != this) { if (_relayoutSubtreeRoot != null && _relayoutSubtreeRoot != this) {
int count = 1; int count = 1;
...@@ -752,10 +759,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { ...@@ -752,10 +759,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget {
header += ' NEEDS-LAYOUT'; header += ' NEEDS-LAYOUT';
if (!attached) if (!attached)
header += ' DETACHED'; header += ' DETACHED';
prefix += ' '; return header;
String result = '${header}\n${debugDescribeSettings(prefix)}${debugDescribeChildren(prefix)}';
_debugActiveLayout = debugPreviousActiveLayout;
return result;
} }
String debugDescribeSettings(String prefix) => '${prefix}parentData: ${parentData}\n${prefix}constraints: ${constraints}\n'; String debugDescribeSettings(String prefix) => '${prefix}parentData: ${parentData}\n${prefix}constraints: ${constraints}\n';
String debugDescribeChildren(String prefix) => ''; String debugDescribeChildren(String prefix) => '';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment