| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
| 7 | 7 |
| 8 import 'package:sky/animation/animation_performance.dart'; | 8 import 'package:sky/animation/animation_performance.dart'; |
| 9 import 'package:sky/painting/box_painter.dart'; | 9 import 'package:sky/painting/box_painter.dart'; |
| 10 import 'package:sky/theme/colors.dart'; | 10 import 'package:sky/theme/colors.dart'; |
| 11 import 'package:sky/theme/shadows.dart'; | 11 import 'package:sky/theme/shadows.dart'; |
| 12 import 'package:sky/widgets/animated_component.dart'; | 12 import 'package:sky/widgets/animated_component.dart'; |
| 13 import 'package:sky/widgets/basic.dart'; | 13 import 'package:sky/widgets/basic.dart'; |
| 14 import 'package:sky/widgets/navigator.dart'; |
| 14 import 'package:sky/widgets/popup_menu_item.dart'; | 15 import 'package:sky/widgets/popup_menu_item.dart'; |
| 15 import 'package:sky/widgets/scrollable_viewport.dart'; | 16 import 'package:sky/widgets/scrollable_viewport.dart'; |
| 16 | 17 |
| 17 const Duration _kMenuDuration = const Duration(milliseconds: 300); | 18 const Duration _kMenuDuration = const Duration(milliseconds: 300); |
| 18 double _kMenuCloseIntervalEnd = 2.0 / 3.0; | 19 double _kMenuCloseIntervalEnd = 2.0 / 3.0; |
| 19 const double _kMenuWidthStep = 56.0; | 20 const double _kMenuWidthStep = 56.0; |
| 20 const double _kMenuMargin = 16.0; // 24.0 on tablet | 21 const double _kMenuMargin = 16.0; // 24.0 on tablet |
| 21 const double _kMenuMinWidth = 2.0 * _kMenuWidthStep; | 22 const double _kMenuMinWidth = 2.0 * _kMenuWidthStep; |
| 22 const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep; | 23 const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep; |
| 23 const double _kMenuHorizontalPadding = 16.0; | 24 const double _kMenuHorizontalPadding = 16.0; |
| 24 const double _kMenuVerticalPadding = 8.0; | 25 const double _kMenuVerticalPadding = 8.0; |
| 25 | 26 |
| 26 enum PopupMenuStatus { | 27 enum PopupMenuStatus { |
| 27 active, | 28 active, |
| 28 inactive, | 29 inactive, |
| 29 } | 30 } |
| 30 | 31 |
| 31 typedef void PopupMenuStatusChangedCallback(PopupMenuStatus status); | 32 typedef void PopupMenuStatusChangedCallback(PopupMenuStatus status); |
| 32 | 33 |
| 33 class PopupMenu extends AnimatedComponent { | 34 class PopupMenu extends AnimatedComponent { |
| 34 | 35 |
| 35 PopupMenu({ | 36 PopupMenu({ |
| 36 String key, | 37 String key, |
| 37 this.showing, | 38 this.showing, |
| 38 this.onStatusChanged, | 39 this.onStatusChanged, |
| 39 this.items, | 40 this.items, |
| 40 this.level | 41 this.level, |
| 42 this.navigator |
| 41 }) : super(key: key); | 43 }) : super(key: key); |
| 42 | 44 |
| 43 bool showing; | 45 bool showing; |
| 44 PopupMenuStatusChangedCallback onStatusChanged; | 46 PopupMenuStatusChangedCallback onStatusChanged; |
| 45 List<PopupMenuItem> items; | 47 List<PopupMenuItem> items; |
| 46 int level; | 48 int level; |
| 49 Navigator navigator; |
| 47 | 50 |
| 48 AnimatedType<double> _opacity; | 51 AnimatedType<double> _opacity; |
| 49 AnimatedType<double> _width; | 52 AnimatedType<double> _width; |
| 50 AnimatedType<double> _height; | 53 AnimatedType<double> _height; |
| 51 List<AnimatedType<double>> _itemOpacities; | 54 List<AnimatedType<double>> _itemOpacities; |
| 52 AnimatedList _animationList; | 55 AnimatedList _animationList; |
| 53 AnimationPerformance _performance; | 56 AnimationPerformance _performance; |
| 54 | 57 |
| 55 void initState() { | 58 void initState() { |
| 56 _performance = new AnimationPerformance() | 59 _performance = new AnimationPerformance() |
| (...skipping 15 matching lines...) Expand all Loading... |
| 72 _close(); | 75 _close(); |
| 73 } | 76 } |
| 74 onStatusChanged = source.onStatusChanged; | 77 onStatusChanged = source.onStatusChanged; |
| 75 if (level != source.level) { | 78 if (level != source.level) { |
| 76 level = source.level; | 79 level = source.level; |
| 77 _updateBoxPainter(); | 80 _updateBoxPainter(); |
| 78 } | 81 } |
| 79 if (items.length != source.items.length) | 82 if (items.length != source.items.length) |
| 80 _updateAnimationVariables(); | 83 _updateAnimationVariables(); |
| 81 items = source.items; | 84 items = source.items; |
| 85 navigator = source.navigator; |
| 82 super.syncFields(source); | 86 super.syncFields(source); |
| 83 } | 87 } |
| 84 | 88 |
| 85 void _updateAnimationVariables() { | 89 void _updateAnimationVariables() { |
| 86 double unit = 1.0 / (items.length + 1.5); // 1.0 for the width and 0.5 for t
he last item's fade. | 90 double unit = 1.0 / (items.length + 1.5); // 1.0 for the width and 0.5 for t
he last item's fade. |
| 87 _opacity = new AnimatedType<double>(0.0, end: 1.0); | 91 _opacity = new AnimatedType<double>(0.0, end: 1.0); |
| 88 _width = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0,
unit)); | 92 _width = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0,
unit)); |
| 89 _height = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0
, unit * items.length)); | 93 _height = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0
, unit * items.length)); |
| 90 _itemOpacities = new List<AnimatedType<double>>(); | 94 _itemOpacities = new List<AnimatedType<double>>(); |
| 91 for (int i = 0; i < items.length; ++i) { | 95 for (int i = 0; i < items.length; ++i) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 108 backgroundColor: Grey[50], | 112 backgroundColor: Grey[50], |
| 109 borderRadius: 2.0, | 113 borderRadius: 2.0, |
| 110 boxShadow: shadows[level])); | 114 boxShadow: shadows[level])); |
| 111 } | 115 } |
| 112 | 116 |
| 113 PopupMenuStatus get _status => _opacity.value != 0.0 ? PopupMenuStatus.active
: PopupMenuStatus.inactive; | 117 PopupMenuStatus get _status => _opacity.value != 0.0 ? PopupMenuStatus.active
: PopupMenuStatus.inactive; |
| 114 | 118 |
| 115 PopupMenuStatus _lastStatus; | 119 PopupMenuStatus _lastStatus; |
| 116 void _checkForStateChanged() { | 120 void _checkForStateChanged() { |
| 117 PopupMenuStatus status = _status; | 121 PopupMenuStatus status = _status; |
| 118 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null) | 122 if (_lastStatus != null && status != _lastStatus) { |
| 119 onStatusChanged(status); | 123 if (status == PopupMenuStatus.inactive && |
| 124 navigator != null && |
| 125 navigator.currentRoute.key == this) |
| 126 navigator.pop(); |
| 127 if (onStatusChanged != null) |
| 128 onStatusChanged(status); |
| 129 } |
| 120 _lastStatus = status; | 130 _lastStatus = status; |
| 121 } | 131 } |
| 122 | 132 |
| 133 |
| 123 void _open() { | 134 void _open() { |
| 124 _animationList.interval = null; | 135 _animationList.interval = null; |
| 125 _performance.play(); | 136 _performance.play(); |
| 137 if (navigator != null) |
| 138 navigator.pushState(this, (_) => _close()); |
| 126 } | 139 } |
| 127 | 140 |
| 128 void _close() { | 141 void _close() { |
| 129 _animationList.interval = new Interval(0.0, _kMenuCloseIntervalEnd); | 142 _animationList.interval = new Interval(0.0, _kMenuCloseIntervalEnd); |
| 130 _performance.reverse(); | 143 _performance.reverse(); |
| 131 } | 144 } |
| 132 | 145 |
| 133 BoxPainter _painter; | 146 BoxPainter _painter; |
| 134 | 147 |
| 135 Widget build() { | 148 Widget build() { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 165 ) | 178 ) |
| 166 ) | 179 ) |
| 167 ) | 180 ) |
| 168 ) | 181 ) |
| 169 ) | 182 ) |
| 170 ) | 183 ) |
| 171 ); | 184 ); |
| 172 } | 185 } |
| 173 | 186 |
| 174 } | 187 } |
| OLD | NEW |