diff options
Diffstat (limited to 'java')
19 files changed, 367 insertions, 109 deletions
diff --git a/java/res/values-hi/strings.xml b/java/res/values-hi/strings.xml index 01bba5c6e..dcbbcd97c 100644 --- a/java/res/values-hi/strings.xml +++ b/java/res/values-hi/strings.xml @@ -31,7 +31,7 @@ <string name="correction_category" msgid="2236750915056607613">"पाठ सुधार"</string> <string name="gesture_typing_category" msgid="497263612130532630">"जेस्चर लिखना"</string> <string name="misc_category" msgid="6894192814868233453">"अन्य विकल्प"</string> - <string name="advanced_settings" msgid="362895144495591463">"उन्नत सेटिंग"</string> + <string name="advanced_settings" msgid="362895144495591463">"अतिरिक्त सेटिंग"</string> <string name="advanced_settings_summary" msgid="4487980456152830271">"विशेषज्ञों के लिए विकल्प"</string> <string name="include_other_imes_in_language_switch_list" msgid="4533689960308565519">"अन्य इनपुट पद्धतियों पर जाएं"</string> <string name="include_other_imes_in_language_switch_list_summary" msgid="840637129103317635">"भाषा स्विच कुंजी में अन्य इनपुट पद्धतियां भी शामिल हैं"</string> diff --git a/java/res/values-land/dimens.xml b/java/res/values-land/dimens.xml index c954e60da..42a746b60 100644 --- a/java/res/values-land/dimens.xml +++ b/java/res/values-land/dimens.xml @@ -75,5 +75,9 @@ <dimen name="gesture_floating_preview_vertical_padding">15dp</dimen> <!-- Emoji keyboard --> - <fraction name="emoji_keyboard_key_width">8.3333%p</fraction> + <fraction name="emoji_keyboard_key_width">10%p</fraction> + <fraction name="emoji_keyboard_row_height">50%p</fraction> + <fraction name="emoji_keyboard_key_letter_size">60%p</fraction> + <integer name="emoji_keyboard_max_key_count">20</integer> + </resources> diff --git a/java/res/values-lo/donottranslate.xml b/java/res/values-lo/donottranslate.xml new file mode 100644 index 000000000..a9893feec --- /dev/null +++ b/java/res/values-lo/donottranslate.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** +** Copyright 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. +*/ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Whether this language uses spaces between words --> + <bool name="current_language_has_spaces">false</bool> +</resources> diff --git a/java/res/values-pt-rPT/strings.xml b/java/res/values-pt-rPT/strings.xml index bad0bd669..cd89a7765 100644 --- a/java/res/values-pt-rPT/strings.xml +++ b/java/res/values-pt-rPT/strings.xml @@ -134,7 +134,7 @@ <string name="select_language" msgid="3693815588777926848">"Idiomas de introdução"</string> <string name="hint_add_to_dictionary" msgid="573678656946085380">"Toque novamente para guardar"</string> <string name="has_dictionary" msgid="6071847973466625007">"Dicionário disponível"</string> - <string name="prefs_enable_log" msgid="6620424505072963557">"Activar comentários do utilizador"</string> + <string name="prefs_enable_log" msgid="6620424505072963557">"Ativar comentários do utilizador"</string> <string name="prefs_description_log" msgid="7525225584555429211">"Envie automaticamente estatísticas de utilização e relatórios de falhas e ajude-nos a melhorar este editor do método de introdução."</string> <string name="keyboard_layout" msgid="8451164783510487501">"Tema do teclado"</string> <string name="subtype_en_GB" msgid="88170601942311355">"Inglês (RU)"</string> diff --git a/java/res/values-th/donottranslate.xml b/java/res/values-th/donottranslate.xml index aeeebed15..a9893feec 100644 --- a/java/res/values-th/donottranslate.xml +++ b/java/res/values-th/donottranslate.xml @@ -18,6 +18,6 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Whether this language uses spaces --> + <!-- Whether this language uses spaces between words --> <bool name="current_language_has_spaces">false</bool> </resources> diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 7de93e6e3..88e327f26 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -117,6 +117,9 @@ <!-- Emoji keyboard --> <fraction name="emoji_keyboard_key_width">14.2857%p</fraction> + <fraction name="emoji_keyboard_row_height">33%p</fraction> + <fraction name="emoji_keyboard_key_letter_size">90%p</fraction> + <integer name="emoji_keyboard_max_key_count">21</integer> <!-- Inset used in Accessibility mode to avoid accidental key presses when a finger slides off the screen. --> <dimen name="accessibility_edge_slop">8dp</dimen> @@ -124,4 +127,5 @@ <integer name="user_dictionary_max_word_length" translatable="false">48</integer> <dimen name="language_on_spacebar_horizontal_margin">1dp</dimen> + </resources> diff --git a/java/res/values/donottranslate.xml b/java/res/values/donottranslate.xml index 52ebe161c..82c5ce456 100644 --- a/java/res/values/donottranslate.xml +++ b/java/res/values/donottranslate.xml @@ -31,7 +31,7 @@ <string name="symbols_word_separators">"	 \n"()[]{}*&<>+=|.,;:!?/_\"</string> <!-- Word connectors --> <string name="symbols_word_connectors">\'-</string> - <!-- Whether this language uses spaces --> + <!-- Whether this language uses spaces between words --> <bool name="current_language_has_spaces">true</bool> <!-- Always show the suggestion strip --> diff --git a/java/res/xml/kbd_emoji_recents.xml b/java/res/xml/kbd_emoji_recents.xml index f56b79ab7..73926ecc0 100644 --- a/java/res/xml/kbd_emoji_recents.xml +++ b/java/res/xml/kbd_emoji_recents.xml @@ -21,8 +21,9 @@ <Keyboard xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin" latin:keyWidth="@fraction/emoji_keyboard_key_width" - latin:keyLetterSize="90%p" + latin:keyLetterSize="@fraction/emoji_keyboard_key_letter_size" latin:keyLabelSize="60%p" + latin:rowHeight="@fraction/emoji_keyboard_row_height" > <GridRows latin:codesArray="@array/emoji_recents" diff --git a/java/res/xml/key_space_5kw.xml b/java/res/xml/key_space_5kw.xml index 02ee42fd2..b6d38fb33 100644 --- a/java/res/xml/key_space_5kw.xml +++ b/java/res/xml/key_space_5kw.xml @@ -23,7 +23,7 @@ > <switch> <case - latin:languageCode="fa" + latin:languageCode="fa|ne" latin:languageSwitchKeyEnabled="true" > <Key @@ -35,7 +35,7 @@ latin:keyStyle="zwnjKeyStyle" /> </case> <case - latin:languageCode="fa" + latin:languageCode="fa|ne" latin:languageSwitchKeyEnabled="false" > <Key diff --git a/java/res/xml/key_styles_currency.xml b/java/res/xml/key_styles_currency.xml index 094465167..b7677a20d 100644 --- a/java/res/xml/key_styles_currency.xml +++ b/java/res/xml/key_styles_currency.xml @@ -97,13 +97,14 @@ iw: Hebrew (New Sheqel) lo: Lao (Kip) mn: Mongolian (Tugrik) + ne: Nepali (Nepalese Rupee) th: Thai (Baht) uk: Ukrainian (Hryvnia) vi: Vietnamese (Dong) --> <!-- TODO: The currency sign of Turkish Lira was created in 2012 and assigned U+20BA for its unicode, although there is no font glyph for it as of November 2012. --> <case - latin:languageCode="fa|hi|iw|lo|mn|th|uk|vi" + latin:languageCode="fa|hi|iw|lo|mn|ne|th|uk|vi" > <!-- U+00A3: "£" POUND SIGN U+20AC: "€" EURO SIGN diff --git a/java/res/xml/keyboard_layout_set_nepali_romanized.xml b/java/res/xml/keyboard_layout_set_nepali_romanized.xml index 82f36cfbd..fbbc6a5a0 100644 --- a/java/res/xml/keyboard_layout_set_nepali_romanized.xml +++ b/java/res/xml/keyboard_layout_set_nepali_romanized.xml @@ -44,6 +44,9 @@ latin:elementName="symbols" latin:elementKeyboard="@xml/kbd_symbols" /> <Element + latin:elementName="symbolsShifted" + latin:elementKeyboard="@xml/kbd_symbols_shift" /> + <Element latin:elementName="phone" latin:elementKeyboard="@xml/kbd_phone" /> <Element diff --git a/java/res/xml/keyboard_layout_set_nepali_traditional.xml b/java/res/xml/keyboard_layout_set_nepali_traditional.xml index 2a6dc8e83..4a3b60153 100644 --- a/java/res/xml/keyboard_layout_set_nepali_traditional.xml +++ b/java/res/xml/keyboard_layout_set_nepali_traditional.xml @@ -44,6 +44,9 @@ latin:elementName="symbols" latin:elementKeyboard="@xml/kbd_symbols" /> <Element + latin:elementName="symbolsShifted" + latin:elementKeyboard="@xml/kbd_symbols_shift" /> + <Element latin:elementName="phone" latin:elementKeyboard="@xml/kbd_phone" /> <Element diff --git a/java/res/xml/rowkeys_nepali_romanized3.xml b/java/res/xml/rowkeys_nepali_romanized3.xml index 5660596f0..166d028a3 100644 --- a/java/res/xml/rowkeys_nepali_romanized3.xml +++ b/java/res/xml/rowkeys_nepali_romanized3.xml @@ -48,7 +48,7 @@ latin:keyLabelFlags="fontNormal" /> <!-- U+0923: "ण" DEVANAGARI LETTER NNA --> <Key - latin:keyLabel="श" + latin:keyLabel="ण" latin:keyLabelFlags="fontNormal" /> <!-- Because the font rendering system prior to API version 16 can't automatically render dotted circle for incomplete combining letter of some scripts, different diff --git a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java index 2e05dd382..d28b5088c 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiKeyboardView.java @@ -19,15 +19,18 @@ package com.android.inputmethod.keyboard; import static com.android.inputmethod.latin.Constants.NOT_A_COORDINATE; import android.content.Context; +import android.content.SharedPreferences; 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.preference.PreferenceManager; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; @@ -38,14 +41,13 @@ 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; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.SubtypeSwitcher; +import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.CollectionUtils; import com.android.inputmethod.latin.utils.ResourceUtils; @@ -81,17 +83,25 @@ 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 final int CATEGORY_ID_UNSPECIFIED = -1; + public static final int CATEGORY_ID_RECENTS = 0; + public static final int CATEGORY_ID_PEOPLE = 1; + public static final int CATEGORY_ID_OBJECTS = 2; + public static final int CATEGORY_ID_NATURE = 3; + public static final int CATEGORY_ID_PLACES = 4; + public static final int CATEGORY_ID_SYMBOLS = 5; + public static final int CATEGORY_ID_EMOTICONS = 6; + + private static class CategoryProperties { + public int mCategoryId; + public int mPageCount; + public CategoryProperties(final int categoryId, final int pageCount) { + mCategoryId = categoryId; + mPageCount = pageCount; + } + } private static class EmojiCategory { - private static final int DEFAULT_MAX_ROW_SIZE = 3; private static final String[] sCategoryName = { "recents", "people", @@ -117,114 +127,183 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange KeyboardId.ELEMENT_EMOJI_CATEGORY3, KeyboardId.ELEMENT_EMOJI_CATEGORY4, KeyboardId.ELEMENT_EMOJI_CATEGORY5, - KeyboardId.ELEMENT_EMOJI_CATEGORY6, }; - private Resources mRes; + KeyboardId.ELEMENT_EMOJI_CATEGORY6 }; + private final SharedPreferences mPrefs; + private final int mMaxPageKeyCount; private final KeyboardLayoutSet mLayoutSet; private final HashMap<String, Integer> mCategoryNameToIdMap = CollectionUtils.newHashMap(); - private final ArrayList<Integer> mShownCategories = new ArrayList<Integer>(); + private final ArrayList<CategoryProperties> mShownCategories = + CollectionUtils.newArrayList(); private final ConcurrentHashMap<Long, DynamicGridKeyboard> mCategoryKeyboardMap = new ConcurrentHashMap<Long, DynamicGridKeyboard>(); - private int mCurrentCategory = CATEGORY_UNSPECIFIED; + private int mCurrentCategoryId = CATEGORY_ID_UNSPECIFIED; + private int mCurrentCategoryPageId = 0; - public EmojiCategory(final Resources res, final KeyboardLayoutSet layoutSet) { - mRes = res; + public EmojiCategory(final SharedPreferences prefs, final Resources res, + final KeyboardLayoutSet layoutSet) { + mPrefs = prefs; + mMaxPageKeyCount = res.getInteger(R.integer.emoji_keyboard_max_key_count); mLayoutSet = layoutSet; for (int i = 0; i < sCategoryName.length; ++i) { mCategoryNameToIdMap.put(sCategoryName[i], i); } - mShownCategories.add(CATEGORY_RECENTS); + addShownCategoryId(CATEGORY_ID_RECENTS); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - mShownCategories.add(CATEGORY_PEOPLE); - mShownCategories.add(CATEGORY_OBJECTS); - mShownCategories.add(CATEGORY_NATURE); - mShownCategories.add(CATEGORY_PLACES); - // TODO: Restore last saved category - mCurrentCategory = CATEGORY_PEOPLE; + addShownCategoryId(CATEGORY_ID_PEOPLE); + addShownCategoryId(CATEGORY_ID_OBJECTS); + addShownCategoryId(CATEGORY_ID_NATURE); + addShownCategoryId(CATEGORY_ID_PLACES); + mCurrentCategoryId = CATEGORY_ID_PEOPLE; } else { - // TODO: Restore last saved category - mCurrentCategory = CATEGORY_SYMBOLS; + mCurrentCategoryId = CATEGORY_ID_SYMBOLS; } - mShownCategories.add(CATEGORY_SYMBOLS); - mShownCategories.add(CATEGORY_EMOTICONS); + addShownCategoryId(CATEGORY_ID_SYMBOLS); + addShownCategoryId(CATEGORY_ID_EMOTICONS); + getKeyboard(CATEGORY_ID_RECENTS, 0 /* cagetoryPageId */) + .loadRecentKeys(mCategoryKeyboardMap.values()); + } + + private void addShownCategoryId(int categoryId) { + // Load a keyboard of categoryId + getKeyboard(categoryId, 0 /* cagetoryPageId */); + final CategoryProperties properties = + new CategoryProperties(categoryId, getCategoryPageCount(categoryId)); + mShownCategories.add(properties); } - public String getCategoryName(int category) { - return sCategoryName[category]; + public String getCategoryName(int categoryId, int categoryPageId) { + return sCategoryName[categoryId] + "-" + categoryPageId; } public int getCategoryId(String name) { - return mCategoryNameToIdMap.get(name); + final String[] strings = name.split("-"); + return mCategoryNameToIdMap.get(strings[0]); } - public int getCategoryIcon(int category) { - return sCategoryIcon[category]; + public int getCategoryIcon(int categoryId) { + return sCategoryIcon[categoryId]; } - public String getCategoryLabel(int category) { - return sCategoryLabel[category]; + public String getCategoryLabel(int categoryId) { + return sCategoryLabel[categoryId]; } - public ArrayList<Integer> getShownCategories() { + public ArrayList<CategoryProperties> getShownCategories() { return mShownCategories; } - public int getCurrentCategory() { - // TODO: Record current category. - return mCurrentCategory; + public int getCurrentCategoryId() { + return mCurrentCategoryId; + } + + public void setCurrentCategoryId(int categoryId) { + mCurrentCategoryId = categoryId; + } + + public void setCurrentCategoryPageId(int id) { + mCurrentCategoryPageId = id; } - public void setCurrentCategory(int category) { - mCurrentCategory = category; + public void saveLastTypedCategoryPage() { + Settings.writeEmojiCategoryLastTypedId( + mPrefs, mCurrentCategoryId, mCurrentCategoryPageId); } public boolean isInRecentTab() { - return mCurrentCategory == CATEGORY_RECENTS; + return mCurrentCategoryId == CATEGORY_ID_RECENTS; } - public int getTabIdFromCategory(int category) { + public int getTabIdFromCategoryId(int categoryId) { for (int i = 0; i < mShownCategories.size(); ++i) { - if (mShownCategories.get(i) == category) { + if (mShownCategories.get(i).mCategoryId == categoryId) { return i; } } - Log.w(TAG, "category not found: " + category); + Log.w(TAG, "categoryId not found: " + categoryId); + return 0; + } + + // Returns the view pager's page position for the categoryId + public int getPageIdFromCategoryId(int categoryId) { + final int lastSavedCategoryPageId = + Settings.readEmojiCategoryLastTypedId(mPrefs, categoryId); + int sum = 0; + for (int i = 0; i < mShownCategories.size(); ++i) { + final CategoryProperties props = mShownCategories.get(i); + if (props.mCategoryId == categoryId) { + return sum + lastSavedCategoryPageId; + } + sum += props.mPageCount; + } + Log.w(TAG, "categoryId not found: " + categoryId); return 0; } public int getRecentTabId() { - return getTabIdFromCategory(CATEGORY_RECENTS); + return getTabIdFromCategoryId(CATEGORY_ID_RECENTS); } - public int getCategoryFromTabId(int tabId) { - return mShownCategories.get(tabId); + private int getCategoryPageCount(int categoryId) { + final Keyboard keyboard = mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); + return (keyboard.getKeys().length - 1) / mMaxPageKeyCount + 1; } - public DynamicGridKeyboard getKeyboard(int category, int id) { + // Returns a pair of the category id and the category page id from the view pager's page + // position. The category page id is numbered in each category. And the view page position + // is the position of the current shown page in the view pager which contains all pages of + // all categories. + public Pair<Integer, Integer> getCategoryIdAndPageIdFromPagePosition(int position) { + int sum = 0; + for (CategoryProperties properties : mShownCategories) { + final int temp = sum; + sum += properties.mPageCount; + if (sum > position) { + return new Pair<Integer, Integer>(properties.mCategoryId, position - temp); + } + } + return null; + } + + // Returns a keyboard from the view pager's page position. + public DynamicGridKeyboard getKeyboardFromPagePosition(int position) { + final Pair<Integer, Integer> categoryAndId = + getCategoryIdAndPageIdFromPagePosition(position); + if (categoryAndId != null) { + return getKeyboard(categoryAndId.first, categoryAndId.second); + } + return null; + } + + public DynamicGridKeyboard getKeyboard(int categoryId, int id) { synchronized(mCategoryKeyboardMap) { - final long key = (((long) category) << 32) | id; + final long key = (((long) categoryId) << Constants.MAX_INT_BIT_COUNT) | 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); + if (categoryId != CATEGORY_ID_RECENTS) { 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; + mLayoutSet.getKeyboard(sCategoryElementId[categoryId]); + final Key[][] sortedKeys = sortKeys(keyboard.getKeys(), mMaxPageKeyCount); + for (int i = 0; i < sortedKeys.length; ++i) { + final DynamicGridKeyboard tempKbd = new DynamicGridKeyboard(mPrefs, + mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), + mMaxPageKeyCount, categoryId, i /* categoryPageId */); + for (Key emojiKey : sortedKeys[i]) { + if (emojiKey == null) { + break; + } + tempKbd.addKeyLast(emojiKey); } - kbd.addKeyLast(emojiKey); + mCategoryKeyboardMap.put((((long) categoryId) + << Constants.MAX_INT_BIT_COUNT) | i, tempKbd); } + kbd = mCategoryKeyboardMap.get(key); } else { - kbd = new DynamicGridKeyboard( + kbd = new DynamicGridKeyboard(mPrefs, mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS), - DEFAULT_MAX_ROW_SIZE); + mMaxPageKeyCount, categoryId, 0 /* categoryPageId */); + mCategoryKeyboardMap.put(key, kbd); } - mCategoryKeyboardMap.put(key, kbd); } else { kbd = mCategoryKeyboardMap.get(key); } @@ -232,6 +311,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange } } + public int getTotalPageCountOfAllCategories() { + int sum = 0; + for (CategoryProperties properties : mShownCategories) { + sum += properties.mPageCount; + } + return sum; + } + private Key[][] sortKeys(Key[] inKeys, int maxPageCount) { Key[] keys = Arrays.copyOf(inKeys, inKeys.length); Arrays.sort(keys, 0, keys.length, new Comparator<Key>() { @@ -287,14 +374,14 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder( context, null /* editorInfo */); final Resources res = context.getResources(); + final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res); builder.setSubtype(SubtypeSwitcher.getInstance().getEmojiSubtype()); builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res), - (int)ResourceUtils.getDefaultKeyboardHeight(res) - + res.getDimensionPixelSize(R.dimen.suggestions_strip_height)); + emojiLp.mEmojiKeyboardHeight); builder.setOptions(false, false, false /* lanuageSwitchKeyEnabled */); mLayoutSet = builder.build(); - mEmojiCategory = new EmojiCategory(context.getResources(), builder.build()); - // TODO: Save/restore recent keys from/to preferences. + mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context), + context.getResources(), builder.build()); } @Override @@ -310,20 +397,20 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange setMeasuredDimension(width, height); } - private void addTab(final TabHost host, final int category) { - final String tabId = mEmojiCategory.getCategoryName(category); + private void addTab(final TabHost host, final int categoryId) { + final String tabId = mEmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */); final TabHost.TabSpec tspec = host.newTabSpec(tabId); tspec.setContent(R.id.emoji_keyboard_dummy); - if (mEmojiCategory.getCategoryIcon(category) != 0) { + if (mEmojiCategory.getCategoryIcon(categoryId) != 0) { final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate( R.layout.emoji_keyboard_tab_icon, null); - iconView.setImageResource(mEmojiCategory.getCategoryIcon(category)); + iconView.setImageResource(mEmojiCategory.getCategoryIcon(categoryId)); tspec.setIndicator(iconView); } - if (mEmojiCategory.getCategoryLabel(category) != null) { + if (mEmojiCategory.getCategoryLabel(categoryId) != null) { final TextView textView = (TextView)LayoutInflater.from(getContext()).inflate( R.layout.emoji_keyboard_tab_label, null); - textView.setText(mEmojiCategory.getCategoryLabel(category)); + textView.setText(mEmojiCategory.getCategoryLabel(categoryId)); textView.setTextColor(mTabLabelColor); tspec.setIndicator(textView); } @@ -334,8 +421,8 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange protected void onFinishInflate() { mTabHost = (TabHost)findViewById(R.id.emoji_category_tabhost); mTabHost.setup(); - for (final int i : mEmojiCategory.getShownCategories()) { - addTab(mTabHost, i); + for (final CategoryProperties properties : mEmojiCategory.getShownCategories()) { + addTab(mTabHost, properties.mCategoryId); } mTabHost.setOnTabChangedListener(this); mTabHost.getTabWidget().setStripEnabled(true); @@ -350,7 +437,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange final EmojiLayoutParams emojiLp = new EmojiLayoutParams(res); emojiLp.setPagerProps(mEmojiPager); - setCurrentCategory(mEmojiCategory.getCurrentCategory(), true /* force */); + setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */); final LinearLayout actionBar = (LinearLayout)findViewById(R.id.emoji_action_bar); emojiLp.setActionBarProps(actionBar); @@ -377,14 +464,17 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public void onTabChanged(final String tabId) { - final int category = mEmojiCategory.getCategoryId(tabId); - setCurrentCategory(category, false /* force */); + final int categoryId = mEmojiCategory.getCategoryId(tabId); + setCurrentCategoryId(categoryId, false /* force */); } @Override public void onPageSelected(final int position) { - setCurrentCategory(mEmojiCategory.getCategoryFromTabId(position), false /* force */); + final Pair<Integer, Integer> newPos = + mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position); + setCurrentCategoryId(newPos.first /* categoryId */, false /* force */); + mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */); } @Override @@ -416,6 +506,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public void onKeyClick(final Key key) { mEmojiKeyboardAdapter.addRecentKey(key); + mEmojiCategory.saveLastTypedCategoryPage(); final int code = key.getCode(); if (code == Constants.CODE_OUTPUT_TEXT) { mKeyboardActionListener.onTextInput(key.getOutputText()); @@ -432,25 +523,25 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange mKeyboardActionListener = listener; } - private void setCurrentCategory(final int category, final boolean force) { - if (mEmojiCategory.getCurrentCategory() == category && !force) { + private void setCurrentCategoryId(final int categoryId, final boolean force) { + if (mEmojiCategory.getCurrentCategoryId() == categoryId && !force) { return; } - mEmojiCategory.setCurrentCategory(category); - final int newTabId = mEmojiCategory.getTabIdFromCategory(category); - if (force || mEmojiPager.getCurrentItem() != newTabId) { - mEmojiPager.setCurrentItem(newTabId, true /* smoothScroll */); + mEmojiCategory.setCurrentCategoryId(categoryId); + final int newTabId = mEmojiCategory.getTabIdFromCategoryId(categoryId); + final int newCategoryPageId = mEmojiCategory.getPageIdFromCategoryId(categoryId); + if (force || mEmojiCategory.getCategoryIdAndPageIdFromPagePosition( + mEmojiPager.getCurrentItem()).first != categoryId) { + mEmojiPager.setCurrentItem(newCategoryPageId, true /* smoothScroll */); } if (force || mTabHost.getCurrentTab() != newTabId) { mTabHost.setCurrentTab(newTabId); } - // TODO: Record current category } private static class EmojiKeyboardAdapter extends PagerAdapter { private final ScrollKeyboardView.OnKeyClickListener mListener; - private final KeyboardLayoutSet mLayoutSet; private final DynamicGridKeyboard mRecentsKeyboard; private final SparseArray<ScrollKeyboardView> mActiveKeyboardView = CollectionUtils.newSparseArray(); @@ -462,8 +553,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange final ScrollKeyboardView.OnKeyClickListener listener) { mEmojiCategory = emojiCategory; mListener = listener; - mLayoutSet = layoutSet; - mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_RECENTS, 0); + mRecentsKeyboard = mEmojiCategory.getKeyboard(CATEGORY_ID_RECENTS, 0); } public void addRecentKey(final Key key) { @@ -480,7 +570,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public int getCount() { - return mEmojiCategory.getShownCategories().size(); + return mEmojiCategory.getTotalPageCountOfAllCategories(); } @Override @@ -499,7 +589,7 @@ public final class EmojiKeyboardView extends LinearLayout implements OnTabChange @Override public Object instantiateItem(final ViewGroup container, final int position) { final Keyboard keyboard = - mEmojiCategory.getKeyboard(mEmojiCategory.getCategoryFromTabId(position), 0); + mEmojiCategory.getKeyboardFromPagePosition(position); 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/EmojiLayoutParams.java b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java index 6486fc9db..5570d594d 100644 --- a/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java +++ b/java/src/com/android/inputmethod/keyboard/EmojiLayoutParams.java @@ -27,6 +27,8 @@ import android.widget.LinearLayout; public class EmojiLayoutParams { private static final int DEFAULT_KEYBOARD_ROWS = 4; + public final int mEmojiPagerHeight; + private final int mEmojiPagerBottomMargin; public final int mEmojiKeyboardHeight; public final int mEmojiActionBarHeight; public final int mKeyVerticalGap; @@ -49,13 +51,15 @@ public class EmojiLayoutParams { + mKeyVerticalGap; mEmojiActionBarHeight = ((int) baseheight) / DEFAULT_KEYBOARD_ROWS - (mKeyVerticalGap - mBottomPadding) / 2; - mEmojiKeyboardHeight = defaultKeyboardHeight - mEmojiActionBarHeight; + mEmojiPagerHeight = defaultKeyboardHeight - mEmojiActionBarHeight; + mEmojiPagerBottomMargin = mKeyVerticalGap / 2; + mEmojiKeyboardHeight = mEmojiPagerHeight - mEmojiPagerBottomMargin - 1; } public void setPagerProps(ViewPager vp) { final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams(); - lp.height = mEmojiKeyboardHeight - mKeyVerticalGap / 2; - lp.bottomMargin = mKeyVerticalGap / 2; + lp.height = mEmojiPagerHeight - mEmojiPagerBottomMargin; + lp.bottomMargin = mEmojiPagerBottomMargin; vp.setLayoutParams(lp); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java index 22708975a..f203eb7d7 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/internal/DynamicGridKeyboard.java @@ -16,32 +16,41 @@ package com.android.inputmethod.keyboard.internal; +import android.content.SharedPreferences; import android.text.TextUtils; +import com.android.inputmethod.keyboard.EmojiKeyboardView; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; +import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.settings.Settings; import com.android.inputmethod.latin.utils.CollectionUtils; import java.util.ArrayDeque; +import java.util.Collection; /** * This is a Keyboard class where you can add keys dynamically shown in a grid layout */ -// TODO: Save/restore recent keys from/to preferences. public class DynamicGridKeyboard extends Keyboard { private static final int TEMPLATE_KEY_CODE_0 = 0x30; private static final int TEMPLATE_KEY_CODE_1 = 0x31; + // Recent codes are saved as an integer array, so we use comma as a separater. + private static final String RECENT_KEY_SEPARATOR = Constants.STRING_COMMA; + private final SharedPreferences mPrefs; private final int mLeftPadding; private final int mHorizontalStep; private final int mVerticalStep; private final int mColumnsNum; private final int mMaxKeyCount; + private final boolean mIsRecents; private final ArrayDeque<GridKey> mGridKeys = CollectionUtils.newArrayDeque(); private Key[] mCachedGridKeys; - public DynamicGridKeyboard(final Keyboard templateKeyboard, final int maxRows) { + public DynamicGridKeyboard(final SharedPreferences prefs, final Keyboard templateKeyboard, + final int maxKeyCount, final int categoryId, final int categoryPageId) { super(templateKeyboard); final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0); final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1); @@ -49,7 +58,9 @@ public class DynamicGridKeyboard extends Keyboard { mHorizontalStep = Math.abs(key1.getX() - key0.getX()); mVerticalStep = key0.getHeight() + mVerticalGap; mColumnsNum = mBaseWidth / mHorizontalStep; - mMaxKeyCount = mColumnsNum * maxRows; + mMaxKeyCount = maxKeyCount; + mIsRecents = categoryId == EmojiKeyboardView.CATEGORY_ID_RECENTS; + mPrefs = prefs; } private Key getTemplateKey(final int code) { @@ -63,6 +74,9 @@ public class DynamicGridKeyboard extends Keyboard { public void addKeyFirst(final Key usedKey) { addKey(usedKey, true); + if (mIsRecents) { + saveRecentKeys(); + } } public void addKeyLast(final Key usedKey) { @@ -94,6 +108,31 @@ public class DynamicGridKeyboard extends Keyboard { } } + private void saveRecentKeys() { + final StringBuilder sb = new StringBuilder(); + for (final Key key : mGridKeys) { + sb.append(key.getCode()).append(RECENT_KEY_SEPARATOR); + } + Settings.writeEmojiRecentKeys(mPrefs, sb.toString()); + } + + public void loadRecentKeys(Collection<DynamicGridKeyboard> keyboards) { + final String str = Settings.readEmojiRecentKeys(mPrefs); + for (String s : str.split(RECENT_KEY_SEPARATOR)) { + if (TextUtils.isEmpty(s)) { + continue; + } + final int code = Integer.valueOf(s); + for (DynamicGridKeyboard kbd : keyboards) { + final Key key = kbd.getKey(code); + if (key != null) { + addKeyLast(key); + break; + } + } + } + } + private int getKeyX(final int index) { final int column = index % mColumnsNum; return column * mHorizontalStep + mLeftPadding; diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java index de7f2e25c..a72595f7c 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardTextsSet.java @@ -383,7 +383,7 @@ public final class KeyboardTextsSet { // Label for "switch to more symbol" modifier key. Must be short to fit on key! /* 124 */ "= \\ <", // Label for "switch to more symbol" modifier key on tablets. Must be short to fit on key! - /* 125 */ "~ [ {", + /* 125 */ "~ [ <", // Label for "Tab" key. Must be short to fit on key! /* 126 */ "Tab", // Label for "switch to phone numeric" key. Must be short to fit on key! @@ -2366,6 +2366,63 @@ public final class KeyboardTextsSet { /* 47 */ "!text/double_9qm_rqm", }; + /* Language ne: Nepali */ + private static final String[] LANGUAGE_ne = { + /* 0~ */ + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, + /* ~44 */ + // Label for "switch to alphabetic" key. + // U+0915: "क" DEVANAGARI LETTER KA + // U+0916: "ख" DEVANAGARI LETTER KHA + // U+0917: "ग" DEVANAGARI LETTER GA + /* 45 */ "\u0915\u0916\u0917", + /* 46~ */ + null, null, null, null, null, + /* ~50 */ + // U+0930/U+0941/U+002E "रु." NEPALESE RUPEE SIGN + /* 51 */ "\u0930\u0941.", + /* 52~ */ + null, null, null, null, null, null, null, null, null, null, null, + /* ~62 */ + // U+0967: "१" DEVANAGARI DIGIT ONE + /* 63 */ "\u0967", + // U+0968: "२" DEVANAGARI DIGIT TWO + /* 64 */ "\u0968", + // U+0969: "३" DEVANAGARI DIGIT THREE + /* 65 */ "\u0969", + // U+096A: "४" DEVANAGARI DIGIT FOUR + /* 66 */ "\u096A", + // U+096B: "५" DEVANAGARI DIGIT FIVE + /* 67 */ "\u096B", + // U+096C: "६" DEVANAGARI DIGIT SIX + /* 68 */ "\u096C", + // U+096D: "७" DEVANAGARI DIGIT SEVEN + /* 69 */ "\u096D", + // U+096E: "८" DEVANAGARI DIGIT EIGHT + /* 70 */ "\u096E", + // U+096F: "९" DEVANAGARI DIGIT NINE + /* 71 */ "\u096F", + // U+0966: "०" DEVANAGARI DIGIT ZERO + /* 72 */ "\u0966", + // Label for "switch to symbols" key. + /* 73 */ "?\u0967\u0968\u0969", + // Label for "switch to symbols with microphone" key. This string shouldn't include the "mic" + // part because it'll be appended by the code. + /* 74 */ "\u0967\u0968\u0969", + /* 75 */ "1", + /* 76 */ "2", + /* 77 */ "3", + /* 78 */ "4", + /* 79 */ "5", + /* 80 */ "6", + /* 81 */ "7", + /* 82 */ "8", + /* 83 */ "9", + /* 84 */ "0", + }; + /* Language nl: Dutch */ private static final String[] LANGUAGE_nl = { // U+00E1: "á" LATIN SMALL LETTER A WITH ACUTE @@ -3357,6 +3414,7 @@ public final class KeyboardTextsSet { "mk", LANGUAGE_mk, /* Macedonian */ "mn", LANGUAGE_mn, /* Mongolian */ "nb", LANGUAGE_nb, /* Norwegian Bokmål */ + "ne", LANGUAGE_ne, /* Nepali */ "nl", LANGUAGE_nl, /* Dutch */ "pl", LANGUAGE_pl, /* Polish */ "pt", LANGUAGE_pt, /* Portuguese */ diff --git a/java/src/com/android/inputmethod/latin/Constants.java b/java/src/com/android/inputmethod/latin/Constants.java index 8aec03f71..029ba02ed 100644 --- a/java/src/com/android/inputmethod/latin/Constants.java +++ b/java/src/com/android/inputmethod/latin/Constants.java @@ -220,7 +220,11 @@ public final class Constants { } } + public static final int MAX_INT_BIT_COUNT = 32; + public static final String STRING_COMMA = ","; + private Constants() { // This utility class is not publicly instantiable. } + } diff --git a/java/src/com/android/inputmethod/latin/settings/Settings.java b/java/src/com/android/inputmethod/latin/settings/Settings.java index 8732a59f8..c1a917d44 100644 --- a/java/src/com/android/inputmethod/latin/settings/Settings.java +++ b/java/src/com/android/inputmethod/latin/settings/Settings.java @@ -97,6 +97,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_SEND_FEEDBACK = "send_feedback"; public static final String PREF_ABOUT_KEYBOARD = "about_keyboard"; + // Emoji + public static final String PREF_EMOJI_RECENT_KEYS = "emoji_recent_keys"; + public static final String PREF_EMOJI_CATEGORY_LAST_TYPED_ID = "emoji_category_last_typed_id"; + private Resources mRes; private SharedPreferences mPrefs; private SettingsValues mSettingsValues; @@ -363,4 +367,24 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang final String tokenStr = mPrefs.getString(PREF_LAST_USED_PERSONALIZATION_TOKEN, null); return StringUtils.hexStringToByteArray(tokenStr); } + + public static void writeEmojiRecentKeys(final SharedPreferences prefs, String str) { + prefs.edit().putString(PREF_EMOJI_RECENT_KEYS, str).apply(); + } + + public static String readEmojiRecentKeys(final SharedPreferences prefs) { + return prefs.getString(PREF_EMOJI_RECENT_KEYS, ""); + } + + public static void writeEmojiCategoryLastTypedId( + final SharedPreferences prefs, final int category, final int id) { + final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + category; + prefs.edit().putInt(key, id).apply(); + } + + public static int readEmojiCategoryLastTypedId( + final SharedPreferences prefs, final int category) { + final String key = PREF_EMOJI_CATEGORY_LAST_TYPED_ID + category; + return prefs.getInt(key, 0); + } } |