| Index: sky/framework/components/popup_menu.dart
|
| diff --git a/sky/framework/components/popup_menu.dart b/sky/framework/components/popup_menu.dart
|
| index 18996b75c2dfd88cb19b9ea1bf1226c7a2c23194..c3bf1afb15598b0dda0887511c17aa5c9cf3c3bd 100644
|
| --- a/sky/framework/components/popup_menu.dart
|
| +++ b/sky/framework/components/popup_menu.dart
|
| @@ -7,14 +7,14 @@ import '../animation/animated_value.dart';
|
| import '../fn.dart';
|
| import '../theme/colors.dart';
|
| import '../theme/view-configuration.dart';
|
| +import 'dart:async';
|
| import 'dart:math' as math;
|
| import 'dart:sky' as sky;
|
| import 'material.dart';
|
| import 'popup_menu_item.dart';
|
|
|
| -const double _kItemFadeDuration = 300.0;
|
| -const double _kItemFadeDelay = 100.0;
|
| -const double _kMenuExpandDuration = 300.0;
|
| +const double _kMenuOpenDuration = 300.0;
|
| +const double _kMenuCloneDuration = 200.0;
|
|
|
| class PopupMenuController {
|
| bool isOpen = false;
|
| @@ -22,14 +22,13 @@ class PopupMenuController {
|
|
|
| void open() {
|
| isOpen = true;
|
| - position.animateTo(1.0, _kMenuExpandDuration);
|
| + position.animateTo(1.0, _kMenuOpenDuration);
|
| }
|
|
|
| - void close() {
|
| - position.animateTo(0.0, _kMenuExpandDuration);
|
| - // TODO(abarth): We shouldn't mark the menu as closed until the animation
|
| - // completes.
|
| - isOpen = false;
|
| + Future close() {
|
| + return position.animateTo(0.0, _kMenuCloneDuration).then((_) {
|
| + isOpen = false;
|
| + });
|
| }
|
| }
|
|
|
| @@ -45,35 +44,32 @@ class PopupMenu extends AnimatedComponent {
|
| PopupMenuController controller;
|
|
|
| double _position;
|
| - List<AnimatedValue> _opacities;
|
| int _width;
|
| int _height;
|
|
|
| PopupMenu({ Object key, this.controller, this.items, this.level })
|
| : super(key: key) {
|
| animateField(controller.position, #_position);
|
| -
|
| onDidMount(_measureSize);
|
| }
|
|
|
| - void _ensureItemAnimations() {
|
| - if (_opacities != null && controller.isOpen)
|
| - return;
|
| - _opacities = new List.from(items.map((_) => new AnimatedValue(0.0)));
|
| - int i = 0;
|
| - _opacities.forEach((opacity) {
|
| - opacity.animateTo(1.0, _kItemFadeDuration,
|
| - initialDelay: _kItemFadeDelay * ++i);
|
| - });
|
| + double _opacityFor(int i) {
|
| + if (_position == null || _position == 1.0)
|
| + return null;
|
| + double unit = 1.0 / items.length;
|
| + double duration = 1.5 * unit;
|
| + double start = i * unit;
|
| + return math.max(0.0, math.min(1.0, (_position - start) / duration));
|
| }
|
|
|
| String _inlineStyle() {
|
| - if (_position == null || _position == 1.0 || _height == null || _width == null)
|
| + if (_position == null || _position == 1.0 ||
|
| + _height == null || _width == null)
|
| return null;
|
| return '''
|
| - opacity: ${math.min(1.0, _position * 1.5)};
|
| - width: ${math.min(_width, _width * _position * 3.0)}px;
|
| - height: ${_height * _position}px;''';
|
| + opacity: ${math.min(1.0, _position * 3.0)};
|
| + width: ${math.min(_width, _width * (0.5 + _position * 2.0))}px;
|
| + height: ${math.min(_height, _height * _position * 1.5)}px;''';
|
| }
|
|
|
| void _measureSize() {
|
| @@ -85,24 +81,16 @@ class PopupMenu extends AnimatedComponent {
|
| }
|
|
|
| Node build() {
|
| - _ensureItemAnimations();
|
| -
|
| - List<Node> children = [];
|
| -
|
| - if (controller.isOpen) {
|
| - int i = 0;
|
| - items.forEach((List<Node> item) {
|
| - children.add(
|
| - new PopupMenuItem(key: i, children: item, opacity: _opacities[i]));
|
| - ++i;
|
| - });
|
| - }
|
| + int i = 0;
|
| + List<Node> children = new List.from(items.map((List<Node> item) {
|
| + double opacity = _opacityFor(i);
|
| + return new PopupMenuItem(key: i++, children: item, opacity: opacity);
|
| + }));
|
|
|
| return new Material(
|
| style: _style,
|
| inlineStyle: _inlineStyle(),
|
| children: children,
|
| - level: level
|
| - );
|
| + level: level);
|
| }
|
| }
|
|
|