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

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

Issue 1223073002: AnimatedContainer: generalized Container widget that handles animating values (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
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:sky' as sky; 5 import 'dart:sky' as sky;
6 6
7 import '../animation/animation_performance.dart'; 7 import '../animation/animation_performance.dart';
8 import '../animation/curves.dart'; 8 import '../animation/curves.dart';
9 import '../theme/shadows.dart'; 9 import '../theme/shadows.dart';
10 import 'animated_component.dart'; 10 import 'animated_component.dart';
11 import 'animated_container.dart';
11 import 'basic.dart'; 12 import 'basic.dart';
12 import 'theme.dart'; 13 import 'theme.dart';
13 14
14 // TODO(eseidel): Draw width should vary based on device size: 15 // TODO(eseidel): Draw width should vary based on device size:
15 // http://www.google.com/design/spec/layout/structure.html#structure-side-nav 16 // http://www.google.com/design/spec/layout/structure.html#structure-side-nav
16 17
17 // Mobile: 18 // Mobile:
18 // Width = Screen width − 56 dp 19 // Width = Screen width − 56 dp
19 // Maximum width: 320dp 20 // Maximum width: 320dp
20 // Maximum width applies only when using a left nav. When using a right nav, 21 // Maximum width applies only when using a left nav. When using a right nav,
21 // the panel can cover the full width of the screen. 22 // the panel can cover the full width of the screen.
22 23
23 // Desktop/Tablet: 24 // Desktop/Tablet:
24 // Maximum width for a left nav is 400dp. 25 // Maximum width for a left nav is 400dp.
25 // The right nav can vary depending on content. 26 // The right nav can vary depending on content.
26 27
27 const double _kWidth = 304.0; 28 const double _kWidth = 304.0;
28 const double _kMinFlingVelocity = 0.4; 29 const double _kMinFlingVelocity = 0.4;
29 const int _kBaseSettleDurationMS = 246; 30 const Duration _kBaseSettleDuration = const Duration(milliseconds: 246);
30 // TODO(mpcomplete): The curve must be linear if we want the drawer to track 31 // TODO(mpcomplete): The curve must be linear if we want the drawer to track
31 // the user's finger. Odeon remedies this by attaching spring forces to the 32 // the user's finger. Odeon remedies this by attaching spring forces to the
32 // initial timeline when animating (so it doesn't look linear). 33 // initial timeline when animating (so it doesn't look linear).
33 const Curve _kAnimationCurve = linear; 34 const Curve _kAnimationCurve = linear;
34 35
35 typedef void DrawerStatusChangeHandler (bool showing); 36 typedef void DrawerStatusChangeHandler (bool showing);
36 37
37 class DrawerController { 38 class DrawerController {
38 DrawerController(this.onStatusChange) { 39 DrawerController(this.onStatusChange) {
39 performance = new AnimationPerformance() 40 container = new AnimatedContainer()
40 ..duration = new Duration(milliseconds: _kBaseSettleDurationMS) 41 ..position = new AnimatedType<Point>(
41 ..variable = position; 42 new Point(-_kWidth, 0.0), end: Point.origin, curve: _kAnimationCurve);
43 performance = container.createPerformance(
44 container.position, duration: _kBaseSettleDuration);
42 performance.timeline.onValueChanged.listen(_checkValue); 45 performance.timeline.onValueChanged.listen(_checkValue);
43 } 46 }
44 final DrawerStatusChangeHandler onStatusChange; 47 final DrawerStatusChangeHandler onStatusChange;
45 48
46 AnimationPerformance performance; 49 AnimationPerformance performance;
47 final AnimatedPosition position = new AnimatedPosition( 50 AnimatedContainer container;
48 new Point(-_kWidth, 0.0), Point.origin, curve: _kAnimationCurve); 51
52 double get xPosition => container.position.value.x;
49 53
50 bool _oldClosedState = true; 54 bool _oldClosedState = true;
51 void _checkValue(_) { 55 void _checkValue(_) {
52 var newClosedState = isClosed; 56 var newClosedState = isClosed;
53 if (onStatusChange != null && _oldClosedState != newClosedState) { 57 if (onStatusChange != null && _oldClosedState != newClosedState) {
54 onStatusChange(!newClosedState); 58 onStatusChange(!newClosedState);
55 _oldClosedState = newClosedState; 59 _oldClosedState = newClosedState;
56 } 60 }
57 } 61 }
58 62
59 bool get isClosed => performance.isDismissed; 63 bool get isClosed => performance.isDismissed;
60 bool get _isMostlyClosed => position.value.x <= -_kWidth/2; 64 bool get _isMostlyClosed => xPosition <= -_kWidth/2;
61 65
62 void open() => performance.play(); 66 void open() => performance.play();
63 67
64 void close() => performance.reverse(); 68 void close() => performance.reverse();
65 69
66 void _settle() => _isMostlyClosed ? close() : open(); 70 void _settle() => _isMostlyClosed ? close() : open();
67 71
68 void handleMaskTap(_) => close(); 72 void handleMaskTap(_) => close();
69 73
70 // TODO(mpcomplete): Figure out how to generalize these handlers on a 74 // TODO(mpcomplete): Figure out how to generalize these handlers on a
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 Widget build() { 125 Widget build() {
122 // TODO(mpcomplete): animate as a fade-in. 126 // TODO(mpcomplete): animate as a fade-in.
123 double scaler = controller.performance.progress; 127 double scaler = controller.performance.progress;
124 Color maskColor = new Color.fromARGB((0x7F * scaler).floor(), 0, 0, 0); 128 Color maskColor = new Color.fromARGB((0x7F * scaler).floor(), 0, 0, 0);
125 129
126 var mask = new Listener( 130 var mask = new Listener(
127 child: new Container(decoration: new BoxDecoration(backgroundColor: maskCo lor)), 131 child: new Container(decoration: new BoxDecoration(backgroundColor: maskCo lor)),
128 onGestureTap: controller.handleMaskTap 132 onGestureTap: controller.handleMaskTap
129 ); 133 );
130 134
131 Widget content = controller.position.build( 135 Widget content = controller.container.build(
132 new Container( 136 new Container(
133 decoration: new BoxDecoration( 137 decoration: new BoxDecoration(
134 backgroundColor: Theme.of(this).canvasColor, 138 backgroundColor: Theme.of(this).canvasColor,
135 boxShadow: shadows[level]), 139 boxShadow: shadows[level]),
136 width: _kWidth, 140 width: _kWidth,
137 child: new Block(children) 141 child: new Block(children)
138 )); 142 ));
139 143
140 return new Listener( 144 return new Listener(
141 child: new Stack([ mask, content ]), 145 child: new Stack([ mask, content ]),
142 onPointerDown: controller.handlePointerDown, 146 onPointerDown: controller.handlePointerDown,
143 onPointerMove: controller.handlePointerMove, 147 onPointerMove: controller.handlePointerMove,
144 onPointerUp: controller.handlePointerUp, 148 onPointerUp: controller.handlePointerUp,
145 onPointerCancel: controller.handlePointerCancel, 149 onPointerCancel: controller.handlePointerCancel,
146 onGestureFlingStart: controller.handleFlingStart 150 onGestureFlingStart: controller.handleFlingStart
147 ); 151 );
148 } 152 }
149 153
150 } 154 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698