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 final class InputView extends LinearLayout {
     27     private View mSuggestionStripContainer;
     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         mSuggestionStripContainer = findViewById(R.id.suggestions_container);
     47         mKeyboardView = findViewById(R.id.keyboard_view);
     48     }
     49 
     50     @Override
     51     public boolean dispatchTouchEvent(MotionEvent me) {
     52         if (mSuggestionStripContainer.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
     61     // {@link SuggestionStripView}.
     62     private boolean forwardTouchEvent(MotionEvent me) {
     63         final Rect rect = mInputViewRect;
     64         this.getGlobalVisibleRect(rect);
     65         final int x = (int)me.getX() + rect.left;
     66         final int y = (int)me.getY() + rect.top;
     67 
     68         final Rect forwardingRect = mEventForwardingRect;
     69         mKeyboardView.getGlobalVisibleRect(forwardingRect);
     70         if (!mIsForwardingEvent && !forwardingRect.contains(x, y)) {
     71             return false;
     72         }
     73 
     74         final int forwardingLimitY = forwardingRect.top + mKeyboardTopPadding;
     75         boolean sendToTarget = false;
     76 
     77         switch (me.getAction()) {
     78         case MotionEvent.ACTION_DOWN:
     79             if (y < forwardingLimitY) {
     80                 // This down event and further move and up events should be forwarded to the target.
     81                 mIsForwardingEvent = true;
     82                 sendToTarget = true;
     83             }
     84             break;
     85         case MotionEvent.ACTION_MOVE:
     86             sendToTarget = mIsForwardingEvent;
     87             break;
     88         case MotionEvent.ACTION_UP:
     89         case MotionEvent.ACTION_CANCEL:
     90             sendToTarget = mIsForwardingEvent;
     91             mIsForwardingEvent = false;
     92             break;
     93         }
     94 
     95         if (!sendToTarget) {
     96             return false;
     97         }
     98 
     99         final Rect receivingRect = mEventReceivingRect;
    100         mSuggestionStripContainer.getGlobalVisibleRect(receivingRect);
    101         final int translatedX = x - receivingRect.left;
    102         final int translatedY;
    103         if (y < forwardingLimitY) {
    104             // The forwarded event should have coordinates that are inside of the target.
    105             translatedY = Math.min(y - receivingRect.top, receivingRect.height() - 1);
    106         } else {
    107             translatedY = y - receivingRect.top;
    108         }
    109         me.setLocation(translatedX, translatedY);
    110         mSuggestionStripContainer.dispatchTouchEvent(me);
    111         return true;
    112     }
    113 }
    114