Commit e2ff169d authored by Hans Muller's avatar Hans Muller Committed by GitHub

Have the scale gesture callback uses details objects (#6204)

parent 55bc771f
......@@ -78,29 +78,29 @@ class _GridPhotoViewerState extends State<GridPhotoViewer> with SingleTickerProv
});
}
void _handleOnScaleStart(Point focalPoint) {
void _handleOnScaleStart(ScaleStartDetails details) {
setState(() {
_lastScale = 1.0;
_lastFocalPoint = focalPoint;
_lastFocalPoint = details.focalPoint;
// The fling animation stops if an input gesture starts.
_controller.stop();
});
}
void _handleOnScaleUpdate(double scale, Point focalPoint) {
void _handleOnScaleUpdate(ScaleUpdateDetails details) {
setState(() {
_scale = (_scale + (scale - _lastScale)).clamp(1.0, 3.0);
_lastScale = scale;
_focalPoint = _clampFocalPoint(_focalPoint + (_lastFocalPoint - focalPoint));
_lastFocalPoint = focalPoint;
_scale = (_scale + (details.scale - _lastScale)).clamp(1.0, 3.0);
_lastScale = details.scale;
_focalPoint = _clampFocalPoint(_focalPoint + (_lastFocalPoint - details.focalPoint));
_lastFocalPoint = details.focalPoint;
});
}
void _handleOnScaleEnd(Velocity flingVelocity) {
final double magnitude = flingVelocity.pixelsPerSecond.distance;
void _handleOnScaleEnd(ScaleEndDetails details) {
final double magnitude = details.velocity.pixelsPerSecond.distance;
if (magnitude < _kMinFlingVelocity)
return;
final Offset direction = flingVelocity.pixelsPerSecond / magnitude;
final Offset direction = details.velocity.pixelsPerSecond / magnitude;
final RenderBox box = context.findRenderObject();
final double distance = (Point.origin & box.size).shortestSide;
_flingAnimation = new Tween<Point>(
......
......@@ -79,21 +79,21 @@ class _GestureDemoState extends State<GestureDemo> {
bool _doubleTapEnabled = true;
bool _longPressEnabled = true;
void _handleScaleStart(Point focalPoint) {
void _handleScaleStart(ScaleStartDetails details) {
setState(() {
_startingFocalPoint = focalPoint;
_startingFocalPoint = details.focalPoint;
_previousOffset = _offset;
_previousZoom = _zoom;
});
}
void _handleScaleUpdate(double scale, Point focalPoint) {
void _handleScaleUpdate(ScaleUpdateDetails details) {
setState(() {
_zoom = (_previousZoom * scale);
_zoom = (_previousZoom * details.scale);
// Ensure that item under the focal point stays in the same place despite zooming
Offset normalizedOffset = (_startingFocalPoint.toOffset() - _previousOffset) / _previousZoom;
_offset = focalPoint.toOffset() - normalizedOffset * _zoom;
_offset = details.focalPoint.toOffset() - normalizedOffset * _zoom;
});
}
......
......@@ -27,16 +27,63 @@ enum ScaleState {
started,
}
/// Details for [GestureScaleStartCallback].
class ScaleStartDetails {
/// Creates details for [GestureScaleStartCallback].
///
/// The [focalPoint] argument must not be null.
ScaleStartDetails({ this.focalPoint: Point.origin }) {
assert(focalPoint != null);
}
/// The initial focal point of the pointers in contact with the screen.
/// Reported in global coordinates.
final Point focalPoint;
}
/// Details for [GestureScaleUpdateCallback].
class ScaleUpdateDetails {
/// Creates details for [GestureScaleUpdateCallback].
///
/// The [focalPoint] and [scale] arguments must not be null. The [scale]
/// argument must be greater than or equal to zero.
ScaleUpdateDetails({ this.focalPoint: Point.origin, this.scale: 1.0 }) {
assert(focalPoint != null);
assert(scale != null && scale >= 0.0);
}
/// The focal point of the pointers in contact with the screen. Reported in
/// global coordinates.
final Point focalPoint;
/// The scale implied by the pointers in contact with the screen. A value
/// greater than or equal to zero.
final double scale;
}
/// Details for [GestureScaleEndCallback].
class ScaleEndDetails {
/// Creates details for [GestureScaleEndCallback].
///
/// The [velocity] argument must not be null.
ScaleEndDetails({ this.velocity: Velocity.zero }) {
assert(velocity != null);
}
/// The velocity of the last pointer to be lifted off of the screen.
final Velocity velocity;
}
/// Signature for when the pointers in contact with the screen have established
/// a focal point and initial scale of 1.0.
typedef void GestureScaleStartCallback(Point focalPoint);
typedef void GestureScaleStartCallback(ScaleStartDetails details);
/// Signature for when the pointers in contact with the screen have indicated a
/// new focal point and/or scale.
typedef void GestureScaleUpdateCallback(double scale, Point focalPoint);
typedef void GestureScaleUpdateCallback(ScaleUpdateDetails details);
/// Signature for when the pointers are no longer in contact with the screen.
typedef void GestureScaleEndCallback(Velocity flingVelocity);
typedef void GestureScaleEndCallback(ScaleEndDetails details);
bool _isFlingGesture(Velocity velocity) {
assert(velocity != null);
......@@ -133,9 +180,9 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
final Offset pixelsPerSecond = velocity.pixelsPerSecond;
if (pixelsPerSecond.distanceSquared > kMaxFlingVelocity * kMaxFlingVelocity)
velocity = new Velocity(pixelsPerSecond: (pixelsPerSecond / pixelsPerSecond.distance) * kMaxFlingVelocity);
onEnd(velocity);
onEnd(new ScaleEndDetails(velocity: velocity));
} else {
onEnd(Velocity.zero);
onEnd(new ScaleEndDetails(velocity: Velocity.zero));
}
}
_state = ScaleState.accepted;
......@@ -153,11 +200,11 @@ class ScaleGestureRecognizer extends OneSequenceGestureRecognizer {
if (_state == ScaleState.accepted && !configChanged) {
_state = ScaleState.started;
if (onStart != null)
onStart(focalPoint);
onStart(new ScaleStartDetails(focalPoint: focalPoint));
}
if (_state == ScaleState.started && onUpdate != null)
onUpdate(_scaleFactor, focalPoint);
onUpdate(new ScaleUpdateDetails(scale: _scaleFactor, focalPoint: focalPoint));
}
@override
......
......@@ -26,6 +26,9 @@ export 'package:flutter/gestures.dart' show
GestureScaleStartCallback,
GestureScaleUpdateCallback,
GestureScaleEndCallback,
ScaleStartDetails,
ScaleUpdateDetails,
ScaleEndDetails,
TapDownDetails,
TapUpDetails,
Velocity;
......
......@@ -16,19 +16,19 @@ void main() {
bool didStartScale = false;
Point updatedFocalPoint;
scale.onStart = (Point focalPoint) {
scale.onStart = (ScaleStartDetails details) {
didStartScale = true;
updatedFocalPoint = focalPoint;
updatedFocalPoint = details.focalPoint;
};
double updatedScale;
scale.onUpdate = (double scale, Point focalPoint) {
updatedScale = scale;
updatedFocalPoint = focalPoint;
scale.onUpdate = (ScaleUpdateDetails details) {
updatedScale = details.scale;
updatedFocalPoint = details.focalPoint;
};
bool didEndScale = false;
scale.onEnd = (Velocity flingVelocity) {
scale.onEnd = (ScaleEndDetails details) {
didEndScale = true;
};
......
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