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