diff --git a/sky/packages/sky/lib/rendering/box.dart b/sky/packages/sky/lib/rendering/box.dart index e9ce2a3572b8a..e5fde90979f0c 100644 --- a/sky/packages/sky/lib/rendering/box.dart +++ b/sky/packages/sky/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/sky/packages/sky/lib/rendering/flex.dart b/sky/packages/sky/lib/rendering/flex.dart index ebc985eb1a237..a546f96fec7c1 100644 --- a/sky/packages/sky/lib/rendering/flex.dart +++ b/sky/packages/sky/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); - defaultPaint(context, offset); - context.canvas.restore(); - } else { + if (_overflow <= 0.0) { defaultPaint(context, offset); + return; } - } - void debugPaintSize(PaintingContext context, Offset offset) { - super.debugPaintSize(context, offset); - if (_overflow <= 0) - return; + // 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; + }); + } - // 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); + String toStringName() { + String header = super.toStringName(); + if (_overflow > 0.0) + header += ' OVERFLOWING'; + return header; } + } diff --git a/sky/packages/sky/lib/rendering/object.dart b/sky/packages/sky/lib/rendering/object.dart index 6099e29715532..ebc63889883b9 100644 --- a/sky/packages/sky/lib/rendering/object.dart +++ b/sky/packages/sky/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) => ''; diff --git a/sky/tests/widgets/flex-expected.txt b/sky/tests/widgets/flex-expected.txt new file mode 100644 index 0000000000000..3b78544c6b375 --- /dev/null +++ b/sky/tests/widgets/flex-expected.txt @@ -0,0 +1,68 @@ +TestRenderView enabled + +PAINT FOR FRAME #1 ---------------------------------------------- +1 | TestPaintingCanvas() constructor: 800.0 x 600.0 +------------------------------------------------------------------------ + +PAINT FOR FRAME #2 ---------------------------------------------- +2 | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | paintChild RenderPadding at Point(0.0, 0.0) +2 | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | paintChild RenderFlex at Point(50.0, 50.0) +2 | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | paintChild RenderPadding at Point(50.0, 50.0) +2 | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | paintChild RenderDecoratedBox at Point(54.0, 54.0) +2 | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffffffff), drawLooper:true)) +2 | | | | | paintChild RenderClipRRect at Point(54.0, 54.0) +2 | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | saveLayer(Rect.fromLTRB(54.0, 54.0, 354.0, 546.0), Paint(color:Color(0xff000000))) +2 | | | | | | clipRRect() +2 | | | | | | paintChild RenderConstrainedBox at Point(54.0, 54.0) +2 | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | paintChild RenderFlex at Point(54.0, 54.0) +2 | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | paintChild RenderParagraph at Point(54.0, 54.0) +2 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | translate(54.0, 54.0) +2 | | | | | | | | | translate(-54.0, -54.0) +2 | | | | | | | | paintChild RenderDecoratedBox at Point(54.0, 74.0) +2 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | drawRect(Rect.fromLTRB(54.0, 74.0, 354.0, 546.0), Paint(color:Color(0xff509050))) +2 | | | | | | | | | paintChild RenderFlex at Point(54.0, 74.0) +2 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | | paintChild RenderParagraph at Point(54.0, 74.0) +2 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | | | translate(54.0, 74.0) +2 | | | | | | | | | | | translate(-54.0, -74.0) +2 | | | | | | restore +2 | | | paintChild RenderPadding at Point(358.0, 50.0) +2 | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | paintChild RenderDecoratedBox at Point(362.0, 54.0) +2 | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | drawRRect(Instance of 'RRect', Paint(color:Color(0xffffffff), drawLooper:true)) +2 | | | | | paintChild RenderClipRRect at Point(362.0, 54.0) +2 | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | saveLayer(Rect.fromLTRB(362.0, 54.0, 662.0, 546.0), Paint(color:Color(0xff000000))) +2 | | | | | | clipRRect() +2 | | | | | | paintChild RenderConstrainedBox at Point(362.0, 54.0) +2 | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | paintChild RenderFlex at Point(362.0, 54.0) +2 | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | paintChild RenderDecoratedBox at Point(362.0, 54.0) +2 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | drawRect(Rect.fromLTRB(362.0, 54.0, 662.0, 526.0), Paint(color:Color(0xff509050))) +2 | | | | | | | | | paintChild RenderFlex at Point(362.0, 54.0) +2 | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | | paintChild RenderParagraph at Point(362.0, 54.0) +2 | | | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | | | translate(362.0, 54.0) +2 | | | | | | | | | | | translate(-362.0, -54.0) +2 | | | | | | | | paintChild RenderParagraph at Point(362.0, 526.0) +2 | | | | | | | | | TestPaintingCanvas() constructor: 800.0 x 600.0 +2 | | | | | | | | | translate(362.0, 526.0) +2 | | | | | | | | | translate(-362.0, -526.0) +2 | | | | | | restore +------------------------------------------------------------------------ +PAINTED 2 FRAMES diff --git a/sky/tests/widgets/flex.dart b/sky/tests/widgets/flex.dart new file mode 100644 index 0000000000000..4f9f55d5c2ffc --- /dev/null +++ b/sky/tests/widgets/flex.dart @@ -0,0 +1,69 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:sky/widgets.dart'; + +import '../resources/display_list.dart'; + +class TestApp extends App { + Widget build() { + return new Container( + padding: new EdgeDims.all(50.0), + child: new Flex([ + new Card( + child: new Container( + width: 300.0, + height: 500.0, + child: new Flex([ + new Text('TOP'), + new Flexible( + child: new Container( + decoration: new BoxDecoration(backgroundColor: new Color(0xFF509050)), + child: new Flex([new Text('bottom')], + direction: FlexDirection.vertical, + alignItems: FlexAlignItems.stretch + ) + ) + ) + ], + alignItems: FlexAlignItems.stretch, + direction: FlexDirection.vertical + ) + ) + ), + new Card( + child: new Container( + width: 300.0, + height: 500.0, + child: new Flex([ + new Flexible( + child: new Container( + decoration: new BoxDecoration(backgroundColor: new Color(0xFF509050)), + child: new Flex([new Text('top')], + direction: FlexDirection.vertical, + alignItems: FlexAlignItems.stretch + ) + ) + ), + new Text('BOTTOM') + ], + alignItems: FlexAlignItems.stretch, + direction: FlexDirection.vertical + ) + ) + ) + ], + direction: FlexDirection.horizontal + ) + ); + } +} + +main() async { + TestRenderView renderViewOverride = new TestRenderView(); + TestApp app = new TestApp(); + runApp(app, renderViewOverride: renderViewOverride); + await renderViewOverride.checkFrame(); + renderViewOverride.endTest(); +}