| OLD | NEW |
| (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/generators.dart'; | |
| 6 import '../animation/mechanics.dart'; | |
| 7 import '../animation/scroll_behavior.dart'; | |
| 8 import '../fn.dart'; | |
| 9 import '../theme/view_configuration.dart' as config; | |
| 10 import 'dart:math' as math; | |
| 11 import 'dart:sky' as sky; | |
| 12 | |
| 13 const double _kMillisecondsPerSecond = 1000.0; | |
| 14 | |
| 15 double _velocityForFlingGesture(sky.GestureEvent event) { | |
| 16 return math.max(-config.kMaxFlingVelocity, math.min(config.kMaxFlingVelocity, | |
| 17 -event.velocityY)) / _kMillisecondsPerSecond; | |
| 18 } | |
| 19 | |
| 20 abstract class ScrollClient { | |
| 21 bool ancestorScrolled(Scrollable ancestor); | |
| 22 } | |
| 23 | |
| 24 abstract class Scrollable extends Component { | |
| 25 | |
| 26 double _scrollOffset = 0.0; | |
| 27 double get scrollOffset => _scrollOffset; | |
| 28 | |
| 29 ScrollBehavior _scrollBehavior; | |
| 30 ScrollBehavior createScrollBehavior(); | |
| 31 ScrollBehavior get scrollBehavior { | |
| 32 if (_scrollBehavior == null) | |
| 33 _scrollBehavior = createScrollBehavior(); | |
| 34 return _scrollBehavior; | |
| 35 } | |
| 36 | |
| 37 Simulation _simulation; | |
| 38 | |
| 39 Scrollable({Object key}) : super(key: key) { | |
| 40 onDidUnmount(_stopSimulation); | |
| 41 } | |
| 42 | |
| 43 UINode buildContent(); | |
| 44 | |
| 45 UINode build() { | |
| 46 return new EventListenerNode( | |
| 47 buildContent(), | |
| 48 onPointerDown: _handlePointerDown, | |
| 49 onPointerUp: _handlePointerUpOrCancel, | |
| 50 onPointerCancel: _handlePointerUpOrCancel, | |
| 51 onGestureFlingStart: _handleFlingStart, | |
| 52 onGestureFlingCancel: _handleFlingCancel, | |
| 53 onGestureScrollUpdate: _handleScrollUpdate, | |
| 54 onWheel: _handleWheel | |
| 55 ); | |
| 56 } | |
| 57 | |
| 58 List<ScrollClient> _registeredScrollClients; | |
| 59 | |
| 60 void registerScrollClient(ScrollClient notifiee) { | |
| 61 if (_registeredScrollClients == null) | |
| 62 _registeredScrollClients = new List<ScrollClient>(); | |
| 63 setState(() { | |
| 64 _registeredScrollClients.add(notifiee); | |
| 65 }); | |
| 66 } | |
| 67 | |
| 68 void unregisterScrollClient(ScrollClient notifiee) { | |
| 69 if (_registeredScrollClients == null) | |
| 70 return; | |
| 71 setState(() { | |
| 72 _registeredScrollClients.remove(notifiee); | |
| 73 }); | |
| 74 } | |
| 75 | |
| 76 bool scrollTo(double newScrollOffset) { | |
| 77 if (newScrollOffset == _scrollOffset) | |
| 78 return false; | |
| 79 setState(() { | |
| 80 _scrollOffset = newScrollOffset; | |
| 81 }); | |
| 82 if (_registeredScrollClients != null) { | |
| 83 var newList = null; | |
| 84 _registeredScrollClients.forEach((target) { | |
| 85 if (target.ancestorScrolled(this)) { | |
| 86 if (newList == null) | |
| 87 newList = new List<ScrollClient>(); | |
| 88 newList.add(target); | |
| 89 } | |
| 90 }); | |
| 91 setState(() { | |
| 92 _registeredScrollClients = newList; | |
| 93 }); | |
| 94 } | |
| 95 return true; | |
| 96 } | |
| 97 | |
| 98 bool scrollBy(double scrollDelta) { | |
| 99 var newScrollOffset = scrollBehavior.applyCurve(_scrollOffset, scrollDelta); | |
| 100 return scrollTo(newScrollOffset); | |
| 101 } | |
| 102 | |
| 103 void _stopSimulation() { | |
| 104 if (_simulation == null) | |
| 105 return; | |
| 106 _simulation.cancel(); | |
| 107 _simulation = null; | |
| 108 } | |
| 109 | |
| 110 void _startSimulation(Particle particle) { | |
| 111 _stopSimulation(); | |
| 112 _simulation = scrollBehavior.release(particle); | |
| 113 if (_simulation == null) | |
| 114 return; | |
| 115 _simulation.onTick.listen((_) => scrollTo(particle.position)); | |
| 116 } | |
| 117 | |
| 118 Particle _createParticle([double velocity = 0.0]) { | |
| 119 return new Particle(position: _scrollOffset, velocity: velocity); | |
| 120 } | |
| 121 | |
| 122 void _handlePointerDown(_) { | |
| 123 _stopSimulation(); | |
| 124 } | |
| 125 | |
| 126 void _handlePointerUpOrCancel(_) { | |
| 127 if (_simulation == null) | |
| 128 _startSimulation(_createParticle()); | |
| 129 } | |
| 130 | |
| 131 void _handleScrollUpdate(sky.GestureEvent event) { | |
| 132 scrollBy(-event.dy); | |
| 133 } | |
| 134 | |
| 135 void _handleFlingStart(sky.GestureEvent event) { | |
| 136 _startSimulation(_createParticle(_velocityForFlingGesture(event))); | |
| 137 } | |
| 138 | |
| 139 void _handleFlingCancel(sky.GestureEvent event) { | |
| 140 _startSimulation(_createParticle()); | |
| 141 } | |
| 142 | |
| 143 void _handleWheel(sky.WheelEvent event) { | |
| 144 scrollBy(-event.offsetY); | |
| 145 } | |
| 146 } | |
| OLD | NEW |