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

Side by Side Diff: sky/framework/components/drawer.dart

Issue 1132063007: Rationalize Dart mojo and sky package structure (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 7 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
(Empty)
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
3 // found in the LICENSE file.
4
5 import 'animated_component.dart';
6 import '../animation/animated_value.dart';
7 import '../animation/curves.dart';
8 import '../fn.dart';
9 import '../theme/colors.dart';
10 import 'dart:math' as math;
11 import 'dart:sky' as sky;
12 import 'material.dart';
13
14 const double _kWidth = 304.0;
15 const double _kMinFlingVelocity = 0.4;
16 const double _kBaseSettleDurationMS = 246.0;
17 const double _kMaxSettleDurationMS = 600.0;
18 const Curve _kAnimationCurve = parabolicRise;
19
20 typedef void DrawerStatusChangeHandler (bool showing);
21
22 class DrawerController {
23
24 DrawerController(this.onStatusChange) {
25 position = new AnimatedValue(-_kWidth, onChange: _checkValue);
26 }
27 final DrawerStatusChangeHandler onStatusChange;
28 AnimatedValue position;
29
30 bool _oldClosedState = true;
31 void _checkValue() {
32 var newClosedState = isClosed;
33 if (onStatusChange != null && _oldClosedState != newClosedState) {
34 onStatusChange(!newClosedState);
35 _oldClosedState = newClosedState;
36 }
37 }
38
39 bool get isClosed => position.value == -_kWidth;
40 bool get _isMostlyClosed => position.value <= -_kWidth / 2;
41 void toggle(_) => _isMostlyClosed ? _open() : _close();
42
43 void handleMaskTap(_) => _close();
44 void handlePointerDown(_) => position.stop();
45
46 void handlePointerMove(sky.PointerEvent event) {
47 if (position.isAnimating)
48 return;
49 position.value = math.min(0.0, math.max(position.value + event.dx, -_kWidth) );
50 }
51
52 void handlePointerUp(_) {
53 if (!position.isAnimating)
54 _settle();
55 }
56
57 void handlePointerCancel(_) {
58 if (!position.isAnimating)
59 _settle();
60 }
61
62 void _open() => _animateToPosition(0.0);
63
64 void _close() => _animateToPosition(-_kWidth);
65
66 void _settle() => _isMostlyClosed ? _close() : _open();
67
68 void _animateToPosition(double targetPosition) {
69 double distance = (targetPosition - position.value).abs();
70 if (distance != 0) {
71 double targetDuration = distance / _kWidth * _kBaseSettleDurationMS;
72 double duration = math.min(targetDuration, _kMaxSettleDurationMS);
73 position.animateTo(targetPosition, duration, curve: _kAnimationCurve);
74 }
75 }
76
77 void handleFlingStart(event) {
78 double direction = event.velocityX.sign;
79 double velocityX = event.velocityX.abs() / 1000;
80 if (velocityX < _kMinFlingVelocity)
81 return;
82
83 double targetPosition = direction < 0.0 ? -_kWidth : 0.0;
84 double distance = (targetPosition - position.value).abs();
85 double duration = distance / velocityX;
86
87 if (distance > 0)
88 position.animateTo(targetPosition, duration, curve: linear);
89 }
90 }
91
92 class Drawer extends AnimatedComponent {
93 // TODO(abarth): We need a better way to become a container for absolutely
94 // positioned elements.
95 static final Style _style = new Style('''
96 transform: translateX(0);''');
97
98 static final Style _maskStyle = new Style('''
99 background-color: black;
100 will-change: opacity;
101 position: absolute;
102 top: 0;
103 left: 0;
104 bottom: 0;
105 right: 0;'''
106 );
107
108 static final Style _contentStyle = new Style('''
109 background-color: ${Grey[50]};
110 will-change: transform;
111 position: absolute;
112 width: ${_kWidth}px;
113 top: 0;
114 left: 0;
115 bottom: 0;'''
116 );
117
118 List<UINode> children;
119 int level;
120 DrawerController controller;
121
122 double _position;
123
124 Drawer({
125 Object key,
126 this.controller,
127 this.children,
128 this.level: 0
129 }) : super(key: key) {
130 animateField(controller.position, #_position);
131 }
132
133 UINode build() {
134 String maskInlineStyle = 'opacity: ${(_position / _kWidth + 1) * 0.5}';
135 String contentInlineStyle = 'transform: translateX(${_position}px)';
136
137 var mask = new EventListenerNode(
138 new Container(
139 style: _maskStyle,
140 inlineStyle: maskInlineStyle
141 ),
142 onGestureTap: controller.handleMaskTap,
143 onGestureFlingStart: controller.handleFlingStart
144 );
145
146 Material content = new Material(
147 content: new Container(
148 style: _contentStyle,
149 inlineStyle: contentInlineStyle,
150 children: children
151 ),
152 level: level);
153
154 return new EventListenerNode(
155 new Container(
156 style: _style,
157 children: [ mask, content ]
158 ),
159 onPointerDown: controller.handlePointerDown,
160 onPointerMove: controller.handlePointerMove,
161 onPointerUp: controller.handlePointerUp,
162 onPointerCancel: controller.handlePointerCancel
163 );
164 }
165 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698