Commit 74f7d9ef authored by Adam Barth's avatar Adam Barth

Move Drawer to GestureDetector

This fixes an issue in the stocks app in horizontal mode where you could both
scroll and drag the drawer at the same time.
parent 4c79cc22
...@@ -15,14 +15,14 @@ enum DragState { ...@@ -15,14 +15,14 @@ enum DragState {
} }
typedef void GestureDragStartCallback(); typedef void GestureDragStartCallback();
typedef void GestureDragUpdateCallback(double scrollDelta); typedef void GestureDragUpdateCallback(double delta);
typedef void GestureDragEndCallback(sky.Offset velocity); typedef void GestureDragEndCallback(sky.Offset velocity);
typedef void GesturePanStartCallback(); typedef void GesturePanStartCallback();
typedef void GesturePanUpdateCallback(sky.Offset scrollDelta); typedef void GesturePanUpdateCallback(sky.Offset delta);
typedef void GesturePanEndCallback(sky.Offset velocity); typedef void GesturePanEndCallback(sky.Offset velocity);
typedef void _GesturePolymorphicUpdateCallback<T>(T scrollDelta); typedef void _GesturePolymorphicUpdateCallback<T>(T delta);
int _eventTime(sky.PointerEvent event) => (event.timeStamp * 1000.0).toInt(); // microseconds int _eventTime(sky.PointerEvent event) => (event.timeStamp * 1000.0).toInt(); // microseconds
...@@ -121,8 +121,7 @@ class VerticalDragGestureRecognizer extends _DragGestureRecognizer<double> { ...@@ -121,8 +121,7 @@ class VerticalDragGestureRecognizer extends _DragGestureRecognizer<double> {
}) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd); }) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd);
double get _initialPendingDragDelta => 0.0; double get _initialPendingDragDelta => 0.0;
// Notice that we negate dy because scroll offsets go in the opposite direction. double _getDragDelta(sky.PointerEvent event) => event.dy;
double _getDragDelta(sky.PointerEvent event) => -event.dy;
bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop; bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop;
} }
...@@ -135,7 +134,7 @@ class HorizontalDragGestureRecognizer extends _DragGestureRecognizer<double> { ...@@ -135,7 +134,7 @@ class HorizontalDragGestureRecognizer extends _DragGestureRecognizer<double> {
}) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd); }) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd);
double get _initialPendingDragDelta => 0.0; double get _initialPendingDragDelta => 0.0;
double _getDragDelta(sky.PointerEvent event) => -event.dx; double _getDragDelta(sky.PointerEvent event) => event.dx;
bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop; bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop;
} }
...@@ -148,8 +147,7 @@ class PanGestureRecognizer extends _DragGestureRecognizer<sky.Offset> { ...@@ -148,8 +147,7 @@ class PanGestureRecognizer extends _DragGestureRecognizer<sky.Offset> {
}) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd); }) : super(router: router, onStart: onStart, onUpdate: onUpdate, onEnd: onEnd);
sky.Offset get _initialPendingDragDelta => sky.Offset.zero; sky.Offset get _initialPendingDragDelta => sky.Offset.zero;
// Notice that we negate dy because scroll offsets go in the opposite direction. sky.Offset _getDragDelta(sky.PointerEvent event) => new sky.Offset(event.dx, event.dy);
sky.Offset _getDragDelta(sky.PointerEvent event) => new sky.Offset(event.dx, -event.dy);
bool get _hasSufficientPendingDragDeltaToAccept { bool get _hasSufficientPendingDragDeltaToAccept {
return _pendingDragDelta.dx.abs() > kTouchSlop || _pendingDragDelta.dy.abs() > kTouchSlop; return _pendingDragDelta.dx.abs() > kTouchSlop || _pendingDragDelta.dy.abs() > kTouchSlop;
} }
......
...@@ -119,7 +119,7 @@ class Dismissable extends StatefulComponent { ...@@ -119,7 +119,7 @@ class Dismissable extends StatefulComponent {
}); });
} }
void _handleDragUpdate(double scrollOffset) { void _handleDragUpdate(double delta) {
if (!_isActive || _fadePerformance.isAnimating) if (!_isActive || _fadePerformance.isAnimating)
return; return;
...@@ -127,19 +127,19 @@ class Dismissable extends StatefulComponent { ...@@ -127,19 +127,19 @@ class Dismissable extends StatefulComponent {
switch(direction) { switch(direction) {
case DismissDirection.horizontal: case DismissDirection.horizontal:
case DismissDirection.vertical: case DismissDirection.vertical:
_dragExtent -= scrollOffset; _dragExtent += delta;
break; break;
case DismissDirection.up: case DismissDirection.up:
case DismissDirection.left: case DismissDirection.left:
if (_dragExtent - scrollOffset < 0) if (_dragExtent + delta < 0)
_dragExtent -= scrollOffset; _dragExtent += delta;
break; break;
case DismissDirection.down: case DismissDirection.down:
case DismissDirection.right: case DismissDirection.right:
if (_dragExtent - scrollOffset > 0) if (_dragExtent + delta > 0)
_dragExtent -= scrollOffset; _dragExtent += delta;
break; break;
} }
......
...@@ -109,13 +109,11 @@ class Drawer extends StatefulComponent { ...@@ -109,13 +109,11 @@ class Drawer extends StatefulComponent {
) )
); );
return new Listener( return new GestureDetector(
child: new Stack([ mask, content ]), onHorizontalDragStart: _performance.stop,
onPointerDown: handlePointerDown, onHorizontalDragUpdate: _handleDragUpdate,
onPointerMove: handlePointerMove, onHorizontalDragEnd: _handleDragEnd,
onPointerUp: handlePointerUp, child: new Stack([ mask, content ])
onPointerCancel: handlePointerCancel,
onGestureFlingStart: handleFlingStart
); );
} }
...@@ -132,41 +130,17 @@ class Drawer extends StatefulComponent { ...@@ -132,41 +130,17 @@ class Drawer extends StatefulComponent {
void _settle() { _isMostlyClosed ? _performance.reverse() : _performance.play(); } void _settle() { _isMostlyClosed ? _performance.reverse() : _performance.play(); }
// TODO(mpcomplete): Figure out how to generalize these handlers on a void _handleDragUpdate(double delta) {
// "PannableThingy" interface. _performance.progress += delta / _kWidth;
EventDisposition handlePointerDown(_) {
_performance.stop();
return EventDisposition.processed;
}
EventDisposition handlePointerMove(sky.PointerEvent event) {
if (_performance.isAnimating)
return EventDisposition.ignored;
_performance.progress += event.dx / _kWidth;
return EventDisposition.processed;
} }
EventDisposition handlePointerUp(_) { void _handleDragEnd(Offset velocity) {
if (!_performance.isAnimating) { if (velocity.dx.abs() >= _kMinFlingVelocity) {
_performance.fling(velocity: velocity.dx * _kFlingVelocityScale);
return;
} else {
_settle(); _settle();
return EventDisposition.processed;
} }
return EventDisposition.ignored;
} }
EventDisposition handlePointerCancel(_) {
if (!_performance.isAnimating) {
_settle();
return EventDisposition.processed;
}
return EventDisposition.ignored;
}
EventDisposition handleFlingStart(event) {
if (event.velocityX.abs() >= _kMinFlingVelocity) {
_performance.fling(velocity: event.velocityX * _kFlingVelocityScale);
return EventDisposition.processed;
}
return EventDisposition.ignored;
}
} }
...@@ -83,7 +83,7 @@ abstract class Scrollable extends StatefulComponent { ...@@ -83,7 +83,7 @@ abstract class Scrollable extends StatefulComponent {
GestureDragUpdateCallback _getDragUpdateHandler(ScrollDirection direction) { GestureDragUpdateCallback _getDragUpdateHandler(ScrollDirection direction) {
if (scrollDirection != direction || !scrollBehavior.isScrollable) if (scrollDirection != direction || !scrollBehavior.isScrollable)
return null; return null;
return scrollBy; return _handleDragUpdate;
} }
GestureDragEndCallback _getDragEndHandler(ScrollDirection direction) { GestureDragEndCallback _getDragEndHandler(ScrollDirection direction) {
...@@ -181,6 +181,12 @@ abstract class Scrollable extends StatefulComponent { ...@@ -181,6 +181,12 @@ abstract class Scrollable extends StatefulComponent {
return EventDisposition.processed; return EventDisposition.processed;
} }
void _handleDragUpdate(double delta) {
// We negate the delta here because a positive scroll offset moves the
// the content up (or to the left) rather than down (or the right).
scrollBy(-delta);
}
void _handleDragEnd(Offset velocity) { void _handleDragEnd(Offset velocity) {
if (velocity != Offset.zero) { if (velocity != Offset.zero) {
_startToEndAnimation(velocity: _scrollVelocity(velocity)); _startToEndAnimation(velocity: _scrollVelocity(velocity));
......
...@@ -53,14 +53,14 @@ void main() { ...@@ -53,14 +53,14 @@ void main() {
router.route(pointer.move(new Point(20.0, 20.0))); router.route(pointer.move(new Point(20.0, 20.0)));
expect(didStartPan, isTrue); expect(didStartPan, isTrue);
didStartPan = false; didStartPan = false;
expect(updatedScrollDelta, new sky.Offset(10.0, -10.0)); expect(updatedScrollDelta, new sky.Offset(10.0, 10.0));
updatedScrollDelta = null; updatedScrollDelta = null;
expect(didEndPan, isFalse); expect(didEndPan, isFalse);
expect(didTap, isFalse); expect(didTap, isFalse);
router.route(pointer.move(new Point(20.0, 25.0))); router.route(pointer.move(new Point(20.0, 25.0)));
expect(didStartPan, isFalse); expect(didStartPan, isFalse);
expect(updatedScrollDelta, new sky.Offset(0.0, -5.0)); expect(updatedScrollDelta, new sky.Offset(0.0, 5.0));
updatedScrollDelta = null; updatedScrollDelta = null;
expect(didEndPan, isFalse); expect(didEndPan, isFalse);
expect(didTap, isFalse); expect(didTap, isFalse);
......
...@@ -43,7 +43,7 @@ void main() { ...@@ -43,7 +43,7 @@ void main() {
Point secondLocation = new Point(10.0, 9.0); Point secondLocation = new Point(10.0, 9.0);
tester.dispatchEvent(pointer.move(secondLocation), firstLocation); tester.dispatchEvent(pointer.move(secondLocation), firstLocation);
expect(didStartDrag, isFalse); expect(didStartDrag, isFalse);
expect(updatedDragDelta, 1.0); expect(updatedDragDelta, -1.0);
updatedDragDelta = null; updatedDragDelta = null;
expect(didEndDrag, isFalse); expect(didEndDrag, isFalse);
...@@ -86,6 +86,6 @@ void main() { ...@@ -86,6 +86,6 @@ void main() {
tester.dispatchEvent(pointer.up(), downLocation); tester.dispatchEvent(pointer.up(), downLocation);
expect(gestureCount, 2); expect(gestureCount, 2);
expect(dragDistance, -20.0); expect(dragDistance, 20.0);
}); });
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment