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

Side by Side Diff: sky/sdk/lib/framework/components2/drawer.dart

Issue 1177243002: Refactor fn2.dart, since it breached our 1000-line threshold. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 6 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 '../animation/animated_value.dart';
6 import '../animation/curves.dart';
7 import '../fn2.dart';
8 import '../theme2/colors.dart';
9 import '../theme2/shadows.dart';
10 import 'animated_component.dart';
11 import 'dart:math' as math;
12 import 'dart:sky' as sky;
13 import 'material.dart';
14 import 'package:vector_math/vector_math.dart';
15
16 // TODO(eseidel): Draw width should vary based on device size:
17 // http://www.google.com/design/spec/layout/structure.html#structure-side-nav
18
19 // Mobile:
20 // Width = Screen width − 56 dp
21 // Maximum width: 320dp
22 // Maximum width applies only when using a left nav. When using a right nav,
23 // the panel can cover the full width of the screen.
24
25 // Desktop/Tablet:
26 // Maximum width for a left nav is 400dp.
27 // The right nav can vary depending on content.
28
29 const double _kWidth = 304.0;
30 const double _kMinFlingVelocity = 0.4;
31 const double _kBaseSettleDurationMS = 246.0;
32 const double _kMaxSettleDurationMS = 600.0;
33 const Curve _kAnimationCurve = parabolicRise;
34
35 typedef void DrawerStatusChangeHandler (bool showing);
36
37 class DrawerController {
38
39 DrawerController(this.onStatusChange) {
40 position = new AnimatedValue(-_kWidth, onChange: _checkValue);
41 }
42 final DrawerStatusChangeHandler onStatusChange;
43 AnimatedValue position;
44
45 bool _oldClosedState = true;
46 void _checkValue() {
47 var newClosedState = isClosed;
48 if (onStatusChange != null && _oldClosedState != newClosedState) {
49 onStatusChange(!newClosedState);
50 _oldClosedState = newClosedState;
51 }
52 }
53
54 bool get isClosed => position.value == -_kWidth;
55 bool get _isMostlyClosed => position.value <= -_kWidth / 2;
56 void toggle() => _isMostlyClosed ? _open() : _close();
57
58 void handleMaskTap(_) => _close();
59 void handlePointerDown(_) => position.stop();
60
61 void handlePointerMove(sky.PointerEvent event) {
62 if (position.isAnimating)
63 return;
64 position.value = math.min(0.0, math.max(position.value + event.dx, -_kWidth) );
65 }
66
67 void handlePointerUp(_) {
68 if (!position.isAnimating)
69 _settle();
70 }
71
72 void handlePointerCancel(_) {
73 if (!position.isAnimating)
74 _settle();
75 }
76
77 void _open() => _animateToPosition(0.0);
78
79 void _close() => _animateToPosition(-_kWidth);
80
81 void _settle() => _isMostlyClosed ? _close() : _open();
82
83 void _animateToPosition(double targetPosition) {
84 double distance = (targetPosition - position.value).abs();
85 if (distance != 0) {
86 double targetDuration = distance / _kWidth * _kBaseSettleDurationMS;
87 double duration = math.min(targetDuration, _kMaxSettleDurationMS);
88 position.animateTo(targetPosition, duration, curve: _kAnimationCurve);
89 }
90 }
91
92 void handleFlingStart(event) {
93 double direction = event.velocityX.sign;
94 double velocityX = event.velocityX.abs() / 1000;
95 if (velocityX < _kMinFlingVelocity)
96 return;
97
98 double targetPosition = direction < 0.0 ? -_kWidth : 0.0;
99 double distance = (targetPosition - position.value).abs();
100 double duration = distance / velocityX;
101
102 if (distance > 0)
103 position.animateTo(targetPosition, duration, curve: linear);
104 }
105
106 }
107
108 class Drawer extends AnimatedComponent {
109
110 Drawer({
111 Object key,
112 this.controller,
113 this.children,
114 this.level: 0
115 }) : super(key: key) {
116 animate(controller.position, (double value) {
117 _position = value;
118 });
119 }
120
121 List<UINode> children;
122 int level;
123 DrawerController controller;
124
125 void syncFields(Drawer source) {
126 children = source.children;
127 level = source.level;
128 controller = source.controller;
129 super.syncFields(source);
130 }
131
132 double _position;
133
134 UINode build() {
135 Matrix4 transform = new Matrix4.identity();
136 transform.translate(_position);
137
138 double scaler = _position / _kWidth + 1;
139 Color maskColor = new Color.fromARGB((0x7F * scaler).floor(), 0, 0, 0);
140
141 var mask = new EventListenerNode(
142 new Container(decoration: new BoxDecoration(backgroundColor: maskColor)),
143 onGestureTap: controller.handleMaskTap,
144 onGestureFlingStart: controller.handleFlingStart
145 );
146
147 Container content = new Container(
148 decoration: new BoxDecoration(
149 backgroundColor: Grey[50],
150 boxShadow: Shadow[level]),
151 width: _kWidth,
152 transform: transform,
153 child: new Block(children)
154 );
155
156 return new EventListenerNode(
157 new Stack([ mask, content ]),
158 onPointerDown: controller.handlePointerDown,
159 onPointerMove: controller.handlePointerMove,
160 onPointerUp: controller.handlePointerUp,
161 onPointerCancel: controller.handlePointerCancel
162 );
163 }
164
165 }
OLDNEW
« no previous file with comments | « sky/sdk/lib/framework/components2/checkbox.dart ('k') | sky/sdk/lib/framework/components2/drawer_header.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698