diff --git a/examples/widgets/scrollbar.dart b/examples/widgets/scrollbar.dart index 4e3ecc24048..dcbdc59985a 100644 --- a/examples/widgets/scrollbar.dart +++ b/examples/widgets/scrollbar.dart @@ -33,7 +33,8 @@ class ScrollbarAppState extends State { Widget scrollable = new Container( margin: new EdgeDims.symmetric(horizontal: 6.0), // TODO(hansmuller) 6.0 should be based on _kScrollbarThumbWidth child: new Center( - shrinkWrap: ShrinkWrap.both, + widthFactor: 1.0, + heightFactor: 1.0, child: new Container( width: 80.0, height: _itemExtent * 5.0, diff --git a/packages/flutter/lib/src/material/material_button.dart b/packages/flutter/lib/src/material/material_button.dart index 65eb954615f..e3044290efb 100644 --- a/packages/flutter/lib/src/material/material_button.dart +++ b/packages/flutter/lib/src/material/material_button.dart @@ -92,7 +92,7 @@ abstract class MaterialButtonState extends State { Widget contents = new Container( padding: new EdgeDims.symmetric(horizontal: 8.0), child: new Center( - shrinkWrap: ShrinkWrap.width, + widthFactor: 1.0, child: config.child ) ); diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 64a7902edd4..efb3cd60327 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -344,7 +344,7 @@ class Tab extends StatelessComponent { } Container centeredLabel = new Container( - child: new Center(child: labelContent, shrinkWrap: ShrinkWrap.both), + child: new Center(child: labelContent, widthFactor: 1.0, heightFactor: 1.0), constraints: new BoxConstraints(minWidth: _kMinTabWidth), padding: _kTabLabelPadding ); diff --git a/packages/flutter/lib/src/rendering/shifted_box.dart b/packages/flutter/lib/src/rendering/shifted_box.dart index f1b46ac9fb8..d4eb6af0cbc 100644 --- a/packages/flutter/lib/src/rendering/shifted_box.dart +++ b/packages/flutter/lib/src/rendering/shifted_box.dart @@ -143,13 +143,6 @@ class RenderPadding extends RenderShiftedBox { } } -enum ShrinkWrap { - width, - height, - both, - none -} - class RenderPositionedBox extends RenderShiftedBox { // This box aligns a child box within itself. It's only useful for @@ -161,12 +154,13 @@ class RenderPositionedBox extends RenderShiftedBox { RenderPositionedBox({ RenderBox child, FractionalOffset alignment: const FractionalOffset(0.5, 0.5), - ShrinkWrap shrinkWrap: ShrinkWrap.none + double widthFactor, + double heightFactor }) : _alignment = alignment, - _shrinkWrap = shrinkWrap, + _widthFactor = widthFactor, + _heightFactor = heightFactor, super(child) { assert(alignment != null); - assert(shrinkWrap != null); } FractionalOffset get alignment => _alignment; @@ -179,31 +173,40 @@ class RenderPositionedBox extends RenderShiftedBox { markNeedsLayout(); } - ShrinkWrap _shrinkWrap; - ShrinkWrap get shrinkWrap => _shrinkWrap; - void set shrinkWrap (ShrinkWrap value) { - assert(value != null); - if (_shrinkWrap == value) + double _widthFactor; + double get widthFactor => _widthFactor; + void set widthFactor (double value) { + if (_widthFactor == value) return; - _shrinkWrap = value; + _widthFactor = value; markNeedsLayout(); } - // These are only valid during performLayout() and paint(), since they rely on constraints which is only set after layout() is called. - bool get _shinkWrapWidth => _shrinkWrap == ShrinkWrap.width || _shrinkWrap == ShrinkWrap.both || constraints.maxWidth == double.INFINITY; - bool get _shinkWrapHeight => _shrinkWrap == ShrinkWrap.height || _shrinkWrap == ShrinkWrap.both || constraints.maxHeight == double.INFINITY; + double _heightFactor; + double get heightFactor => _heightFactor; + void set heightFactor (double value) { + if (_heightFactor == value) + return; + _heightFactor = value; + markNeedsLayout(); + } void performLayout() { + final bool shrinkWrapWidth = widthFactor != null || constraints.maxWidth == double.INFINITY; + final bool shrinkWrapHeight = heightFactor != null || constraints.maxHeight == double.INFINITY; + if (child != null) { child.layout(constraints.loosen(), parentUsesSize: true); - size = constraints.constrain(new Size(_shinkWrapWidth ? child.size.width : double.INFINITY, - _shinkWrapHeight ? child.size.height : double.INFINITY)); - Offset delta = size - child.size; + final Size desiredSize = new Size(child.size.width * (_widthFactor ?? 1.0), + child.size.height * (_heightFactor ?? 1.0)); + size = constraints.constrain(new Size(shrinkWrapWidth ? desiredSize.width : double.INFINITY, + shrinkWrapHeight ? desiredSize.height : double.INFINITY)); + final Offset delta = size - desiredSize; final BoxParentData childParentData = child.parentData; - childParentData.position = (delta.scale(_alignment.x, _alignment.y)).toPoint(); + childParentData.position = delta.scale(_alignment.x, _alignment.y).toPoint(); } else { - size = constraints.constrain(new Size(_shinkWrapWidth ? 0.0 : double.INFINITY, - _shinkWrapHeight ? 0.0 : double.INFINITY)); + size = constraints.constrain(new Size(shrinkWrapWidth ? 0.0 : double.INFINITY, + shrinkWrapHeight ? 0.0 : double.INFINITY)); } } diff --git a/packages/flutter/lib/src/widgets/basic.dart b/packages/flutter/lib/src/widgets/basic.dart index 1a21b2d30a8..a99e007081b 100644 --- a/packages/flutter/lib/src/widgets/basic.dart +++ b/packages/flutter/lib/src/widgets/basic.dart @@ -48,7 +48,6 @@ export 'package:flutter/rendering.dart' show Rect, ScrollDirection, Shape, - ShrinkWrap, Size, StyledTextSpan, TextAlign, @@ -238,26 +237,27 @@ class Align extends OneChildRenderObjectWidget { Align({ Key key, this.alignment: const FractionalOffset(0.5, 0.5), - this.shrinkWrap: ShrinkWrap.none, + this.widthFactor, + this.heightFactor, Widget child - }) : super(key: key, child: child) { - assert(shrinkWrap != null); - } + }) : super(key: key, child: child); final FractionalOffset alignment; - final ShrinkWrap shrinkWrap; + final double widthFactor; + final double heightFactor; - RenderPositionedBox createRenderObject() => new RenderPositionedBox(alignment: alignment, shrinkWrap: shrinkWrap); + RenderPositionedBox createRenderObject() => new RenderPositionedBox(alignment: alignment, widthFactor: widthFactor, heightFactor: heightFactor); void updateRenderObject(RenderPositionedBox renderObject, Align oldWidget) { renderObject.alignment = alignment; - renderObject.shrinkWrap = shrinkWrap; + renderObject.widthFactor = widthFactor; + renderObject.heightFactor = heightFactor; } } class Center extends Align { - Center({ Key key, ShrinkWrap shrinkWrap: ShrinkWrap.none, Widget child }) - : super(key: key, shrinkWrap: shrinkWrap, child: child); + Center({ Key key, widthFactor, heightFactor, Widget child }) + : super(key: key, widthFactor: widthFactor, heightFactor: heightFactor, child: child); } class CustomOneChildLayout extends OneChildRenderObjectWidget { diff --git a/packages/unit/test/rendering/positioned_box_test.dart b/packages/unit/test/rendering/positioned_box_test.dart index aaa783efc19..3b71b9159e2 100644 --- a/packages/unit/test/rendering/positioned_box_test.dart +++ b/packages/unit/test/rendering/positioned_box_test.dart @@ -21,22 +21,49 @@ void main() { additionalConstraints: new BoxConstraints.tight(new Size(100.0, 100.0)), child: new RenderDecoratedBox(decoration: new BoxDecoration()) ); - RenderPositionedBox positioner = new RenderPositionedBox(child: sizer, shrinkWrap: ShrinkWrap.width); + RenderPositionedBox positioner = new RenderPositionedBox(child: sizer, widthFactor: 1.0); layout(positioner, constraints: new BoxConstraints.loose(new Size(200.0, 200.0))); expect(positioner.size.width, equals(100.0), reason: "positioner width"); expect(positioner.size.height, equals(200.0), reason: "positioner height"); - positioner.shrinkWrap = ShrinkWrap.height; + positioner.widthFactor = null; + positioner.heightFactor = 1.0; pumpFrame(); expect(positioner.size.width, equals(200.0), reason: "positioner width"); expect(positioner.size.height, equals(100.0), reason: "positioner height"); - positioner.shrinkWrap = ShrinkWrap.both; + positioner.widthFactor = 1.0; pumpFrame(); expect(positioner.size.width, equals(100.0), reason: "positioner width"); expect(positioner.size.height, equals(100.0), reason: "positioner height"); }); + + test('RenderPositionedBox width and height factors', () { + RenderConstrainedBox sizer = new RenderConstrainedBox( + additionalConstraints: new BoxConstraints.tight(new Size(100.0, 100.0)), + child: new RenderDecoratedBox(decoration: new BoxDecoration()) + ); + RenderPositionedBox positioner = new RenderPositionedBox(child: sizer, widthFactor: 1.0, heightFactor: 0.0); + layout(positioner, constraints: new BoxConstraints.loose(new Size(200.0, 200.0))); + + expect(positioner.size.width, equals(100.0)); + expect(positioner.size.height, equals(0.0)); + + positioner.widthFactor = 0.5; + positioner.heightFactor = 0.5; + pumpFrame(); + + expect(positioner.size.width, equals(50.0)); + expect(positioner.size.height, equals(50.0)); + + positioner.widthFactor = null; + positioner.heightFactor = null; + pumpFrame(); + + expect(positioner.size.width, equals(200.0)); + expect(positioner.size.height, equals(200.0)); + }); }