Home | History | Annotate | Download | only in latin
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
      5  * use this file except in compliance with the License. You may obtain a copy of
      6  * the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     13  * License for the specific language governing permissions and limitations under
     14  * the License.
     15  */
     16 
     17 package com.android.inputmethod.latin;
     18 
     19 import android.content.Context;
     20 import android.graphics.Rect;
     21 import android.util.AttributeSet;
     22 import android.view.MotionEvent;
     23 import android.view.View;
     24 import android.widget.LinearLayout;
     25 
     26 public class InputView extends LinearLayout {
     27     private View mSuggestionsContainer;
     28     private View mKeyboardView;
     29     private int mKeyboardTopPadding;
     30 
     31     private boolean mIsForwardingEvent;
     32     private final Rect mInputViewRect = new Rect();
     33     private final Rect mEventForwardingRect = new Rect();
     34     private final Rect mEventReceivingRect = new Rect();
     35 
     36     public InputView(Context context, AttributeSet attrs) {
     37         super(context, attrs, 0);
     38     }
     39 
     40     public void setKeyboardGeometry(int keyboardTopPadding) {
     41         mKeyboardTopPadding = keyboardTopPadding;
     42     }
     43 
     44     @Override
     45     protected void onFinishInflate() {
     46         mSuggestionsContainer = findViewById(R.id.suggestions_container);
     47         mKeyboardView = findViewById(R.id.keyboard_view);
     48     }
     49 
     50     @Override
     51     public boolean dispatchTouchEvent(MotionEvent me) {
     52         if (mSuggestionsContainer.getVisibility() == VISIBLE
     53                 && mKeyboardView.getVisibility() == VISIBLE
     54                 && forwardTouchEvent(me)) {
     55             return true;
     56         }
     57         return super.dispatchTouchEvent(me);
     58     }
     59 
     60     // The touch events that hit the top padding of keyboard should be forwarded to SuggestionsView.
     61     private boolean forwardTouchEvent(MotionEvent me) {
     62         final Rect rect = mInputViewRect;
     63         this.getGlobalVisibleRect(rect);
     64         final int x = (int)me.getX() + rect.left;
     65         final int y = (int)me.getY() + rect.top;
     66 
     67         final Rect forwardingRect = mEventForwardingRect;
     68         mKeyboardView.getGlobalVisibleRect(forwardingRect);
     69         if (!mIsForwardingEvent && !forwardingRect.contains(x, y)) {
     70             return false;
     71         }
     72 
     73         final int forwardingLimitY = forwardingRect.top + mKeyboardTopPadding;
     74         boolean sendToTarget = false;
     75 
     76         switch (me.getAction()) {
     77         case MotionEvent.ACTION_DOWN:
     78             if (y < forwardingLimitY) {
     79                 // This down event and further move and up events should be forwarded to the target.
     80                 mIsForwardingEvent = true;
     81                 sendToTarget = true;
     82             }
     83             break;
     84         case MotionEvent.ACTION_MOVE:
     85             sendToTarget = mIsForwardingEvent;
     86             break;
     87         case MotionEvent.ACTION_UP:
     88         case MotionEvent.ACTION_CANCEL:
     89             sendToTarget = mIsForwardingEvent;
     90             mIsForwardingEvent = false;
     91             break;
     92         }
     93 
     94         if (!sendToTarget) {
     95             return false;
     96         }
     97 
     98         final Rect receivingRect = mEventReceivingRect;
     99         mSuggestionsContainer.getGlobalVisibleRect(receivingRect);
    100         final int translatedX = x - receivingRect.left;
    101         final int translatedY;
    102         if (y < forwardingLimitY) {
    103             // The forwarded event should have coordinates that are inside of the target.
    104             translatedY = Math.min(y - receivingRect.top, receivingRect.height() - 1);
    105         } else {
    106             translatedY = y - receivingRect.top;
    107         }
    108         me.setLocation(translatedX, translatedY);
    109         mSuggestionsContainer.dispatchTouchEvent(me);
    110         return true;
    111     }
    112 }
    113