|
1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- |
|
2 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
3 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
4 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
5 |
|
6 package org.mozilla.gecko; |
|
7 |
|
8 import java.util.Timer; |
|
9 import java.util.TimerTask; |
|
10 |
|
11 import org.mozilla.gecko.util.GamepadUtils; |
|
12 |
|
13 import android.view.InputDevice; |
|
14 import android.view.MotionEvent; |
|
15 import android.view.View; |
|
16 |
|
17 public class ScrollAnimator implements View.OnGenericMotionListener { |
|
18 private Timer mScrollTimer; |
|
19 private int mX; |
|
20 private int mY; |
|
21 |
|
22 // Assuming 60fps, this will make the view scroll once per frame |
|
23 static final long MS_PER_FRAME = 1000 / 60; |
|
24 |
|
25 // Maximum number of pixels that can be scrolled per frame |
|
26 static final float MAX_SCROLL = 0.075f * GeckoAppShell.getDpi(); |
|
27 |
|
28 private class ScrollRunnable extends TimerTask { |
|
29 private View mView; |
|
30 |
|
31 public ScrollRunnable(View view) { |
|
32 mView = view; |
|
33 } |
|
34 |
|
35 @Override |
|
36 public final void run() { |
|
37 mView.scrollBy(mX, mY); |
|
38 } |
|
39 } |
|
40 |
|
41 @Override |
|
42 public boolean onGenericMotion(View view, MotionEvent event) { |
|
43 if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0) { |
|
44 switch (event.getAction()) { |
|
45 case MotionEvent.ACTION_MOVE: |
|
46 // Cancel the animation if the joystick is in a neutral position |
|
47 if (GamepadUtils.isValueInDeadZone(event, MotionEvent.AXIS_X) && |
|
48 GamepadUtils.isValueInDeadZone(event, MotionEvent.AXIS_Y)) { |
|
49 if (mScrollTimer != null) { |
|
50 mScrollTimer.cancel(); |
|
51 mScrollTimer = null; |
|
52 } |
|
53 return true; |
|
54 } |
|
55 |
|
56 // Scroll with a velocity relative to the screen DPI |
|
57 mX = (int) (event.getAxisValue(MotionEvent.AXIS_X) * MAX_SCROLL); |
|
58 mY = (int) (event.getAxisValue(MotionEvent.AXIS_Y) * MAX_SCROLL); |
|
59 |
|
60 // Start the timer; the view will continue to scroll as long as |
|
61 // the joystick is not in the deadzone. |
|
62 if (mScrollTimer == null) { |
|
63 mScrollTimer = new Timer(); |
|
64 ScrollRunnable task = new ScrollRunnable(view); |
|
65 mScrollTimer.scheduleAtFixedRate(task, 0, MS_PER_FRAME); |
|
66 } |
|
67 |
|
68 return true; |
|
69 } |
|
70 } |
|
71 |
|
72 return false; |
|
73 } |
|
74 |
|
75 /** |
|
76 * Cancels the running scroll animation if it is in progress. |
|
77 */ |
|
78 public void cancel() { |
|
79 if (mScrollTimer != null) { |
|
80 mScrollTimer.cancel(); |
|
81 mScrollTimer = null; |
|
82 } |
|
83 } |
|
84 } |