Move non-distinct multitouch support to a separate class
Move code that support non-distinct multitouch screen device to the NonDistinchMultitouchHelper class. Change-Id: I2e44f782b83dbcd095ee8e51c36b0766da0cd457main
parent
a299421f67
commit
b6cc3a85ab
|
@ -53,6 +53,7 @@ import com.android.inputmethod.keyboard.internal.GestureFloatingPreviewText;
|
|||
import com.android.inputmethod.keyboard.internal.GestureTrailsPreview;
|
||||
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
|
||||
import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
|
||||
import com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper;
|
||||
import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
|
||||
import com.android.inputmethod.keyboard.internal.SlidingKeyInputPreview;
|
||||
import com.android.inputmethod.latin.Constants;
|
||||
|
@ -179,9 +180,7 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
|||
private int mGestureFloatingPreviewTextLingerTimeout;
|
||||
|
||||
private KeyDetector mKeyDetector;
|
||||
private final boolean mHasDistinctMultitouch;
|
||||
private int mOldPointerCount = 1;
|
||||
private Key mOldKey;
|
||||
private final NonDistinctMultitouchHelper mNonDistinctMultitouchHelper;
|
||||
|
||||
private final KeyTimerHandler mKeyTimerHandler;
|
||||
|
||||
|
@ -423,13 +422,16 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
|||
public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
|
||||
PointerTracker.init(getResources());
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
final boolean forceNonDistinctMultitouch = prefs.getBoolean(
|
||||
DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, false);
|
||||
final boolean hasDistinctMultitouch = context.getPackageManager()
|
||||
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
|
||||
mHasDistinctMultitouch = hasDistinctMultitouch && !forceNonDistinctMultitouch;
|
||||
PointerTracker.init(getResources());
|
||||
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT)
|
||||
&& !forceNonDistinctMultitouch;
|
||||
mNonDistinctMultitouchHelper = hasDistinctMultitouch ? null
|
||||
: new NonDistinctMultitouchHelper();
|
||||
|
||||
mPreviewPlacerView = new PreviewPlacerView(context, attrs);
|
||||
|
||||
final TypedArray mainKeyboardViewAttr = context.obtainStyledAttributes(
|
||||
|
@ -1032,25 +1034,21 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
|||
if (getKeyboard() == null) {
|
||||
return false;
|
||||
}
|
||||
// TODO: Add multi-touch to single-touch event converter for non-distinct multi-touch
|
||||
// device.
|
||||
if (mNonDistinctMultitouchHelper != null) {
|
||||
if (me.getPointerCount() > 1 && mKeyTimerHandler.isInKeyRepeat()) {
|
||||
// Key repeating timer will be canceled if 2 or more keys are in action.
|
||||
mKeyTimerHandler.cancelKeyRepeatTimer();
|
||||
}
|
||||
// Non distinct multitouch screen support
|
||||
mNonDistinctMultitouchHelper.processMotionEvent(me, this);
|
||||
return true;
|
||||
}
|
||||
return processMotionEvent(me);
|
||||
}
|
||||
|
||||
public boolean processMotionEvent(final MotionEvent me) {
|
||||
final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
|
||||
final int action = me.getActionMasked();
|
||||
final int pointerCount = me.getPointerCount();
|
||||
final int oldPointerCount = mOldPointerCount;
|
||||
mOldPointerCount = pointerCount;
|
||||
|
||||
// TODO: cleanup this code into a multi-touch to single-touch event converter class?
|
||||
// If the device does not have distinct multi-touch support panel, ignore all multi-touch
|
||||
// events except a transition from/to single-touch.
|
||||
if (nonDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
final long eventTime = me.getEventTime();
|
||||
final int index = me.getActionIndex();
|
||||
final int id = me.getPointerId(index);
|
||||
|
@ -1068,50 +1066,6 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
|
|||
me, action, eventTime, index, id, x, y);
|
||||
}
|
||||
|
||||
if (mKeyTimerHandler.isInKeyRepeat()) {
|
||||
final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
|
||||
// Key repeating timer will be canceled if 2 or more keys are in action, and current
|
||||
// event (UP or DOWN) is non-modifier key.
|
||||
if (pointerCount > 1 && !tracker.isModifier()) {
|
||||
mKeyTimerHandler.cancelKeyRepeatTimer();
|
||||
}
|
||||
// Up event will pass through.
|
||||
}
|
||||
|
||||
// TODO: cleanup this code into a multi-touch to single-touch event converter class?
|
||||
// Translate mutli-touch event to single-touch events on the device that has no distinct
|
||||
// multi-touch panel.
|
||||
if (nonDistinctMultitouch) {
|
||||
// Use only main (id=0) pointer tracker.
|
||||
final PointerTracker tracker = PointerTracker.getPointerTracker(0, this);
|
||||
if (pointerCount == 1 && oldPointerCount == 2) {
|
||||
// Multi-touch to single touch transition.
|
||||
// Send a down event for the latest pointer if the key is different from the
|
||||
// previous key.
|
||||
final Key newKey = tracker.getKeyOn(x, y);
|
||||
if (mOldKey != newKey) {
|
||||
tracker.onDownEvent(x, y, eventTime, this);
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
tracker.onUpEvent(x, y, eventTime);
|
||||
}
|
||||
}
|
||||
} else if (pointerCount == 2 && oldPointerCount == 1) {
|
||||
// Single-touch to multi-touch transition.
|
||||
// Send an up event for the last pointer.
|
||||
final int[] lastCoords = CoordinateUtils.newInstance();
|
||||
mOldKey = tracker.getKeyOn(
|
||||
CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords));
|
||||
tracker.onUpEvent(
|
||||
CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords), eventTime);
|
||||
} else if (pointerCount == 1 && oldPointerCount == 1) {
|
||||
tracker.processMotionEvent(action, x, y, eventTime, this);
|
||||
} else {
|
||||
Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
|
||||
+ " (old " + oldPointerCount + ")");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (action == MotionEvent.ACTION_MOVE) {
|
||||
for (int i = 0; i < pointerCount; i++) {
|
||||
final int pointerId = me.getPointerId(i);
|
||||
|
|
|
@ -478,6 +478,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
|||
mPointerId = id;
|
||||
mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
|
||||
id, sGestureStrokeParams, sGesturePreviewParams);
|
||||
setKeyEventHandler(handler);
|
||||
}
|
||||
|
||||
private void setKeyEventHandler(final KeyEventHandler handler) {
|
||||
setKeyDetectorInner(handler.getKeyDetector());
|
||||
mListener = handler.getKeyboardActionListener();
|
||||
mDrawingProxy = handler.getDrawingProxy();
|
||||
|
@ -891,10 +895,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
|||
if (DEBUG_EVENT) {
|
||||
printTouchEvent("onDownEvent:", x, y, eventTime);
|
||||
}
|
||||
mDrawingProxy = handler.getDrawingProxy();
|
||||
mTimerProxy = handler.getTimerProxy();
|
||||
setKeyboardActionListener(handler.getKeyboardActionListener());
|
||||
setKeyDetectorInner(handler.getKeyDetector());
|
||||
setKeyEventHandler(handler);
|
||||
// Naive up-to-down noise filter.
|
||||
final long deltaT = eventTime - mUpTime;
|
||||
if (deltaT < sParams.mTouchNoiseThresholdTime) {
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (C) 2013 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.inputmethod.keyboard.internal;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import com.android.inputmethod.keyboard.Key;
|
||||
import com.android.inputmethod.keyboard.PointerTracker;
|
||||
import com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler;
|
||||
import com.android.inputmethod.latin.utils.CoordinateUtils;
|
||||
|
||||
public final class NonDistinctMultitouchHelper {
|
||||
private static final String TAG = NonDistinctMultitouchHelper.class.getSimpleName();
|
||||
|
||||
private int mOldPointerCount = 1;
|
||||
private Key mOldKey;
|
||||
|
||||
public void processMotionEvent(final MotionEvent me, final KeyEventHandler keyEventHandler) {
|
||||
final int pointerCount = me.getPointerCount();
|
||||
final int oldPointerCount = mOldPointerCount;
|
||||
mOldPointerCount = pointerCount;
|
||||
// Ignore continuous multitouch events because we can't trust the coordinates in mulitouch
|
||||
// events.
|
||||
if (pointerCount > 1 && oldPointerCount > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
final int action = me.getActionMasked();
|
||||
final int index = me.getActionIndex();
|
||||
final long eventTime = me.getEventTime();
|
||||
final int x = (int)me.getX(index);
|
||||
final int y = (int)me.getY(index);
|
||||
// Use only main (id=0) pointer tracker.
|
||||
final PointerTracker mainTracker = PointerTracker.getPointerTracker(0, keyEventHandler);
|
||||
|
||||
// In single touch.
|
||||
if (oldPointerCount == 1 && pointerCount == 1) {
|
||||
mainTracker.processMotionEvent(action, x, y, eventTime, keyEventHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
// Single-touch to multi-touch transition.
|
||||
if (oldPointerCount == 1 && pointerCount == 2) {
|
||||
// Send an up event for the last pointer, be cause we can't trust the corrdinates of
|
||||
// this multitouch event.
|
||||
final int[] lastCoords = CoordinateUtils.newInstance();
|
||||
mainTracker.getLastCoordinates(lastCoords);
|
||||
mOldKey = mainTracker.getKeyOn(
|
||||
CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords));
|
||||
// TODO: Stop calling PointerTracker.onUpEvent directly.
|
||||
mainTracker.onUpEvent(
|
||||
CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords), eventTime);
|
||||
return;
|
||||
}
|
||||
|
||||
// Multi-touch to single touch transition.
|
||||
if (oldPointerCount == 2 && pointerCount == 1) {
|
||||
// Send a down event for the latest pointer if the key is different from the
|
||||
// previous key.
|
||||
final Key newKey = mainTracker.getKeyOn(x, y);
|
||||
if (mOldKey != newKey) {
|
||||
// TODO: Stop calling PointerTracker.onDownEvent directly.
|
||||
mainTracker.onDownEvent(x, y, eventTime, keyEventHandler);
|
||||
if (action == MotionEvent.ACTION_UP) {
|
||||
// TODO: Stop calling PointerTracker.onUpEvent directly.
|
||||
mainTracker.onUpEvent(x, y, eventTime);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Log.w(TAG, "Unknown touch panel behavior: pointer count is "
|
||||
+ pointerCount + " (previously " + oldPointerCount + ")");
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue