aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorSatoshi Kataoka <satok@google.com>2013-09-13 19:06:22 +0900
committerSatoshi Kataoka <satok@google.com>2013-09-13 21:18:57 +0900
commitb0bf7e729b5a3ec6dc481d72f04d7dad0e12672a (patch)
treefd5a191418aa66aa392523c0fd5c8a94205d6e1c /java/src
parentb9db10d62eec89259705c979ed2a294be6ded51c (diff)
downloadlatinime-b0bf7e729b5a3ec6dc481d72f04d7dad0e12672a.tar.gz
latinime-b0bf7e729b5a3ec6dc481d72f04d7dad0e12672a.tar.xz
latinime-b0bf7e729b5a3ec6dc481d72f04d7dad0e12672a.zip
Use DynamicGridKeyboard for EmojiPager
Bug: 10538430 Change-Id: Iff84e306faaa8e87d107e418d5c61c5613b57430
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java111
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java65
2 files changed, 127 insertions, 49 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
index 9996a6d6a..2e05dd382 100644
--- a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
+import android.graphics.Rect;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
@@ -37,7 +38,9 @@ import android.widget.TabHost;
import android.widget.TabHost.OnTabChangeListener;
import android.widget.TextView;
+import com.android.inputmethod.keyboard.internal.CodesArrayParser;
import com.android.inputmethod.keyboard.internal.DynamicGridKeyboard;
+import com.android.inputmethod.keyboard.internal.KeyboardParams;
import com.android.inputmethod.keyboard.internal.ScrollKeyboardView;
import com.android.inputmethod.keyboard.internal.ScrollViewWithNotifier;
import com.android.inputmethod.latin.Constants;
@@ -47,7 +50,10 @@ import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.ResourceUtils;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
/**
* View class to implement Emoji keyboards.
@@ -75,16 +81,17 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
+ private static final int CATEGORY_UNSPECIFIED = -1;
+ private static final int CATEGORY_RECENTS = 0;
+ private static final int CATEGORY_PEOPLE = 1;
+ private static final int CATEGORY_OBJECTS = 2;
+ private static final int CATEGORY_NATURE = 3;
+ private static final int CATEGORY_PLACES = 4;
+ private static final int CATEGORY_SYMBOLS = 5;
+ private static final int CATEGORY_EMOTICONS = 6;
+
private static class EmojiCategory {
- private int mCurrentCategory = CATEGORY_UNSPECIFIED;
- private static final int CATEGORY_UNSPECIFIED = -1;
- private static final int CATEGORY_RECENTS = 0;
- private static final int CATEGORY_PEOPLE = 1;
- private static final int CATEGORY_OBJECTS = 2;
- private static final int CATEGORY_NATURE = 3;
- private static final int CATEGORY_PLACES = 4;
- private static final int CATEGORY_SYMBOLS = 5;
- private static final int CATEGORY_EMOTICONS = 6;
+ private static final int DEFAULT_MAX_ROW_SIZE = 3;
private static final String[] sCategoryName = {
"recents",
"people",
@@ -111,10 +118,18 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
KeyboardId.ELEMENT_EMOJI_CATEGORY4,
KeyboardId.ELEMENT_EMOJI_CATEGORY5,
KeyboardId.ELEMENT_EMOJI_CATEGORY6, };
+ private Resources mRes;
+ private final KeyboardLayoutSet mLayoutSet;
private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap();
private final ArrayList<Integer> mShownCategories = new ArrayList<Integer>();
+ private final ConcurrentHashMap<Long, DynamicGridKeyboard>
+ mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>();
- public EmojiCategory() {
+ private int mCurrentCategory = CATEGORY_UNSPECIFIED;
+
+ public EmojiCategory(final Resources res, final KeyboardLayoutSet layoutSet) {
+ mRes = res;
+ mLayoutSet = layoutSet;
for (int i = 0; i < sCategoryName.length; ++i) {
mCategoryNameToIdMap.put(sCategoryName[i], i);
}
@@ -185,12 +200,71 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
return mShownCategories.get(tabId);
}
- public int getElementIdFromTabId(int tabId) {
- return sCategoryElementId[getCategoryFromTabId(tabId)];
+ public DynamicGridKeyboard getKeyboard(int category, int id) {
+ synchronized(mCategoryKeyboardMap) {
+ final long key = (((long) category) << 32) | id;
+ final DynamicGridKeyboard kbd;
+ if (!mCategoryKeyboardMap.containsKey(key)) {
+ if (category != CATEGORY_RECENTS) {
+ kbd = new DynamicGridKeyboard(
+ mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
+ DEFAULT_MAX_ROW_SIZE);
+ final Keyboard keyboard =
+ mLayoutSet.getKeyboard(sCategoryElementId[category]);
+ // TODO: Calculate maxPageCount dynamically
+ final Key[][] sortedKeys = sortKeys(keyboard.getKeys(), 21);
+ for (Key emojiKey : sortedKeys[0]) {
+ if (emojiKey == null) {
+ break;
+ }
+ kbd.addKeyLast(emojiKey);
+ }
+ } else {
+ kbd = new DynamicGridKeyboard(
+ mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
+ DEFAULT_MAX_ROW_SIZE);
+ }
+ mCategoryKeyboardMap.put(key, kbd);
+ } else {
+ kbd = mCategoryKeyboardMap.get(key);
+ }
+ return kbd;
+ }
+ }
+
+ private Key[][] sortKeys(Key[] inKeys, int maxPageCount) {
+ Key[] keys = Arrays.copyOf(inKeys, inKeys.length);
+ Arrays.sort(keys, 0, keys.length, new Comparator<Key>() {
+ @Override
+ public int compare(Key lhs, Key rhs) {
+ final Rect lHitBox = lhs.getHitBox();
+ final Rect rHitBox = rhs.getHitBox();
+ if (lHitBox.top < rHitBox.top) {
+ return -1;
+ } else if (lHitBox.top > rHitBox.top) {
+ return 1;
+ }
+ if (lHitBox.left < rHitBox.left) {
+ return -1;
+ } else if (lHitBox.left > rHitBox.left) {
+ return 1;
+ }
+ if (lhs.getCode() == rhs.getCode()) {
+ return 0;
+ }
+ return lhs.getCode() < rhs.getCode() ? -1 : 1;
+ }
+ });
+ final int pageCount = (keys.length - 1) / maxPageCount + 1;
+ final Key[][] retval = new Key[pageCount][maxPageCount];
+ for (int i = 0; i < keys.length; ++i) {
+ retval[i / maxPageCount][i % maxPageCount] = keys[i];
+ }
+ return retval;
}
}
- private final EmojiCategory mEmojiCategory = new EmojiCategory();
+ private final EmojiCategory mEmojiCategory;
public EmojiKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.emojiKeyboardViewStyle);
@@ -219,6 +293,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
+ res.getDimensionPixelSize(R.dimen.suggestions_strip_height));
builder.setOptions(false, false, false /* lanuageSwitchKeyEnabled */);
mLayoutSet = builder.build();
+ mEmojiCategory = new EmojiCategory(context.getResources(), builder.build());
// TODO: Save/restore recent keys from/to preferences.
}
@@ -388,15 +463,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
mEmojiCategory = emojiCategory;
mListener = listener;
mLayoutSet = layoutSet;
- mRecentsKeyboard = new DynamicGridKeyboard(
- layoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS));
+ mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_RECENTS, 0);
}
public void addRecentKey(final Key key) {
if (mEmojiCategory.isInRecentTab()) {
return;
}
- mRecentsKeyboard.addRecentKey(key);
+ mRecentsKeyboard.addKeyFirst(key);
final KeyboardView recentKeyboardView =
mActiveKeyboardView.get(mEmojiCategory.getRecentTabId());
if (recentKeyboardView != null) {
@@ -424,9 +498,8 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange
@Override
public Object instantiateItem(final ViewGroup container, final int position) {
- final int elementId = mEmojiCategory.getElementIdFromTabId(position);
- final Keyboard keyboard = (elementId == KeyboardId.ELEMENT_EMOJI_RECENTS)
- ? mRecentsKeyboard : mLayoutSet.getKeyboard(elementId);
+ final Keyboard keyboard =
+ mEmojiCategory.getKeyboard(mEmojiCategory.getCategoryFromTabId(position), 0);
final LayoutInflater inflater = LayoutInflater.from(container.getContext());
final View view = inflater.inflate(
R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
index a226891b4..22708975a 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java
@@ -23,7 +23,6 @@ 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 where you can add keys dynamically shown in a grid layout
@@ -37,12 +36,12 @@ public class DynamicGridKeyboard extends Keyboard {
private final int mHorizontalStep;
private final int mVerticalStep;
private final int mColumnsNum;
- private final int mMaxRecentKeyCount;
- private final ArrayDeque<RecentKey> mRecentKeys = CollectionUtils.newArrayDeque();
+ private final int mMaxKeyCount;
+ private final ArrayDeque<GridKey> mGridKeys = CollectionUtils.newArrayDeque();
- private Key[] mCachedRecentKeys;
+ private Key[] mCachedGridKeys;
- public DynamicGridKeyboard(final Keyboard templateKeyboard) {
+ public DynamicGridKeyboard(final Keyboard templateKeyboard, final int maxRows) {
super(templateKeyboard);
final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0);
final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1);
@@ -50,8 +49,7 @@ public class DynamicGridKeyboard extends Keyboard {
mHorizontalStep = Math.abs(key1.getX() - key0.getX());
mVerticalStep = key0.getHeight() + mVerticalGap;
mColumnsNum = mBaseWidth / mHorizontalStep;
- final int rowsNum = mBaseHeight / mVerticalStep;
- mMaxRecentKeyCount = mColumnsNum * rowsNum;
+ mMaxKeyCount = mColumnsNum * maxRows;
}
private Key getTemplateKey(final int code) {
@@ -63,27 +61,34 @@ public class DynamicGridKeyboard extends Keyboard {
throw new RuntimeException("Can't find template key: code=" + code);
}
- private final Random random = new Random();
+ public void addKeyFirst(final Key usedKey) {
+ addKey(usedKey, true);
+ }
+
+ public void addKeyLast(final Key usedKey) {
+ addKey(usedKey, false);
+ }
- 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)) {
+ private void addKey(final Key usedKey, final boolean addFirst) {
+ synchronized (mGridKeys) {
+ mCachedGridKeys = null;
+ final GridKey key = new GridKey(usedKey);
+ while (mGridKeys.remove(key)) {
// Remove duplicate keys.
}
- mRecentKeys.addFirst(key);
- while (mRecentKeys.size() > mMaxRecentKeyCount) {
- mRecentKeys.removeLast();
+ if (addFirst) {
+ mGridKeys.addFirst(key);
+ } else {
+ mGridKeys.addLast(key);
+ }
+ while (mGridKeys.size() > mMaxKeyCount) {
+ mGridKeys.removeLast();
}
int index = 0;
- for (final RecentKey recentKey : mRecentKeys) {
+ for (final GridKey gridKey : mGridKeys) {
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);
+ gridKey.updateCorrdinates(keyX, keyY);
index++;
}
}
@@ -101,26 +106,26 @@ public class DynamicGridKeyboard extends Keyboard {
@Override
public Key[] getKeys() {
- synchronized (mRecentKeys) {
- if (mCachedRecentKeys != null) {
- return mCachedRecentKeys;
+ synchronized (mGridKeys) {
+ if (mCachedGridKeys != null) {
+ return mCachedGridKeys;
}
- mCachedRecentKeys = mRecentKeys.toArray(new Key[mRecentKeys.size()]);
- return mCachedRecentKeys;
+ mCachedGridKeys = mGridKeys.toArray(new Key[mGridKeys.size()]);
+ return mCachedGridKeys;
}
}
@Override
public Key[] getNearestKeys(final int x, final int y) {
- // TODO: Calculate the nearest key index in mRecentKeys from x and y.
+ // TODO: Calculate the nearest key index in mGridKeys from x and y.
return getKeys();
}
- static final class RecentKey extends Key {
+ static final class GridKey extends Key {
private int mCurrentX;
private int mCurrentY;
- public RecentKey(final Key originalKey) {
+ public GridKey(final Key originalKey) {
super(originalKey);
}
@@ -151,7 +156,7 @@ public class DynamicGridKeyboard extends Keyboard {
@Override
public String toString() {
- return "RecentKey: " + super.toString();
+ return "GridKey: " + super.toString();
}
}
}