Chromium Code Reviews| 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: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 'basic.dart'; | 11 import 'basic.dart'; |
| 12 import 'theme.dart'; | 12 import 'theme.dart'; |
| 13 | 13 |
| 14 // TODO(eseidel): Draw width should vary based on device size: | 14 // TODO(eseidel): Draw width should vary based on device size: |
| 15 // http://www.google.com/design/spec/layout/structure.html#structure-side-nav | 15 // http://www.google.com/design/spec/layout/structure.html#structure-side-nav |
| 16 | 16 |
| 17 // Mobile: | 17 // Mobile: |
| 18 // Width = Screen width − 56 dp | 18 // Width = Screen width − 56 dp |
| 19 // Maximum width: 320dp | 19 // Maximum width: 320dp |
| 20 // Maximum width applies only when using a left nav. When using a right nav, | 20 // 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. | 21 // the panel can cover the full width of the screen. |
| 22 | 22 |
| 23 // Desktop/Tablet: | 23 // Desktop/Tablet: |
| 24 // Maximum width for a left nav is 400dp. | 24 // Maximum width for a left nav is 400dp. |
| 25 // The right nav can vary depending on content. | 25 // The right nav can vary depending on content. |
| 26 | 26 |
| 27 const double _kWidth = 304.0; | 27 const double _kWidth = 304.0; |
| 28 const double _kMinFlingVelocity = 0.4; | 28 const double _kMinFlingVelocity = 0.4; |
| 29 const int _kBaseSettleDurationMS = 246; | 29 const int _kBaseSettleDurationMS = 246; |
| 30 const Curve _kAnimationCurve = parabolicRise; | 30 // 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 // initial timeline when animating (so it doesn't look linear). | |
| 33 const Curve _kAnimationCurve = linear; | |
| 31 | 34 |
| 32 typedef void DrawerStatusChangeHandler (bool showing); | 35 typedef void DrawerStatusChangeHandler (bool showing); |
| 33 | 36 |
| 34 class DrawerController { | 37 class DrawerController { |
| 35 DrawerController(this.onStatusChange) { | 38 DrawerController(this.onStatusChange) { |
| 36 performance = new AnimationPerformance() | 39 performance = new AnimationPerformance() |
| 37 ..duration = new Duration(milliseconds: _kBaseSettleDurationMS) | 40 ..duration = new Duration(milliseconds: _kBaseSettleDurationMS) |
| 38 ..variable = position; | 41 ..variable = position; |
| 39 performance.timeline.onValueChanged.listen(_checkValue); | 42 performance.timeline.onValueChanged.listen(_checkValue); |
| 40 } | 43 } |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 64 | 67 |
| 65 void handleMaskTap(_) => close(); | 68 void handleMaskTap(_) => close(); |
| 66 | 69 |
| 67 // TODO(mpcomplete): Figure out how to generalize these handlers on a | 70 // TODO(mpcomplete): Figure out how to generalize these handlers on a |
| 68 // "PannableThingy" interface. | 71 // "PannableThingy" interface. |
| 69 void handlePointerDown(_) => performance.stop(); | 72 void handlePointerDown(_) => performance.stop(); |
| 70 | 73 |
| 71 void handlePointerMove(sky.PointerEvent event) { | 74 void handlePointerMove(sky.PointerEvent event) { |
| 72 if (performance.isAnimating) | 75 if (performance.isAnimating) |
| 73 return; | 76 return; |
| 74 performance.progress += event.dx / _kWidth; | 77 performance.progress += event.dx / _kWidth; |
|
Matt Perry
2015/07/06 20:30:28
This part is why we need a linear curve. We're upd
| |
| 75 } | 78 } |
| 76 | 79 |
| 77 void handlePointerUp(_) { | 80 void handlePointerUp(_) { |
| 78 if (!performance.isAnimating) | 81 if (!performance.isAnimating) |
| 79 _settle(); | 82 _settle(); |
| 80 } | 83 } |
| 81 | 84 |
| 82 void handlePointerCancel(_) { | 85 void handlePointerCancel(_) { |
| 83 if (!performance.isAnimating) | 86 if (!performance.isAnimating) |
| 84 _settle(); | 87 _settle(); |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 110 level = source.level; | 113 level = source.level; |
| 111 controller = source.controller; | 114 controller = source.controller; |
| 112 super.syncFields(source); | 115 super.syncFields(source); |
| 113 } | 116 } |
| 114 | 117 |
| 115 // TODO(mpcomplete): the animation system should handle building, maybe? Or | 118 // TODO(mpcomplete): the animation system should handle building, maybe? Or |
| 116 // at least setting the transform. Figure out how this could work for things | 119 // at least setting the transform. Figure out how this could work for things |
| 117 // like fades, slides, rotates, pinch, etc. | 120 // like fades, slides, rotates, pinch, etc. |
| 118 Widget build() { | 121 Widget build() { |
| 119 // TODO(mpcomplete): animate as a fade-in. | 122 // TODO(mpcomplete): animate as a fade-in. |
| 120 double scaler = controller.performance.progress + 1.0; | 123 double scaler = controller.performance.progress; |
| 121 Color maskColor = new Color.fromARGB((0x7F * scaler).floor(), 0, 0, 0); | 124 Color maskColor = new Color.fromARGB((0x7F * scaler).floor(), 0, 0, 0); |
| 122 | 125 |
| 123 var mask = new Listener( | 126 var mask = new Listener( |
| 124 child: new Container(decoration: new BoxDecoration(backgroundColor: maskCo lor)), | 127 child: new Container(decoration: new BoxDecoration(backgroundColor: maskCo lor)), |
| 125 onGestureTap: controller.handleMaskTap | 128 onGestureTap: controller.handleMaskTap |
| 126 ); | 129 ); |
| 127 | 130 |
| 128 Widget content = controller.position.build( | 131 Widget content = controller.position.build( |
| 129 new Container( | 132 new Container( |
| 130 decoration: new BoxDecoration( | 133 decoration: new BoxDecoration( |
| 131 backgroundColor: Theme.of(this).canvasColor, | 134 backgroundColor: Theme.of(this).canvasColor, |
| 132 boxShadow: shadows[level]), | 135 boxShadow: shadows[level]), |
| 133 width: _kWidth, | 136 width: _kWidth, |
| 134 child: new Block(children) | 137 child: new Block(children) |
| 135 )); | 138 )); |
| 136 | 139 |
| 137 return new Listener( | 140 return new Listener( |
| 138 child: new Stack([ mask, content ]), | 141 child: new Stack([ mask, content ]), |
| 139 onPointerDown: controller.handlePointerDown, | 142 onPointerDown: controller.handlePointerDown, |
| 140 onPointerMove: controller.handlePointerMove, | 143 onPointerMove: controller.handlePointerMove, |
| 141 onPointerUp: controller.handlePointerUp, | 144 onPointerUp: controller.handlePointerUp, |
| 142 onPointerCancel: controller.handlePointerCancel, | 145 onPointerCancel: controller.handlePointerCancel, |
| 143 onGestureFlingStart: controller.handleFlingStart | 146 onGestureFlingStart: controller.handleFlingStart |
| 144 ); | 147 ); |
| 145 } | 148 } |
| 146 | 149 |
| 147 } | 150 } |
| OLD | NEW |