diff --git a/sdk/lib/rendering/box.dart b/sdk/lib/rendering/box.dart index f6de4f4e61b..515f58c9f43 100644 --- a/sdk/lib/rendering/box.dart +++ b/sdk/lib/rendering/box.dart @@ -494,7 +494,35 @@ class RenderConstrainedBox extends RenderProxyBox { } class RenderShrinkWrapWidth extends RenderProxyBox { - RenderShrinkWrapWidth({ RenderBox child }) : super(child); + RenderShrinkWrapWidth({ + double stepWidth, + double stepHeight, + RenderBox child + }) : _stepWidth = stepWidth, _stepHeight = stepHeight, super(child); + + double _stepWidth; + double get stepWidth => _stepWidth; + void set stepWidth(double value) { + if (value == _stepWidth) + return; + _stepWidth = value; + markNeedsLayout(); + } + + double _stepHeight; + double get stepHeight => _stepHeight; + void set stepHeight(double value) { + if (value == _stepHeight) + return; + _stepHeight = value; + markNeedsLayout(); + } + + static double applyStep(double input, double step) { + if (step == null) + return input; + return (input / step).ceil() * step; + } BoxConstraints _getInnerConstraints(BoxConstraints constraints) { double width = child.getMaxIntrinsicWidth(constraints); @@ -503,33 +531,37 @@ class RenderShrinkWrapWidth extends RenderProxyBox { } double getMinIntrinsicWidth(BoxConstraints constraints) { - if (child != null) - return child.getMaxIntrinsicWidth(constraints); - return constraints.constrainWidth(0.0); + if (child == null) + return constraints.constrainWidth(0.0); + double childResult = child.getMinIntrinsicWidth(constraints); + return constraints.constrainWidth(applyStep(childResult, _stepWidth)); } double getMaxIntrinsicWidth(BoxConstraints constraints) { - if (child != null) - return child.getMaxIntrinsicWidth(constraints); - return constraints.constrainWidth(0.0); + if (child == null) + return constraints.constrainWidth(0.0); + double childResult = child.getMaxIntrinsicWidth(constraints); + return constraints.constrainWidth(applyStep(childResult, _stepWidth)); } double getMinIntrinsicHeight(BoxConstraints constraints) { - if (child != null) - return child.getMinIntrinsicHeight(_getInnerConstraints(constraints)); - return constraints.constrainWidth(0.0); + if (child == null) + return constraints.constrainWidth(0.0); + double childResult = child.getMinIntrinsicHeight(_getInnerConstraints(constraints)); + return constraints.constrainHeight(applyStep(childResult, _stepHeight)); } double getMaxIntrinsicHeight(BoxConstraints constraints) { - if (child != null) - return child.getMaxIntrinsicHeight(_getInnerConstraints(constraints)); - return constraints.constrainWidth(0.0); + if (child == null) + return constraints.constrainWidth(0.0); + double childResult = child.getMaxIntrinsicHeight(_getInnerConstraints(constraints)); + return constraints.constrainHeight(applyStep(childResult, _stepHeight)); } void performLayout() { if (child != null) { child.layout(_getInnerConstraints(constraints), parentUsesSize: true); - size = child.size; + size = new Size(applyStep(child.size.width, _stepWidth), applyStep(child.size.height, _stepHeight)); } else { performResize(); } diff --git a/sdk/lib/widgets/basic.dart b/sdk/lib/widgets/basic.dart index d64ec052740..cfbbdf8a764 100644 --- a/sdk/lib/widgets/basic.dart +++ b/sdk/lib/widgets/basic.dart @@ -231,11 +231,27 @@ class ConstrainedBox extends OneChildRenderObjectWrapper { } class ShrinkWrapWidth extends OneChildRenderObjectWrapper { - ShrinkWrapWidth({ String key, Widget child }) - : super(key: key, child: child); + + ShrinkWrapWidth({ + String key, + this.stepWidth, + this.stepHeight, + Widget child + }): super(key: key, child: child); RenderShrinkWrapWidth get root => super.root; + + final double stepWidth; + final double stepHeight; + RenderShrinkWrapWidth createNode() => new RenderShrinkWrapWidth(); + + void syncRenderObject(ShrinkWrapWidth old) { + super.syncRenderObject(old); + root.stepWidth = stepWidth; + root.stepHeight = stepHeight; + } + } class SizeObserver extends OneChildRenderObjectWrapper { diff --git a/sdk/lib/widgets/popup_menu.dart b/sdk/lib/widgets/popup_menu.dart index 336b90280b7..6fdf366dc30 100644 --- a/sdk/lib/widgets/popup_menu.dart +++ b/sdk/lib/widgets/popup_menu.dart @@ -17,6 +17,10 @@ import 'popup_menu_item.dart'; const double _kMenuOpenDuration = 300.0; const double _kMenuCloseDuration = 200.0; const double _kMenuCloseDelay = 100.0; +const double _kMenuWidthStep = 56.0; +const double _kMenuMinWidth = 1.5 * _kMenuWidthStep; +const double _kMenuHorizontalPadding = 16.0; +const double _kMenuVerticalPadding = 8.0; enum MenuState { hidden, opening, open, closing } @@ -64,7 +68,7 @@ class PopupMenu extends AnimatedComponent { } PopupMenuController controller; - List items; + List items; int level; void syncFields(PopupMenu source) { @@ -95,16 +99,25 @@ class PopupMenu extends AnimatedComponent { return new Opacity( opacity: math.min(1.0, controller.position.value * 3.0), - child: new ShrinkWrapWidth( - child: new CustomPaint( - callback: (sky.Canvas canvas, Size size) { - double width = math.min(size.width, size.width * (0.5 + controller.position.value * 2.0)); - double height = math.min(size.height, size.height * controller.position.value * 1.5); - _painter.paint(canvas, new Rect.fromLTRB(size.width - width, 0.0, width, height)); - }, - child: new Container( - padding: const EdgeDims.all(8.0), - child: new Block(children) + child: new CustomPaint( + callback: (sky.Canvas canvas, Size size) { + double width = math.min(size.width, size.width * (0.5 + controller.position.value * 2.0)); + double height = math.min(size.height, size.height * controller.position.value * 1.5); + _painter.paint(canvas, new Rect.fromLTRB(size.width - width, 0.0, width, height)); + }, + child: new ConstrainedBox( + constraints: new BoxConstraints( + minWidth: _kMenuMinWidth + ), + child: new ShrinkWrapWidth( + stepWidth: _kMenuWidthStep, + child: new Container( + padding: const EdgeDims.symmetric( + horizontal: _kMenuHorizontalPadding, + vertical: _kMenuVerticalPadding + ), + child: new Block(children) + ) ) ) ) diff --git a/sdk/lib/widgets/popup_menu_item.dart b/sdk/lib/widgets/popup_menu_item.dart index 42c0ce40ad6..17147cd10a8 100644 --- a/sdk/lib/widgets/popup_menu_item.dart +++ b/sdk/lib/widgets/popup_menu_item.dart @@ -21,8 +21,7 @@ class PopupMenuItem extends Component { opacity: opacity, child: new InkWell( child: new Container( - constraints: const BoxConstraints(minWidth: 112.0), - padding: const EdgeDims.all(16.0), + height: 48.0, child: new DefaultTextStyle( style: textStyle, child: child