/* * 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 final class InputView extends LinearLayout { private View mSuggestionStripContainer; 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() { mSuggestionStripContainer = findViewById(R.id.suggestions_container); mKeyboardView = findViewById(R.id.keyboard_view); } @Override public boolean dispatchTouchEvent(MotionEvent me) { if (mSuggestionStripContainer.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 // {@link SuggestionStripView}. 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; mSuggestionStripContainer.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); mSuggestionStripContainer.dispatchTouchEvent(me); return true; } }