| 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'; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 this.onStatusChanged, | 39 this.onStatusChanged, |
| 40 this.items, | 40 this.items, |
| 41 this.level | 41 this.level |
| 42 }) : super(key: key); | 42 }) : super(key: key); |
| 43 | 43 |
| 44 bool showing; | 44 bool showing; |
| 45 PopupMenuStatusChangedCallback onStatusChanged; | 45 PopupMenuStatusChangedCallback onStatusChanged; |
| 46 List<PopupMenuItem> items; | 46 List<PopupMenuItem> items; |
| 47 int level; | 47 int level; |
| 48 | 48 |
| 49 AnimatedType<double> _position; | 49 AnimatedType<double> _opacity; |
| 50 AnimatedType<double> _height; |
| 51 AnimatedType<double> _width; |
| 52 List<AnimatedType<double>> _itemOpacities; |
| 50 AnimationPerformance _performance; | 53 AnimationPerformance _performance; |
| 51 | 54 |
| 52 void initState() { | 55 void initState() { |
| 53 _position = new AnimatedType<double>(0.0, end: 1.0); | |
| 54 _performance = new AnimationPerformance() | 56 _performance = new AnimationPerformance() |
| 55 ..variable = _position | |
| 56 ..addListener(_checkForStateChanged); | 57 ..addListener(_checkForStateChanged); |
| 58 _updateAnimationVariables(); |
| 57 watch(_performance); | 59 watch(_performance); |
| 58 _updateBoxPainter(); | 60 _updateBoxPainter(); |
| 59 if (showing) | 61 if (showing) |
| 60 _open(); | 62 _open(); |
| 61 } | 63 } |
| 62 | 64 |
| 63 void syncFields(PopupMenu source) { | 65 void syncFields(PopupMenu source) { |
| 64 if (showing != source.showing) { | 66 if (showing != source.showing) { |
| 65 showing = source.showing; | 67 showing = source.showing; |
| 66 if (showing) | 68 if (showing) |
| 67 _open(); | 69 _open(); |
| 68 else | 70 else |
| 69 _close(); | 71 _close(); |
| 70 } | 72 } |
| 71 onStatusChanged = source.onStatusChanged; | 73 onStatusChanged = source.onStatusChanged; |
| 72 if (level != source.level) { | 74 if (level != source.level) { |
| 73 level = source.level; | 75 level = source.level; |
| 74 _updateBoxPainter(); | 76 _updateBoxPainter(); |
| 75 } | 77 } |
| 78 if (items.length != source.items.length) |
| 79 _updateAnimationVariables(); |
| 76 items = source.items; | 80 items = source.items; |
| 77 super.syncFields(source); | 81 super.syncFields(source); |
| 78 } | 82 } |
| 79 | 83 |
| 84 void _updateAnimationVariables() { |
| 85 _opacity = new AnimatedType<double>(0.0, end: 1.0); |
| 86 _width = new AnimatedType<double>(0.5, end: 1.0, interval: new Interval(0.0,
0.5)); |
| 87 _height = new AnimatedType<double>(0.0, end: 1.0, interval: new Interval(0.0
, 0.33)); |
| 88 _itemOpacities = new List<AnimatedType<double>>(); |
| 89 double unit = 1.0 / items.length; |
| 90 for (int i = 0; i < items.length; ++i) { |
| 91 double start = i * unit; |
| 92 double end = (start + 1.5 * unit).clamp(0.0, 1.0); |
| 93 _itemOpacities.add(new AnimatedType<double>( |
| 94 0.0, end: 1.0, interval: new Interval(start, end))); |
| 95 } |
| 96 List<AnimatedVariable> variables = new List<AnimatedVariable>() |
| 97 ..add(_opacity) |
| 98 ..add(_width) |
| 99 ..add(_height) |
| 100 ..addAll(_itemOpacities); |
| 101 _performance.variable = new AnimatedList(variables); |
| 102 } |
| 103 |
| 80 void _updateBoxPainter() { | 104 void _updateBoxPainter() { |
| 81 _painter = new BoxPainter(new BoxDecoration( | 105 _painter = new BoxPainter(new BoxDecoration( |
| 82 backgroundColor: Grey[50], | 106 backgroundColor: Grey[50], |
| 83 borderRadius: 2.0, | 107 borderRadius: 2.0, |
| 84 boxShadow: shadows[level])); | 108 boxShadow: shadows[level])); |
| 85 } | 109 } |
| 86 | 110 |
| 87 PopupMenuStatus get _status => _position.value != 0.0 ? PopupMenuStatus.active
: PopupMenuStatus.inactive; | 111 PopupMenuStatus get _status => _opacity.value != 0.0 ? PopupMenuStatus.active
: PopupMenuStatus.inactive; |
| 88 | 112 |
| 89 PopupMenuStatus _lastStatus; | 113 PopupMenuStatus _lastStatus; |
| 90 void _checkForStateChanged() { | 114 void _checkForStateChanged() { |
| 91 PopupMenuStatus status = _status; | 115 PopupMenuStatus status = _status; |
| 92 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null) | 116 if (_lastStatus != null && status != _lastStatus && onStatusChanged != null) |
| 93 onStatusChanged(status); | 117 onStatusChanged(status); |
| 94 _lastStatus = status; | 118 _lastStatus = status; |
| 95 } | 119 } |
| 96 | 120 |
| 97 void _open() { | 121 void _open() { |
| 98 _performance | 122 _performance |
| 99 ..duration = _kMenuOpenDuration | 123 ..duration = _kMenuOpenDuration |
| 100 ..play(); | 124 ..play(); |
| 101 } | 125 } |
| 102 | 126 |
| 103 void _close() { | 127 void _close() { |
| 104 _performance | 128 _performance |
| 105 ..duration = _kMenuCloseDuration | 129 ..duration = _kMenuCloseDuration |
| 106 ..reverse(); | 130 ..reverse(); |
| 107 } | 131 } |
| 108 | 132 |
| 109 BoxPainter _painter; | 133 BoxPainter _painter; |
| 110 | 134 |
| 111 double _opacityFor(int i) { | |
| 112 assert(_position.value != null); | |
| 113 if (_position.value == null || _position.value == 1.0) | |
| 114 return 1.0; | |
| 115 double unit = 1.0 / items.length; | |
| 116 double duration = 1.5 * unit; | |
| 117 double start = i * unit; | |
| 118 return math.max(0.0, math.min(1.0, (_position.value - start) / duration)); | |
| 119 } | |
| 120 | |
| 121 Widget build() { | 135 Widget build() { |
| 122 int i = 0; | 136 int i = 0; |
| 123 List<Widget> children = new List.from(items.map((Widget item) { | 137 List<Widget> children = new List.from(items.map((Widget item) { |
| 124 return new Opacity(opacity: _opacityFor(i++), child: item); | 138 return new Opacity(opacity: _itemOpacities[i++].value, child: item); |
| 125 })); | 139 })); |
| 126 | 140 |
| 127 return new Opacity( | 141 return new Opacity( |
| 128 opacity: math.min(1.0, _position.value * 3.0), | 142 opacity: math.min(1.0, _opacity.value * 3.0), |
| 129 child: new Container( | 143 child: new Container( |
| 130 margin: new EdgeDims.all(_kMenuMargin), | 144 margin: new EdgeDims.all(_kMenuMargin), |
| 131 child: new CustomPaint( | 145 child: new CustomPaint( |
| 132 callback: (sky.Canvas canvas, Size size) { | 146 callback: (sky.Canvas canvas, Size size) { |
| 133 double width = math.min(size.width, size.width * (0.5 + _position.va
lue * 2.0)); | 147 double width = _width.value * size.width; |
| 134 double height = math.min(size.height, size.height * _position.value
* 1.5); | 148 double height = _height.value * size.height; |
| 135 _painter.paint(canvas, new Rect.fromLTRB(size.width - width, 0.0, wi
dth, height)); | 149 _painter.paint(canvas, new Rect.fromLTRB(size.width - width, 0.0, wi
dth, height)); |
| 136 }, | 150 }, |
| 137 child: new ConstrainedBox( | 151 child: new ConstrainedBox( |
| 138 constraints: new BoxConstraints( | 152 constraints: new BoxConstraints( |
| 139 minWidth: _kMenuMinWidth, | 153 minWidth: _kMenuMinWidth, |
| 140 maxWidth: _kMenuMaxWidth | 154 maxWidth: _kMenuMaxWidth |
| 141 ), | 155 ), |
| 142 child: new ShrinkWrapWidth( | 156 child: new ShrinkWrapWidth( |
| 143 stepWidth: _kMenuWidthStep, | 157 stepWidth: _kMenuWidthStep, |
| 144 child: new ScrollableViewport( | 158 child: new ScrollableViewport( |
| 145 child: new Container( | 159 child: new Container( |
| 146 padding: const EdgeDims.symmetric( | 160 padding: const EdgeDims.symmetric( |
| 147 horizontal: _kMenuHorizontalPadding, | 161 horizontal: _kMenuHorizontalPadding, |
| 148 vertical: _kMenuVerticalPadding | 162 vertical: _kMenuVerticalPadding |
| 149 ), | 163 ), |
| 150 child: new Block(children) | 164 child: new Block(children) |
| 151 ) | 165 ) |
| 152 ) | 166 ) |
| 153 ) | 167 ) |
| 154 ) | 168 ) |
| 155 ) | 169 ) |
| 156 ) | 170 ) |
| 157 ); | 171 ); |
| 158 } | 172 } |
| 159 | 173 |
| 160 } | 174 } |
| OLD | NEW |