blob: ba5bde45a4cb9d07ef39852aecc36718d399ddba [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chromoting;
import android.content.Context;
import android.widget.Scroller;
/**
* This is the abstract class that implements a fling animation job.
* This class uses an android scroller to calculate the fling physics.
* Subclass will only need to implement the abstracted processAction(deltaX, deltaY) method to
* consume the calculated change of x and y.
*/
public abstract class FlingAnimationJob implements AnimationJob {
/** Used to calculate the flinging physics. */
// Note that the implementation of scroller.isFinished() may not be reliable
// since it (mFinished) will only be updated when computeScrollOffset() is called.
private Scroller mScroller;
/**
* Consumes deltaX and deltaY calculated by the scroller.
* This method will be called in processAnimation(). Subclasses should implement this method
* to consume the calculated change of x and y.
* @param deltaX change of x
* @param deltaY change of y
*/
protected abstract void processAction(float deltaX, float deltaY);
/**
* Constructs a FlingAnimationJob (used by subclasses for initialization).
* @param context the context to initialize the scroller
*/
protected FlingAnimationJob(Context context) {
mScroller = new Scroller(context);
}
/**
* Initializes the scroller and start the scrolling animation.
* @param velocityX fling start velocity of x
* @param velocityY fling start velocity of y
*/
public void startAnimation(float velocityX, float velocityY) {
// The fling physics calculation is based on screen coordinates, so that it will
// behave consistently at different zoom levels (and will work nicely at high zoom
// levels, since |mScroller| outputs integer coordinates). However, the desktop
// will usually be panned as the cursor is moved across the desktop, which means the
// transformation mapping from screen to desktop coordinates will change. To deal with
// this, the cursor movement is computed from relative coordinate changes from
// |mScroller|. This means the fling can be started at (0, 0) with no bounding
// constraints - the cursor is already constrained by the desktop size.
mScroller.fling(0, 0, (int) velocityX, (int) velocityY,
Integer.MIN_VALUE, Integer.MAX_VALUE,
Integer.MIN_VALUE, Integer.MAX_VALUE);
mScroller.computeScrollOffset();
}
@Override
public boolean processAnimation() {
int previousX = mScroller.getCurrX();
int previousY = mScroller.getCurrY();
if (!mScroller.computeScrollOffset()) {
return false;
}
int deltaX = mScroller.getCurrX() - previousX;
int deltaY = mScroller.getCurrY() - previousY;
processAction(deltaX, deltaY);
return true;
}
@Override
public void abortAnimation() {
mScroller.abortAnimation();
}
}