From d81ec90c5ffb729255c6d4cc1a4772efa6f0e0c3 Mon Sep 17 00:00:00 2001 From: Hixie Date: Fri, 21 Aug 2015 15:29:15 -0700 Subject: [PATCH] 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. --- packages/flutter/lib/rendering/box.dart | 1 + packages/flutter/lib/rendering/flex.dart | 99 +++++++++++++--------- packages/flutter/lib/rendering/object.dart | 12 ++- 3 files changed, 68 insertions(+), 44 deletions(-) diff --git a/packages/flutter/lib/rendering/box.dart b/packages/flutter/lib/rendering/box.dart index e9ce2a3572..e5fde90979 100644 --- a/packages/flutter/lib/rendering/box.dart +++ b/packages/flutter/lib/rendering/box.dart @@ -396,6 +396,7 @@ abstract class RenderBox extends RenderObject { assert(value._owner.parent == this); } _size = inDebugBuild ? new _DebugSize(value, this, debugCanParentUseSize) : value; + assert(debugDoesMeetConstraints()); } void applyPaintTransform(Matrix4 transform) { diff --git a/packages/flutter/lib/rendering/flex.dart b/packages/flutter/lib/rendering/flex.dart index ebc985eb1a..a546f96fec 100644 --- a/packages/flutter/lib/rendering/flex.dart +++ b/packages/flutter/lib/rendering/flex.dart @@ -85,7 +85,6 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin _textBaseline; void set textBaseline (TextBaseline value) { @@ -95,6 +94,7 @@ class RenderFlex extends RenderBox with ContainerRenderObjectMixin 0) { - context.canvas.save(); - context.canvas.clipRect(offset & size); + if (_overflow <= 0.0) { defaultPaint(context, offset); - context.canvas.restore(); - } else { - defaultPaint(context, offset); - } - } - - void debugPaintSize(PaintingContext context, Offset offset) { - super.debugPaintSize(context, offset); - if (_overflow <= 0) return; - - // Draw a red rectangle over the overflow area in debug mode - // You should be using a Clip if you want to clip your children - Paint paint = new Paint()..color = const Color(0x7FFF0000); - Rect overflowRect; - switch(direction) { - case FlexDirection.horizontal: - overflowRect = offset + new Offset(size.width, 0.0) & - new Size(_overflow, size.height); - break; - case FlexDirection.vertical: - overflowRect = offset + new Offset(0.0, size.height) & - new Size(size.width, _overflow); - break; } - context.canvas.drawRect(overflowRect, paint); + + // We have overflow. Clip it. + context.canvas.save(); + context.canvas.clipRect(offset & size); + defaultPaint(context, offset); + context.canvas.restore(); + assert(() { + // 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. + + // If you do want clipping, use a RenderClip (Clip in the + // Widgets library). + + Paint markerPaint = new Paint()..color = const Color(0xE0FF0000); + Paint highlightPaint = new Paint()..color = const Color(0x7FFF0000); + const kMarkerSize = 0.1; + Rect markerRect, overflowRect; + switch(direction) { + 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) & + new Size(_overflow, size.height); + break; + 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) & + new Size(size.width, _overflow); + break; + } + 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; + } + } diff --git a/packages/flutter/lib/rendering/object.dart b/packages/flutter/lib/rendering/object.dart index 6099e29715..ebc6388988 100644 --- a/packages/flutter/lib/rendering/object.dart +++ b/packages/flutter/lib/rendering/object.dart @@ -738,6 +738,13 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { String toString([String prefix = '']) { RenderObject debugPreviousActiveLayout = _debugActiveLayout; _debugActiveLayout = null; + String header = toStringName(); + prefix += ' '; + String result = '${header}\n${debugDescribeSettings(prefix)}${debugDescribeChildren(prefix)}'; + _debugActiveLayout = debugPreviousActiveLayout; + return result; + } + String toStringName() { String header = '${runtimeType}'; if (_relayoutSubtreeRoot != null && _relayoutSubtreeRoot != this) { int count = 1; @@ -752,10 +759,7 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { header += ' NEEDS-LAYOUT'; if (!attached) header += ' DETACHED'; - prefix += ' '; - String result = '${header}\n${debugDescribeSettings(prefix)}${debugDescribeChildren(prefix)}'; - _debugActiveLayout = debugPreviousActiveLayout; - return result; + return header; } String debugDescribeSettings(String prefix) => '${prefix}parentData: ${parentData}\n${prefix}constraints: ${constraints}\n'; String debugDescribeChildren(String prefix) => '';