Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1795)

Unified Diff: content/public/android/java/src/org/chromium/content/browser/JoystickScrollProvider.java

Issue 1089663002: (NOT FOR REVIEW) Smooth gamepad scroll via scrollBy (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: scrollBy Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/android/java/src/org/chromium/content/browser/JoystickScrollProvider.java
diff --git a/content/public/android/java/src/org/chromium/content/browser/JoystickScrollProvider.java b/content/public/android/java/src/org/chromium/content/browser/JoystickScrollProvider.java
new file mode 100644
index 0000000000000000000000000000000000000000..4960d479b9cb0a8ea663d71b25031c14fbf783bf
--- /dev/null
+++ b/content/public/android/java/src/org/chromium/content/browser/JoystickScrollProvider.java
@@ -0,0 +1,113 @@
+// Copyright 2015 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.content.browser;
+
+import android.graphics.PointF;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.MotionEvent;
+import android.view.animation.AnimationUtils;
+
+/**
+ * This class implements auto scrolling and panning
+ * for gamepad left joystick motion event.
+ */
+public class JoystickScrollProvider implements Runnable {
+ private static final String TAG = "JoystickScrollProvider";
+ private static final float JOYSTICK_SCROLL_FACTOR_MULTIPLIER = 25f;
+ // Joystick produces "noise", 0.20f has proven a safe value to
+ // remove noise and still allow reasonable input range.
+ private static final float JOYSTICK_SCROLL_DEADZONE = 0.2f;
+ private static final float SCROLL_FACTOR_FALLBACK = 128f;
+
+ private final ContentViewCore mView;
+ private final PointF mScrollVelocity = new PointF();
+ private boolean mAutoScrollEnabled;
+ private float mScrollFactor;
+ private long mLastAnimateTimeMillis;
+
+ JoystickScrollProvider(ContentViewCore contentView) {
+ mView = contentView;
+ mAutoScrollEnabled = false;
+ }
+
+ public void run() {
+ if (mView.getSoftKeyboardShowFlag() || !mView.getContainerView().hasWindowFocus()) {
+ stop();
+ return;
+ }
+
+ final long timeMillis = AnimationUtils.currentAnimationTimeMillis();
+ if (mLastAnimateTimeMillis != 0 && timeMillis > mLastAnimateTimeMillis) {
sshelke 2015/05/12 12:03:47 Do we miss first event each time since we are chec
jdduke (slow) 2015/05/12 15:13:11 Yup, that sounds reasonable. Missing the first eve
+ final long dt = timeMillis - mLastAnimateTimeMillis;
sshelke 2015/05/12 12:03:47 run() function always be called after animation in
jdduke (slow) 2015/05/12 15:13:11 Subtractions are cheap, I don't think we should ma
+ final int dx = (int) (mScrollVelocity.x * dt / 1000.f);
+ final int dy = (int) (mScrollVelocity.y * dt / 1000.f);
+ mView.scrollBy(dx, dy);
jdduke (slow) 2015/05/18 21:40:59 Hmm, we should probably include the "pointer" coor
sshelke 2015/05/19 10:54:30 How can we get pointer location? since view can de
+ }
+ mAutoScrollEnabled = true;
+ mLastAnimateTimeMillis = timeMillis;
+ mView.getContainerView().postOnAnimation(this);
+ }
+
+ /**
+ * This function processes left joystick event and computes new
+ * scroll offest in pixels which is propertional to axes movement.
+ * It also starts runnable to scroll content view core equal to
+ * scroll offset pixels.
+ */
+ public void onMotion(MotionEvent event) {
+ computeNewScrollVelocity(event);
+ if (mScrollVelocity.x != 0 || mScrollVelocity.y != 0) {
+ if (!mAutoScrollEnabled) {
+ run();
+ }
+ } else {
+ stop();
+ }
+ }
+
+ private void stop() {
+ mLastAnimateTimeMillis = 0;
+ if (mAutoScrollEnabled) {
+ mAutoScrollEnabled = false;
+ mView.getContainerView().removeCallbacks(this);
+ }
+ }
+
+ /**
+ * Translates joystick axes movement to a scroll velocity.
+ */
+ private void computeNewScrollVelocity(MotionEvent event) {
+ if (mScrollFactor == 0) {
+ TypedValue outValue = new TypedValue();
+ if (!mView.getContext().getTheme().resolveAttribute(
+ android.R.attr.listPreferredItemHeight, outValue, true)) {
+ mScrollFactor = outValue.getDimension(
+ mView.getContext().getResources().getDisplayMetrics());
+ } else {
+ Log.w(TAG, "Theme attribute listPreferredItemHeight not defined"
+ + "switching to fallback scroll factor ");
+ mScrollFactor = SCROLL_FACTOR_FALLBACK
+ * mView.getRenderCoordinates().getDeviceScaleFactor();
+ }
+ }
+ mScrollVelocity.x = getFilteredAxisValue(event, MotionEvent.AXIS_X) * mScrollFactor
+ * JOYSTICK_SCROLL_FACTOR_MULTIPLIER;
+ mScrollVelocity.y = getFilteredAxisValue(event, MotionEvent.AXIS_Y) * mScrollFactor
+ * JOYSTICK_SCROLL_FACTOR_MULTIPLIER;
+ }
+
+ /**
+ * Removes noise from joystick motion events.
+ */
+ private float getFilteredAxisValue(MotionEvent event, int axis) {
+ float axisValWithNoise = event.getAxisValue(axis);
+ return ((axisValWithNoise > JOYSTICK_SCROLL_DEADZONE)
+ ? axisValWithNoise - JOYSTICK_SCROLL_DEADZONE
+ : ((axisValWithNoise < -JOYSTICK_SCROLL_DEADZONE)
+ ? axisValWithNoise + JOYSTICK_SCROLL_DEADZONE
+ : 0));
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698