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.keyboard; 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.View; 24 import android.widget.PopupWindow; 25 26 import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; 27 import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; 28 import com.android.inputmethod.latin.R; 29 30 /** 31 * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting 32 * key presses and touch movements. 33 */ 34 public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel { 35 private final int[] mCoordinates = new int[2]; 36 37 private final KeyDetector mKeyDetector; 38 39 private Controller mController; 40 private KeyboardActionListener mListener; 41 private int mOriginX; 42 private int mOriginY; 43 44 private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter(); 45 46 private final KeyboardActionListener mMiniKeyboardListener = 47 new KeyboardActionListener.Adapter() { 48 @Override 49 public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { 50 mListener.onCodeInput(primaryCode, keyCodes, x, y); 51 } 52 53 @Override 54 public void onTextInput(CharSequence text) { 55 mListener.onTextInput(text); 56 } 57 58 @Override 59 public void onCancelInput() { 60 mListener.onCancelInput(); 61 } 62 63 @Override 64 public void onPress(int primaryCode, boolean withSliding) { 65 mListener.onPress(primaryCode, withSliding); 66 } 67 @Override 68 public void onRelease(int primaryCode, boolean withSliding) { 69 mListener.onRelease(primaryCode, withSliding); 70 } 71 }; 72 73 public MiniKeyboardView(Context context, AttributeSet attrs) { 74 this(context, attrs, R.attr.miniKeyboardViewStyle); 75 } 76 77 public MiniKeyboardView(Context context, AttributeSet attrs, int defStyle) { 78 super(context, attrs, defStyle); 79 80 final Resources res = context.getResources(); 81 mKeyDetector = new MoreKeysDetector( 82 res.getDimension(R.dimen.mini_keyboard_slide_allowance)); 83 setKeyPreviewPopupEnabled(false, 0); 84 } 85 86 @Override 87 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 88 final Keyboard keyboard = getKeyboard(); 89 if (keyboard != null) { 90 final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); 91 final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); 92 setMeasuredDimension(width, height); 93 } else { 94 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 95 } 96 } 97 98 @Override 99 public void setKeyboard(Keyboard keyboard) { 100 super.setKeyboard(keyboard); 101 mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), 102 -getPaddingTop() + mVerticalCorrection); 103 } 104 105 @Override 106 public KeyDetector getKeyDetector() { 107 return mKeyDetector; 108 } 109 110 @Override 111 public KeyboardActionListener getKeyboardActionListener() { 112 return mMiniKeyboardListener; 113 } 114 115 @Override 116 public DrawingProxy getDrawingProxy() { 117 return this; 118 } 119 120 @Override 121 public TimerProxy getTimerProxy() { 122 return EMPTY_TIMER_PROXY; 123 } 124 125 @Override 126 public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) { 127 // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a 128 // delay of 0. The delay does not matter actually since the popup is not shown anyway. 129 super.setKeyPreviewPopupEnabled(false, 0); 130 } 131 132 @Override 133 public void setShifted(boolean shifted) { 134 final Keyboard keyboard = getKeyboard(); 135 if (keyboard.setShifted(shifted)) { 136 invalidateAllKeys(); 137 } 138 } 139 140 @Override 141 public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY, 142 PopupWindow window, KeyboardActionListener listener) { 143 mController = controller; 144 mListener = listener; 145 final View container = (View)getParent(); 146 final MiniKeyboard miniKeyboard = (MiniKeyboard)getKeyboard(); 147 148 parentView.getLocationInWindow(mCoordinates); 149 final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX() 150 + parentView.getPaddingLeft(); 151 final int x = wrapUp(Math.max(0, Math.min(miniKeyboardLeft, 152 parentView.getWidth() - miniKeyboard.mOccupiedWidth)) 153 - container.getPaddingLeft() + mCoordinates[0], 154 container.getMeasuredWidth(), 0, parentView.getWidth()); 155 final int y = pointY 156 - (container.getMeasuredHeight() - container.getPaddingBottom()) 157 + parentView.getPaddingTop() + mCoordinates[1]; 158 159 window.setContentView(container); 160 window.setWidth(container.getMeasuredWidth()); 161 window.setHeight(container.getMeasuredHeight()); 162 window.showAtLocation(parentView, Gravity.NO_GRAVITY, x, y); 163 164 mOriginX = x + container.getPaddingLeft() - mCoordinates[0]; 165 mOriginY = y + container.getPaddingTop() - mCoordinates[1]; 166 } 167 168 private static int wrapUp(int x, int width, int left, int right) { 169 if (x < left) 170 return left; 171 if (x + width > right) 172 return right - width; 173 return x; 174 } 175 176 private boolean mIsDismissing; 177 178 @Override 179 public boolean dismissMoreKeysPanel() { 180 if (mIsDismissing) return false; 181 mIsDismissing = true; 182 final boolean dismissed = mController.dismissMoreKeysPanel(); 183 mIsDismissing = false; 184 return dismissed; 185 } 186 187 @Override 188 public int translateX(int x) { 189 return x - mOriginX; 190 } 191 192 @Override 193 public int translateY(int y) { 194 return y - mOriginY; 195 } 196 } 197