mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-06 14:50:14 +00:00
Allow resizing emoji and clipboard views in one-handed mode (#337)
This commit is contained in:
parent
9a62d85dbf
commit
9f21f540af
19 changed files with 195 additions and 146 deletions
|
@ -7,9 +7,13 @@
|
||||||
package org.dslul.openboard.inputmethod.compat;
|
package org.dslul.openboard.inputmethod.compat;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.TabHost;
|
import android.widget.TabHost;
|
||||||
|
|
||||||
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
|
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Custom version of {@link TabHost} that triggers its {@link TabHost.OnTabChangeListener} when
|
* Custom version of {@link TabHost} that triggers its {@link TabHost.OnTabChangeListener} when
|
||||||
* a tab is reselected. It is hacky but it avoids importing material widgets lib.
|
* a tab is reselected. It is hacky but it avoids importing material widgets lib.
|
||||||
|
@ -55,4 +59,13 @@ public class TabHostCompat extends TabHost implements TabHost.OnTabChangeListene
|
||||||
public void setFireOnTabChangeListenerOnReselection(boolean whether) {
|
public void setFireOnTabChangeListenerOnReselection(boolean whether) {
|
||||||
mFireOnTabChangeListenerOnReselection = whether;
|
mFireOnTabChangeListenerOnReselection = whether;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
|
final Resources res = getContext().getResources();
|
||||||
|
// fill full width, otherwise the layout is messed up
|
||||||
|
final int width = ResourceUtils.getDefaultKeyboardWidth(res);
|
||||||
|
final int height = res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height);
|
||||||
|
setMeasuredDimension(width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,12 +49,12 @@ public class Keyboard {
|
||||||
/** Total height of the keyboard, including the padding and keys */
|
/** Total height of the keyboard, including the padding and keys */
|
||||||
public final int mOccupiedHeight;
|
public final int mOccupiedHeight;
|
||||||
/** Total width of the keyboard, including the padding and keys */
|
/** Total width of the keyboard, including the padding and keys */
|
||||||
public final int mOccupiedWidth;
|
public int mOccupiedWidth;
|
||||||
|
|
||||||
/** Base height of the keyboard, used to calculate rows' height */
|
/** Base height of the keyboard, used to calculate rows' height */
|
||||||
public final int mBaseHeight;
|
public final int mBaseHeight;
|
||||||
/** Base width of the keyboard, used to calculate keys' width */
|
/** Base width of the keyboard, used to calculate keys' width */
|
||||||
public final int mBaseWidth;
|
public int mBaseWidth;
|
||||||
|
|
||||||
/** The padding above the keyboard */
|
/** The padding above the keyboard */
|
||||||
public final int mTopPadding;
|
public final int mTopPadding;
|
||||||
|
|
|
@ -46,6 +46,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
private View mMainKeyboardFrame;
|
private View mMainKeyboardFrame;
|
||||||
private MainKeyboardView mKeyboardView;
|
private MainKeyboardView mKeyboardView;
|
||||||
private EmojiPalettesView mEmojiPalettesView;
|
private EmojiPalettesView mEmojiPalettesView;
|
||||||
|
private View mEmojiTabStripView;
|
||||||
|
private View mSuggestionStripView;
|
||||||
private ClipboardHistoryView mClipboardHistoryView;
|
private ClipboardHistoryView mClipboardHistoryView;
|
||||||
private LatinIME mLatinIME;
|
private LatinIME mLatinIME;
|
||||||
private RichInputMethodManager mRichImm;
|
private RichInputMethodManager mRichImm;
|
||||||
|
@ -272,8 +274,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
private void setMainKeyboardFrame(
|
private void setMainKeyboardFrame(
|
||||||
@NonNull final SettingsValues settingsValues,
|
@NonNull final SettingsValues settingsValues,
|
||||||
@NonNull final KeyboardSwitchState toggleState) {
|
@NonNull final KeyboardSwitchState toggleState) {
|
||||||
final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState)
|
final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState) ? View.GONE : View.VISIBLE;
|
||||||
? View.GONE : View.VISIBLE;
|
|
||||||
mKeyboardView.setVisibility(visibility);
|
mKeyboardView.setVisibility(visibility);
|
||||||
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
||||||
// @see #getVisibleKeyboardView() and
|
// @see #getVisibleKeyboardView() and
|
||||||
|
@ -281,6 +282,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
mMainKeyboardFrame.setVisibility(visibility);
|
mMainKeyboardFrame.setVisibility(visibility);
|
||||||
mEmojiPalettesView.setVisibility(View.GONE);
|
mEmojiPalettesView.setVisibility(View.GONE);
|
||||||
mEmojiPalettesView.stopEmojiPalettes();
|
mEmojiPalettesView.stopEmojiPalettes();
|
||||||
|
mEmojiTabStripView.setVisibility(View.GONE);
|
||||||
|
mSuggestionStripView.setVisibility(View.VISIBLE);
|
||||||
mClipboardHistoryView.setVisibility(View.GONE);
|
mClipboardHistoryView.setVisibility(View.GONE);
|
||||||
mClipboardHistoryView.stopClipboardHistory();
|
mClipboardHistoryView.stopClipboardHistory();
|
||||||
}
|
}
|
||||||
|
@ -292,11 +295,14 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
Log.d(TAG, "setEmojiKeyboard");
|
Log.d(TAG, "setEmojiKeyboard");
|
||||||
}
|
}
|
||||||
final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
||||||
mMainKeyboardFrame.setVisibility(View.GONE);
|
mMainKeyboardFrame.setVisibility(View.VISIBLE);
|
||||||
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
||||||
// @see #getVisibleKeyboardView() and
|
// @see #getVisibleKeyboardView() and
|
||||||
// @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
|
// @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
|
||||||
mKeyboardView.setVisibility(View.GONE);
|
mKeyboardView.setVisibility(View.GONE);
|
||||||
|
mSuggestionStripView.setVisibility(View.GONE);
|
||||||
|
mEmojiTabStripView.setVisibility(View.VISIBLE);
|
||||||
|
mClipboardHistoryView.setVisibility(View.GONE);
|
||||||
mEmojiPalettesView.startEmojiPalettes(
|
mEmojiPalettesView.startEmojiPalettes(
|
||||||
mKeyboardLayoutSet.mLocaleKeyTexts.getLabelAlphabet(),
|
mKeyboardLayoutSet.mLocaleKeyTexts.getLabelAlphabet(),
|
||||||
mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet);
|
mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet);
|
||||||
|
@ -310,11 +316,14 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
Log.d(TAG, "setClipboardKeyboard");
|
Log.d(TAG, "setClipboardKeyboard");
|
||||||
}
|
}
|
||||||
final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET);
|
||||||
mMainKeyboardFrame.setVisibility(View.GONE);
|
mMainKeyboardFrame.setVisibility(View.VISIBLE);
|
||||||
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
// The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}.
|
||||||
// @see #getVisibleKeyboardView() and
|
// @see #getVisibleKeyboardView() and
|
||||||
// @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
|
// @see LatinIME#onComputeInset(android.inputmethodservice.InputMethodService.Insets)
|
||||||
mKeyboardView.setVisibility(View.GONE);
|
mKeyboardView.setVisibility(View.GONE);
|
||||||
|
mEmojiTabStripView.setVisibility(View.GONE);
|
||||||
|
mSuggestionStripView.setVisibility(View.VISIBLE);
|
||||||
|
mEmojiPalettesView.setVisibility(View.GONE);
|
||||||
mClipboardHistoryView.startClipboardHistory(
|
mClipboardHistoryView.startClipboardHistory(
|
||||||
mLatinIME.getClipboardHistoryManager(),
|
mLatinIME.getClipboardHistoryManager(),
|
||||||
mKeyboardLayoutSet.mLocaleKeyTexts.getLabelAlphabet(),
|
mKeyboardLayoutSet.mLocaleKeyTexts.getLabelAlphabet(),
|
||||||
|
@ -429,15 +438,23 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
if (mKeyboardViewWrapper.getOneHandedModeEnabled() == enabled) {
|
if (mKeyboardViewWrapper.getOneHandedModeEnabled() == enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
mEmojiPalettesView.clearKeyboardCache();
|
||||||
final Settings settings = Settings.getInstance();
|
final Settings settings = Settings.getInstance();
|
||||||
mKeyboardViewWrapper.setOneHandedModeEnabled(enabled);
|
mKeyboardViewWrapper.setOneHandedModeEnabled(enabled);
|
||||||
mKeyboardViewWrapper.setOneHandedGravity(settings.getCurrent().mOneHandedModeGravity);
|
mKeyboardViewWrapper.setOneHandedGravity(settings.getCurrent().mOneHandedModeGravity);
|
||||||
|
|
||||||
settings.writeOneHandedModeEnabled(enabled);
|
settings.writeOneHandedModeEnabled(enabled);
|
||||||
|
|
||||||
// Reload the entire keyboard set with the same parameters
|
// Reload the entire keyboard set with the same parameters, and switch to the previous layout
|
||||||
|
boolean wasEmoji = isShowingEmojiPalettes();
|
||||||
|
boolean wasClipboard = isShowingClipboardHistory();
|
||||||
loadKeyboard(mLatinIME.getCurrentInputEditorInfo(), settings.getCurrent(),
|
loadKeyboard(mLatinIME.getCurrentInputEditorInfo(), settings.getCurrent(),
|
||||||
mLatinIME.getCurrentAutoCapsState(), mLatinIME.getCurrentRecapitalizeState());
|
mLatinIME.getCurrentAutoCapsState(), mLatinIME.getCurrentRecapitalizeState());
|
||||||
|
if (wasEmoji)
|
||||||
|
setEmojiKeyboard();
|
||||||
|
else if (wasClipboard) {
|
||||||
|
setClipboardKeyboard();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Implements {@link KeyboardState.SwitchActions}.
|
// Implements {@link KeyboardState.SwitchActions}.
|
||||||
|
@ -499,9 +516,17 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
} else if (isShowingClipboardHistory()) {
|
} else if (isShowingClipboardHistory()) {
|
||||||
return mClipboardHistoryView;
|
return mClipboardHistoryView;
|
||||||
}
|
}
|
||||||
|
return mKeyboardView;
|
||||||
|
}
|
||||||
|
|
||||||
|
public View getWrapperView() {
|
||||||
return mKeyboardViewWrapper;
|
return mKeyboardViewWrapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public View getEmojiTabStrip() {
|
||||||
|
return mEmojiTabStripView;
|
||||||
|
}
|
||||||
|
|
||||||
public MainKeyboardView getMainKeyboardView() {
|
public MainKeyboardView getMainKeyboardView() {
|
||||||
return mKeyboardView;
|
return mKeyboardView;
|
||||||
}
|
}
|
||||||
|
@ -540,6 +565,9 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions {
|
||||||
mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
|
mEmojiPalettesView.setKeyboardActionListener(mLatinIME);
|
||||||
mClipboardHistoryView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
mClipboardHistoryView.setHardwareAcceleratedDrawingEnabled(isHardwareAcceleratedDrawingEnabled);
|
||||||
mClipboardHistoryView.setKeyboardActionListener(mLatinIME);
|
mClipboardHistoryView.setKeyboardActionListener(mLatinIME);
|
||||||
|
mEmojiTabStripView = mCurrentInputView.findViewById(R.id.emoji_tab_strip);
|
||||||
|
mSuggestionStripView = mCurrentInputView.findViewById(R.id.suggestion_strip_view);
|
||||||
|
mEmojiPalettesView.initialStart();
|
||||||
|
|
||||||
return mCurrentInputView;
|
return mCurrentInputView;
|
||||||
}
|
}
|
||||||
|
|
|
@ -213,12 +213,7 @@ public class KeyboardView extends View {
|
||||||
}
|
}
|
||||||
|
|
||||||
mKeyboard = keyboard;
|
mKeyboard = keyboard;
|
||||||
final SettingsValues sv = Settings.getInstance().getCurrent();
|
mKeyScaleForText = (float) Math.sqrt(1 / Settings.getInstance().getCurrent().mKeyboardHeightScale);
|
||||||
// scale should not depend on mOneHandedModeScale for emoji and clipboard, because those views are not affected by one-handed mode (yet)
|
|
||||||
if (keyboard.mId.isEmojiKeyboard() || keyboard.mId.mElementId == KeyboardId.ELEMENT_CLIPBOARD)
|
|
||||||
mKeyScaleForText = (float) Math.sqrt(1 / sv.mKeyboardHeightScale);
|
|
||||||
else
|
|
||||||
mKeyScaleForText = (float) Math.sqrt(sv.mOneHandedModeScale / sv.mKeyboardHeightScale);
|
|
||||||
final int scaledKeyHeight = (int) ((keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap) * mKeyScaleForText);
|
final int scaledKeyHeight = (int) ((keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap) * mKeyScaleForText);
|
||||||
mKeyDrawParams.updateParams(scaledKeyHeight, mKeyVisualAttributes);
|
mKeyDrawParams.updateParams(scaledKeyHeight, mKeyVisualAttributes);
|
||||||
mKeyDrawParams.updateParams(scaledKeyHeight, keyboard.mKeyVisualAttributes);
|
mKeyDrawParams.updateParams(scaledKeyHeight, keyboard.mKeyVisualAttributes);
|
||||||
|
@ -362,6 +357,7 @@ public class KeyboardView extends View {
|
||||||
canvas.translate(keyDrawX, keyDrawY);
|
canvas.translate(keyDrawX, keyDrawY);
|
||||||
|
|
||||||
final KeyVisualAttributes attr = key.getVisualAttributes();
|
final KeyVisualAttributes attr = key.getVisualAttributes();
|
||||||
|
// don't use the raw key height, linear font scaling with height is too extreme
|
||||||
final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams((int) (key.getHeight() * mKeyScaleForText), attr);
|
final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams((int) (key.getHeight() * mKeyScaleForText), attr);
|
||||||
params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
|
params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
|
||||||
|
|
||||||
|
|
|
@ -56,14 +56,16 @@ class ClipboardHistoryView @JvmOverloads constructor(
|
||||||
keyboardViewAttr.recycle()
|
keyboardViewAttr.recycle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: add another strip to clipboard, with select all, arrow keys, select, copy, clear buttons
|
||||||
|
// at the bottom, remove the clear button and add the keys like in the emoji view (abc, space, delete)
|
||||||
|
// also allow swipe to remove a word from clipboard history (except current clip and pinned clips)
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
val res = context.resources
|
val res = context.resources
|
||||||
// The main keyboard expands to the entire this {@link KeyboardView}.
|
// The main keyboard expands to the entire this {@link KeyboardView}.
|
||||||
val width = (ResourceUtils.getDefaultKeyboardWidth(res) + paddingLeft + paddingRight)
|
val width = ResourceUtils.getKeyboardWidth(res, Settings.getInstance().current) + paddingLeft + paddingRight
|
||||||
val height = (ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current)
|
val height = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current) + paddingTop + paddingBottom
|
||||||
+ res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
|
findViewById<FrameLayout>(R.id.clipboard_action_bar)?.layoutParams?.width = width
|
||||||
+ paddingTop + paddingBottom)
|
|
||||||
setMeasuredDimension(width, height)
|
setMeasuredDimension(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,6 +156,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
|
||||||
}
|
}
|
||||||
clipboardRecyclerView.apply {
|
clipboardRecyclerView.apply {
|
||||||
adapter = clipboardAdapter
|
adapter = clipboardAdapter
|
||||||
|
layoutParams.width = ResourceUtils.getKeyboardWidth(context.resources, Settings.getInstance().current)
|
||||||
}
|
}
|
||||||
Settings.getInstance().current.mColors.setBackground(this, ColorType.CLIPBOARD_BACKGROUND)
|
Settings.getInstance().current.mColors.setBackground(this, ColorType.CLIPBOARD_BACKGROUND)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,7 @@ class ClipboardLayoutParams(res: Resources) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current)
|
val defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current)
|
||||||
val suggestionStripHeight = res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
|
val defaultKeyboardWidth = ResourceUtils.getKeyboardWidth(res, Settings.getInstance().current)
|
||||||
val defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res)
|
|
||||||
|
|
||||||
if (Settings.getInstance().current.mNarrowKeyGaps) {
|
if (Settings.getInstance().current.mNarrowKeyGaps) {
|
||||||
keyVerticalGap = res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow,
|
keyVerticalGap = res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow,
|
||||||
|
@ -45,8 +44,9 @@ class ClipboardLayoutParams(res: Resources) {
|
||||||
topPadding = res.getFraction(R.fraction.config_keyboard_top_padding_holo,
|
topPadding = res.getFraction(R.fraction.config_keyboard_top_padding_holo,
|
||||||
defaultKeyboardHeight, defaultKeyboardHeight).toInt()
|
defaultKeyboardHeight, defaultKeyboardHeight).toInt()
|
||||||
|
|
||||||
actionBarHeight = (defaultKeyboardHeight - bottomPadding - topPadding) / DEFAULT_KEYBOARD_ROWS - keyVerticalGap / 2
|
val rowCount = DEFAULT_KEYBOARD_ROWS + if (Settings.getInstance().current.mShowsNumberRow) 1 else 0
|
||||||
listHeight = defaultKeyboardHeight + suggestionStripHeight - actionBarHeight - bottomPadding
|
actionBarHeight = (defaultKeyboardHeight - bottomPadding - topPadding) / rowCount - keyVerticalGap / 2
|
||||||
|
listHeight = defaultKeyboardHeight - actionBarHeight - bottomPadding
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setListProperties(recycler: RecyclerView) {
|
fun setListProperties(recycler: RecyclerView) {
|
||||||
|
|
|
@ -49,19 +49,33 @@ final class DynamicGridKeyboard extends Keyboard {
|
||||||
private List<Key> mCachedGridKeys;
|
private List<Key> mCachedGridKeys;
|
||||||
|
|
||||||
public DynamicGridKeyboard(final SharedPreferences prefs, final Keyboard templateKeyboard,
|
public DynamicGridKeyboard(final SharedPreferences prefs, final Keyboard templateKeyboard,
|
||||||
final int maxKeyCount, final int categoryId) {
|
final int maxKeyCount, final int categoryId, final int width) {
|
||||||
super(templateKeyboard);
|
super(templateKeyboard);
|
||||||
|
// todo: would be better to keep them final and not require width, but how to properly set width of the template keyboard?
|
||||||
|
// an alternative would be to always create the templateKeyboard with full width
|
||||||
|
final int paddingWidth = mOccupiedWidth - mBaseWidth;
|
||||||
|
mBaseWidth = width - paddingWidth;
|
||||||
|
mOccupiedWidth = width;
|
||||||
final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0);
|
final Key key0 = getTemplateKey(TEMPLATE_KEY_CODE_0);
|
||||||
final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1);
|
final Key key1 = getTemplateKey(TEMPLATE_KEY_CODE_1);
|
||||||
mHorizontalGap = Math.abs(key1.getX() - key0.getX()) - key0.getWidth();
|
final int horizontalGap = Math.abs(key1.getX() - key0.getX()) - key0.getWidth();
|
||||||
mHorizontalStep = key0.getWidth() + mHorizontalGap;
|
final float widthScale = determineWidthScale(key0.getWidth() + horizontalGap);
|
||||||
mVerticalStep = key0.getHeight() + mVerticalGap;
|
mHorizontalGap = (int) (horizontalGap * widthScale);
|
||||||
|
mHorizontalStep = (int) ((key0.getWidth() + horizontalGap) * widthScale);
|
||||||
|
mVerticalStep = (int) ((key0.getHeight() + mVerticalGap) / Math.sqrt(Settings.getInstance().getCurrent().mKeyboardHeightScale));
|
||||||
mColumnsNum = mBaseWidth / mHorizontalStep;
|
mColumnsNum = mBaseWidth / mHorizontalStep;
|
||||||
mMaxKeyCount = maxKeyCount;
|
mMaxKeyCount = maxKeyCount;
|
||||||
mIsRecents = categoryId == EmojiCategory.ID_RECENTS;
|
mIsRecents = categoryId == EmojiCategory.ID_RECENTS;
|
||||||
mPrefs = prefs;
|
mPrefs = prefs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// determine a width scale so emojis evenly fill the entire width
|
||||||
|
private float determineWidthScale(final float horizontalStep) {
|
||||||
|
final float columnsNumRaw = mBaseWidth / horizontalStep;
|
||||||
|
final float columnsNum = Math.round(columnsNumRaw);
|
||||||
|
return columnsNumRaw / columnsNum;
|
||||||
|
}
|
||||||
|
|
||||||
private Key getTemplateKey(final int code) {
|
private Key getTemplateKey(final int code) {
|
||||||
for (final Key key : super.getSortedKeys()) {
|
for (final Key key : super.getSortedKeys()) {
|
||||||
if (key.getCode() == code) {
|
if (key.getCode() == code) {
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardId;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
|
||||||
import org.dslul.openboard.inputmethod.latin.R;
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
import org.dslul.openboard.inputmethod.latin.settings.Settings;
|
||||||
|
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -118,8 +119,7 @@ final class EmojiCategory {
|
||||||
private final HashMap<String, Integer> mCategoryNameToIdMap = new HashMap<>();
|
private final HashMap<String, Integer> mCategoryNameToIdMap = new HashMap<>();
|
||||||
private final int[] mCategoryTabIconId = new int[sCategoryName.length];
|
private final int[] mCategoryTabIconId = new int[sCategoryName.length];
|
||||||
private final ArrayList<CategoryProperties> mShownCategories = new ArrayList<>();
|
private final ArrayList<CategoryProperties> mShownCategories = new ArrayList<>();
|
||||||
private final ConcurrentHashMap<Long, DynamicGridKeyboard> mCategoryKeyboardMap =
|
private final ConcurrentHashMap<Long, DynamicGridKeyboard> mCategoryKeyboardMap = new ConcurrentHashMap<>();
|
||||||
new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
private int mCurrentCategoryId = EmojiCategory.ID_UNSPECIFIED;
|
private int mCurrentCategoryId = EmojiCategory.ID_UNSPECIFIED;
|
||||||
private int mCurrentCategoryPageId = 0;
|
private int mCurrentCategoryPageId = 0;
|
||||||
|
@ -132,8 +132,7 @@ final class EmojiCategory {
|
||||||
mLayoutSet = layoutSet;
|
mLayoutSet = layoutSet;
|
||||||
for (int i = 0; i < sCategoryName.length; ++i) {
|
for (int i = 0; i < sCategoryName.length; ++i) {
|
||||||
mCategoryNameToIdMap.put(sCategoryName[i], i);
|
mCategoryNameToIdMap.put(sCategoryName[i], i);
|
||||||
mCategoryTabIconId[i] = emojiPaletteViewAttr.getResourceId(
|
mCategoryTabIconId[i] = emojiPaletteViewAttr.getResourceId(sCategoryTabIconAttr[i], 0);
|
||||||
sCategoryTabIconAttr[i], 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int defaultCategoryId = EmojiCategory.ID_SMILEYS_EMOTION;
|
int defaultCategoryId = EmojiCategory.ID_SMILEYS_EMOTION;
|
||||||
|
@ -168,6 +167,10 @@ final class EmojiCategory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearKeyboardCache() {
|
||||||
|
mCategoryKeyboardMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private void addShownCategoryId(final int categoryId) {
|
private void addShownCategoryId(final int categoryId) {
|
||||||
// Load a keyboard of categoryId
|
// Load a keyboard of categoryId
|
||||||
final CategoryProperties properties = new CategoryProperties(categoryId);
|
final CategoryProperties properties = new CategoryProperties(categoryId);
|
||||||
|
@ -294,10 +297,11 @@ final class EmojiCategory {
|
||||||
return mCategoryKeyboardMap.get(categoryKeyboardMapKey);
|
return mCategoryKeyboardMap.get(categoryKeyboardMapKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final int currentWidth = ResourceUtils.getKeyboardWidth(mRes, Settings.getInstance().getCurrent());
|
||||||
if (categoryId == EmojiCategory.ID_RECENTS) {
|
if (categoryId == EmojiCategory.ID_RECENTS) {
|
||||||
final DynamicGridKeyboard kbd = new DynamicGridKeyboard(mPrefs,
|
final DynamicGridKeyboard kbd = new DynamicGridKeyboard(mPrefs,
|
||||||
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||||
mMaxRecentsKeyCount, categoryId);
|
mMaxRecentsKeyCount, categoryId, currentWidth);
|
||||||
mCategoryKeyboardMap.put(categoryKeyboardMapKey, kbd);
|
mCategoryKeyboardMap.put(categoryKeyboardMapKey, kbd);
|
||||||
return kbd;
|
return kbd;
|
||||||
}
|
}
|
||||||
|
@ -309,15 +313,14 @@ final class EmojiCategory {
|
||||||
for (int pageId = 0; pageId < sortedKeysPages.length; ++pageId) {
|
for (int pageId = 0; pageId < sortedKeysPages.length; ++pageId) {
|
||||||
final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs,
|
final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs,
|
||||||
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||||
keyCountPerPage, categoryId);
|
keyCountPerPage, categoryId, currentWidth);
|
||||||
for (final Key emojiKey : sortedKeysPages[pageId]) {
|
for (final Key emojiKey : sortedKeysPages[pageId]) {
|
||||||
if (emojiKey == null) {
|
if (emojiKey == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tempKeyboard.addKeyLast(emojiKey);
|
tempKeyboard.addKeyLast(emojiKey);
|
||||||
}
|
}
|
||||||
mCategoryKeyboardMap.put(
|
mCategoryKeyboardMap.put(getCategoryKeyboardMapKey(categoryId, pageId), tempKeyboard);
|
||||||
getCategoryKeyboardMapKey(categoryId, pageId), tempKeyboard);
|
|
||||||
}
|
}
|
||||||
return mCategoryKeyboardMap.get(categoryKeyboardMapKey);
|
return mCategoryKeyboardMap.get(categoryKeyboardMapKey);
|
||||||
}
|
}
|
||||||
|
@ -326,7 +329,7 @@ final class EmojiCategory {
|
||||||
private int computeMaxKeyCountPerPage() {
|
private int computeMaxKeyCountPerPage() {
|
||||||
final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs,
|
final DynamicGridKeyboard tempKeyboard = new DynamicGridKeyboard(mPrefs,
|
||||||
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
mLayoutSet.getKeyboard(KeyboardId.ELEMENT_EMOJI_RECENTS),
|
||||||
0, 0);
|
0, 0, ResourceUtils.getKeyboardWidth(mRes, Settings.getInstance().getCurrent()));
|
||||||
return MAX_LINE_COUNT_PER_PAGE * tempKeyboard.getColumnsCount();
|
return MAX_LINE_COUNT_PER_PAGE * tempKeyboard.getColumnsCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@ final class EmojiLayoutParams {
|
||||||
public EmojiLayoutParams(final Resources res) {
|
public EmojiLayoutParams(final Resources res) {
|
||||||
final SettingsValues settingsValues = Settings.getInstance().getCurrent();
|
final SettingsValues settingsValues = Settings.getInstance().getCurrent();
|
||||||
final int defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
|
final int defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
|
||||||
final int defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
|
final int defaultKeyboardWidth = ResourceUtils.getKeyboardWidth(res, settingsValues);
|
||||||
if (settingsValues.mNarrowKeyGaps) {
|
if (settingsValues.mNarrowKeyGaps) {
|
||||||
mKeyVerticalGap = (int) res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow,
|
mKeyVerticalGap = (int) res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow,
|
||||||
defaultKeyboardHeight, defaultKeyboardHeight);
|
defaultKeyboardHeight, defaultKeyboardHeight);
|
||||||
|
@ -77,6 +77,7 @@ final class EmojiLayoutParams {
|
||||||
public void setActionBarProperties(final LinearLayout ll) {
|
public void setActionBarProperties(final LinearLayout ll) {
|
||||||
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
|
final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams();
|
||||||
lp.height = getActionBarHeight();
|
lp.height = getActionBarHeight();
|
||||||
|
lp.width = ResourceUtils.getKeyboardWidth(ll.getResources(), Settings.getInstance().getCurrent());
|
||||||
ll.setLayoutParams(lp);
|
ll.setLayoutParams(lp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -110,8 +110,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
final Keyboard keyboard = getKeyboard();
|
final Keyboard keyboard = getKeyboard();
|
||||||
if (keyboard instanceof DynamicGridKeyboard) {
|
if (keyboard instanceof DynamicGridKeyboard) {
|
||||||
final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
|
final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight();
|
||||||
final int occupiedHeight =
|
final int occupiedHeight = ((DynamicGridKeyboard) keyboard).getDynamicOccupiedHeight();
|
||||||
((DynamicGridKeyboard) keyboard).getDynamicOccupiedHeight();
|
|
||||||
final int height = occupiedHeight + getPaddingTop() + getPaddingBottom();
|
final int height = occupiedHeight + getPaddingTop() + getPaddingBottom();
|
||||||
setMeasuredDimension(width, height);
|
setMeasuredDimension(width, height);
|
||||||
return;
|
return;
|
||||||
|
@ -185,8 +184,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
}
|
}
|
||||||
|
|
||||||
final View container = mMoreKeysKeyboardContainer;
|
final View container = mMoreKeysKeyboardContainer;
|
||||||
final MoreKeysKeyboardView moreKeysKeyboardView =
|
final MoreKeysKeyboardView moreKeysKeyboardView = container.findViewById(R.id.more_keys_keyboard_view);
|
||||||
container.findViewById(R.id.more_keys_keyboard_view);
|
|
||||||
moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
|
moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
|
||||||
container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
|
||||||
|
|
||||||
|
@ -198,8 +196,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
? CoordinateUtils.x(lastCoords)
|
? CoordinateUtils.x(lastCoords)
|
||||||
: key.getX() + key.getWidth() / 2;
|
: key.getX() + key.getWidth() / 2;
|
||||||
final int pointY = key.getY();
|
final int pointY = key.getY();
|
||||||
moreKeysKeyboardView.showMoreKeysPanel(this, this,
|
moreKeysKeyboardView.showMoreKeysPanel(this, this, pointX, pointY, mListener);
|
||||||
pointX, pointY, mListener);
|
|
||||||
return moreKeysKeyboardView;
|
return moreKeysKeyboardView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,10 +250,8 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onHoverEvent(final MotionEvent event) {
|
public boolean onHoverEvent(final MotionEvent event) {
|
||||||
final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> accessibilityDelegate =
|
final KeyboardAccessibilityDelegate<EmojiPageKeyboardView> accessibilityDelegate = mAccessibilityDelegate;
|
||||||
mAccessibilityDelegate;
|
if (accessibilityDelegate != null && AccessibilityUtils.Companion.getInstance().isTouchExplorationEnabled()) {
|
||||||
if (accessibilityDelegate != null
|
|
||||||
&& AccessibilityUtils.Companion.getInstance().isTouchExplorationEnabled()) {
|
|
||||||
return accessibilityDelegate.onHoverEvent(event);
|
return accessibilityDelegate.onHoverEvent(event);
|
||||||
}
|
}
|
||||||
return super.onHoverEvent(event);
|
return super.onHoverEvent(event);
|
||||||
|
@ -387,12 +382,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
} else if (key == currentKey && pendingKeyDown != null) {
|
} else if (key == currentKey && pendingKeyDown != null) {
|
||||||
pendingKeyDown.run();
|
pendingKeyDown.run();
|
||||||
// Trigger key-release event a little later so that a user can see visual feedback.
|
// Trigger key-release event a little later so that a user can see visual feedback.
|
||||||
mHandler.postDelayed(new Runnable() {
|
mHandler.postDelayed(() -> callListenerOnReleaseKey(key, true), KEY_RELEASE_DELAY_TIME);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
callListenerOnReleaseKey(key, true /* withRegistering */);
|
|
||||||
}
|
|
||||||
}, KEY_RELEASE_DELAY_TIME);
|
|
||||||
} else if (key != null) {
|
} else if (key != null) {
|
||||||
callListenerOnReleaseKey(key, true /* withRegistering */);
|
callListenerOnReleaseKey(key, true /* withRegistering */);
|
||||||
}
|
}
|
||||||
|
@ -402,7 +392,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean onCancel(final MotionEvent e) {
|
public boolean onCancel(final MotionEvent e) {
|
||||||
releaseCurrentKey(false /* withKeyRegistering */);
|
releaseCurrentKey(false);
|
||||||
dismissMoreKeysPanel();
|
dismissMoreKeysPanel();
|
||||||
cancelLongPress();
|
cancelLongPress();
|
||||||
return true;
|
return true;
|
||||||
|
@ -417,7 +407,7 @@ public final class EmojiPageKeyboardView extends KeyboardView implements
|
||||||
// Touched key has changed, release previous key's callbacks and
|
// Touched key has changed, release previous key's callbacks and
|
||||||
// re-register them for the new key.
|
// re-register them for the new key.
|
||||||
if (key != mCurrentKey && !isShowingMoreKeysPanel) {
|
if (key != mCurrentKey && !isShowingMoreKeysPanel) {
|
||||||
releaseCurrentKey(false /* withKeyRegistering */);
|
releaseCurrentKey(false);
|
||||||
mCurrentKey = key;
|
mCurrentKey = key;
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -30,6 +30,7 @@ import org.dslul.openboard.inputmethod.compat.TabHostCompat;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.Key;
|
import org.dslul.openboard.inputmethod.keyboard.Key;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardActionListener;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardActionListener;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardLayoutSet;
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardView;
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardView;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyDrawParams;
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyDrawParams;
|
||||||
import org.dslul.openboard.inputmethod.keyboard.internal.KeyVisualAttributes;
|
import org.dslul.openboard.inputmethod.keyboard.internal.KeyVisualAttributes;
|
||||||
|
@ -108,7 +109,7 @@ public final class EmojiPalettesView extends LinearLayout
|
||||||
final Resources res = context.getResources();
|
final Resources res = context.getResources();
|
||||||
mEmojiLayoutParams = new EmojiLayoutParams(res);
|
mEmojiLayoutParams = new EmojiLayoutParams(res);
|
||||||
builder.setSubtype(RichInputMethodSubtype.getEmojiSubtype());
|
builder.setSubtype(RichInputMethodSubtype.getEmojiSubtype());
|
||||||
builder.setKeyboardGeometry(ResourceUtils.getDefaultKeyboardWidth(res),
|
builder.setKeyboardGeometry(ResourceUtils.getKeyboardWidth(res, Settings.getInstance().getCurrent()),
|
||||||
mEmojiLayoutParams.mEmojiKeyboardHeight);
|
mEmojiLayoutParams.mEmojiKeyboardHeight);
|
||||||
final KeyboardLayoutSet layoutSet = builder.build();
|
final KeyboardLayoutSet layoutSet = builder.build();
|
||||||
final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs,
|
final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs,
|
||||||
|
@ -133,10 +134,9 @@ public final class EmojiPalettesView extends LinearLayout
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||||
final Resources res = getContext().getResources();
|
final Resources res = getContext().getResources();
|
||||||
// The main keyboard expands to the entire this {@link KeyboardView}.
|
// The main keyboard expands to the entire this {@link KeyboardView}.
|
||||||
final int width = ResourceUtils.getDefaultKeyboardWidth(res)
|
final int width = ResourceUtils.getKeyboardWidth(res, Settings.getInstance().getCurrent())
|
||||||
+ getPaddingLeft() + getPaddingRight();
|
+ getPaddingLeft() + getPaddingRight();
|
||||||
final int height = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().getCurrent())
|
final int height = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().getCurrent())
|
||||||
+ res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
|
|
||||||
+ getPaddingTop() + getPaddingBottom();
|
+ getPaddingTop() + getPaddingBottom();
|
||||||
setMeasuredDimension(width, height);
|
setMeasuredDimension(width, height);
|
||||||
}
|
}
|
||||||
|
@ -155,14 +155,10 @@ public final class EmojiPalettesView extends LinearLayout
|
||||||
host.addTab(tspec);
|
host.addTab(tspec);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void initialStart() { // needs to be delayed for access to EmojiTabStrip, which is not a child of this view
|
||||||
protected void onFinishInflate() {
|
mTabHost = KeyboardSwitcher.getInstance().getEmojiTabStrip().findViewById(R.id.emoji_category_tabhost);
|
||||||
super.onFinishInflate();
|
|
||||||
|
|
||||||
mTabHost = findViewById(R.id.emoji_category_tabhost);
|
|
||||||
mTabHost.setup();
|
mTabHost.setup();
|
||||||
for (final EmojiCategory.CategoryProperties properties
|
for (final EmojiCategory.CategoryProperties properties : mEmojiCategory.getShownCategories()) {
|
||||||
: mEmojiCategory.getShownCategories()) {
|
|
||||||
addTab(mTabHost, properties.mCategoryId);
|
addTab(mTabHost, properties.mCategoryId);
|
||||||
}
|
}
|
||||||
mTabHost.setOnTabChangedListener(this);
|
mTabHost.setOnTabChangedListener(this);
|
||||||
|
@ -226,9 +222,6 @@ public final class EmojiPalettesView extends LinearLayout
|
||||||
// Enable reselection after the first setCurrentCategoryAndPageId() init call
|
// Enable reselection after the first setCurrentCategoryAndPageId() init call
|
||||||
mTabHost.setFireOnTabChangeListenerOnReselection(true);
|
mTabHost.setFireOnTabChangeListenerOnReselection(true);
|
||||||
|
|
||||||
final LinearLayout actionBar = findViewById(R.id.emoji_action_bar);
|
|
||||||
mEmojiLayoutParams.setActionBarProperties(actionBar);
|
|
||||||
|
|
||||||
// deleteKey depends only on OnTouchListener.
|
// deleteKey depends only on OnTouchListener.
|
||||||
mDeleteKey = findViewById(R.id.emoji_keyboard_delete);
|
mDeleteKey = findViewById(R.id.emoji_keyboard_delete);
|
||||||
mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId);
|
mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId);
|
||||||
|
@ -378,6 +371,7 @@ public final class EmojiPalettesView extends LinearLayout
|
||||||
if (deleteIconResId != 0) {
|
if (deleteIconResId != 0) {
|
||||||
mDeleteKey.setImageResource(deleteIconResId);
|
mDeleteKey.setImageResource(deleteIconResId);
|
||||||
}
|
}
|
||||||
|
mEmojiLayoutParams.setActionBarProperties(findViewById(R.id.emoji_action_bar));
|
||||||
final KeyDrawParams params = new KeyDrawParams();
|
final KeyDrawParams params = new KeyDrawParams();
|
||||||
params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);
|
params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr);
|
||||||
setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params);
|
setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params);
|
||||||
|
@ -480,4 +474,8 @@ public final class EmojiPalettesView extends LinearLayout
|
||||||
v.setPressed(false);
|
v.setPressed(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearKeyboardCache() {
|
||||||
|
mEmojiCategory.clearKeyboardCache();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,7 @@ import org.dslul.openboard.inputmethod.latin.R
|
||||||
import org.dslul.openboard.inputmethod.latin.common.Constants
|
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||||
import org.dslul.openboard.inputmethod.latin.common.StringUtils
|
import org.dslul.openboard.inputmethod.latin.common.StringUtils
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||||
import kotlin.math.round
|
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
class EmojiParser(private val params: KeyboardParams, private val context: Context) {
|
class EmojiParser(private val params: KeyboardParams, private val context: Context) {
|
||||||
|
@ -62,18 +62,23 @@ class EmojiParser(private val params: KeyboardParams, private val context: Conte
|
||||||
*/
|
*/
|
||||||
val row = ArrayList<KeyParams>(emojiArray.size)
|
val row = ArrayList<KeyParams>(emojiArray.size)
|
||||||
var currentX = params.mLeftPadding.toFloat()
|
var currentX = params.mLeftPadding.toFloat()
|
||||||
val currentY = params.mTopPadding.toFloat()
|
val currentY = params.mTopPadding.toFloat() // no need to ever change, assignment to rows into rows is done in DynamicGridKeyboard
|
||||||
|
|
||||||
val widthScale = getWidthScale()
|
// determine key width for default settings (no number row, no one-handed mode, 100% height and bottom padding scale)
|
||||||
// extra scale for height only, to undo the effect of number row increasing absolute key height
|
// this is a bit long, but ensures that emoji size stays the same, independent of these settings
|
||||||
// todo: with this things look ok, but number row still slightly affects emoji size (which it should not)
|
val defaultKeyWidth = (ResourceUtils.getDefaultKeyboardWidth(context.resources) - params.mLeftPadding - params.mRightPadding) * params.mDefaultRelativeKeyWidth
|
||||||
val numScale = if (Settings.getInstance().current.mShowsNumberRow) 1.25f else 1f
|
val keyWidth = defaultKeyWidth * sqrt(Settings.getInstance().current.mKeyboardHeightScale)
|
||||||
|
val defaultKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(context.resources, false)
|
||||||
|
val defaultBottomPadding = context.resources.getFraction(R.fraction.config_keyboard_bottom_padding_holo, defaultKeyboardHeight, defaultKeyboardHeight);
|
||||||
|
val emojiKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(context.resources, false) * 0.75f + params.mVerticalGap - defaultBottomPadding - context.resources.getDimensionPixelSize(R.dimen.config_emoji_category_page_id_height)
|
||||||
|
val keyHeight = emojiKeyboardHeight * params.mDefaultRelativeRowHeight * Settings.getInstance().current.mKeyboardHeightScale // still apply height scale to key
|
||||||
|
|
||||||
emojiArray.forEachIndexed { i, codeArraySpec ->
|
emojiArray.forEachIndexed { i, codeArraySpec ->
|
||||||
val keyParams = parseEmojiKey(codeArraySpec, moreEmojisArray?.get(i)?.takeIf { it.isNotEmpty() }) ?: return@forEachIndexed
|
val keyParams = parseEmojiKey(codeArraySpec, moreEmojisArray?.get(i)?.takeIf { it.isNotEmpty() }) ?: return@forEachIndexed
|
||||||
keyParams.setDimensionsFromRelativeSize(currentX, currentY)
|
keyParams.xPos = currentX
|
||||||
keyParams.mFullHeight /= numScale
|
keyParams.yPos = currentY
|
||||||
keyParams.mFullWidth *= widthScale
|
keyParams.mFullWidth = keyWidth
|
||||||
|
keyParams.mFullHeight = keyHeight
|
||||||
currentX += keyParams.mFullWidth
|
currentX += keyParams.mFullWidth
|
||||||
row.add(keyParams)
|
row.add(keyParams)
|
||||||
// if (row.size % numColumns == spacerIndex) { // also removed for now (would be missing setting the size and updating x
|
// if (row.size % numColumns == spacerIndex) { // also removed for now (would be missing setting the size and updating x
|
||||||
|
@ -83,18 +88,6 @@ class EmojiParser(private val params: KeyboardParams, private val context: Conte
|
||||||
return arrayListOf(row)
|
return arrayListOf(row)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getWidthScale(): Float {
|
|
||||||
// height scale affects emoji size, but then emojis may be too wide or too narrow
|
|
||||||
// so we re-scale width too
|
|
||||||
// but not with exactly the same factor, adjust it a little so emojis fill the entire available width
|
|
||||||
// this looks much better than setting some offset in DynamicGridKeyboard (to center the rows)
|
|
||||||
val numColumnsNew = round(1f / (params.mDefaultRelativeKeyWidth * sqrt(Settings.getInstance().current.mKeyboardHeightScale)))
|
|
||||||
val numColumnsOld = round(1f / params.mDefaultRelativeKeyWidth)
|
|
||||||
return numColumnsOld / numColumnsNew - 0.0001f // small offset to have more emojis in a row in edge cases
|
|
||||||
}
|
|
||||||
|
|
||||||
// private fun Float.roundTo(even: Boolean) = if (toInt() % 2 == if (even) 0 else 1) toInt() else toInt() + 1
|
|
||||||
|
|
||||||
private fun getLabelAndCode(spec: String): Pair<String, Int>? {
|
private fun getLabelAndCode(spec: String): Pair<String, Int>? {
|
||||||
val specAndSdk = spec.split("||")
|
val specAndSdk = spec.split("||")
|
||||||
if (specAndSdk.getOrNull(1)?.toIntOrNull()?.let { it > Build.VERSION.SDK_INT } == true) return null
|
if (specAndSdk.getOrNull(1)?.toIntOrNull()?.let { it > Build.VERSION.SDK_INT } == true) return null
|
||||||
|
|
|
@ -5,7 +5,6 @@ package org.dslul.openboard.inputmethod.latin
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
import android.graphics.Color
|
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
|
@ -13,6 +12,7 @@ import android.view.View
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.ImageButton
|
import android.widget.ImageButton
|
||||||
import org.dslul.openboard.inputmethod.keyboard.KeyboardActionListener
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardActionListener
|
||||||
|
import org.dslul.openboard.inputmethod.keyboard.KeyboardSwitcher
|
||||||
import org.dslul.openboard.inputmethod.latin.common.ColorType
|
import org.dslul.openboard.inputmethod.latin.common.ColorType
|
||||||
import org.dslul.openboard.inputmethod.latin.common.Constants
|
import org.dslul.openboard.inputmethod.latin.common.Constants
|
||||||
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
import org.dslul.openboard.inputmethod.latin.settings.Settings
|
||||||
|
@ -29,7 +29,6 @@ class KeyboardWrapperView @JvmOverloads constructor(
|
||||||
|
|
||||||
private lateinit var stopOneHandedModeBtn: ImageButton
|
private lateinit var stopOneHandedModeBtn: ImageButton
|
||||||
private lateinit var switchOneHandedModeBtn: ImageButton
|
private lateinit var switchOneHandedModeBtn: ImageButton
|
||||||
private lateinit var keyboardView: View
|
|
||||||
private lateinit var resizeOneHandedModeBtn: ImageButton
|
private lateinit var resizeOneHandedModeBtn: ImageButton
|
||||||
private val iconStopOneHandedModeId: Int
|
private val iconStopOneHandedModeId: Int
|
||||||
private val iconSwitchOneHandedModeId: Int
|
private val iconSwitchOneHandedModeId: Int
|
||||||
|
@ -62,7 +61,6 @@ class KeyboardWrapperView @JvmOverloads constructor(
|
||||||
resizeOneHandedModeBtn = findViewById(R.id.btn_resize_one_handed_mode)
|
resizeOneHandedModeBtn = findViewById(R.id.btn_resize_one_handed_mode)
|
||||||
resizeOneHandedModeBtn.setImageResource(iconResizeOneHandedModeId)
|
resizeOneHandedModeBtn.setImageResource(iconResizeOneHandedModeId)
|
||||||
resizeOneHandedModeBtn.visibility = GONE
|
resizeOneHandedModeBtn.visibility = GONE
|
||||||
keyboardView = findViewById(R.id.keyboard_view)
|
|
||||||
|
|
||||||
stopOneHandedModeBtn.setOnClickListener(this)
|
stopOneHandedModeBtn.setOnClickListener(this)
|
||||||
switchOneHandedModeBtn.setOnClickListener(this)
|
switchOneHandedModeBtn.setOnClickListener(this)
|
||||||
|
@ -141,6 +139,7 @@ class KeyboardWrapperView @JvmOverloads constructor(
|
||||||
|
|
||||||
val isLeftGravity = oneHandedGravity == Gravity.LEFT
|
val isLeftGravity = oneHandedGravity == Gravity.LEFT
|
||||||
val width = right - left
|
val width = right - left
|
||||||
|
val keyboardView = KeyboardSwitcher.getInstance().visibleKeyboardView
|
||||||
val spareWidth = width - keyboardView.measuredWidth
|
val spareWidth = width - keyboardView.measuredWidth
|
||||||
|
|
||||||
val keyboardLeft = if (isLeftGravity) 0 else spareWidth
|
val keyboardLeft = if (isLeftGravity) 0 else spareWidth
|
||||||
|
|
|
@ -1248,7 +1248,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
if (mInputView == null) {
|
if (mInputView == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final View visibleKeyboardView = mKeyboardSwitcher.getVisibleKeyboardView();
|
final View visibleKeyboardView = mKeyboardSwitcher.getWrapperView();
|
||||||
if (visibleKeyboardView == null || !hasSuggestionStripView()) {
|
if (visibleKeyboardView == null || !hasSuggestionStripView()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1261,11 +1261,7 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
mInsetsUpdater.setInsets(outInsets);
|
mInsetsUpdater.setInsets(outInsets);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int suggestionsHeight = (!mKeyboardSwitcher.isShowingEmojiPalettes()
|
final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - mSuggestionStripView.getHeight();
|
||||||
&& !mKeyboardSwitcher.isShowingClipboardHistory()
|
|
||||||
&& mSuggestionStripView.getVisibility() == View.VISIBLE)
|
|
||||||
? mSuggestionStripView.getHeight() : 0;
|
|
||||||
final int visibleTopY = inputHeight - visibleKeyboardView.getHeight() - suggestionsHeight;
|
|
||||||
mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY);
|
mSuggestionStripView.setMoreSuggestionsHeight(visibleTopY);
|
||||||
// Need to set expanded touchable region only if a keyboard view is being shown.
|
// Need to set expanded touchable region only if a keyboard view is being shown.
|
||||||
if (visibleKeyboardView.isShown()) {
|
if (visibleKeyboardView.isShown()) {
|
||||||
|
|
|
@ -192,7 +192,7 @@ public final class ResourceUtils {
|
||||||
return (int)(defaultKeyboardHeight * settingsValues.mKeyboardHeightScale);
|
return (int)(defaultKeyboardHeight * settingsValues.mKeyboardHeightScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getDefaultKeyboardHeight(final Resources res, final boolean showsNumberRow) {
|
public static int getDefaultKeyboardHeight(final Resources res, final boolean showsNumberRow) {
|
||||||
final DisplayMetrics dm = res.getDisplayMetrics();
|
final DisplayMetrics dm = res.getDisplayMetrics();
|
||||||
final float keyboardHeight = res.getDimension(R.dimen.config_default_keyboard_height) * (showsNumberRow ? 1.25f : 1f);
|
final float keyboardHeight = res.getDimension(R.dimen.config_default_keyboard_height) * (showsNumberRow ? 1.25f : 1f);
|
||||||
final float maxKeyboardHeight = res.getFraction(
|
final float maxKeyboardHeight = res.getFraction(
|
||||||
|
|
|
@ -14,40 +14,6 @@
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
style="?attr/emojiPalettesViewStyle"
|
style="?attr/emojiPalettesViewStyle"
|
||||||
>
|
>
|
||||||
<LinearLayout
|
|
||||||
android:id="@+id/emoji_tab_strip"
|
|
||||||
android:orientation="horizontal"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/config_suggestions_strip_height"
|
|
||||||
style="?attr/suggestionStripViewStyle"
|
|
||||||
>
|
|
||||||
<org.dslul.openboard.inputmethod.compat.TabHostCompat
|
|
||||||
android:id="@+id/emoji_category_tabhost"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_weight="87.5"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
>
|
|
||||||
<TabWidget
|
|
||||||
android:id="@android:id/tabs"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:divider="@null" />
|
|
||||||
<FrameLayout
|
|
||||||
android:id="@android:id/tabcontent"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="0dip"
|
|
||||||
>
|
|
||||||
<!-- Empty placeholder that TabHost requires. But we don't use it to actually
|
|
||||||
display anything. We monitor the tab changes and change the ViewPager.
|
|
||||||
Similarly the ViewPager swipes are intercepted and passed to the TabHost. -->
|
|
||||||
<View
|
|
||||||
android:id="@+id/emoji_keyboard_dummy"
|
|
||||||
android:layout_width="0dip"
|
|
||||||
android:layout_height="0dip"
|
|
||||||
android:visibility="gone" />
|
|
||||||
</FrameLayout>
|
|
||||||
</org.dslul.openboard.inputmethod.compat.TabHostCompat>
|
|
||||||
</LinearLayout>
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/emoji_keyboard_list"
|
android:id="@+id/emoji_keyboard_list"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
|
@ -13,10 +13,4 @@
|
||||||
<include
|
<include
|
||||||
android:id="@+id/main_keyboard_frame"
|
android:id="@+id/main_keyboard_frame"
|
||||||
layout="@layout/main_keyboard_frame" />
|
layout="@layout/main_keyboard_frame" />
|
||||||
<include
|
|
||||||
android:id="@+id/emoji_palettes_view"
|
|
||||||
layout="@layout/emoji_palettes_view" />
|
|
||||||
<include
|
|
||||||
android:id="@+id/clipboard_history_view"
|
|
||||||
layout="@layout/clipboard_history_view" />
|
|
||||||
</org.dslul.openboard.inputmethod.latin.InputView>
|
</org.dslul.openboard.inputmethod.latin.InputView>
|
||||||
|
|
|
@ -12,15 +12,9 @@
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:orientation="vertical" >
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<!-- To ensure that key preview popup is correctly placed when the current system locale is
|
<include
|
||||||
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
|
android:id="@+id/strip_container"
|
||||||
<org.dslul.openboard.inputmethod.latin.suggestions.SuggestionStripView
|
layout="@layout/strip_container" />
|
||||||
android:id="@+id/suggestion_strip_view"
|
|
||||||
android:layoutDirection="ltr"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="@dimen/config_suggestions_strip_height"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
style="?attr/suggestionStripViewStyle" />
|
|
||||||
|
|
||||||
<!-- To ensure that key preview popup is correctly placed when the current system locale is
|
<!-- To ensure that key preview popup is correctly placed when the current system locale is
|
||||||
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
|
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
|
||||||
|
@ -35,6 +29,12 @@
|
||||||
android:layoutDirection="ltr"
|
android:layoutDirection="ltr"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
<include
|
||||||
|
android:id="@+id/emoji_palettes_view"
|
||||||
|
layout="@layout/emoji_palettes_view" />
|
||||||
|
<include
|
||||||
|
android:id="@+id/clipboard_history_view"
|
||||||
|
layout="@layout/clipboard_history_view" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/btn_stop_one_handed_mode"
|
android:id="@+id/btn_stop_one_handed_mode"
|
||||||
|
|
55
app/src/main/res/layout/strip_container.xml
Normal file
55
app/src/main/res/layout/strip_container.xml
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2014 The Android Open Source Project
|
||||||
|
modified
|
||||||
|
SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
|
||||||
|
-->
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="@dimen/config_suggestions_strip_height">
|
||||||
|
<!-- To ensure that key preview popup is correctly placed when the current system locale is
|
||||||
|
one of RTL locales, layoutDirection="ltr" is needed in the SDK version 17+. -->
|
||||||
|
<org.dslul.openboard.inputmethod.latin.suggestions.SuggestionStripView
|
||||||
|
android:id="@+id/suggestion_strip_view"
|
||||||
|
android:layoutDirection="ltr"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
style="?attr/suggestionStripViewStyle" />
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/emoji_tab_strip"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
style="?attr/suggestionStripViewStyle"
|
||||||
|
>
|
||||||
|
<org.dslul.openboard.inputmethod.compat.TabHostCompat
|
||||||
|
android:id="@+id/emoji_category_tabhost"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_weight="87.5"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
>
|
||||||
|
<TabWidget
|
||||||
|
android:id="@android:id/tabs"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:divider="@null" />
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@android:id/tabcontent"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="0dip"
|
||||||
|
>
|
||||||
|
<!-- Empty placeholder that TabHost requires. But we don't use it to actually
|
||||||
|
display anything. We monitor the tab changes and change the ViewPager.
|
||||||
|
Similarly the ViewPager swipes are intercepted and passed to the TabHost. -->
|
||||||
|
<View
|
||||||
|
android:id="@+id/emoji_keyboard_dummy"
|
||||||
|
android:layout_width="0dip"
|
||||||
|
android:layout_height="0dip"
|
||||||
|
android:visibility="gone" />
|
||||||
|
</FrameLayout>
|
||||||
|
</org.dslul.openboard.inputmethod.compat.TabHostCompat>
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
Loading…
Add table
Add a link
Reference in a new issue