+
+ @Override
+ public boolean onGenericMotionEvent(MotionEvent event) {
+ boolean handled = super.onGenericMotionEvent(event);
+ if (!handled) {
+ handled = mGestureDetector.onGenericMotionEvent(event);
+ if (!handled
+ && (event.getSource() & TouchNavGestureDetector.SOURCE_TOUCH_NAVIGATION)
+ == TouchNavGestureDetector.SOURCE_TOUCH_NAVIGATION) {
+ int action = event.getActionMasked();
+ switch (action) {
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ sendScaledMotionEvent(event);
+ handled = true;
+ break;
+ }
+ }
+ }
+ return handled;
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ boolean handled = super.onKeyDown(keyCode, event);
+ if (!handled) {
+ if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER || keyCode == KeyEvent.KEYCODE_ENTER) {
+ startFinishOutput();
+ handled = true;
+ }
+ }
+ return handled;
+ }
+
+ /**
+ * Returns whether a scroll happened.
+ */
+ @Override
+ public boolean onScroll(MotionEvent downEvent, MotionEvent currentEvent, float deltaX,
+ float deltaY) {
+ // If <5mm from the start, consider it a click. Used for smoother
+ // clicks.
+ if (!mDidStartDrag) {
+ float distanceX = Math.abs((currentEvent.getX() - downEvent.getX()) / mResolutionX);
+ float distanceY = Math.abs((currentEvent.getY() - downEvent.getY()) / mResolutionY);
+ if (distanceX < MIN_SCROLL_LENGTH && distanceY < MIN_SCROLL_LENGTH) {
+ // Not moved enough to scroll.
+ return false;
+ }
+ }
+ // Moved enough to scroll.
+ mDidStartDrag = true;
+ sendScaledMotionEvent(currentEvent);
+ return true;
+ }
+
+ @Override
+ public boolean onFling(MotionEvent downEvent, MotionEvent currentEvent, float velX,
+ float velY) {
+ sendScaledMotionEvent(currentEvent);
+ return true;
+ }
+
+ @Override
+ public boolean onDown(MotionEvent downEvent) {
+ mDidStartDrag = false;
+ InputDevice device = downEvent.getDevice();
+ MotionRange motionRangeX = device.getMotionRange(MotionEvent.AXIS_X);
+ MotionRange motionRangeY = device.getMotionRange(MotionEvent.AXIS_Y);
+
+ if (motionRangeX == null || motionRangeY == null) {
+ return false;
+ }
+
+ mResolutionX = motionRangeX.getResolution();
+ mResolutionY = motionRangeY.getResolution();
+
+ if (mResolutionX == 0) {
+ mResolutionX = TouchNavGestureDetector.DEFAULT_TOUCH_RESOLUTION;
+ }
+ if (mResolutionY == 0) {
+ mResolutionY = TouchNavGestureDetector.DEFAULT_TOUCH_RESOLUTION;
+ }
+
+ // This is the conversion between a drag on the device vs. a drag on
+ // the screen.
+ mTouchPadToViewRatioX = mCropView.getWidth() / motionRangeX.getRange();
+ mTouchPadToViewRatioY = mCropView.getHeight() / motionRangeY.getRange();
+
+ sendScaledMotionEvent(downEvent);
+ return true;
+ }
+
+ private void sendScaledMotionEvent(MotionEvent event) {
+ final int scaledX = (int) (mTouchPadToViewRatioX * event.getX());
+ final int scaledY = (int) (mTouchPadToViewRatioY * event.getY());
+ final MotionEvent ev = MotionEvent.obtain(event.getEventTime(), event.getEventTime(),
+ event.getActionMasked(), scaledX, scaledY, 0);
+ mCropView.onTouchEvent(ev);
+ ev.recycle();
+ }
+