Forward touch events above the keyboard to the suggestions strip

The gutter area between the suggestions strip and the top-row keys
looks like a part of the suggestions strip, and the touch events
landing on the area should be forwarded to the suggestions strip.

Bug: 5246673
Change-Id: I92af763be0feed21aa36ceffb5d575abe554f19e
main
Tadashi G. Takaoka 2011-09-20 16:16:34 +09:00
parent e4ff4d6b1c
commit f451ed2012
3 changed files with 118 additions and 4 deletions

View File

@ -18,7 +18,7 @@
*/ */
--> -->
<LinearLayout <com.android.inputmethod.latin.InputView
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
android:orientation="vertical" android:orientation="vertical"
@ -61,4 +61,4 @@
android:layout_alignParentBottom="true" android:layout_alignParentBottom="true"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</LinearLayout> </com.android.inputmethod.latin.InputView>

View File

@ -32,6 +32,7 @@ import android.view.inputmethod.EditorInfo;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.keyboard.internal.ModifierKeyState; import com.android.inputmethod.keyboard.internal.ModifierKeyState;
import com.android.inputmethod.keyboard.internal.ShiftKeyState; import com.android.inputmethod.keyboard.internal.ShiftKeyState;
import com.android.inputmethod.latin.InputView;
import com.android.inputmethod.latin.LatinIME; import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.LocaleUtils; import com.android.inputmethod.latin.LocaleUtils;
@ -62,7 +63,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private SubtypeSwitcher mSubtypeSwitcher; private SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs; private SharedPreferences mPrefs;
private View mCurrentInputView; private InputView mCurrentInputView;
private LatinKeyboardView mKeyboardView; private LatinKeyboardView mKeyboardView;
private LatinIME mInputMethodService; private LatinIME mInputMethodService;
private String mPackageName; private String mPackageName;
@ -230,6 +231,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private void setKeyboard(final Keyboard keyboard) { private void setKeyboard(final Keyboard keyboard) {
final Keyboard oldKeyboard = mKeyboardView.getKeyboard(); final Keyboard oldKeyboard = mKeyboardView.getKeyboard();
mKeyboardView.setKeyboard(keyboard); mKeyboardView.setKeyboard(keyboard);
mCurrentInputView.setKeyboardGeometry(keyboard.mTopPadding);
mCurrentId = keyboard.mId; mCurrentId = keyboard.mId;
mSwitchState = getSwitchState(mCurrentId); mSwitchState = getSwitchState(mCurrentId);
updateShiftLockState(keyboard); updateShiftLockState(keyboard);
@ -762,7 +764,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) {
try { try {
setContextThemeWrapper(mInputMethodService, newThemeIndex); setContextThemeWrapper(mInputMethodService, newThemeIndex);
mCurrentInputView = LayoutInflater.from(mThemeContext).inflate( mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(
R.layout.input_view, null); R.layout.input_view, null);
tryGC = false; tryGC = false;
} catch (OutOfMemoryError e) { } catch (OutOfMemoryError e) {

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2011 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.latin;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
public class InputView extends LinearLayout {
private View mSuggestionsContainer;
private View mKeyboardView;
private int mKeyboardTopPadding;
private boolean mIsForwardingEvent;
private final Rect mInputViewRect = new Rect();
private final Rect mEventForwardingRect = new Rect();
private final Rect mEventReceivingRect = new Rect();
public InputView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}
public void setKeyboardGeometry(int keyboardTopPadding) {
mKeyboardTopPadding = keyboardTopPadding;
}
@Override
protected void onFinishInflate() {
mSuggestionsContainer = findViewById(R.id.suggestions_container);
mKeyboardView = findViewById(R.id.keyboard_view);
}
@Override
public boolean dispatchTouchEvent(MotionEvent me) {
if (mSuggestionsContainer.getVisibility() == VISIBLE
&& mKeyboardView.getVisibility() == VISIBLE
&& forwardTouchEvent(me)) {
return true;
}
return super.dispatchTouchEvent(me);
}
// The touch events that hit the top padding of keyboard should be forwarded to SuggestionsView.
private boolean forwardTouchEvent(MotionEvent me) {
final Rect rect = mInputViewRect;
this.getGlobalVisibleRect(rect);
final int x = (int)me.getX() + rect.left;
final int y = (int)me.getY() + rect.top;
final Rect forwardingRect = mEventForwardingRect;
mKeyboardView.getGlobalVisibleRect(forwardingRect);
if (!mIsForwardingEvent && !forwardingRect.contains(x, y)) {
return false;
}
final int forwardingLimitY = forwardingRect.top + mKeyboardTopPadding;
boolean sendToTarget = false;
switch (me.getAction()) {
case MotionEvent.ACTION_DOWN:
if (y < forwardingLimitY) {
// This down event and further move and up events should be forwarded to the target.
mIsForwardingEvent = true;
sendToTarget = true;
}
break;
case MotionEvent.ACTION_MOVE:
sendToTarget = mIsForwardingEvent;
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
sendToTarget = mIsForwardingEvent;
mIsForwardingEvent = false;
break;
}
if (!sendToTarget) {
return false;
}
final Rect receivingRect = mEventReceivingRect;
mSuggestionsContainer.getGlobalVisibleRect(receivingRect);
final int translatedX = x - receivingRect.left;
final int translatedY;
if (y < forwardingLimitY) {
// The forwarded event should have coordinates that are inside of the target.
translatedY = Math.min(y - receivingRect.top, receivingRect.height() - 1);
} else {
translatedY = y - receivingRect.top;
}
me.setLocation(translatedX, translatedY);
mSuggestionsContainer.dispatchTouchEvent(me);
return true;
}
}