Home | History | Annotate | Download | only in suggestions
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of 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,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.latin.suggestions;
     18 
     19 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.util.AttributeSet;
     22 import android.view.Gravity;
     23 import android.view.MotionEvent;
     24 import android.view.View;
     25 import android.widget.PopupWindow;
     26 
     27 import com.android.inputmethod.keyboard.KeyDetector;
     28 import com.android.inputmethod.keyboard.Keyboard;
     29 import com.android.inputmethod.keyboard.KeyboardActionListener;
     30 import com.android.inputmethod.keyboard.KeyboardView;
     31 import com.android.inputmethod.keyboard.MoreKeysDetector;
     32 import com.android.inputmethod.keyboard.MoreKeysPanel;
     33 import com.android.inputmethod.keyboard.PointerTracker;
     34 import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
     35 import com.android.inputmethod.keyboard.PointerTracker.KeyEventHandler;
     36 import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
     37 import com.android.inputmethod.latin.R;
     38 
     39 /**
     40  * A view that renders a virtual {@link MoreSuggestions}. It handles rendering of keys and detecting
     41  * key presses and touch movements.
     42  */
     43 public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
     44     private final int[] mCoordinates = new int[2];
     45 
     46     final KeyDetector mModalPanelKeyDetector;
     47     private final KeyDetector mSlidingPanelKeyDetector;
     48 
     49     private Controller mController;
     50     KeyboardActionListener mListener;
     51     private int mOriginX;
     52     private int mOriginY;
     53 
     54     static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter();
     55 
     56     final KeyboardActionListener mSuggestionsPaneListener =
     57             new KeyboardActionListener.Adapter() {
     58         @Override
     59         public void onPressKey(int primaryCode) {
     60             mListener.onPressKey(primaryCode);
     61         }
     62 
     63         @Override
     64         public void onReleaseKey(int primaryCode, boolean withSliding) {
     65             mListener.onReleaseKey(primaryCode, withSliding);
     66         }
     67 
     68         @Override
     69         public void onCodeInput(int primaryCode, int x, int y) {
     70             final int index = primaryCode - MoreSuggestions.SUGGESTION_CODE_BASE;
     71             if (index >= 0 && index < SuggestionsView.MAX_SUGGESTIONS) {
     72                 mListener.onCustomRequest(index);
     73             }
     74         }
     75 
     76         @Override
     77         public void onCancelInput() {
     78             mListener.onCancelInput();
     79         }
     80     };
     81 
     82     public MoreSuggestionsView(Context context, AttributeSet attrs) {
     83         this(context, attrs, R.attr.moreSuggestionsViewStyle);
     84     }
     85 
     86     public MoreSuggestionsView(Context context, AttributeSet attrs, int defStyle) {
     87         super(context, attrs, defStyle);
     88 
     89         final Resources res = context.getResources();
     90         mModalPanelKeyDetector = new KeyDetector(/* keyHysteresisDistance */ 0);
     91         mSlidingPanelKeyDetector = new MoreKeysDetector(
     92                 res.getDimension(R.dimen.more_suggestions_slide_allowance));
     93         setKeyPreviewPopupEnabled(false, 0);
     94     }
     95 
     96     @Override
     97     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
     98         final Keyboard keyboard = getKeyboard();
     99         if (keyboard != null) {
    100             final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
    101             final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
    102             setMeasuredDimension(width, height);
    103         } else {
    104             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    105         }
    106     }
    107 
    108     @Override
    109     public void setKeyboard(Keyboard keyboard) {
    110         super.setKeyboard(keyboard);
    111         mModalPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), -getPaddingTop());
    112         mSlidingPanelKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
    113                 -getPaddingTop() + mVerticalCorrection);
    114     }
    115 
    116     @Override
    117     public KeyDetector getKeyDetector() {
    118         return mSlidingPanelKeyDetector;
    119     }
    120 
    121     @Override
    122     public KeyboardActionListener getKeyboardActionListener() {
    123         return mSuggestionsPaneListener;
    124     }
    125 
    126     @Override
    127     public DrawingProxy getDrawingProxy() {
    128         return this;
    129     }
    130 
    131     @Override
    132     public TimerProxy getTimerProxy() {
    133         return EMPTY_TIMER_PROXY;
    134     }
    135 
    136     @Override
    137     public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
    138         // Suggestions pane needs no pop-up key preview displayed, so we pass always false with a
    139         // delay of 0. The delay does not matter actually since the popup is not shown anyway.
    140         super.setKeyPreviewPopupEnabled(false, 0);
    141     }
    142 
    143     @Override
    144     public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY,
    145             PopupWindow window, KeyboardActionListener listener) {
    146         mController = controller;
    147         mListener = listener;
    148         final View container = (View)getParent();
    149         final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
    150         final int defaultCoordX = pane.mOccupiedWidth / 2;
    151         // The coordinates of panel's left-top corner in parentView's coordinate system.
    152         final int x = pointX - defaultCoordX - container.getPaddingLeft();
    153         final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
    154 
    155         window.setContentView(container);
    156         window.setWidth(container.getMeasuredWidth());
    157         window.setHeight(container.getMeasuredHeight());
    158         parentView.getLocationInWindow(mCoordinates);
    159         window.showAtLocation(parentView, Gravity.NO_GRAVITY,
    160                 x + mCoordinates[0], y + mCoordinates[1]);
    161 
    162         mOriginX = x + container.getPaddingLeft();
    163         mOriginY = y + container.getPaddingTop();
    164     }
    165 
    166     private boolean mIsDismissing;
    167 
    168     @Override
    169     public boolean dismissMoreKeysPanel() {
    170         if (mIsDismissing || mController == null) return false;
    171         mIsDismissing = true;
    172         final boolean dismissed = mController.dismissMoreKeysPanel();
    173         mIsDismissing = false;
    174         return dismissed;
    175     }
    176 
    177     @Override
    178     public int translateX(int x) {
    179         return x - mOriginX;
    180     }
    181 
    182     @Override
    183     public int translateY(int y) {
    184         return y - mOriginY;
    185     }
    186 
    187     private final KeyEventHandler mModalPanelKeyEventHandler = new KeyEventHandler() {
    188         @Override
    189         public KeyDetector getKeyDetector() {
    190             return mModalPanelKeyDetector;
    191         }
    192 
    193         @Override
    194         public KeyboardActionListener getKeyboardActionListener() {
    195             return mSuggestionsPaneListener;
    196         }
    197 
    198         @Override
    199         public DrawingProxy getDrawingProxy() {
    200             return MoreSuggestionsView.this;
    201         }
    202 
    203         @Override
    204         public TimerProxy getTimerProxy() {
    205             return EMPTY_TIMER_PROXY;
    206         }
    207     };
    208 
    209     @Override
    210     public boolean onTouchEvent(MotionEvent me) {
    211         final int action = me.getAction();
    212         final long eventTime = me.getEventTime();
    213         final int index = me.getActionIndex();
    214         final int id = me.getPointerId(index);
    215         final PointerTracker tracker = PointerTracker.getPointerTracker(id, this);
    216         final int x = (int)me.getX(index);
    217         final int y = (int)me.getY(index);
    218         tracker.processMotionEvent(action, x, y, eventTime, mModalPanelKeyEventHandler);
    219         return true;
    220     }
    221 }
    222