| 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/popup_menu_item.dart'; | 14 import 'package:sky/widgets/popup_menu_item.dart'; |
| 15 import 'package:sky/widgets/scrollable_viewport.dart'; | 15 import 'package:sky/widgets/scrollable_viewport.dart'; |
| 16 | 16 |
| 17 const Duration _kMenuOpenDuration = const Duration(milliseconds: 300); | 17 const Duration _kMenuDuration = const Duration(milliseconds: 300); |
| 18 const Duration _kMenuCloseDuration = const Duration(milliseconds: 200); | 18 double _kMenuCloseIntervalEnd = 2.0 / 3.0; |
| 19 const Duration _kMenuCloseDelay = const Duration(milliseconds: 100); | |
| 20 const double _kMenuWidthStep = 56.0; | 19 const double _kMenuWidthStep = 56.0; |
| 21 const double _kMenuMargin = 16.0; // 24.0 on tablet | 20 const double _kMenuMargin = 16.0; // 24.0 on tablet |
| 22 const double _kMenuMinWidth = 2.0 * _kMenuWidthStep; | 21 const double _kMenuMinWidth = 2.0 * _kMenuWidthStep; |
| 23 const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep; | 22 const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep; |
| 24 const double _kMenuHorizontalPadding = 16.0; | 23 const double _kMenuHorizontalPadding = 16.0; |
| 25 const double _kMenuVerticalPadding = 8.0; | 24 const double _kMenuVerticalPadding = 8.0; |
| 26 | 25 |
| 27 enum PopupMenuStatus { | 26 enum PopupMenuStatus { |
| 28 active, | 27 active, |
| 29 inactive, | 28 inactive, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 43 | 42 |
| 44 bool showing; | 43 bool showing; |
| 45 PopupMenuStatusChangedCallback onStatusChanged; | 44 PopupMenuStatusChangedCallback onStatusChanged; |
| 46 List<PopupMenuItem> items; | 45 List<PopupMenuItem> items; |
| 47 int level; | 46 int level; |
| 48 | 47 |
| 49 AnimatedType<double> _opacity; | 48 AnimatedType<double> _opacity; |
| 50 AnimatedType<double> _width; | 49 AnimatedType<double> _width; |
| 51 AnimatedType<double> _height; | 50 AnimatedType<double> _height; |
| 52 List<AnimatedType<double>> _itemOpacities; | 51 List<AnimatedType<double>> _itemOpacities; |
| 52 AnimatedList _animationList; |
| 53 AnimationPerformance _performance; | 53 AnimationPerformance _performance; |
| 54 | 54 |
| 55 void initState() { | 55 void initState() { |
| 56 _performance = new AnimationPerformance() | 56 _performance = new AnimationPerformance() |
| 57 ..duration = _kMenuDuration |
| 57 ..addListener(_checkForStateChanged); | 58 ..addListener(_checkForStateChanged); |
| 58 _updateAnimationVariables(); | 59 _updateAnimationVariables(); |
| 59 watch(_performance); | 60 watch(_performance); |
| 60 _updateBoxPainter(); | 61 _updateBoxPainter(); |
| 61 if (showing) | 62 if (showing) |
| 62 _open(); | 63 _open(); |
| 63 } | 64 } |
| 64 | 65 |
| 65 void syncFields(PopupMenu source) { | 66 void syncFields(PopupMenu source) { |
| 66 if (showing != source.showing) { | 67 if (showing != source.showing) { |
| 67 showing = source.showing; | 68 showing = source.showing; |
| 68 if (showing) | 69 if (showing) |
| 69 _open(); | 70 _open(); |
| 70 else | 71 else |
| 71 _close(); | 72 _close(); |
| 72 } | 73 } |
| 73 onStatusChanged = source.onStatusChanged; | 74 onStatusChanged = source.onStatusChanged; |
| 74 if (level != source.level) { | 75 if (level != source.level) { |
| 75 level = source.level; | 76 level = source.level; |
| 76 _updateBoxPainter(); | 77 _updateBoxPainter(); |
| 77 } | 78 } |
| 78 if (items.length != source.items.length) | 79 if (items.length != source.items.length) |
| 79 _updateAnimationVariables(); | 80 _updateAnimationVariables(); |
| 80 items = source.items; | 81 items = source.items; |
| 81 super.syncFields(source); | 82 super.syncFields(source); |
| 82 } | 83 } |
| 83 | 84 |
| 84 void _updateAnimationVariables() { | 85 void _updateAnimationVariables() { |
| 85 double unit = 1.0 / (items.length + 1); | 86 double unit = 1.0 / (items.length + 1.5); // 1.0 for the width and 0.5 for t
he last item's fade. |
| 86 _opacity = new AnimatedType<double>(0.0, end: 1.0); | 87 _opacity = new AnimatedType<double>(0.0, end: 1.0); |
| 87 _width = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0,
unit)); | 88 _width = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0,
unit)); |
| 88 _height = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0
, 0.5)); | 89 _height = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0
, unit * items.length)); |
| 89 _itemOpacities = new List<AnimatedType<double>>(); | 90 _itemOpacities = new List<AnimatedType<double>>(); |
| 90 for (int i = 0; i < items.length; ++i) { | 91 for (int i = 0; i < items.length; ++i) { |
| 91 double start = (i + 1) * unit; | 92 double start = (i + 1) * unit; |
| 92 double end = (start + 1.5 * unit).clamp(0.0, 1.0); | 93 double end = (start + 1.5 * unit).clamp(0.0, 1.0); |
| 93 _itemOpacities.add(new AnimatedType<double>( | 94 _itemOpacities.add(new AnimatedType<double>( |
| 94 0.0, end: 1.0, interval: new Interval(start, end))); | 95 0.0, end: 1.0, interval: new Interval(start, end))); |
| 95 } | 96 } |
| 96 List<AnimatedVariable> variables = new List<AnimatedVariable>() | 97 List<AnimatedVariable> variables = new List<AnimatedVariable>() |
| 97 ..add(_opacity) | 98 ..add(_opacity) |
| 98 ..add(_width) | 99 ..add(_width) |
| 99 ..add(_height) | 100 ..add(_height) |
| 100 ..addAll(_itemOpacities); | 101 ..addAll(_itemOpacities); |
| 101 _performance.variable = new AnimatedList(variables); | 102 _animationList = new AnimatedList(variables); |
| 103 _performance.variable = _animationList; |
| 102 } | 104 } |
| 103 | 105 |
| 104 void _updateBoxPainter() { | 106 void _updateBoxPainter() { |
| 105 _painter = new BoxPainter(new BoxDecoration( | 107 _painter = new BoxPainter(new BoxDecoration( |
| 106 backgroundColor: Grey[50], | 108 backgroundColor: Grey[50], |
| 107 borderRadius: 2.0, | 109 borderRadius: 2.0, |
| 108 boxShadow: shadows[level])); | 110 boxShadow: shadows[level])); |
| 109 } | 111 } |
| 110 | 112 |
| 111 PopupMenuStatus get _status => _opacity.value != 0.0 ? PopupMenuStatus.active
: PopupMenuStatus.inactive; | 113 PopupMenuStatus get _status => _opacity.value != 0.0 ? PopupMenuStatus.active
: PopupMenuStatus.inactive; |
| 112 | 114 |
| 113 PopupMenuStatus _lastStatus; | 115 PopupMenuStatus _lastStatus; |
| 114 void _checkForStateChanged() { | 116 void _checkForStateChanged() { |
| 115 PopupMenuStatus status = _status; | 117 PopupMenuStatus status = _status; |
| 116 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null) | 118 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null) |
| 117 onStatusChanged(status); | 119 onStatusChanged(status); |
| 118 _lastStatus = status; | 120 _lastStatus = status; |
| 119 } | 121 } |
| 120 | 122 |
| 121 void _open() { | 123 void _open() { |
| 122 _performance | 124 _animationList.interval = null; |
| 123 ..duration = _kMenuOpenDuration | 125 _performance.play(); |
| 124 ..play(); | |
| 125 } | 126 } |
| 126 | 127 |
| 127 void _close() { | 128 void _close() { |
| 128 _performance | 129 _animationList.interval = new Interval(0.0, _kMenuCloseIntervalEnd); |
| 129 ..duration = _kMenuCloseDuration | 130 _performance.reverse(); |
| 130 ..reverse(); | |
| 131 } | 131 } |
| 132 | 132 |
| 133 BoxPainter _painter; | 133 BoxPainter _painter; |
| 134 | 134 |
| 135 Widget build() { | 135 Widget build() { |
| 136 int i = 0; | 136 int i = 0; |
| 137 List<Widget> children = new List.from(items.map((Widget item) { | 137 List<Widget> children = new List.from(items.map((Widget item) { |
| 138 return new Opacity(opacity: _itemOpacities[i++].value, child: item); | 138 return new Opacity(opacity: _itemOpacities[i++].value, child: item); |
| 139 })); | 139 })); |
| 140 | 140 |
| (...skipping 24 matching lines...) Expand all Loading... |
| 165 ) | 165 ) |
| 166 ) | 166 ) |
| 167 ) | 167 ) |
| 168 ) | 168 ) |
| 169 ) | 169 ) |
| 170 ) | 170 ) |
| 171 ); | 171 ); |
| 172 } | 172 } |
| 173 | 173 |
| 174 } | 174 } |
| OLD | NEW |