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.
This commit is contained in:
Adam Barth 2016-06-02 23:45:49 -07:00
parent 5245d3889d
commit 2d4acb8041
16 changed files with 236 additions and 169 deletions

View file

@ -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<Window> {
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;
});
}

View file

@ -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>(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<T extends dynamic> 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<T extends dynamic> extends OneSequenceGestu
GestureDragStartCallback onStart;
/// A pointer that is in contact with the screen and moving has moved again.
GesturePolymorphicUpdateCallback<T> 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<T extends dynamic> 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<int, VelocityTracker> _velocityTrackers = new Map<int, VelocityTracker>();
@ -119,9 +162,9 @@ abstract class DragGestureRecognizer<T extends dynamic> 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<T extends dynamic> 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<T extends dynamic> 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<T extends dynamic> 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<T extends dynamic> extends OneSequenceGestu
/// See also:
///
/// * [VerticalMultiDragGestureRecognizer]
class VerticalDragGestureRecognizer extends DragGestureRecognizer<double> {
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<double> {
/// See also:
///
/// * [HorizontalMultiDragGestureRecognizer]
class HorizontalDragGestureRecognizer extends DragGestureRecognizer<double> {
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<double> {
///
/// * [ImmediateMultiDragGestureRecognizer]
/// * [DelayedMultiDragGestureRecognizer]
class PanGestureRecognizer extends DragGestureRecognizer<Offset> {
@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';
}

View file

@ -97,17 +97,17 @@ class _BottomSheetState extends State<BottomSheet> {
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();

View file

@ -173,7 +173,7 @@ class DrawerControllerState extends State<DrawerController> {
AnimationController _controller;
void _handleDragDown(Point position) {
void _handleDragDown(DragDownDetails details) {
_controller.stop();
_ensureHistoryEntry();
}
@ -195,15 +195,15 @@ class DrawerControllerState extends State<DrawerController> {
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 {

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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
));
}
}
}

View file

@ -151,7 +151,7 @@ class _DismissableState extends State<Dismissable> {
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<Dismissable> {
});
}
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<Dismissable> {
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) {

View file

@ -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;
}
}

View file

@ -522,7 +522,7 @@ class ScrollableState<T extends Scrollable> extends State<T> {
_simulation = null;
}
void _handleDragStart(_) {
void _handleDragStart(DragStartDetails details) {
_startScroll();
}
@ -542,12 +542,12 @@ class ScrollableState<T extends Scrollable> extends State<T> {
new ScrollNotification(this, ScrollNotificationKind.started).dispatch(context);
}
void _handleDragUpdate(double delta) {
scrollBy(pixelOffsetToScrollOffset(delta));
void _handleDragUpdate(DragUpdateDetails details) {
scrollBy(pixelOffsetToScrollOffset(details.primaryDelta));
}
Future<Null> _handleDragEnd(Velocity velocity) {
double scrollVelocity = pixelDeltaToScrollOffset(velocity.pixelsPerSecond) / Duration.MILLISECONDS_PER_SECOND;
Future<Null> _handleDragEnd(DragEndDetails details) {
double scrollVelocity = pixelDeltaToScrollOffset(details.velocity.pixelsPerSecond) / Duration.MILLISECONDS_PER_SECOND;
return fling(scrollVelocity).then(_endScroll);
}

View file

@ -66,9 +66,9 @@ class _SemanticsDebuggerState extends State<SemanticsDebugger> {
_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;
});

View file

@ -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) {

View file

@ -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;
};

View file

@ -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;
};

View file

@ -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(