From 803ea61d552e9c1df34f5d58f1e59e5b7612d6e1 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Wed, 28 Aug 2013 08:58:57 +0900 Subject: [PATCH] Add recents keyboard Bug: 6370846 Change-Id: I5dc235395fe9b3bd95711fee2fe9b678b4660760 --- java/res/values-v18/emoji-categories.xml | 13 -- java/res/values-v19/emoji-categories.xml | 13 -- java/res/values/emoji-categories.xml | 9 +- .../com/android/inputmethod/keyboard/Key.java | 7 +- .../keyboard/internal/RecentsKeyboard.java | 157 ++++++++++++++++++ .../keyboard/internal/ScrollKeyboardView.java | 1 + 6 files changed, 165 insertions(+), 35 deletions(-) create mode 100644 java/src/com/android/inputmethod/keyboard/internal/RecentsKeyboard.java diff --git a/java/res/values-v18/emoji-categories.xml b/java/res/values-v18/emoji-categories.xml index 17a2053d2..2ea08159b 100644 --- a/java/res/values-v18/emoji-categories.xml +++ b/java/res/values-v18/emoji-categories.xml @@ -17,19 +17,6 @@ - - - 52 - 45 - 43 - 45 - 4E - 54 - = 19). There is another emoji code point list for JB-MR2 under res/xml/values and values-v18.--> - - - 52 - 45 - 43 - 45 - 4E - 54 - - 52 - 45 - 43 - 45 - 4E - 54 + + 30 + 31 { } public final int getDrawX() { + final int x = getX(); final OptionalAttributes attrs = mOptionalAttributes; - return (attrs == null) ? mX : mX + attrs.mVisualInsetsLeft; + return (attrs == null) ? x : x + attrs.mVisualInsetsLeft; } public final int getDrawWidth() { @@ -823,9 +824,9 @@ public class Key implements Comparable { * @return the square of the distance of the point from the nearest edge of the key */ public int squaredDistanceToEdge(final int x, final int y) { - final int left = mX; + final int left = getX(); final int right = left + mWidth; - final int top = mY; + final int top = getY(); final int bottom = top + mHeight; final int edgeX = x < left ? left : (x > right ? right : x); final int edgeY = y < top ? top : (y > bottom ? bottom : y); diff --git a/java/src/com/android/inputmethod/keyboard/internal/RecentsKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/RecentsKeyboard.java new file mode 100644 index 000000000..629c60460 --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/RecentsKeyboard.java @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2013 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.internal; + +import android.text.TextUtils; + +import com.android.inputmethod.keyboard.Key; +import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.utils.CollectionUtils; + +import java.util.ArrayDeque; +import java.util.Random; + +/** + * This is a Keyboard class to host recently used keys. + */ +// TODO: Save/restore recent keys from/to preferences. +public class RecentsKeyboard extends Keyboard { + private static final int TEMPLATE_KEY_CODE_0 = 0x30; + private static final int TEMPLATE_KEY_CODE_1 = 0x31; + + private final int mLeftPadding; + private final int mHorizontalStep; + private final int mVerticalStep; + private final int mColumnsNum; + private final int mMaxRecentKeyCount; + private final ArrayDeque mRecentKeys = CollectionUtils.newArrayDeque(); + + private Key[] mCachedRecentKeys; + + public RecentsKeyboard(final Keyboard templateKeyboard) { + super(templateKeyboard); + final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0); + final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1); + mLeftPadding = key0.getX(); + mHorizontalStep = Math.abs(key1.getX() - key0.getX()); + mVerticalStep = key0.getHeight() + mVerticalGap; + mColumnsNum = mBaseWidth / mHorizontalStep; + final int rowsNum = mBaseHeight / mVerticalStep; + mMaxRecentKeyCount = mColumnsNum * rowsNum; + } + + private Key getTemplateKey(final int code) { + for (final Key key : super.getKeys()) { + if (key.getCode() == code) { + return key; + } + } + throw new RuntimeException("Can't find template key: code=" + code); + } + + private final Random random = new Random(); + + public void addRecentKey(final Key usedKey) { + synchronized (mRecentKeys) { + mCachedRecentKeys = null; + final RecentKey key = (usedKey instanceof RecentKey) + ? (RecentKey)usedKey : new RecentKey(usedKey); + while (mRecentKeys.remove(key)) { + // Remove duplicate keys. + } + mRecentKeys.addFirst(key); + while (mRecentKeys.size() > mMaxRecentKeyCount) { + mRecentKeys.removeLast(); + } + int index = 0; + for (final RecentKey recentKey : mRecentKeys) { + final int keyX = getKeyX(index); + final int keyY = getKeyY(index); + final int x = keyX+random.nextInt(recentKey.getWidth()); + final int y = keyY+random.nextInt(recentKey.getHeight()); + recentKey.updateCorrdinates(keyX, keyY); + index++; + } + } + } + + private int getKeyX(final int index) { + final int column = index % mColumnsNum; + return column * mHorizontalStep + mLeftPadding; + } + + private int getKeyY(final int index) { + final int row = index / mColumnsNum; + return row * mVerticalStep + mTopPadding; + } + + @Override + public Key[] getKeys() { + synchronized (mRecentKeys) { + if (mCachedRecentKeys != null) { + return mCachedRecentKeys; + } + mCachedRecentKeys = mRecentKeys.toArray(new Key[mRecentKeys.size()]); + return mCachedRecentKeys; + } + } + + @Override + public Key[] getNearestKeys(final int x, final int y) { + // TODO: Calculate the nearest key index in mRecentKeys from x and y. + return getKeys(); + } + + static final class RecentKey extends Key { + private int mCurrentX; + private int mCurrentY; + + public RecentKey(final Key originalKey) { + super(originalKey); + } + + public void updateCorrdinates(final int x, final int y) { + mCurrentX = x; + mCurrentY = y; + getHitBox().offsetTo(x, y); + } + + @Override + public int getX() { + return mCurrentX; + } + + @Override + public int getY() { + return mCurrentY; + } + + @Override + public boolean equals(final Object o) { + if (!(o instanceof Key)) return false; + final Key key = (Key)o; + if (getCode() != key.getCode()) return false; + if (!TextUtils.equals(getLabel(), key.getLabel())) return false; + return TextUtils.equals(getOutputText(), key.getOutputText()); + } + + @Override + public String toString() { + return "RecentKey: " + super.toString(); + } + } +} diff --git a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java index 2628f59a8..b8ee976e8 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/ScrollKeyboardView.java @@ -33,6 +33,7 @@ import com.android.inputmethod.latin.R; * This is an extended {@link KeyboardView} class that hosts a scroll keyboard. * Multi-touch unsupported. No {@link PointerTracker}s. No gesture support. */ +// TODO: Implement key popup preview. public final class ScrollKeyboardView extends KeyboardView implements ScrollViewWithNotifier.ScrollListener, GestureDetector.OnGestureListener { private static final boolean PAGINATION = false;