Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: sky/sdk/lib/widgets/popup_menu.dart

Issue 1223113004: Polish the menu animation (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« sky/sdk/lib/base/debug.dart ('K') | « sky/sdk/lib/base/debug.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
165 ) 165 )
166 ) 166 )
167 ) 167 )
168 ) 168 )
169 ) 169 )
170 ) 170 )
171 ); 171 );
172 } 172 }
173 173
174 } 174 }
OLDNEW
« sky/sdk/lib/base/debug.dart ('K') | « sky/sdk/lib/base/debug.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698