diff --git a/java/res/layout/emoji_keyboard_page.xml b/java/res/layout/emoji_keyboard_page.xml
deleted file mode 100644
index 3e5881783..000000000
--- a/java/res/layout/emoji_keyboard_page.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
diff --git a/java/res/layout/emoji_keyboard_tab_icon.xml b/java/res/layout/emoji_keyboard_tab_icon.xml
deleted file mode 100644
index 15f9c3a3e..000000000
--- a/java/res/layout/emoji_keyboard_tab_icon.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-
-
-
-
-
-
diff --git a/java/res/layout/emoji_palettes_view.xml b/java/res/layout/emoji_palettes_view.xml
deleted file mode 100644
index df1b61ba3..000000000
--- a/java/res/layout/emoji_palettes_view.xml
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java b/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
deleted file mode 100644
index d7f2556ef..000000000
--- a/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPageKeyboardView.java
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * 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 org.futo.inputmethod.keyboard.emoji;
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.accessibility.AccessibilityEvent;
-
-import org.futo.inputmethod.accessibility.AccessibilityUtils;
-import org.futo.inputmethod.accessibility.KeyboardAccessibilityDelegate;
-import org.futo.inputmethod.keyboard.Key;
-import org.futo.inputmethod.keyboard.KeyDetector;
-import org.futo.inputmethod.keyboard.Keyboard;
-import org.futo.inputmethod.keyboard.KeyboardView;
-import org.futo.inputmethod.latin.R;
-
-/**
- * This is an extended {@link KeyboardView} class that hosts an emoji page keyboard.
- * Multi-touch unsupported. No gesture support.
- */
-// TODO: Implement key popup preview.
-public final class EmojiPageKeyboardView extends KeyboardView implements
- GestureDetector.OnGestureListener {
- private static final long KEY_PRESS_DELAY_TIME = 250; // msec
- private static final long KEY_RELEASE_DELAY_TIME = 30; // msec
-
- public interface OnKeyEventListener {
- public void onPressKey(Key key);
- public void onReleaseKey(Key key);
- }
-
- private static final OnKeyEventListener EMPTY_LISTENER = new OnKeyEventListener() {
- @Override
- public void onPressKey(final Key key) {}
- @Override
- public void onReleaseKey(final Key key) {}
- };
-
- private OnKeyEventListener mListener = EMPTY_LISTENER;
- private final KeyDetector mKeyDetector = new KeyDetector();
- private final GestureDetector mGestureDetector;
- private KeyboardAccessibilityDelegate mAccessibilityDelegate;
-
- public EmojiPageKeyboardView(final Context context, final AttributeSet attrs) {
- this(context, attrs, R.attr.keyboardViewStyle);
- }
-
- public EmojiPageKeyboardView(final Context context, final AttributeSet attrs,
- final int defStyle) {
- super(context, attrs, defStyle);
- mGestureDetector = new GestureDetector(context, this);
- mGestureDetector.setIsLongpressEnabled(false /* isLongpressEnabled */);
- mHandler = new Handler();
- }
-
- public void setOnKeyEventListener(final OnKeyEventListener listener) {
- mListener = listener;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void setKeyboard(final Keyboard keyboard) {
- super.setKeyboard(keyboard);
- mKeyDetector.setKeyboard(keyboard, 0 /* correctionX */, 0 /* correctionY */);
- if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) {
- if (mAccessibilityDelegate == null) {
- mAccessibilityDelegate = new KeyboardAccessibilityDelegate<>(this, mKeyDetector);
- }
- mAccessibilityDelegate.setKeyboard(keyboard);
- } else {
- mAccessibilityDelegate = null;
- }
- }
-
- @Override
- public boolean dispatchPopulateAccessibilityEvent(final AccessibilityEvent event) {
- // Don't populate accessibility event with all Emoji keys.
- return true;
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean onHoverEvent(final MotionEvent event) {
- final KeyboardAccessibilityDelegate accessibilityDelegate =
- mAccessibilityDelegate;
- if (accessibilityDelegate != null
- && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
- return accessibilityDelegate.onHoverEvent(event);
- }
- return super.onHoverEvent(event);
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public boolean onTouchEvent(final MotionEvent e) {
- if (mGestureDetector.onTouchEvent(e)) {
- return true;
- }
- final Key key = getKey(e);
- if (key != null && key != mCurrentKey) {
- releaseCurrentKey(false /* withKeyRegistering */);
- }
- return true;
- }
-
- // {@link GestureEnabler#OnGestureListener} methods.
- private Key mCurrentKey;
- private Runnable mPendingKeyDown;
- private final Handler mHandler;
-
- private Key getKey(final MotionEvent e) {
- final int index = e.getActionIndex();
- final int x = (int)e.getX(index);
- final int y = (int)e.getY(index);
- return mKeyDetector.detectHitKey(x, y);
- }
-
- void callListenerOnReleaseKey(final Key releasedKey, final boolean withKeyRegistering) {
- releasedKey.onReleased();
- invalidateKey(releasedKey);
- if (withKeyRegistering) {
- mListener.onReleaseKey(releasedKey);
- }
- }
-
- void callListenerOnPressKey(final Key pressedKey) {
- mPendingKeyDown = null;
- pressedKey.onPressed();
- invalidateKey(pressedKey);
- mListener.onPressKey(pressedKey);
- }
-
- public void releaseCurrentKey(final boolean withKeyRegistering) {
- mHandler.removeCallbacks(mPendingKeyDown);
- mPendingKeyDown = null;
- final Key currentKey = mCurrentKey;
- if (currentKey == null) {
- return;
- }
- callListenerOnReleaseKey(currentKey, withKeyRegistering);
- mCurrentKey = null;
- }
-
- @Override
- public boolean onDown(final MotionEvent e) {
- final Key key = getKey(e);
- releaseCurrentKey(false /* withKeyRegistering */);
- mCurrentKey = key;
- if (key == null) {
- return false;
- }
- // Do not trigger key-down effect right now in case this is actually a fling action.
- mPendingKeyDown = new Runnable() {
- @Override
- public void run() {
- callListenerOnPressKey(key);
- }
- };
- mHandler.postDelayed(mPendingKeyDown, KEY_PRESS_DELAY_TIME);
- return false;
- }
-
- @Override
- public void onShowPress(final MotionEvent e) {
- // User feedback is done at {@link #onDown(MotionEvent)}.
- }
-
- @Override
- public boolean onSingleTapUp(final MotionEvent e) {
- final Key key = getKey(e);
- final Runnable pendingKeyDown = mPendingKeyDown;
- final Key currentKey = mCurrentKey;
- releaseCurrentKey(false /* withKeyRegistering */);
- if (key == null) {
- return false;
- }
- if (key == currentKey && pendingKeyDown != null) {
- pendingKeyDown.run();
- // Trigger key-release event a little later so that a user can see visual feedback.
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- callListenerOnReleaseKey(key, true /* withRegistering */);
- }
- }, KEY_RELEASE_DELAY_TIME);
- } else {
- callListenerOnReleaseKey(key, true /* withRegistering */);
- }
- return true;
- }
-
- @Override
- public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX,
- final float distanceY) {
- releaseCurrentKey(false /* withKeyRegistering */);
- return false;
- }
-
- @Override
- public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX,
- final float velocityY) {
- releaseCurrentKey(false /* withKeyRegistering */);
- return false;
- }
-
- @Override
- public void onLongPress(final MotionEvent e) {
- // Long press detection of {@link #mGestureDetector} is disabled and not used.
- }
-}
diff --git a/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java b/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java
deleted file mode 100644
index 9103ee236..000000000
--- a/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPalettesAdapter.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2014 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 org.futo.inputmethod.keyboard.emoji;
-
-import androidx.viewpager.widget.PagerAdapter;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import org.futo.inputmethod.keyboard.Key;
-import org.futo.inputmethod.keyboard.Keyboard;
-import org.futo.inputmethod.keyboard.KeyboardView;
-import org.futo.inputmethod.latin.R;
-
-final class EmojiPalettesAdapter extends PagerAdapter {
- private static final String TAG = EmojiPalettesAdapter.class.getSimpleName();
- private static final boolean DEBUG_PAGER = false;
-
- private final EmojiPageKeyboardView.OnKeyEventListener mListener;
- private final DynamicGridKeyboard mRecentsKeyboard;
- private final SparseArray mActiveKeyboardViews = new SparseArray<>();
- private final EmojiCategory mEmojiCategory;
- private int mActivePosition = 0;
-
- public EmojiPalettesAdapter(final EmojiCategory emojiCategory,
- final EmojiPageKeyboardView.OnKeyEventListener listener) {
- mEmojiCategory = emojiCategory;
- mListener = listener;
- mRecentsKeyboard = mEmojiCategory.getKeyboard(EmojiCategory.ID_RECENTS, 0);
- }
-
- public void flushPendingRecentKeys() {
- mRecentsKeyboard.flushPendingRecentKeys();
- final KeyboardView recentKeyboardView =
- mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
- if (recentKeyboardView != null) {
- recentKeyboardView.invalidateAllKeys();
- }
- }
-
- public void addRecentKey(final Key key) {
- if (mEmojiCategory.isInRecentTab()) {
- mRecentsKeyboard.addPendingKey(key);
- return;
- }
- mRecentsKeyboard.addKeyFirst(key);
- final KeyboardView recentKeyboardView =
- mActiveKeyboardViews.get(mEmojiCategory.getRecentTabId());
- if (recentKeyboardView != null) {
- recentKeyboardView.invalidateAllKeys();
- }
- }
-
- public void onPageScrolled() {
- releaseCurrentKey(false /* withKeyRegistering */);
- }
-
- public void releaseCurrentKey(final boolean withKeyRegistering) {
- // Make sure the delayed key-down event (highlight effect and haptic feedback) will be
- // canceled.
- final EmojiPageKeyboardView currentKeyboardView =
- mActiveKeyboardViews.get(mActivePosition);
- if (currentKeyboardView == null) {
- return;
- }
- currentKeyboardView.releaseCurrentKey(withKeyRegistering);
- }
-
- @Override
- public int getCount() {
- return mEmojiCategory.getTotalPageCountOfAllCategories();
- }
-
- @Override
- public void setPrimaryItem(final ViewGroup container, final int position,
- final Object object) {
- if (mActivePosition == position) {
- return;
- }
- final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(mActivePosition);
- if (oldKeyboardView != null) {
- oldKeyboardView.releaseCurrentKey(false /* withKeyRegistering */);
- oldKeyboardView.deallocateMemory();
- }
- mActivePosition = position;
- }
-
- @Override
- public Object instantiateItem(final ViewGroup container, final int position) {
- if (DEBUG_PAGER) {
- Log.d(TAG, "instantiate item: " + position);
- }
- final EmojiPageKeyboardView oldKeyboardView = mActiveKeyboardViews.get(position);
- if (oldKeyboardView != null) {
- oldKeyboardView.deallocateMemory();
- // This may be redundant but wanted to be safer..
- mActiveKeyboardViews.remove(position);
- }
- final Keyboard keyboard =
- mEmojiCategory.getKeyboardFromPagePosition(position);
- final LayoutInflater inflater = LayoutInflater.from(container.getContext());
- final EmojiPageKeyboardView keyboardView = (EmojiPageKeyboardView)inflater.inflate(
- R.layout.emoji_keyboard_page, container, false /* attachToRoot */);
- keyboardView.setKeyboard(keyboard);
- keyboardView.setOnKeyEventListener(mListener);
- container.addView(keyboardView);
- mActiveKeyboardViews.put(position, keyboardView);
- return keyboardView;
- }
-
- @Override
- public boolean isViewFromObject(final View view, final Object object) {
- return view == object;
- }
-
- @Override
- public void destroyItem(final ViewGroup container, final int position,
- final Object object) {
- if (DEBUG_PAGER) {
- Log.d(TAG, "destroy item: " + position + ", " + object.getClass().getSimpleName());
- }
- final EmojiPageKeyboardView keyboardView = mActiveKeyboardViews.get(position);
- if (keyboardView != null) {
- keyboardView.deallocateMemory();
- mActiveKeyboardViews.remove(position);
- }
- if (object instanceof View) {
- container.removeView((View)object);
- } else {
- Log.w(TAG, "Warning!!! Emoji palette may be leaking. " + object);
- }
- }
-}
diff --git a/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPalettesView.java b/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPalettesView.java
deleted file mode 100644
index c3568ffd0..000000000
--- a/java/src/org/futo/inputmethod/keyboard/emoji/EmojiPalettesView.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * 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 org.futo.inputmethod.keyboard.emoji;
-
-import static org.futo.inputmethod.latin.common.Constants.NOT_A_COORDINATE;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Color;
-import android.graphics.drawable.Drawable;
-import android.preference.PreferenceManager;
-import androidx.viewpager.widget.ViewPager;
-import android.util.AttributeSet;
-import android.util.Pair;
-import android.util.TypedValue;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageButton;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-import android.widget.TabHost;
-import android.widget.TabHost.OnTabChangeListener;
-import android.widget.TabWidget;
-import android.widget.TextView;
-
-import org.futo.inputmethod.keyboard.Key;
-import org.futo.inputmethod.keyboard.KeyboardActionListener;
-import org.futo.inputmethod.keyboard.KeyboardLayoutSet;
-import org.futo.inputmethod.keyboard.KeyboardView;
-import org.futo.inputmethod.keyboard.internal.KeyDrawParams;
-import org.futo.inputmethod.keyboard.internal.KeyVisualAttributes;
-import org.futo.inputmethod.keyboard.internal.KeyboardIconsSet;
-import org.futo.inputmethod.latin.AudioAndHapticFeedbackManager;
-import org.futo.inputmethod.latin.R;
-import org.futo.inputmethod.latin.RichInputMethodSubtype;
-import org.futo.inputmethod.latin.common.Constants;
-import org.futo.inputmethod.latin.utils.ResourceUtils;
-
-/**
- * View class to implement Emoji palettes.
- * The Emoji keyboard consists of group of views layout/emoji_palettes_view.
- *
- * - Emoji category tabs.
- *
- Delete button.
- *
- Emoji keyboard pages that can be scrolled by swiping horizontally or by selecting a tab.
- *
- Back to main keyboard button and enter button.
- *
- * Because of the above reasons, this class doesn't extend {@link KeyboardView}.
- */
-public final class EmojiPalettesView extends LinearLayout implements OnTabChangeListener,
- ViewPager.OnPageChangeListener, View.OnClickListener, View.OnTouchListener,
- EmojiPageKeyboardView.OnKeyEventListener {
- private final int mFunctionalKeyBackgroundId;
- private final int mSpacebarBackgroundId;
- private final boolean mCategoryIndicatorEnabled;
- private final int mCategoryIndicatorDrawableResId;
- private final int mCategoryIndicatorBackgroundResId;
- private final int mCategoryPageIndicatorColor;
- private final int mCategoryPageIndicatorBackground;
- private EmojiPalettesAdapter mEmojiPalettesAdapter;
- private final EmojiLayoutParams mEmojiLayoutParams;
- private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener;
-
- private ImageButton mDeleteKey;
- private TextView mAlphabetKeyLeft;
- private TextView mAlphabetKeyRight;
- private View mSpacebar;
- // TODO: Remove this workaround.
- private View mSpacebarIcon;
- private TabHost mTabHost;
- private ViewPager mEmojiPager;
- private int mCurrentPagerPosition = 0;
- private EmojiCategoryPageIndicatorView mEmojiCategoryPageIndicatorView;
-
- private KeyboardActionListener mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER;
-
- private final EmojiCategory mEmojiCategory;
-
- public EmojiPalettesView(final Context context, final AttributeSet attrs) {
- this(context, attrs, R.attr.emojiPalettesViewStyle);
- }
-
- public EmojiPalettesView(final Context context, final AttributeSet attrs, final int defStyle) {
- super(context, attrs, defStyle);
- final TypedArray keyboardViewAttr = context.obtainStyledAttributes(attrs,
- R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
- final int keyBackgroundId = keyboardViewAttr.getResourceId(
- R.styleable.KeyboardView_keyBackground, 0);
- mFunctionalKeyBackgroundId = keyboardViewAttr.getResourceId(
- R.styleable.KeyboardView_functionalKeyBackground, keyBackgroundId);
- mSpacebarBackgroundId = keyboardViewAttr.getResourceId(
- R.styleable.KeyboardView_spacebarBackground, keyBackgroundId);
- keyboardViewAttr.recycle();
- final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(
- context, null /* editorInfo */);
- final Resources res = context.getResources();
- mEmojiLayoutParams = new EmojiLayoutParams(res);
- builder.setSubtype(RichInputMethodSubtype.getEmojiSubtype());
- builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
- mEmojiLayoutParams.mEmojiKeyboardHeight);
- final KeyboardLayoutSet layoutSet = builder.build();
- final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs,
- R.styleable.EmojiPalettesView, defStyle, R.style.EmojiPalettesView);
- mEmojiCategory = new EmojiCategory(PreferenceManager.getDefaultSharedPreferences(context),
- res, layoutSet, emojiPalettesViewAttr);
- mCategoryIndicatorEnabled = emojiPalettesViewAttr.getBoolean(
- R.styleable.EmojiPalettesView_categoryIndicatorEnabled, false);
- mCategoryIndicatorDrawableResId = emojiPalettesViewAttr.getResourceId(
- R.styleable.EmojiPalettesView_categoryIndicatorDrawable, 0);
- mCategoryIndicatorBackgroundResId = emojiPalettesViewAttr.getResourceId(
- R.styleable.EmojiPalettesView_categoryIndicatorBackground, 0);
- mCategoryPageIndicatorColor = emojiPalettesViewAttr.getColor(
- R.styleable.EmojiPalettesView_categoryPageIndicatorColor, 0);
- mCategoryPageIndicatorBackground = emojiPalettesViewAttr.getColor(
- R.styleable.EmojiPalettesView_categoryPageIndicatorBackground, 0);
- emojiPalettesViewAttr.recycle();
- mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener();
- }
-
- @Override
- protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
- final Resources res = getContext().getResources();
- // The main keyboard expands to the entire this {@link KeyboardView}.
- final int width = ResourceUtils.getDefaultKeyboardWidth(res)
- + getPaddingLeft() + getPaddingRight();
- final int height = ResourceUtils.getDefaultKeyboardHeight(res)
- + res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
- + getPaddingTop() + getPaddingBottom();
- setMeasuredDimension(width, height);
- }
-
- private void addTab(final TabHost host, final int categoryId) {
- final String tabId = EmojiCategory.getCategoryName(categoryId, 0 /* categoryPageId */);
- final TabHost.TabSpec tspec = host.newTabSpec(tabId);
- tspec.setContent(R.id.emoji_keyboard_dummy);
- final ImageView iconView = (ImageView)LayoutInflater.from(getContext()).inflate(
- R.layout.emoji_keyboard_tab_icon, null);
- // TODO: Replace background color with its own setting rather than using the
- // category page indicator background as a workaround.
- iconView.setBackgroundColor(mCategoryPageIndicatorBackground);
- iconView.setImageResource(mEmojiCategory.getCategoryTabIcon(categoryId));
- iconView.setContentDescription(mEmojiCategory.getAccessibilityDescription(categoryId));
- tspec.setIndicator(iconView);
- host.addTab(tspec);
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mTabHost = (TabHost) findViewById(R.id.emoji_category_tabhost);
- mTabHost.setup();
- for (final EmojiCategory.CategoryProperties properties
- : mEmojiCategory.getShownCategories()) {
- addTab(mTabHost, properties.mCategoryId);
- }
- mTabHost.setOnTabChangedListener(this);
- final TabWidget tabWidget = mTabHost.getTabWidget();
- tabWidget.setStripEnabled(mCategoryIndicatorEnabled);
- if (mCategoryIndicatorEnabled) {
- // On TabWidget's strip, what looks like an indicator is actually a background.
- // And what looks like a background are actually left and right drawables.
- tabWidget.setBackgroundResource(mCategoryIndicatorDrawableResId);
- tabWidget.setLeftStripDrawable(mCategoryIndicatorBackgroundResId);
- tabWidget.setRightStripDrawable(mCategoryIndicatorBackgroundResId);
- }
-
- mEmojiPalettesAdapter = new EmojiPalettesAdapter(mEmojiCategory, this);
-
- mEmojiPager = (ViewPager) findViewById(R.id.emoji_keyboard_pager);
- mEmojiPager.setAdapter(mEmojiPalettesAdapter);
- mEmojiPager.setOnPageChangeListener(this);
- mEmojiPager.setOffscreenPageLimit(0);
- mEmojiPager.setPersistentDrawingCache(PERSISTENT_NO_CACHE);
- mEmojiLayoutParams.setPagerProperties(mEmojiPager);
-
- mEmojiCategoryPageIndicatorView =
- (EmojiCategoryPageIndicatorView) findViewById(R.id.emoji_category_page_id_view);
- mEmojiCategoryPageIndicatorView.setColors(
- mCategoryPageIndicatorColor, mCategoryPageIndicatorBackground);
- mEmojiLayoutParams.setCategoryPageIdViewProperties(mEmojiCategoryPageIndicatorView);
-
- setCurrentCategoryId(mEmojiCategory.getCurrentCategoryId(), true /* force */);
-
- final LinearLayout actionBar = (LinearLayout) findViewById(R.id.emoji_action_bar);
- mEmojiLayoutParams.setActionBarProperties(actionBar);
-
- // deleteKey depends only on OnTouchListener.
- mDeleteKey = (ImageButton) findViewById(R.id.emoji_keyboard_delete);
- mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId);
- mDeleteKey.setTag(Constants.CODE_DELETE);
- mDeleteKey.setOnTouchListener(mDeleteKeyOnTouchListener);
-
- // {@link #mAlphabetKeyLeft}, {@link #mAlphabetKeyRight, and spaceKey depend on
- // {@link View.OnClickListener} as well as {@link View.OnTouchListener}.
- // {@link View.OnTouchListener} is used as the trigger of key-press, while
- // {@link View.OnClickListener} is used as the trigger of key-release which does not occur
- // if the event is canceled by moving off the finger from the view.
- // The text on alphabet keys are set at
- // {@link #startEmojiPalettes(String,int,float,Typeface)}.
- mAlphabetKeyLeft = (TextView) findViewById(R.id.emoji_keyboard_alphabet_left);
- mAlphabetKeyLeft.setBackgroundResource(mFunctionalKeyBackgroundId);
- mAlphabetKeyLeft.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
- mAlphabetKeyLeft.setOnTouchListener(this);
- mAlphabetKeyLeft.setOnClickListener(this);
- mAlphabetKeyRight = (TextView) findViewById(R.id.emoji_keyboard_alphabet_right);
- mAlphabetKeyRight.setBackgroundResource(mFunctionalKeyBackgroundId);
- mAlphabetKeyRight.setTag(Constants.CODE_ALPHA_FROM_EMOJI);
- mAlphabetKeyRight.setOnTouchListener(this);
- mAlphabetKeyRight.setOnClickListener(this);
- mSpacebar = findViewById(R.id.emoji_keyboard_space);
- mSpacebar.setBackgroundResource(mSpacebarBackgroundId);
- mSpacebar.setTag(Constants.CODE_SPACE);
- mSpacebar.setOnTouchListener(this);
- mSpacebar.setOnClickListener(this);
- mEmojiLayoutParams.setKeyProperties(mSpacebar);
- mSpacebarIcon = findViewById(R.id.emoji_keyboard_space_icon);
- }
-
- @Override
- public boolean dispatchTouchEvent(final MotionEvent ev) {
- // Add here to the stack trace to nail down the {@link IllegalArgumentException} exception
- // in MotionEvent that sporadically happens.
- // TODO: Remove this override method once the issue has been addressed.
- return super.dispatchTouchEvent(ev);
- }
-
- @Override
- public void onTabChanged(final String tabId) {
- AudioAndHapticFeedbackManager.getInstance().performHapticAndAudioFeedback(
- Constants.CODE_UNSPECIFIED, this);
- final int categoryId = mEmojiCategory.getCategoryId(tabId);
- setCurrentCategoryId(categoryId, false /* force */);
- updateEmojiCategoryPageIdView();
- }
-
- @Override
- public void onPageSelected(final int position) {
- final Pair newPos =
- mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
- setCurrentCategoryId(newPos.first /* categoryId */, false /* force */);
- mEmojiCategory.setCurrentCategoryPageId(newPos.second /* categoryPageId */);
- updateEmojiCategoryPageIdView();
- mCurrentPagerPosition = position;
- }
-
- @Override
- public void onPageScrollStateChanged(final int state) {
- // Ignore this message. Only want the actual page selected.
- }
-
- @Override
- public void onPageScrolled(final int position, final float positionOffset,
- final int positionOffsetPixels) {
- mEmojiPalettesAdapter.onPageScrolled();
- final Pair newPos =
- mEmojiCategory.getCategoryIdAndPageIdFromPagePosition(position);
- final int newCategoryId = newPos.first;
- final int newCategorySize = mEmojiCategory.getCategoryPageSize(newCategoryId);
- final int currentCategoryId = mEmojiCategory.getCurrentCategoryId();
- final int currentCategoryPageId = mEmojiCategory.getCurrentCategoryPageId();
- final int currentCategorySize = mEmojiCategory.getCurrentCategoryPageSize();
- if (newCategoryId == currentCategoryId) {
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- newCategorySize, newPos.second, positionOffset);
- } else if (newCategoryId > currentCategoryId) {
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- currentCategorySize, currentCategoryPageId, positionOffset);
- } else if (newCategoryId < currentCategoryId) {
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- currentCategorySize, currentCategoryPageId, positionOffset - 1);
- }
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnTouchListener}
- * interface to handle touch events from View-based elements such as the space bar.
- * Note that this method is used only for observing {@link MotionEvent#ACTION_DOWN} to trigger
- * {@link KeyboardActionListener#onPressKey}. {@link KeyboardActionListener#onReleaseKey} will
- * be covered by {@link #onClick} as long as the event is not canceled.
- */
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- if (event.getActionMasked() != MotionEvent.ACTION_DOWN) {
- return false;
- }
- final Object tag = v.getTag();
- if (!(tag instanceof Integer)) {
- return false;
- }
- final int code = (Integer) tag;
- mKeyboardActionListener.onPressKey(
- code, 0 /* repeatCount */, true /* isSinglePointer */);
- // It's important to return false here. Otherwise, {@link #onClick} and touch-down visual
- // feedback stop working.
- return false;
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through {@link android.view.View.OnClickListener}
- * interface to handle non-canceled touch-up events from View-based elements such as the space
- * bar.
- */
- @Override
- public void onClick(View v) {
- final Object tag = v.getTag();
- if (!(tag instanceof Integer)) {
- return;
- }
- final int code = (Integer) tag;
- mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE,
- false /* isKeyRepeat */);
- mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through
- * {@link org.futo.inputmethod.keyboard.emoji.EmojiPageKeyboardView.OnKeyEventListener}
- * interface to handle touch events from non-View-based elements such as Emoji buttons.
- */
- @Override
- public void onPressKey(final Key key) {
- final int code = key.getCode();
- mKeyboardActionListener.onPressKey(code, 0 /* repeatCount */, true /* isSinglePointer */);
- }
-
- /**
- * Called from {@link EmojiPageKeyboardView} through
- * {@link org.futo.inputmethod.keyboard.emoji.EmojiPageKeyboardView.OnKeyEventListener}
- * interface to handle touch events from non-View-based elements such as Emoji buttons.
- */
- @Override
- public void onReleaseKey(final Key key) {
- mEmojiPalettesAdapter.addRecentKey(key);
- mEmojiCategory.saveLastTypedCategoryPage();
- final int code = key.getCode();
- if (code == Constants.CODE_OUTPUT_TEXT) {
- mKeyboardActionListener.onTextInput(key.getOutputText());
- } else {
- mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE,
- false /* isKeyRepeat */);
- }
- mKeyboardActionListener.onReleaseKey(code, false /* withSliding */);
- }
-
- public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) {
- if (!enabled) return;
- // TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off?
- setLayerType(LAYER_TYPE_HARDWARE, null);
- }
-
- private static void setupAlphabetKey(final TextView alphabetKey, final String label,
- final KeyDrawParams params) {
- alphabetKey.setText(label);
- alphabetKey.setTextColor(params.mFunctionalTextColor);
- alphabetKey.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mLabelSize);
- alphabetKey.setTypeface(params.mTypeface);
- }
-
- public void startEmojiPalettes(final String switchToAlphaLabel,
- final KeyVisualAttributes keyVisualAttr,
- final KeyboardIconsSet iconSet) {
- final Drawable deleteDrawable = iconSet.getIconDrawable(KeyboardIconsSet.getIconId(KeyboardIconsSet.NAME_DELETE_KEY));
- if (deleteDrawable != null) {
- mDeleteKey.setBackground(deleteDrawable); //?
- }
- final Drawable spacebarDrawable = iconSet.getIconDrawable(KeyboardIconsSet.getIconId(KeyboardIconsSet.NAME_SPACE_KEY));
- if (spacebarDrawable != null) {
- mSpacebarIcon.setBackground(spacebarDrawable);
- }
- final KeyDrawParams params = new KeyDrawParams();
- params.updateParams(0, mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);
- setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params);
- setupAlphabetKey(mAlphabetKeyRight, switchToAlphaLabel, params);
- mEmojiPager.setAdapter(mEmojiPalettesAdapter);
- mEmojiPager.setCurrentItem(mCurrentPagerPosition);
- }
-
- public void stopEmojiPalettes() {
- mEmojiPalettesAdapter.releaseCurrentKey(true /* withKeyRegistering */);
- mEmojiPalettesAdapter.flushPendingRecentKeys();
- mEmojiPager.setAdapter(null);
- }
-
- public void setKeyboardActionListener(final KeyboardActionListener listener) {
- mKeyboardActionListener = listener;
- mDeleteKeyOnTouchListener.setKeyboardActionListener(listener);
- }
-
- private void updateEmojiCategoryPageIdView() {
- if (mEmojiCategoryPageIndicatorView == null) {
- return;
- }
- mEmojiCategoryPageIndicatorView.setCategoryPageId(
- mEmojiCategory.getCurrentCategoryPageSize(),
- mEmojiCategory.getCurrentCategoryPageId(), 0.0f /* offset */);
- }
-
- private void setCurrentCategoryId(final int categoryId, final boolean force) {
- final int oldCategoryId = mEmojiCategory.getCurrentCategoryId();
- if (oldCategoryId == categoryId && !force) {
- return;
- }
-
- if (oldCategoryId == EmojiCategory.ID_RECENTS) {
- // Needs to save pending updates for recent keys when we get out of the recents
- // category because we don't want to move the recent emojis around while the user
- // is in the recents category.
- mEmojiPalettesAdapter.flushPendingRecentKeys();
- }
-
- 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, false /* smoothScroll */);
- }
- if (force || mTabHost.getCurrentTab() != newTabId) {
- mTabHost.setCurrentTab(newTabId);
- }
- }
-
- private static class DeleteKeyOnTouchListener implements OnTouchListener {
- private KeyboardActionListener mKeyboardActionListener =
- KeyboardActionListener.EMPTY_LISTENER;
-
- public void setKeyboardActionListener(final KeyboardActionListener listener) {
- mKeyboardActionListener = listener;
- }
-
- @Override
- public boolean onTouch(final View v, final MotionEvent event) {
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- onTouchDown(v);
- return true;
- case MotionEvent.ACTION_MOVE:
- final float x = event.getX();
- final float y = event.getY();
- if (x < 0.0f || v.getWidth() < x || y < 0.0f || v.getHeight() < y) {
- // Stop generating key events once the finger moves away from the view area.
- onTouchCanceled(v);
- }
- return true;
- case MotionEvent.ACTION_CANCEL:
- case MotionEvent.ACTION_UP:
- onTouchUp(v);
- return true;
- }
- return false;
- }
-
- private void onTouchDown(final View v) {
- mKeyboardActionListener.onPressKey(Constants.CODE_DELETE,
- 0 /* repeatCount */, true /* isSinglePointer */);
- v.setPressed(true /* pressed */);
- }
-
- private void onTouchUp(final View v) {
- mKeyboardActionListener.onCodeInput(Constants.CODE_DELETE,
- NOT_A_COORDINATE, NOT_A_COORDINATE, false /* isKeyRepeat */);
- mKeyboardActionListener.onReleaseKey(Constants.CODE_DELETE, false /* withSliding */);
- v.setPressed(false /* pressed */);
- }
-
- private void onTouchCanceled(final View v) {
- v.setBackgroundColor(Color.TRANSPARENT);
- }
- }
-}
\ No newline at end of file