From 2affaf91a04d63e0994102299816014a8bbe11e1 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 8 Feb 2012 16:12:11 +0900 Subject: Rename mini keyboard to more keys keyboard Change-Id: Ie4c85e8ca5a1f41a420aae5c1cd9c1cb07e237e5 --- java/src/com/android/inputmethod/keyboard/Key.java | 2 +- .../com/android/inputmethod/keyboard/Keyboard.java | 10 +- .../inputmethod/keyboard/LatinKeyboardView.java | 28 +-- .../android/inputmethod/keyboard/MiniKeyboard.java | 268 -------------------- .../inputmethod/keyboard/MiniKeyboardView.java | 189 --------------- .../inputmethod/keyboard/MoreKeysKeyboard.java | 269 +++++++++++++++++++++ .../inputmethod/keyboard/MoreKeysKeyboardView.java | 189 +++++++++++++++ .../inputmethod/keyboard/ProximityInfo.java | 2 +- 8 files changed, 479 insertions(+), 478 deletions(-) delete mode 100644 java/src/com/android/inputmethod/keyboard/MiniKeyboard.java delete mode 100644 java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java create mode 100644 java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java create mode 100644 java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java (limited to 'java/src') diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index 6eaa606db..5656c38b4 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -245,7 +245,7 @@ public class Key { mActionFlags = actionFlags; mMoreKeys = moreKeys; mMaxMoreKeysColumn = style.getInt(keyAttr, - R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn); + R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn); mLabel = adjustCaseOfStringForKeyboardId(style.getString(keyAttr, R.styleable.Keyboard_Key_keyLabel), preserveCase, params.mId); diff --git a/java/src/com/android/inputmethod/keyboard/Keyboard.java b/java/src/com/android/inputmethod/keyboard/Keyboard.java index 10e0a5b01..cb6a54569 100644 --- a/java/src/com/android/inputmethod/keyboard/Keyboard.java +++ b/java/src/com/android/inputmethod/keyboard/Keyboard.java @@ -121,8 +121,8 @@ public class Keyboard { /** More keys keyboard template */ public final int mMoreKeysTemplate; - /** Maximum column for mini keyboard */ - public final int mMaxMiniKeyboardColumn; + /** Maximum column for more keys keyboard */ + public final int mMaxMoreKeysKeyboardColumn; /** List of keys and icons in this keyboard */ public final Set mKeys; @@ -143,7 +143,7 @@ public class Keyboard { mMostCommonKeyHeight = params.mMostCommonKeyHeight; mMostCommonKeyWidth = params.mMostCommonKeyWidth; mMoreKeysTemplate = params.mMoreKeysTemplate; - mMaxMiniKeyboardColumn = params.mMaxMiniKeyboardColumn; + mMaxMoreKeysKeyboardColumn = params.mMaxMoreKeysKeyboardColumn; mTopPadding = params.mTopPadding; mVerticalGap = params.mVerticalGap; @@ -226,7 +226,7 @@ public class Keyboard { public int mVerticalGap; public int mMoreKeysTemplate; - public int mMaxMiniKeyboardColumn; + public int mMaxMoreKeysKeyboardColumn; public int GRID_WIDTH; public int GRID_HEIGHT; @@ -770,7 +770,7 @@ public class Keyboard { params.mMoreKeysTemplate = keyboardAttr.getResourceId( R.styleable.Keyboard_moreKeysTemplate, 0); - params.mMaxMiniKeyboardColumn = keyAttr.getInt( + params.mMaxMoreKeysKeyboardColumn = keyAttr.getInt( R.styleable.Keyboard_Key_maxMoreKeysColumn, 5); params.mIconsSet.loadIcons(keyboardAttr); diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index 870c7cb25..88a41579d 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -92,13 +92,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke private final Drawable mAutoCorrectionSpacebarLedIcon; private static final int SPACE_LED_LENGTH_PERCENT = 80; - // Mini keyboard + // More keys keyboard private PopupWindow mMoreKeysWindow; private MoreKeysPanel mMoreKeysPanel; private int mMoreKeysPanelPointerTrackerId; private final WeakHashMap mMoreKeysPanelCache = new WeakHashMap(); - private final boolean mConfigShowMiniKeyboardAtTouchedPoint; + private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint; private final PointerTrackerParams mPointerTrackerParams; private final boolean mIsSpacebarTriggeringPopupByLongPress; @@ -137,7 +137,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke break; case MSG_LONGPRESS_KEY: if (tracker != null) { - keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker); + keyboardView.openMoreKeysKeyboardIfRequired(tracker.getKey(), tracker); } else { KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1); } @@ -338,8 +338,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke R.styleable.LatinKeyboardView_keyHysteresisDistance, 0); mKeyDetector = new KeyDetector(keyHysteresisDistance); mKeyTimerHandler = new KeyTimerHandler(this, keyTimerParams); - mConfigShowMiniKeyboardAtTouchedPoint = a.getBoolean( - R.styleable.LatinKeyboardView_showMiniKeyboardAtTouchedPoint, false); + mConfigShowMoreKeysKeyboardAtTouchedPoint = a.getBoolean( + R.styleable.LatinKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false); a.recycle(); PointerTracker.setParameters(mPointerTrackerParams); @@ -435,7 +435,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke super.cancelAllMessages(); } - private boolean openMiniKeyboardIfRequired(Key parentKey, PointerTracker tracker) { + private boolean openMoreKeysKeyboardIfRequired(Key parentKey, PointerTracker tracker) { // Check if we have a popup layout specified first. if (mMoreKeysLayout == 0) { return false; @@ -458,19 +458,19 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke if (container == null) throw new NullPointerException(); - final MiniKeyboardView miniKeyboardView = - (MiniKeyboardView)container.findViewById(R.id.mini_keyboard_view); + final MoreKeysKeyboardView moreKeysKeyboardView = + (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view); final Keyboard parentKeyboard = getKeyboard(); - final Keyboard miniKeyboard = new MiniKeyboard.Builder( + final Keyboard moreKeysKeyboard = new MoreKeysKeyboard.Builder( this, parentKeyboard.mMoreKeysTemplate, parentKey, parentKeyboard).build(); - miniKeyboardView.setKeyboard(miniKeyboard); + moreKeysKeyboardView.setKeyboard(moreKeysKeyboard); container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - return miniKeyboardView; + return moreKeysKeyboardView; } /** - * Called when a key is long pressed. By default this will open mini keyboard associated + * Called when a key is long pressed. By default this will open more keys keyboard associated * with this key. * @param parentKey the key that was long pressed * @param tracker the pointer tracker which pressed the parent key @@ -524,13 +524,13 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke if (mMoreKeysWindow == null) { mMoreKeysWindow = new PopupWindow(getContext()); mMoreKeysWindow.setBackgroundDrawable(null); - mMoreKeysWindow.setAnimationStyle(R.style.MiniKeyboardAnimation); + mMoreKeysWindow.setAnimationStyle(R.style.MoreKeysKeyboardAnimation); } mMoreKeysPanel = moreKeysPanel; mMoreKeysPanelPointerTrackerId = tracker.mPointerId; final Keyboard keyboard = getKeyboard(); - final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX() + final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint) ? tracker.getLastX() : parentKey.mX + parentKey.mWidth / 2; final int pointY = parentKey.mY - keyboard.mVerticalGap; moreKeysPanel.showMoreKeysPanel( diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java deleted file mode 100644 index 4648da1c1..000000000 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboard.java +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package com.android.inputmethod.keyboard; - -import android.graphics.Paint; - -import com.android.inputmethod.keyboard.internal.KeySpecParser; -import com.android.inputmethod.latin.R; - -public class MiniKeyboard extends Keyboard { - private final int mDefaultKeyCoordX; - - private MiniKeyboard(Builder.MiniKeyboardParams params) { - super(params); - mDefaultKeyCoordX = params.getDefaultKeyCoordX() + params.mDefaultKeyWidth / 2; - } - - public int getDefaultCoordX() { - return mDefaultKeyCoordX; - } - - public static class Builder extends Keyboard.Builder { - private final String[] mMoreKeys; - - public static class MiniKeyboardParams extends Keyboard.Params { - /* package */int mTopRowAdjustment; - public int mNumRows; - public int mNumColumns; - public int mLeftKeys; - public int mRightKeys; // includes default key. - - public MiniKeyboardParams() { - super(); - } - - /* package for test */MiniKeyboardParams(int numKeys, int maxColumns, int keyWidth, - int rowHeight, int coordXInParent, int parentKeyboardWidth) { - super(); - setParameters(numKeys, maxColumns, keyWidth, rowHeight, coordXInParent, - parentKeyboardWidth); - } - - /** - * Set keyboard parameters of mini keyboard. - * - * @param numKeys number of keys in this mini keyboard. - * @param maxColumns number of maximum columns of this mini keyboard. - * @param keyWidth mini keyboard key width in pixel, including horizontal gap. - * @param rowHeight mini keyboard row height in pixel, including vertical gap. - * @param coordXInParent coordinate x of the popup key in parent keyboard. - * @param parentKeyboardWidth parent keyboard width in pixel. - */ - public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight, - int coordXInParent, int parentKeyboardWidth) { - if (parentKeyboardWidth / keyWidth < maxColumns) { - throw new IllegalArgumentException( - "Keyboard is too small to hold mini keyboard: " + parentKeyboardWidth - + " " + keyWidth + " " + maxColumns); - } - mDefaultKeyWidth = keyWidth; - mDefaultRowHeight = rowHeight; - - final int numRows = (numKeys + maxColumns - 1) / maxColumns; - mNumRows = numRows; - final int numColumns = getOptimizedColumns(numKeys, maxColumns); - mNumColumns = numColumns; - - final int numLeftKeys = (numColumns - 1) / 2; - final int numRightKeys = numColumns - numLeftKeys; // including default key. - final int maxLeftKeys = coordXInParent / keyWidth; - final int maxRightKeys = Math.max(1, (parentKeyboardWidth - coordXInParent) - / keyWidth); - int leftKeys, rightKeys; - if (numLeftKeys > maxLeftKeys) { - leftKeys = maxLeftKeys; - rightKeys = numColumns - maxLeftKeys; - } else if (numRightKeys > maxRightKeys) { - leftKeys = numColumns - maxRightKeys; - rightKeys = maxRightKeys; - } else { - leftKeys = numLeftKeys; - rightKeys = numRightKeys; - } - // Shift right if the left edge of mini keyboard is on the edge of parent keyboard - // unless the parent key is on the left edge. - if (leftKeys * keyWidth >= coordXInParent && leftKeys > 0) { - leftKeys--; - rightKeys++; - } - // Shift left if the right edge of mini keyboard is on the edge of parent keyboard - // unless the parent key is on the right edge. - if (rightKeys * keyWidth + coordXInParent >= parentKeyboardWidth && rightKeys > 1) { - leftKeys++; - rightKeys--; - } - mLeftKeys = leftKeys; - mRightKeys = rightKeys; - - // Centering of the top row. - final boolean onEdge = (leftKeys == 0 || rightKeys == 1); - if (numRows < 2 || onEdge || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) { - mTopRowAdjustment = 0; - } else if (mLeftKeys < mRightKeys - 1) { - mTopRowAdjustment = 1; - } else { - mTopRowAdjustment = -1; - } - - mBaseWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth; - // Need to subtract the bottom row's gutter only. - mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight - mVerticalGap - + mTopPadding + mBottomPadding; - } - - // Return key position according to column count (0 is default). - /* package */int getColumnPos(int n) { - final int col = n % mNumColumns; - if (col == 0) { - // default position. - return 0; - } - int pos = 0; - int right = 1; // include default position key. - int left = 0; - int i = 0; - while (true) { - // Assign right key if available. - if (right < mRightKeys) { - pos = right; - right++; - i++; - } - if (i >= col) - break; - // Assign left key if available. - if (left < mLeftKeys) { - left++; - pos = -left; - i++; - } - if (i >= col) - break; - } - return pos; - } - - private static int getTopRowEmptySlots(int numKeys, int numColumns) { - final int remainingKeys = numKeys % numColumns; - if (remainingKeys == 0) { - return 0; - } else { - return numColumns - remainingKeys; - } - } - - private int getOptimizedColumns(int numKeys, int maxColumns) { - int numColumns = Math.min(numKeys, maxColumns); - while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) { - numColumns--; - } - return numColumns; - } - - public int getDefaultKeyCoordX() { - return mLeftKeys * mDefaultKeyWidth; - } - - public int getX(int n, int row) { - final int x = getColumnPos(n) * mDefaultKeyWidth + getDefaultKeyCoordX(); - if (isTopRow(row)) { - return x + mTopRowAdjustment * (mDefaultKeyWidth / 2); - } - return x; - } - - public int getY(int row) { - return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding; - } - - public void markAsEdgeKey(Key key, int row) { - if (row == 0) - key.markAsTopEdge(this); - if (isTopRow(row)) - key.markAsBottomEdge(this); - } - - private boolean isTopRow(int rowCount) { - return rowCount == mNumRows - 1; - } - } - - public Builder(KeyboardView view, int xmlId, Key parentKey, Keyboard parentKeyboard) { - super(view.getContext(), new MiniKeyboardParams()); - load(xmlId, parentKeyboard.mId); - - // TODO: Mini keyboard's vertical gap is currently calculated heuristically. - // Should revise the algorithm. - mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2; - mMoreKeys = parentKey.mMoreKeys; - - final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth; - final int previewHeight = view.mKeyPreviewDrawParams.mPreviewBackgroundHeight; - final int width, height; - // Use pre-computed width and height if these values are available and mini keyboard - // has only one key to mitigate visual flicker between key preview and mini keyboard. - if (view.isKeyPreviewPopupEnabled() && mMoreKeys.length == 1 && previewWidth > 0 - && previewHeight > 0) { - width = previewWidth; - height = previewHeight + mParams.mVerticalGap; - } else { - width = getMaxKeyWidth(view, parentKey.mMoreKeys, mParams.mDefaultKeyWidth); - height = parentKeyboard.mMostCommonKeyHeight; - } - mParams.setParameters(mMoreKeys.length, parentKey.mMaxMoreKeysColumn, width, height, - parentKey.mX + (mParams.mDefaultKeyWidth - width) / 2, view.getMeasuredWidth()); - } - - private static int getMaxKeyWidth(KeyboardView view, String[] moreKeys, int minKeyWidth) { - final int padding = (int) view.getContext().getResources() - .getDimension(R.dimen.mini_keyboard_key_horizontal_padding); - Paint paint = null; - int maxWidth = minKeyWidth; - for (String moreKeySpec : moreKeys) { - final String label = KeySpecParser.getLabel(moreKeySpec); - // If the label is single letter, minKeyWidth is enough to hold the label. - if (label != null && label.length() > 1) { - if (paint == null) { - paint = new Paint(); - paint.setAntiAlias(true); - } - final int width = (int)view.getDefaultLabelWidth(label, paint) + padding; - if (maxWidth < width) { - maxWidth = width; - } - } - } - return maxWidth; - } - - @Override - public MiniKeyboard build() { - final MiniKeyboardParams params = mParams; - for (int n = 0; n < mMoreKeys.length; n++) { - final String moreKeySpec = mMoreKeys[n]; - final int row = n / params.mNumColumns; - final Key key = new Key(mResources, params, moreKeySpec, params.getX(n, row), - params.getY(row), params.mDefaultKeyWidth, params.mDefaultRowHeight); - params.markAsEdgeKey(key, row); - params.onAddKey(key); - } - return new MiniKeyboard(params); - } - } -} diff --git a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java deleted file mode 100644 index 72d5b6889..000000000 --- a/java/src/com/android/inputmethod/keyboard/MiniKeyboardView.java +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.inputmethod.keyboard; - -import android.content.Context; -import android.content.res.Resources; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.View; -import android.widget.PopupWindow; - -import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; -import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; -import com.android.inputmethod.latin.R; - -/** - * A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting - * key presses and touch movements. - */ -public class MiniKeyboardView extends KeyboardView implements MoreKeysPanel { - private final int[] mCoordinates = new int[2]; - - private final KeyDetector mKeyDetector; - - private Controller mController; - private KeyboardActionListener mListener; - private int mOriginX; - private int mOriginY; - - private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter(); - - private final KeyboardActionListener mMiniKeyboardListener = - new KeyboardActionListener.Adapter() { - @Override - public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { - mListener.onCodeInput(primaryCode, keyCodes, x, y); - } - - @Override - public void onTextInput(CharSequence text) { - mListener.onTextInput(text); - } - - @Override - public void onCancelInput() { - mListener.onCancelInput(); - } - - @Override - public void onPressKey(int primaryCode) { - mListener.onPressKey(primaryCode); - } - - @Override - public void onReleaseKey(int primaryCode, boolean withSliding) { - mListener.onReleaseKey(primaryCode, withSliding); - } - }; - - public MiniKeyboardView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.miniKeyboardViewStyle); - } - - public MiniKeyboardView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - final Resources res = context.getResources(); - mKeyDetector = new MoreKeysDetector( - res.getDimension(R.dimen.mini_keyboard_slide_allowance)); - setKeyPreviewPopupEnabled(false, 0); - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final Keyboard keyboard = getKeyboard(); - if (keyboard != null) { - final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); - final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); - setMeasuredDimension(width, height); - } else { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } - - @Override - public void setKeyboard(Keyboard keyboard) { - super.setKeyboard(keyboard); - mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), - -getPaddingTop() + mVerticalCorrection); - } - - @Override - public KeyDetector getKeyDetector() { - return mKeyDetector; - } - - @Override - public KeyboardActionListener getKeyboardActionListener() { - return mMiniKeyboardListener; - } - - @Override - public DrawingProxy getDrawingProxy() { - return this; - } - - @Override - public TimerProxy getTimerProxy() { - return EMPTY_TIMER_PROXY; - } - - @Override - public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) { - // Mini keyboard needs no pop-up key preview displayed, so we pass always false with a - // delay of 0. The delay does not matter actually since the popup is not shown anyway. - super.setKeyPreviewPopupEnabled(false, 0); - } - - @Override - public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY, - PopupWindow window, KeyboardActionListener listener) { - mController = controller; - mListener = listener; - final View container = (View)getParent(); - final MiniKeyboard miniKeyboard = (MiniKeyboard)getKeyboard(); - - parentView.getLocationInWindow(mCoordinates); - final int miniKeyboardLeft = pointX - miniKeyboard.getDefaultCoordX() - + parentView.getPaddingLeft(); - final int x = wrapUp(Math.max(0, Math.min(miniKeyboardLeft, - parentView.getWidth() - miniKeyboard.mOccupiedWidth)) - - container.getPaddingLeft() + mCoordinates[0], - container.getMeasuredWidth(), 0, parentView.getWidth()); - final int y = pointY - - (container.getMeasuredHeight() - container.getPaddingBottom()) - + parentView.getPaddingTop() + mCoordinates[1]; - - window.setContentView(container); - window.setWidth(container.getMeasuredWidth()); - window.setHeight(container.getMeasuredHeight()); - window.showAtLocation(parentView, Gravity.NO_GRAVITY, x, y); - - mOriginX = x + container.getPaddingLeft() - mCoordinates[0]; - mOriginY = y + container.getPaddingTop() - mCoordinates[1]; - } - - private static int wrapUp(int x, int width, int left, int right) { - if (x < left) - return left; - if (x + width > right) - return right - width; - return x; - } - - private boolean mIsDismissing; - - @Override - public boolean dismissMoreKeysPanel() { - if (mIsDismissing) return false; - mIsDismissing = true; - final boolean dismissed = mController.dismissMoreKeysPanel(); - mIsDismissing = false; - return dismissed; - } - - @Override - public int translateX(int x) { - return x - mOriginX; - } - - @Override - public int translateY(int y) { - return y - mOriginY; - } -} diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java new file mode 100644 index 000000000..83155f719 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.keyboard; + +import android.graphics.Paint; + +import com.android.inputmethod.keyboard.internal.KeySpecParser; +import com.android.inputmethod.latin.R; + +public class MoreKeysKeyboard extends Keyboard { + private final int mDefaultKeyCoordX; + + private MoreKeysKeyboard(Builder.MoreKeysKeyboardParams params) { + super(params); + mDefaultKeyCoordX = params.getDefaultKeyCoordX() + params.mDefaultKeyWidth / 2; + } + + public int getDefaultCoordX() { + return mDefaultKeyCoordX; + } + + public static class Builder extends Keyboard.Builder { + private final String[] mMoreKeys; + + public static class MoreKeysKeyboardParams extends Keyboard.Params { + /* package */int mTopRowAdjustment; + public int mNumRows; + public int mNumColumns; + public int mLeftKeys; + public int mRightKeys; // includes default key. + + public MoreKeysKeyboardParams() { + super(); + } + + /* package for test */MoreKeysKeyboardParams(int numKeys, int maxColumns, int keyWidth, + int rowHeight, int coordXInParent, int parentKeyboardWidth) { + super(); + setParameters(numKeys, maxColumns, keyWidth, rowHeight, coordXInParent, + parentKeyboardWidth); + } + + /** + * Set keyboard parameters of more keys keyboard. + * + * @param numKeys number of keys in this more keys keyboard. + * @param maxColumns number of maximum columns of this more keys keyboard. + * @param keyWidth more keys keyboard key width in pixel, including horizontal gap. + * @param rowHeight more keys keyboard row height in pixel, including vertical gap. + * @param coordXInParent coordinate x of the key preview in parent keyboard. + * @param parentKeyboardWidth parent keyboard width in pixel. + */ + public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight, + int coordXInParent, int parentKeyboardWidth) { + if (parentKeyboardWidth / keyWidth < maxColumns) { + throw new IllegalArgumentException( + "Keyboard is too small to hold more keys keyboard: " + + parentKeyboardWidth + " " + keyWidth + " " + maxColumns); + } + mDefaultKeyWidth = keyWidth; + mDefaultRowHeight = rowHeight; + + final int numRows = (numKeys + maxColumns - 1) / maxColumns; + mNumRows = numRows; + final int numColumns = getOptimizedColumns(numKeys, maxColumns); + mNumColumns = numColumns; + + final int numLeftKeys = (numColumns - 1) / 2; + final int numRightKeys = numColumns - numLeftKeys; // including default key. + final int maxLeftKeys = coordXInParent / keyWidth; + final int maxRightKeys = Math.max(1, (parentKeyboardWidth - coordXInParent) + / keyWidth); + int leftKeys, rightKeys; + if (numLeftKeys > maxLeftKeys) { + leftKeys = maxLeftKeys; + rightKeys = numColumns - maxLeftKeys; + } else if (numRightKeys > maxRightKeys) { + leftKeys = numColumns - maxRightKeys; + rightKeys = maxRightKeys; + } else { + leftKeys = numLeftKeys; + rightKeys = numRightKeys; + } + // Shift right if the left edge of more keys keyboard is on the edge of parent + // keyboard unless the parent key is on the left edge. + if (leftKeys * keyWidth >= coordXInParent && leftKeys > 0) { + leftKeys--; + rightKeys++; + } + // Shift left if the right edge of more keys keyboard is on the edge of parent + // keyboard unless the parent key is on the right edge. + if (rightKeys * keyWidth + coordXInParent >= parentKeyboardWidth && rightKeys > 1) { + leftKeys++; + rightKeys--; + } + mLeftKeys = leftKeys; + mRightKeys = rightKeys; + + // Centering of the top row. + final boolean onEdge = (leftKeys == 0 || rightKeys == 1); + if (numRows < 2 || onEdge || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) { + mTopRowAdjustment = 0; + } else if (mLeftKeys < mRightKeys - 1) { + mTopRowAdjustment = 1; + } else { + mTopRowAdjustment = -1; + } + + mBaseWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth; + // Need to subtract the bottom row's gutter only. + mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight - mVerticalGap + + mTopPadding + mBottomPadding; + } + + // Return key position according to column count (0 is default). + /* package */int getColumnPos(int n) { + final int col = n % mNumColumns; + if (col == 0) { + // default position. + return 0; + } + int pos = 0; + int right = 1; // include default position key. + int left = 0; + int i = 0; + while (true) { + // Assign right key if available. + if (right < mRightKeys) { + pos = right; + right++; + i++; + } + if (i >= col) + break; + // Assign left key if available. + if (left < mLeftKeys) { + left++; + pos = -left; + i++; + } + if (i >= col) + break; + } + return pos; + } + + private static int getTopRowEmptySlots(int numKeys, int numColumns) { + final int remainingKeys = numKeys % numColumns; + if (remainingKeys == 0) { + return 0; + } else { + return numColumns - remainingKeys; + } + } + + private int getOptimizedColumns(int numKeys, int maxColumns) { + int numColumns = Math.min(numKeys, maxColumns); + while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) { + numColumns--; + } + return numColumns; + } + + public int getDefaultKeyCoordX() { + return mLeftKeys * mDefaultKeyWidth; + } + + public int getX(int n, int row) { + final int x = getColumnPos(n) * mDefaultKeyWidth + getDefaultKeyCoordX(); + if (isTopRow(row)) { + return x + mTopRowAdjustment * (mDefaultKeyWidth / 2); + } + return x; + } + + public int getY(int row) { + return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding; + } + + public void markAsEdgeKey(Key key, int row) { + if (row == 0) + key.markAsTopEdge(this); + if (isTopRow(row)) + key.markAsBottomEdge(this); + } + + private boolean isTopRow(int rowCount) { + return rowCount == mNumRows - 1; + } + } + + public Builder(KeyboardView view, int xmlId, Key parentKey, Keyboard parentKeyboard) { + super(view.getContext(), new MoreKeysKeyboardParams()); + load(xmlId, parentKeyboard.mId); + + // TODO: More keys keyboard's vertical gap is currently calculated heuristically. + // Should revise the algorithm. + mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2; + mMoreKeys = parentKey.mMoreKeys; + + final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth; + final int previewHeight = view.mKeyPreviewDrawParams.mPreviewBackgroundHeight; + final int width, height; + // Use pre-computed width and height if these values are available and more keys + // keyboard has only one key to mitigate visual flicker between key preview and more + // keys keyboard. + if (view.isKeyPreviewPopupEnabled() && mMoreKeys.length == 1 && previewWidth > 0 + && previewHeight > 0) { + width = previewWidth; + height = previewHeight + mParams.mVerticalGap; + } else { + width = getMaxKeyWidth(view, parentKey.mMoreKeys, mParams.mDefaultKeyWidth); + height = parentKeyboard.mMostCommonKeyHeight; + } + mParams.setParameters(mMoreKeys.length, parentKey.mMaxMoreKeysColumn, width, height, + parentKey.mX + (mParams.mDefaultKeyWidth - width) / 2, view.getMeasuredWidth()); + } + + private static int getMaxKeyWidth(KeyboardView view, String[] moreKeys, int minKeyWidth) { + final int padding = (int) view.getContext().getResources() + .getDimension(R.dimen.more_keys_keyboard_key_horizontal_padding); + Paint paint = null; + int maxWidth = minKeyWidth; + for (String moreKeySpec : moreKeys) { + final String label = KeySpecParser.getLabel(moreKeySpec); + // If the label is single letter, minKeyWidth is enough to hold the label. + if (label != null && label.length() > 1) { + if (paint == null) { + paint = new Paint(); + paint.setAntiAlias(true); + } + final int width = (int)view.getDefaultLabelWidth(label, paint) + padding; + if (maxWidth < width) { + maxWidth = width; + } + } + } + return maxWidth; + } + + @Override + public MoreKeysKeyboard build() { + final MoreKeysKeyboardParams params = mParams; + for (int n = 0; n < mMoreKeys.length; n++) { + final String moreKeySpec = mMoreKeys[n]; + final int row = n / params.mNumColumns; + final Key key = new Key(mResources, params, moreKeySpec, params.getX(n, row), + params.getY(row), params.mDefaultKeyWidth, params.mDefaultRowHeight); + params.markAsEdgeKey(key, row); + params.onAddKey(key); + } + return new MoreKeysKeyboard(params); + } + } +} diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java new file mode 100644 index 000000000..b030dd95a --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboardView.java @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.inputmethod.keyboard; + +import android.content.Context; +import android.content.res.Resources; +import android.util.AttributeSet; +import android.view.Gravity; +import android.view.View; +import android.widget.PopupWindow; + +import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; +import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; +import com.android.inputmethod.latin.R; + +/** + * A view that renders a virtual {@link MoreKeysKeyboard}. It handles rendering of keys and + * detecting key presses and touch movements. + */ +public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel { + private final int[] mCoordinates = new int[2]; + + private final KeyDetector mKeyDetector; + + private Controller mController; + private KeyboardActionListener mListener; + private int mOriginX; + private int mOriginY; + + private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy.Adapter(); + + private final KeyboardActionListener mMoreKeysKeyboardListener = + new KeyboardActionListener.Adapter() { + @Override + public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { + mListener.onCodeInput(primaryCode, keyCodes, x, y); + } + + @Override + public void onTextInput(CharSequence text) { + mListener.onTextInput(text); + } + + @Override + public void onCancelInput() { + mListener.onCancelInput(); + } + + @Override + public void onPressKey(int primaryCode) { + mListener.onPressKey(primaryCode); + } + + @Override + public void onReleaseKey(int primaryCode, boolean withSliding) { + mListener.onReleaseKey(primaryCode, withSliding); + } + }; + + public MoreKeysKeyboardView(Context context, AttributeSet attrs) { + this(context, attrs, R.attr.moreKeysKeyboardViewStyle); + } + + public MoreKeysKeyboardView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + final Resources res = context.getResources(); + mKeyDetector = new MoreKeysDetector( + res.getDimension(R.dimen.more_keys_keyboard_slide_allowance)); + setKeyPreviewPopupEnabled(false, 0); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + final Keyboard keyboard = getKeyboard(); + if (keyboard != null) { + final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); + final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); + setMeasuredDimension(width, height); + } else { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + } + + @Override + public void setKeyboard(Keyboard keyboard) { + super.setKeyboard(keyboard); + mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(), + -getPaddingTop() + mVerticalCorrection); + } + + @Override + public KeyDetector getKeyDetector() { + return mKeyDetector; + } + + @Override + public KeyboardActionListener getKeyboardActionListener() { + return mMoreKeysKeyboardListener; + } + + @Override + public DrawingProxy getDrawingProxy() { + return this; + } + + @Override + public TimerProxy getTimerProxy() { + return EMPTY_TIMER_PROXY; + } + + @Override + public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) { + // More keys keyboard needs no pop-up key preview displayed, so we pass always false with a + // delay of 0. The delay does not matter actually since the popup is not shown anyway. + super.setKeyPreviewPopupEnabled(false, 0); + } + + @Override + public void showMoreKeysPanel(View parentView, Controller controller, int pointX, int pointY, + PopupWindow window, KeyboardActionListener listener) { + mController = controller; + mListener = listener; + final View container = (View)getParent(); + final MoreKeysKeyboard moreKeysKeyboard = (MoreKeysKeyboard)getKeyboard(); + + parentView.getLocationInWindow(mCoordinates); + final int moreKeysKeyboardLeft = pointX - moreKeysKeyboard.getDefaultCoordX() + + parentView.getPaddingLeft(); + final int x = wrapUp(Math.max(0, Math.min(moreKeysKeyboardLeft, + parentView.getWidth() - moreKeysKeyboard.mOccupiedWidth)) + - container.getPaddingLeft() + mCoordinates[0], + container.getMeasuredWidth(), 0, parentView.getWidth()); + final int y = pointY + - (container.getMeasuredHeight() - container.getPaddingBottom()) + + parentView.getPaddingTop() + mCoordinates[1]; + + window.setContentView(container); + window.setWidth(container.getMeasuredWidth()); + window.setHeight(container.getMeasuredHeight()); + window.showAtLocation(parentView, Gravity.NO_GRAVITY, x, y); + + mOriginX = x + container.getPaddingLeft() - mCoordinates[0]; + mOriginY = y + container.getPaddingTop() - mCoordinates[1]; + } + + private static int wrapUp(int x, int width, int left, int right) { + if (x < left) + return left; + if (x + width > right) + return right - width; + return x; + } + + private boolean mIsDismissing; + + @Override + public boolean dismissMoreKeysPanel() { + if (mIsDismissing) return false; + mIsDismissing = true; + final boolean dismissed = mController.dismissMoreKeysPanel(); + mIsDismissing = false; + return dismissed; + } + + @Override + public int translateX(int x) { + return x - mOriginX; + } + + @Override + public int translateY(int y) { + return y - mOriginY; + } +} diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java index 2d1a0083d..41e7ef435 100644 --- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java +++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java @@ -59,7 +59,7 @@ public class ProximityInfo { mKeyHeight = keyHeight; mGridNeighbors = new Key[mGridSize][]; if (minWidth == 0 || height == 0) { - // No proximity required. Keyboard might be mini keyboard. + // No proximity required. Keyboard might be more keys keyboard. return; } computeNearestNeighbors(keyWidth, keys, touchPositionCorrection, additionalProximityChars); -- cgit v1.2.3-83-g751a