mobile/android/base/ScrollAnimator.java

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/mobile/android/base/ScrollAnimator.java	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,84 @@
     1.4 +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +package org.mozilla.gecko;
    1.10 +
    1.11 +import java.util.Timer;
    1.12 +import java.util.TimerTask;
    1.13 +
    1.14 +import org.mozilla.gecko.util.GamepadUtils;
    1.15 +
    1.16 +import android.view.InputDevice;
    1.17 +import android.view.MotionEvent;
    1.18 +import android.view.View;
    1.19 +
    1.20 +public class ScrollAnimator implements View.OnGenericMotionListener {
    1.21 +    private Timer mScrollTimer;
    1.22 +    private int mX;
    1.23 +    private int mY;
    1.24 +
    1.25 +    // Assuming 60fps, this will make the view scroll once per frame
    1.26 +    static final long MS_PER_FRAME = 1000 / 60;
    1.27 +
    1.28 +    // Maximum number of pixels that can be scrolled per frame
    1.29 +    static final float MAX_SCROLL = 0.075f * GeckoAppShell.getDpi();
    1.30 +
    1.31 +    private class ScrollRunnable extends TimerTask {
    1.32 +        private View mView;
    1.33 +
    1.34 +        public ScrollRunnable(View view) {
    1.35 +            mView = view;
    1.36 +        }
    1.37 +
    1.38 +        @Override
    1.39 +        public final void run() {
    1.40 +            mView.scrollBy(mX, mY);
    1.41 +        }
    1.42 +    }
    1.43 +
    1.44 +    @Override
    1.45 +    public boolean onGenericMotion(View view, MotionEvent event) {
    1.46 +        if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) {
    1.47 +            switch (event.getAction()) {
    1.48 +            case MotionEvent.ACTION_MOVE:
    1.49 +                // Cancel the animation if the joystick is in a neutral position
    1.50 +                if (GamepadUtils.isValueInDeadZone(event, MotionEvent.AXIS_X) &&
    1.51 +                        GamepadUtils.isValueInDeadZone(event, MotionEvent.AXIS_Y)) {
    1.52 +                    if (mScrollTimer != null) {
    1.53 +                        mScrollTimer.cancel();
    1.54 +                        mScrollTimer = null;
    1.55 +                    }
    1.56 +                    return true;
    1.57 +                }
    1.58 +
    1.59 +                // Scroll with a velocity relative to the screen DPI
    1.60 +                mX = (int) (event.getAxisValue(MotionEvent.AXIS_X) * MAX_SCROLL);
    1.61 +                mY = (int) (event.getAxisValue(MotionEvent.AXIS_Y) * MAX_SCROLL);
    1.62 +
    1.63 +                // Start the timer; the view will continue to scroll as long as
    1.64 +                // the joystick is not in the deadzone.
    1.65 +                if (mScrollTimer == null) {
    1.66 +                    mScrollTimer = new Timer();
    1.67 +                    ScrollRunnable task = new ScrollRunnable(view);
    1.68 +                    mScrollTimer.scheduleAtFixedRate(task, 0, MS_PER_FRAME);
    1.69 +                }
    1.70 +
    1.71 +                return true;
    1.72 +            }
    1.73 +        }
    1.74 +
    1.75 +        return false;
    1.76 +    }
    1.77 +
    1.78 +    /**
    1.79 +     * Cancels the running scroll animation if it is in progress.
    1.80 +     */
    1.81 +    public void cancel() {
    1.82 +        if (mScrollTimer != null) {
    1.83 +            mScrollTimer.cancel();
    1.84 +            mScrollTimer = null;
    1.85 +        }
    1.86 +    }
    1.87 +}

mercurial