From 2d4acb8041aef38b9ef3cfc413cb89a52503d9cc Mon Sep 17 00:00:00 2001 From: Adam Barth Date: Thu, 2 Jun 2016 23:45:49 -0700 Subject: [PATCH] Convert drag gestures to use details objects (#4343) Previously we supplied individual parameters to the various drag and pan callbacks. However, that approach isn't extensible because each new parameter is a breaking change to the API. This patch makes a one-time breaking change to the API to provide a "details" object that we can extend over time as we need to expose more information. The first planned extension is adding enough information to accurately produce an overscroll glow on Android. --- dev/manual_tests/mozart.dart | 12 +- packages/flutter/lib/src/gestures/drag.dart | 191 +++++++++++------- .../lib/src/material/bottom_sheet.dart | 10 +- packages/flutter/lib/src/material/drawer.dart | 12 +- packages/flutter/lib/src/material/slider.dart | 10 +- packages/flutter/lib/src/material/switch.dart | 8 +- .../flutter/lib/src/material/time_picker.dart | 10 +- .../flutter/lib/src/rendering/proxy_box.dart | 32 ++- .../flutter/lib/src/widgets/dismissable.dart | 13 +- .../lib/src/widgets/gesture_detector.dart | 47 +++-- .../flutter/lib/src/widgets/scrollable.dart | 10 +- .../lib/src/widgets/semantics_debugger.dart | 4 +- .../lib/src/widgets/text_selection.dart | 8 +- .../test/gestures/long_press_test.dart | 2 +- .../flutter/test/gestures/scroll_test.dart | 12 +- .../test/widget/gesture_detector_test.dart | 24 +-- 16 files changed, 236 insertions(+), 169 deletions(-) diff --git a/dev/manual_tests/mozart.dart b/dev/manual_tests/mozart.dart index 4d875c0e8d9..d1e56436cc3 100644 --- a/dev/manual_tests/mozart.dart +++ b/dev/manual_tests/mozart.dart @@ -48,7 +48,7 @@ class WindowDecoration extends StatelessWidget { final WindowSide side; final Color color; final GestureTapCallback onTap; - final GesturePanUpdateCallback onPanUpdate; + final GestureDragUpdateCallback onPanUpdate; @override Widget build(BuildContext context) { @@ -106,18 +106,18 @@ class _WindowState extends State { Offset _offset = Offset.zero; Size _size = _kInitialWindowSize; - void _handleResizerDrag(Offset delta) { + void _handleResizerDrag(DragUpdateDetails details) { setState(() { _size = new Size( - math.max(0.0, _size.width + delta.dx), - math.max(0.0, _size.height + delta.dy) + math.max(0.0, _size.width + details.delta.dx), + math.max(0.0, _size.height + details.delta.dy) ); }); } - void _handleRepositionDrag(Offset delta) { + void _handleRepositionDrag(DragUpdateDetails details) { setState(() { - _offset += delta; + _offset += details.delta; }); } diff --git a/packages/flutter/lib/src/gestures/drag.dart b/packages/flutter/lib/src/gestures/drag.dart index 01ed58a82cb..a7f04dd467a 100644 --- a/packages/flutter/lib/src/gestures/drag.dart +++ b/packages/flutter/lib/src/gestures/drag.dart @@ -14,52 +14,97 @@ enum _DragState { accepted, } +/// Details for [GestureDragDownCallback]. +class DragDownDetails { + /// Creates details for a [GestureDragDownCallback]. + /// + /// The [globalPosition] argument must not be null. + DragDownDetails({ this.globalPosition: Point.origin }) { + assert(globalPosition != null); + } + + /// The global position at which the pointer contacted the screen. + final Point globalPosition; +} + /// Signature for when a pointer has contacted the screen and might begin to move. -typedef void GestureDragDownCallback(Point globalPosition); +typedef void GestureDragDownCallback(DragDownDetails details); + +/// Details for [GestureDragStartCallback]. +class DragStartDetails { + /// Creates details for a [GestureDragStartCallback]. + /// + /// The [globalPosition] argument must not be null. + DragStartDetails({ this.globalPosition: Point.origin }) { + assert(globalPosition != null); + } + + /// The global position at which the pointer contacted the screen. + final Point globalPosition; +} /// Signature for when a pointer has contacted the screen and has begun to move. -typedef void GestureDragStartCallback(Point globalPosition); +typedef void GestureDragStartCallback(DragStartDetails details); + +/// Details for [GestureDragUpdateCallback]. +class DragUpdateDetails { + /// Creates details for a [DragUpdateDetails]. + /// + /// The [delta] argument must not be null. + /// + /// If [primaryDelta] is non-null, then its value must match one of the + /// coordinates of [delta] and the other coordinate must be zero. + DragUpdateDetails({ + this.delta: Offset.zero, + this.primaryDelta: 0.0 + }) { + assert(primaryDelta == null + || (primaryDelta == delta.dx && delta.dy == 0.0) + || (primaryDelta == delta.dy && delta.dx == 0.0)); + } + + /// The amount the pointer has moved since the previous update. + /// + /// If the [GestureDragUpdateCallback] is for a one-dimensional drag (e.g., + /// a horizontal or vertical drag), then this offset contains only the delta + /// in that direction (i.e., the coordinate in the other direction is zero). + final Offset delta; + + /// The amount the pointer has moved along the primary axis since the previous + /// update. + /// + /// If the [GestureDragUpdateCallback] is for a one-dimensional drag (e.g., + /// a horizontal or vertical drag), then this value contains the non-zero + /// component of [delta]. Otherwise, if the [GestureDragUpdateCallback] is for + /// a two-dimensional drag (e.g., a pan), then this value is zero. + final double primaryDelta; +} /// Signature for when a pointer that is in contact with the screen and moving -/// in a direction (e.g., vertically or horizontally) has moved in that -/// direction. -typedef void GestureDragUpdateCallback(double delta); +/// has moved again. +typedef void GestureDragUpdateCallback(DragUpdateDetails details); + +/// Details for [GestureDragEndCallback]. +class DragEndDetails { + /// Creates details for a [GestureDragEndCallback]. + /// + /// The [velocity] argument must not be null. + DragEndDetails({ this.velocity: Velocity.zero }) { + assert(velocity != null); + } + + /// The velocity the pointer was moving when it stopped contacting the screen. + final Velocity velocity; +} /// Signature for when a pointer that was previously in contact with the screen -/// and moving in a direction (e.g., vertically or horizontally) is no longer in -/// contact with the screen and was moving at a specific velocity when it -/// stopped contacting the screen. -typedef void GestureDragEndCallback(Velocity velocity); +/// and moving is no longer in contact with the screen. +typedef void GestureDragEndCallback(DragEndDetails details); /// Signature for when the pointer that previously triggered a /// [GestureDragDownCallback] did not complete. typedef void GestureDragCancelCallback(); -/// Signature for when a pointer has contacted the screen and might begin to move. -typedef void GesturePanDownCallback(Point globalPosition); - -/// Signature for when a pointer has contacted the screen and has begun to move. -typedef void GesturePanStartCallback(Point globalPosition); - -/// Signature for when a pointer that is in contact with the screen and moving -/// has moved again. -typedef void GesturePanUpdateCallback(Offset delta); - -/// Signature for when a pointer that was previously in contact with the screen -/// and moving is no longer in contact with the screen and was moving at a -/// specific velocity when it stopped contacting the screen. -typedef void GesturePanEndCallback(Velocity velocity); - -/// Signature for when the pointer that previously triggered a -/// [GesturePanDownCallback] did not complete. -typedef void GesturePanCancelCallback(); - -/// Signature for when a pointer that is in contact with the screen and moving -/// has moved again. For one-dimensional drags (e.g., horizontal or vertical), -/// T is `double`, as in [GestureDragUpdateCallback]. For two-dimensional drags -/// (e.g., pans), T is `Offset`, as in GesturePanUpdateCallback. -typedef void GesturePolymorphicUpdateCallback(T delta); - bool _isFlingGesture(Velocity velocity) { assert(velocity != null); final double speedSquared = velocity.pixelsPerSecond.distanceSquared; @@ -82,9 +127,7 @@ bool _isFlingGesture(Velocity velocity) { /// * [HorizontalDragGestureRecognizer] /// * [VerticalDragGestureRecognizer] /// * [PanGestureRecognizer] -// Having T extend dynamic makes it possible to use the += operator on -// _pendingDragDelta without causing an analysis error. -abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer { +abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer { /// A pointer has contacted the screen and might begin to move. GestureDragDownCallback onDown; @@ -92,7 +135,7 @@ abstract class DragGestureRecognizer extends OneSequenceGestu GestureDragStartCallback onStart; /// A pointer that is in contact with the screen and moving has moved again. - GesturePolymorphicUpdateCallback onUpdate; + GestureDragUpdateCallback onUpdate; /// A pointer that was previously in contact with the screen and moving is no /// longer in contact with the screen and was moving at a specific velocity @@ -104,10 +147,10 @@ abstract class DragGestureRecognizer extends OneSequenceGestu _DragState _state = _DragState.ready; Point _initialPosition; - T _pendingDragDelta; + Offset _pendingDragOffset; - T get _initialPendingDragDelta; - T _getDragDelta(PointerEvent event); + Offset _getDeltaForDetails(Offset delta); + double _getPrimaryDeltaForDetails(Offset delta); bool get _hasSufficientPendingDragDeltaToAccept; Map _velocityTrackers = new Map(); @@ -119,9 +162,9 @@ abstract class DragGestureRecognizer extends OneSequenceGestu if (_state == _DragState.ready) { _state = _DragState.possible; _initialPosition = event.position; - _pendingDragDelta = _initialPendingDragDelta; + _pendingDragOffset = Offset.zero; if (onDown != null) - onDown(_initialPosition); + onDown(new DragDownDetails(globalPosition: _initialPosition)); } } @@ -132,12 +175,16 @@ abstract class DragGestureRecognizer extends OneSequenceGestu VelocityTracker tracker = _velocityTrackers[event.pointer]; assert(tracker != null); tracker.addPosition(event.timeStamp, event.position); - T delta = _getDragDelta(event); + Offset delta = event.delta; if (_state == _DragState.accepted) { - if (onUpdate != null) - onUpdate(delta); + if (onUpdate != null) { + onUpdate(new DragUpdateDetails( + delta: _getDeltaForDetails(delta), + primaryDelta: _getPrimaryDeltaForDetails(delta) + )); + } } else { - _pendingDragDelta += delta; + _pendingDragOffset += delta; if (_hasSufficientPendingDragDeltaToAccept) resolve(GestureDisposition.accepted); } @@ -149,12 +196,16 @@ abstract class DragGestureRecognizer extends OneSequenceGestu void acceptGesture(int pointer) { if (_state != _DragState.accepted) { _state = _DragState.accepted; - T delta = _pendingDragDelta; - _pendingDragDelta = _initialPendingDragDelta; + Offset delta = _pendingDragOffset; + _pendingDragOffset = Offset.zero; if (onStart != null) - onStart(_initialPosition); - if (delta != _initialPendingDragDelta && onUpdate != null) - onUpdate(delta); + onStart(new DragStartDetails(globalPosition: _initialPosition)); + if (delta != Offset.zero && onUpdate != null) { + onUpdate(new DragUpdateDetails( + delta: _getDeltaForDetails(delta), + primaryDelta: _getPrimaryDeltaForDetails(delta) + )); + } } } @@ -183,9 +234,9 @@ abstract class DragGestureRecognizer extends OneSequenceGestu final Offset pixelsPerSecond = velocity.pixelsPerSecond; if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity) velocity = new Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity); - onEnd(velocity); + onEnd(new DragEndDetails(velocity: velocity)); } else { - onEnd(Velocity.zero); + onEnd(new DragEndDetails(velocity: Velocity.zero)); } } _velocityTrackers.clear(); @@ -205,15 +256,15 @@ abstract class DragGestureRecognizer extends OneSequenceGestu /// See also: /// /// * [VerticalMultiDragGestureRecognizer] -class VerticalDragGestureRecognizer extends DragGestureRecognizer { +class VerticalDragGestureRecognizer extends DragGestureRecognizer { @override - double get _initialPendingDragDelta => 0.0; + bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragOffset.dy.abs() > kTouchSlop; @override - double _getDragDelta(PointerEvent event) => event.delta.dy; + Offset _getDeltaForDetails(Offset delta) => new Offset(0.0, delta.dy); @override - bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop; + double _getPrimaryDeltaForDetails(Offset delta) => delta.dy; @override String toStringShort() => 'vertical drag'; @@ -226,15 +277,15 @@ class VerticalDragGestureRecognizer extends DragGestureRecognizer { /// See also: /// /// * [HorizontalMultiDragGestureRecognizer] -class HorizontalDragGestureRecognizer extends DragGestureRecognizer { +class HorizontalDragGestureRecognizer extends DragGestureRecognizer { @override - double get _initialPendingDragDelta => 0.0; + bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragOffset.dx.abs() > kTouchSlop; @override - double _getDragDelta(PointerEvent event) => event.delta.dx; + Offset _getDeltaForDetails(Offset delta) => new Offset(delta.dx, 0.0); @override - bool get _hasSufficientPendingDragDeltaToAccept => _pendingDragDelta.abs() > kTouchSlop; + double _getPrimaryDeltaForDetails(Offset delta) => delta.dx; @override String toStringShort() => 'horizontal drag'; @@ -246,18 +297,18 @@ class HorizontalDragGestureRecognizer extends DragGestureRecognizer { /// /// * [ImmediateMultiDragGestureRecognizer] /// * [DelayedMultiDragGestureRecognizer] -class PanGestureRecognizer extends DragGestureRecognizer { - @override - Offset get _initialPendingDragDelta => Offset.zero; - - @override - Offset _getDragDelta(PointerEvent event) => event.delta; - +class PanGestureRecognizer extends DragGestureRecognizer { @override bool get _hasSufficientPendingDragDeltaToAccept { - return _pendingDragDelta.distance > kPanSlop; + return _pendingDragOffset.distance > kPanSlop; } + @override + Offset _getDeltaForDetails(Offset delta) => delta; + + @override + double _getPrimaryDeltaForDetails(Offset delta) => null; + @override String toStringShort() => 'pan'; } diff --git a/packages/flutter/lib/src/material/bottom_sheet.dart b/packages/flutter/lib/src/material/bottom_sheet.dart index 91243b54b39..45743e7466a 100644 --- a/packages/flutter/lib/src/material/bottom_sheet.dart +++ b/packages/flutter/lib/src/material/bottom_sheet.dart @@ -97,17 +97,17 @@ class _BottomSheetState extends State { bool get _dismissUnderway => config.animationController.status == AnimationStatus.reverse; - void _handleDragUpdate(double delta) { + void _handleDragUpdate(DragUpdateDetails details) { if (_dismissUnderway) return; - config.animationController.value -= delta / (_childHeight ?? delta); + config.animationController.value -= details.primaryDelta / (_childHeight ?? details.primaryDelta); } - void _handleDragEnd(Velocity velocity) { + void _handleDragEnd(DragEndDetails details) { if (_dismissUnderway) return; - if (velocity.pixelsPerSecond.dy > _kMinFlingVelocity) { - double flingVelocity = -velocity.pixelsPerSecond.dy / _childHeight; + if (details.velocity.pixelsPerSecond.dy > _kMinFlingVelocity) { + double flingVelocity = -details.velocity.pixelsPerSecond.dy / _childHeight; config.animationController.fling(velocity: flingVelocity); if (flingVelocity < 0.0) config.onClosing(); diff --git a/packages/flutter/lib/src/material/drawer.dart b/packages/flutter/lib/src/material/drawer.dart index 9862ef56ae9..c6c5567d566 100644 --- a/packages/flutter/lib/src/material/drawer.dart +++ b/packages/flutter/lib/src/material/drawer.dart @@ -173,7 +173,7 @@ class DrawerControllerState extends State { AnimationController _controller; - void _handleDragDown(Point position) { + void _handleDragDown(DragDownDetails details) { _controller.stop(); _ensureHistoryEntry(); } @@ -195,15 +195,15 @@ class DrawerControllerState extends State { return _kWidth; // drawer not being shown currently } - void _move(double delta) { - _controller.value += delta / _width; + void _move(DragUpdateDetails details) { + _controller.value += details.primaryDelta / _width; } - void _settle(Velocity velocity) { + void _settle(DragEndDetails details) { if (_controller.isDismissed) return; - if (velocity.pixelsPerSecond.dx.abs() >= _kMinFlingVelocity) { - _controller.fling(velocity: velocity.pixelsPerSecond.dx / _width); + if (details.velocity.pixelsPerSecond.dx.abs() >= _kMinFlingVelocity) { + _controller.fling(velocity: details.velocity.pixelsPerSecond.dx / _width); } else if (_controller.value < 0.5) { close(); } else { diff --git a/packages/flutter/lib/src/material/slider.dart b/packages/flutter/lib/src/material/slider.dart index fe38837f66f..f474a312d10 100644 --- a/packages/flutter/lib/src/material/slider.dart +++ b/packages/flutter/lib/src/material/slider.dart @@ -290,24 +290,24 @@ class _RenderSlider extends RenderConstrainedBox { return dragValue; } - void _handleDragStart(Point globalPosition) { + void _handleDragStart(DragStartDetails details) { if (onChanged != null) { _active = true; - _currentDragValue = (globalToLocal(globalPosition).x - _kReactionRadius) / _trackLength; + _currentDragValue = (globalToLocal(details.globalPosition).x - _kReactionRadius) / _trackLength; onChanged(_discretizedCurrentDragValue); _reactionController.forward(); markNeedsPaint(); } } - void _handleDragUpdate(double delta) { + void _handleDragUpdate(DragUpdateDetails details) { if (onChanged != null) { - _currentDragValue += delta / _trackLength; + _currentDragValue += details.primaryDelta / _trackLength; onChanged(_discretizedCurrentDragValue); } } - void _handleDragEnd(Velocity velocity) { + void _handleDragEnd(DragEndDetails details) { if (_active) { _active = false; _currentDragValue = 0.0; diff --git a/packages/flutter/lib/src/material/switch.dart b/packages/flutter/lib/src/material/switch.dart index ec71410a4c9..8dd6d1ac233 100644 --- a/packages/flutter/lib/src/material/switch.dart +++ b/packages/flutter/lib/src/material/switch.dart @@ -270,21 +270,21 @@ class _RenderSwitch extends RenderToggleable { HorizontalDragGestureRecognizer _drag; - void _handleDragStart(Point globalPosition) { + void _handleDragStart(DragStartDetails details) { if (onChanged != null) reactionController.forward(); } - void _handleDragUpdate(double delta) { + void _handleDragUpdate(DragUpdateDetails details) { if (onChanged != null) { position ..curve = null ..reverseCurve = null; - positionController.value += delta / _trackInnerLength; + positionController.value += details.primaryDelta / _trackInnerLength; } } - void _handleDragEnd(Velocity velocity) { + void _handleDragEnd(DragEndDetails details) { if (position.value >= 0.5) positionController.forward(); else diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart index c6ac8f3f56e..8b986f9d2a8 100644 --- a/packages/flutter/lib/src/material/time_picker.dart +++ b/packages/flutter/lib/src/material/time_picker.dart @@ -489,24 +489,24 @@ class _DialState extends State<_Dial> { Point _position; Point _center; - void _handlePanStart(Point globalPosition) { + void _handlePanStart(DragStartDetails details) { assert(!_dragging); _dragging = true; RenderBox box = context.findRenderObject(); - _position = box.globalToLocal(globalPosition); + _position = box.globalToLocal(details.globalPosition); double radius = box.size.shortestSide / 2.0; _center = new Point(radius, radius); _updateThetaForPan(); _notifyOnChangedIfNeeded(); } - void _handlePanUpdate(Offset delta) { - _position += delta; + void _handlePanUpdate(DragUpdateDetails details) { + _position += details.delta; _updateThetaForPan(); _notifyOnChangedIfNeeded(); } - void _handlePanEnd(Velocity velocity) { + void _handlePanEnd(DragEndDetails details) { assert(_dragging); _dragging = false; _position = null; diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index fd756e6c10d..11b805e90f7 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -2102,26 +2102,42 @@ class RenderSemanticsGestureHandler extends RenderProxyBox implements SemanticAc @override void handleSemanticScrollLeft() { - if (onHorizontalDragUpdate != null) - onHorizontalDragUpdate(size.width * -scrollFactor); + if (onHorizontalDragUpdate != null) { + final double primaryDelta = size.width * -scrollFactor; + onHorizontalDragUpdate(new DragUpdateDetails( + delta: new Offset(primaryDelta, 0.0), primaryDelta: primaryDelta + )); + } } @override void handleSemanticScrollRight() { - if (onHorizontalDragUpdate != null) - onHorizontalDragUpdate(size.width * scrollFactor); + if (onHorizontalDragUpdate != null) { + final double primaryDelta = size.width * scrollFactor; + onHorizontalDragUpdate(new DragUpdateDetails( + delta: new Offset(primaryDelta, 0.0), primaryDelta: primaryDelta + )); + } } @override void handleSemanticScrollUp() { - if (onVerticalDragUpdate != null) - onVerticalDragUpdate(size.height * -scrollFactor); + if (onVerticalDragUpdate != null) { + final double primaryDelta = size.height * -scrollFactor; + onVerticalDragUpdate(new DragUpdateDetails( + delta: new Offset(0.0, primaryDelta), primaryDelta: primaryDelta + )); + } } @override void handleSemanticScrollDown() { - if (onVerticalDragUpdate != null) - onVerticalDragUpdate(size.height * scrollFactor); + if (onVerticalDragUpdate != null) { + final double primaryDelta = size.height * scrollFactor; + onVerticalDragUpdate(new DragUpdateDetails( + delta: new Offset(0.0, primaryDelta), primaryDelta: primaryDelta + )); + } } } diff --git a/packages/flutter/lib/src/widgets/dismissable.dart b/packages/flutter/lib/src/widgets/dismissable.dart index 619658b604d..5f348bcf20d 100644 --- a/packages/flutter/lib/src/widgets/dismissable.dart +++ b/packages/flutter/lib/src/widgets/dismissable.dart @@ -151,7 +151,7 @@ class _DismissableState extends State { return box.size; } - void _handleDragStart(_) { + void _handleDragStart(DragStartDetails details) { _dragUnderway = true; if (_moveController.isAnimating) { _dragExtent = _moveController.value * _findSize().width * _dragExtent.sign; @@ -165,11 +165,12 @@ class _DismissableState extends State { }); } - void _handleDragUpdate(double delta) { + void _handleDragUpdate(DragUpdateDetails details) { if (!_isActive || _moveController.isAnimating) return; - double oldDragExtent = _dragExtent; + final double delta = details.primaryDelta; + final double oldDragExtent = _dragExtent; switch (config.direction) { case DismissDirection.horizontal: case DismissDirection.vertical: @@ -236,14 +237,14 @@ class _DismissableState extends State { return false; } - void _handleDragEnd(Velocity velocity) { + void _handleDragEnd(DragEndDetails details) { if (!_isActive || _moveController.isAnimating) return; _dragUnderway = false; if (_moveController.isCompleted) { _startResizeAnimation(); - } else if (_isFlingGesture(velocity)) { - double flingVelocity = _directionIsXAxis ? velocity.pixelsPerSecond.dx : velocity.pixelsPerSecond.dy; + } else if (_isFlingGesture(details.velocity)) { + double flingVelocity = _directionIsXAxis ? details.velocity.pixelsPerSecond.dx : details.velocity.pixelsPerSecond.dy; _dragExtent = flingVelocity.sign; _moveController.fling(velocity: flingVelocity.abs() * _kFlingVelocityScale); } else if (_moveController.value > _kDismissThreshold) { diff --git a/packages/flutter/lib/src/widgets/gesture_detector.dart b/packages/flutter/lib/src/widgets/gesture_detector.dart index 22e7d7ab532..70b702e2acf 100644 --- a/packages/flutter/lib/src/widgets/gesture_detector.dart +++ b/packages/flutter/lib/src/widgets/gesture_detector.dart @@ -9,6 +9,10 @@ import 'basic.dart'; import 'framework.dart'; export 'package:flutter/gestures.dart' show + DragDownDetails, + DragStartDetails, + DragUpdateDetails, + DragEndDetails, GestureTapDownCallback, GestureTapUpCallback, GestureTapCallback, @@ -19,11 +23,6 @@ export 'package:flutter/gestures.dart' show GestureDragUpdateCallback, GestureDragEndCallback, GestureDragCancelCallback, - GesturePanDownCallback, - GesturePanStartCallback, - GesturePanUpdateCallback, - GesturePanEndCallback, - GesturePanCancelCallback, GestureScaleStartCallback, GestureScaleUpdateCallback, GestureScaleEndCallback, @@ -162,21 +161,21 @@ class GestureDetector extends StatelessWidget { final GestureDragCancelCallback onHorizontalDragCancel; /// A pointer has contacted the screen and might begin to move. - final GesturePanDownCallback onPanDown; + final GestureDragDownCallback onPanDown; /// A pointer has contacted the screen and has begun to move. - final GesturePanStartCallback onPanStart; + final GestureDragStartCallback onPanStart; /// A pointer that is in contact with the screen and moving has moved again. - final GesturePanUpdateCallback onPanUpdate; + final GestureDragUpdateCallback onPanUpdate; /// A pointer that was previously in contact with the screen and moving /// is no longer in contact with the screen and was moving at a specific /// velocity when it stopped contacting the screen. - final GesturePanEndCallback onPanEnd; + final GestureDragEndCallback onPanEnd; /// The pointer that previously triggered [onPanDown] did not complete. - final GesturePanCancelCallback onPanCancel; + final GestureDragCancelCallback onPanCancel; /// The pointers in contact with the screen have established a focal point and /// initial scale of 1.0. @@ -474,16 +473,16 @@ class _GestureSemantics extends SingleChildRenderObjectWidget { recognizer.onLongPress(); } - void _handleHorizontalDragUpdate(double delta) { + void _handleHorizontalDragUpdate(DragUpdateDetails updateDetails) { { HorizontalDragGestureRecognizer recognizer = owner._recognizers[HorizontalDragGestureRecognizer]; if (recognizer != null) { if (recognizer.onStart != null) - recognizer.onStart(Point.origin); + recognizer.onStart(new DragStartDetails()); if (recognizer.onUpdate != null) - recognizer.onUpdate(delta); + recognizer.onUpdate(updateDetails); if (recognizer.onEnd != null) - recognizer.onEnd(Velocity.zero); + recognizer.onEnd(new DragEndDetails()); return; } } @@ -491,27 +490,27 @@ class _GestureSemantics extends SingleChildRenderObjectWidget { PanGestureRecognizer recognizer = owner._recognizers[PanGestureRecognizer]; if (recognizer != null) { if (recognizer.onStart != null) - recognizer.onStart(Point.origin); + recognizer.onStart(new DragStartDetails()); if (recognizer.onUpdate != null) - recognizer.onUpdate(new Offset(delta, 0.0)); + recognizer.onUpdate(updateDetails); if (recognizer.onEnd != null) - recognizer.onEnd(Velocity.zero); + recognizer.onEnd(new DragEndDetails()); return; } } assert(false); } - void _handleVerticalDragUpdate(double delta) { + void _handleVerticalDragUpdate(DragUpdateDetails updateDetails) { { VerticalDragGestureRecognizer recognizer = owner._recognizers[VerticalDragGestureRecognizer]; if (recognizer != null) { if (recognizer.onStart != null) - recognizer.onStart(Point.origin); + recognizer.onStart(new DragStartDetails()); if (recognizer.onUpdate != null) - recognizer.onUpdate(delta); + recognizer.onUpdate(updateDetails); if (recognizer.onEnd != null) - recognizer.onEnd(Velocity.zero); + recognizer.onEnd(new DragEndDetails()); return; } } @@ -519,11 +518,11 @@ class _GestureSemantics extends SingleChildRenderObjectWidget { PanGestureRecognizer recognizer = owner._recognizers[PanGestureRecognizer]; if (recognizer != null) { if (recognizer.onStart != null) - recognizer.onStart(Point.origin); + recognizer.onStart(new DragStartDetails()); if (recognizer.onUpdate != null) - recognizer.onUpdate(new Offset(0.0, delta)); + recognizer.onUpdate(updateDetails); if (recognizer.onEnd != null) - recognizer.onEnd(Velocity.zero); + recognizer.onEnd(new DragEndDetails()); return; } } diff --git a/packages/flutter/lib/src/widgets/scrollable.dart b/packages/flutter/lib/src/widgets/scrollable.dart index 74272847e7e..5d72dd9da41 100644 --- a/packages/flutter/lib/src/widgets/scrollable.dart +++ b/packages/flutter/lib/src/widgets/scrollable.dart @@ -522,7 +522,7 @@ class ScrollableState extends State { _simulation = null; } - void _handleDragStart(_) { + void _handleDragStart(DragStartDetails details) { _startScroll(); } @@ -542,12 +542,12 @@ class ScrollableState extends State { new ScrollNotification(this, ScrollNotificationKind.started).dispatch(context); } - void _handleDragUpdate(double delta) { - scrollBy(pixelOffsetToScrollOffset(delta)); + void _handleDragUpdate(DragUpdateDetails details) { + scrollBy(pixelOffsetToScrollOffset(details.primaryDelta)); } - Future _handleDragEnd(Velocity velocity) { - double scrollVelocity = pixelDeltaToScrollOffset(velocity.pixelsPerSecond) / Duration.MILLISECONDS_PER_SECOND; + Future _handleDragEnd(DragEndDetails details) { + double scrollVelocity = pixelDeltaToScrollOffset(details.velocity.pixelsPerSecond) / Duration.MILLISECONDS_PER_SECOND; return fling(scrollVelocity).then(_endScroll); } diff --git a/packages/flutter/lib/src/widgets/semantics_debugger.dart b/packages/flutter/lib/src/widgets/semantics_debugger.dart index 686df6e0d6c..0fd8bcf1825 100644 --- a/packages/flutter/lib/src/widgets/semantics_debugger.dart +++ b/packages/flutter/lib/src/widgets/semantics_debugger.dart @@ -66,9 +66,9 @@ class _SemanticsDebuggerState extends State { _lastPointerDownLocation = null; }); } - void _handlePanEnd(Velocity velocity) { + void _handlePanEnd(DragEndDetails details) { assert(_lastPointerDownLocation != null); - _SemanticsDebuggerListener.instance.handlePanEnd(_lastPointerDownLocation, velocity); + _SemanticsDebuggerListener.instance.handlePanEnd(_lastPointerDownLocation, details.velocity); setState(() { _lastPointerDownLocation = null; }); diff --git a/packages/flutter/lib/src/widgets/text_selection.dart b/packages/flutter/lib/src/widgets/text_selection.dart index 1cc9f524241..c08ea39952b 100644 --- a/packages/flutter/lib/src/widgets/text_selection.dart +++ b/packages/flutter/lib/src/widgets/text_selection.dart @@ -205,12 +205,12 @@ class _TextSelectionHandleOverlay extends StatefulWidget { class _TextSelectionHandleOverlayState extends State<_TextSelectionHandleOverlay> { Point _dragPosition; - void _handleDragStart(Point position) { - _dragPosition = position; + void _handleDragStart(DragStartDetails details) { + _dragPosition = details.globalPosition; } - void _handleDragUpdate(double delta) { - _dragPosition += new Offset(delta, 0.0); + void _handleDragUpdate(DragUpdateDetails details) { + _dragPosition += details.delta; TextPosition position = config.renderObject.getPositionForPoint(_dragPosition); if (config.selection.isCollapsed) { diff --git a/packages/flutter/test/gestures/long_press_test.dart b/packages/flutter/test/gestures/long_press_test.dart index 756050f1c80..7bedff9fdb0 100644 --- a/packages/flutter/test/gestures/long_press_test.dart +++ b/packages/flutter/test/gestures/long_press_test.dart @@ -104,7 +104,7 @@ void main() { bool isDangerousStack = false; bool dragStartRecognized = false; - drag.onStart = (Point globalPosition) { + drag.onStart = (DragStartDetails details) { expect(isDangerousStack, isFalse); dragStartRecognized = true; }; diff --git a/packages/flutter/test/gestures/scroll_test.dart b/packages/flutter/test/gestures/scroll_test.dart index 4d623867d29..36b3036c658 100644 --- a/packages/flutter/test/gestures/scroll_test.dart +++ b/packages/flutter/test/gestures/scroll_test.dart @@ -20,12 +20,12 @@ void main() { }; Offset updatedScrollDelta; - pan.onUpdate = (Offset offset) { - updatedScrollDelta = offset; + pan.onUpdate = (DragUpdateDetails details) { + updatedScrollDelta = details.delta; }; bool didEndPan = false; - pan.onEnd = (Velocity velocity) { + pan.onEnd = (DragEndDetails details) { didEndPan = true; }; @@ -85,12 +85,12 @@ void main() { }; double updatedDelta; - drag.onUpdate = (double delta) { - updatedDelta = delta; + drag.onUpdate = (DragUpdateDetails details) { + updatedDelta = details.primaryDelta; }; bool didEndDrag = false; - drag.onEnd = (Velocity velocity) { + drag.onEnd = (DragEndDetails details) { didEndDrag = true; }; diff --git a/packages/flutter/test/widget/gesture_detector_test.dart b/packages/flutter/test/widget/gesture_detector_test.dart index 182af1e4798..4bb42c81bdd 100644 --- a/packages/flutter/test/widget/gesture_detector_test.dart +++ b/packages/flutter/test/widget/gesture_detector_test.dart @@ -12,13 +12,13 @@ void main() { bool didEndDrag = false; Widget widget = new GestureDetector( - onVerticalDragStart: (_) { + onVerticalDragStart: (DragStartDetails details) { didStartDrag = true; }, - onVerticalDragUpdate: (double scrollDelta) { - updatedDragDelta = scrollDelta; + onVerticalDragUpdate: (DragUpdateDetails details) { + updatedDragDelta = details.primaryDelta; }, - onVerticalDragEnd: (Velocity velocity) { + onVerticalDragEnd: (DragEndDetails details) { didEndDrag = true; }, child: new Container( @@ -64,10 +64,10 @@ void main() { Point upLocation = new Point(10.0, 20.0); Widget widget = new GestureDetector( - onVerticalDragUpdate: (double delta) { dragDistance += delta; }, - onVerticalDragEnd: (Velocity velocity) { gestureCount += 1; }, - onHorizontalDragUpdate: (_) { fail("gesture should not match"); }, - onHorizontalDragEnd: (Velocity velocity) { fail("gesture should not match"); }, + onVerticalDragUpdate: (DragUpdateDetails details) { dragDistance += details.primaryDelta; }, + onVerticalDragEnd: (DragEndDetails details) { gestureCount += 1; }, + onHorizontalDragUpdate: (DragUpdateDetails details) { fail("gesture should not match"); }, + onHorizontalDragEnd: (DragEndDetails details) { fail("gesture should not match"); }, child: new Container( decoration: const BoxDecoration( backgroundColor: const Color(0xFF00FF00) @@ -97,13 +97,13 @@ void main() { await tester.pumpWidget( new GestureDetector( - onPanStart: (_) { + onPanStart: (DragStartDetails details) { didStartPan = true; }, - onPanUpdate: (Offset delta) { - panDelta = delta; + onPanUpdate: (DragUpdateDetails details) { + panDelta = details.delta; }, - onPanEnd: (_) { + onPanEnd: (DragEndDetails details) { didEndPan = true; }, child: new Container(