diff --git a/app/src/main/assets/layouts/clip_bottom_row.json b/app/src/main/assets/layouts/clip_bottom_row.json new file mode 100644 index 000000000..2a7c8f6b1 --- /dev/null +++ b/app/src/main/assets/layouts/clip_bottom_row.json @@ -0,0 +1,7 @@ +[ + [ + { "label": "alpha", "width": 0.15 }, + { "label": "space", "width": -1 }, + { "label": "delete", "width": 0.15 } + ] +] diff --git a/app/src/main/assets/layouts/emoji_bottom_row.json b/app/src/main/assets/layouts/emoji_bottom_row.json new file mode 100644 index 000000000..2a7c8f6b1 --- /dev/null +++ b/app/src/main/assets/layouts/emoji_bottom_row.json @@ -0,0 +1,7 @@ +[ + [ + { "label": "alpha", "width": 0.15 }, + { "label": "space", "width": -1 }, + { "label": "delete", "width": 0.15 } + ] +] diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java index 7826c4d84..ac39680a8 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardId.java @@ -63,6 +63,8 @@ public final class KeyboardId { public static final int ELEMENT_EMOJI_CATEGORY16 = 26; public static final int ELEMENT_CLIPBOARD = 27; public static final int ELEMENT_NUMPAD = 28; + public static final int ELEMENT_EMOJI_BOTTOM_ROW = 29; + public static final int ELEMENT_CLIPBOARD_BOTTOM_ROW = 30; public final RichInputMethodSubtype mSubtype; public final int mWidth; @@ -191,6 +193,10 @@ public boolean isEmojiKeyboard() { return mElementId >= ELEMENT_EMOJI_RECENTS && mElementId <= ELEMENT_EMOJI_CATEGORY16; } + public boolean isEmojiClipBottomRow() { + return mElementId == ELEMENT_CLIPBOARD_BOTTOM_ROW || mElementId == ELEMENT_EMOJI_BOTTOM_ROW; + } + public int imeAction() { return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo); } diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardLayoutSet.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardLayoutSet.java index e77b976f3..fb58f0b56 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardLayoutSet.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardLayoutSet.java @@ -18,9 +18,12 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfos; import helium314.keyboard.keyboard.internal.keyboard_parser.LocaleKeyboardInfosKt; import helium314.keyboard.keyboard.internal.keyboard_parser.RawKeyboardParser; +import helium314.keyboard.latin.RichInputMethodManager; import helium314.keyboard.latin.RichInputMethodSubtype; +import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.utils.InputTypeUtils; import helium314.keyboard.latin.utils.Log; +import helium314.keyboard.latin.utils.ResourceUtils; import helium314.keyboard.latin.utils.ScriptUtils; import java.lang.ref.SoftReference; @@ -210,6 +213,18 @@ public Builder(final Context context, @Nullable final EditorInfo ei) { } } + public static KeyboardLayoutSet buildEmojiClipBottomRow(final Context context, @Nullable final EditorInfo ei) { + final Builder builder = new Builder(context, ei); + builder.mParams.mMode = KeyboardId.MODE_TEXT; + // always full width, but height should consider scale and number row to align nicely + // actually the keyboard does not have full height, but at this point we use it to get correct key heights + final int width = ResourceUtils.getDefaultKeyboardWidth(context.getResources()); + final int height = ResourceUtils.getKeyboardHeight(context.getResources(), Settings.getInstance().getCurrent()); + builder.setKeyboardGeometry(width, height); + builder.setSubtype(RichInputMethodManager.getInstance().getCurrentSubtype()); + return builder.build(); + } + public Builder setKeyboardGeometry(final int keyboardWidth, final int keyboardHeight) { mParams.mKeyboardWidth = keyboardWidth; mParams.mKeyboardHeight = keyboardHeight; diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java index 3b7449530..610adcaf2 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java @@ -302,6 +302,7 @@ private void setMainKeyboardFrame( @NonNull final SettingsValues settingsValues, @NonNull final KeyboardSwitchState toggleState) { final int visibility = isImeSuppressedByHardwareKeyboard(settingsValues, toggleState) ? View.GONE : View.VISIBLE; + PointerTracker.switchTo(mKeyboardView); mKeyboardView.setVisibility(visibility); // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}. // @see #getVisibleKeyboardView() and @@ -332,9 +333,8 @@ public void setEmojiKeyboard() { mClipboardStripScrollView.setVisibility(View.GONE); mEmojiTabStripView.setVisibility(View.VISIBLE); mClipboardHistoryView.setVisibility(View.GONE); - mEmojiPalettesView.startEmojiPalettes( - mKeyboardLayoutSet.mLocaleKeyboardInfos.getLabelAlphabet(), - mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet); + mEmojiPalettesView.startEmojiPalettes(mKeyboardView.getKeyVisualAttribute(), + mLatinIME.getCurrentInputEditorInfo(), mLatinIME.mKeyboardActionListener); mEmojiPalettesView.setVisibility(View.VISIBLE); } @@ -355,10 +355,8 @@ public void setClipboardKeyboard() { mClipboardStripScrollView.post(() -> mClipboardStripScrollView.fullScroll(HorizontalScrollView.FOCUS_RIGHT)); mClipboardStripScrollView.setVisibility(View.VISIBLE); mEmojiPalettesView.setVisibility(View.GONE); - mClipboardHistoryView.startClipboardHistory( - mLatinIME.getClipboardHistoryManager(), - mKeyboardLayoutSet.mLocaleKeyboardInfos.getLabelAlphabet(), - mKeyboardView.getKeyVisualAttribute(), keyboard.mIconsSet); + mClipboardHistoryView.startClipboardHistory(mLatinIME.getClipboardHistoryManager(), mKeyboardView.getKeyVisualAttribute(), + mLatinIME.getCurrentInputEditorInfo(), mLatinIME.mKeyboardActionListener); mClipboardHistoryView.setVisibility(View.VISIBLE); } @@ -633,6 +631,7 @@ public View onCreateInputView(@NonNull Context displayContext, final boolean isH if (mKeyboardView != null) { mKeyboardView.closing(); } + PointerTracker.clearOldViewData(); updateKeyboardThemeAndContextThemeWrapper(displayContext, KeyboardTheme.getKeyboardTheme(displayContext)); mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(R.layout.input_view, null); @@ -655,6 +654,7 @@ public View onCreateInputView(@NonNull Context displayContext, final boolean isH mClipboardStripScrollView = mCurrentInputView.findViewById(R.id.clipboard_strip_scroll_view); mSuggestionStripView = mCurrentInputView.findViewById(R.id.suggestion_strip_view); + PointerTracker.switchTo(mKeyboardView); return mCurrentInputView; } diff --git a/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java b/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java index b04286c61..f47dc3ea6 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java +++ b/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.Locale; +import java.util.WeakHashMap; public final class PointerTracker implements PointerTrackerQueue.Element, BatchInputArbiterListener { @@ -73,6 +74,28 @@ public PointerTrackerParams(final TypedArray mainKeyboardViewAttr) { } } + // map to store static objects that should be unique for each DrawingProxy (i.e. MainKeyboardView as of now) + // this is a workaround, so we can have a MainKeyboardView in emoji and clipboard views too + // but it will not allow two simultaneously displayed MainKeyboardViews + private static final WeakHashMap sProxyMap = new WeakHashMap<>(4); + + // called when creating a new InputView + // not sure why this is necessary... maybe misunderstanding regarding WeakHashMap? + public static void clearOldViewData() { + sProxyMap.clear(); + } + + public static void switchTo(DrawingProxy drawingProxy) { + sDrawingProxy = drawingProxy; + Object[] thatArray = sProxyMap.get(drawingProxy); // if it's null, the view we're switching to should not exist + sParams = (PointerTrackerParams) thatArray[0]; + sGestureStrokeRecognitionParams = (GestureStrokeRecognitionParams) thatArray[1]; + sGestureStrokeDrawingParams = (GestureStrokeDrawingParams) thatArray[2]; + sTypingTimeRecorder = (TypingTimeRecorder) thatArray[3]; + sTimerProxy = (TimerProxy) thatArray[4]; + sTrackers = (ArrayList) thatArray[5]; + } + private static final GestureEnabler sGestureEnabler = new GestureEnabler(); // Parameters for pointer handling. @@ -81,7 +104,7 @@ public PointerTrackerParams(final TypedArray mainKeyboardViewAttr) { private static GestureStrokeRecognitionParams sGestureStrokeRecognitionParams; private static GestureStrokeDrawingParams sGestureStrokeDrawingParams; - private static final ArrayList sTrackers = new ArrayList<>(); + private static ArrayList sTrackers = new ArrayList<>(); private static final PointerTrackerQueue sPointerTrackerQueue = new PointerTrackerQueue(); public final int mPointerId; @@ -163,6 +186,16 @@ public static void init(final TypedArray mainKeyboardViewAttr, final TimerProxy sTimerProxy = timerProxy; sDrawingProxy = drawingProxy; + sTrackers = new ArrayList<>(); + + sProxyMap.put(drawingProxy, new Object[] { + sParams, + sGestureStrokeRecognitionParams, + sGestureStrokeDrawingParams, + sTypingTimeRecorder, + sTimerProxy, + sTrackers + }); } // Note that this method is called from a non-UI thread. diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index 33904eae6..b099f4ab4 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -4,17 +4,20 @@ package helium314.keyboard.keyboard.clipboard import android.annotation.SuppressLint import android.content.Context -import android.graphics.drawable.Drawable import android.util.AttributeSet import android.util.TypedValue -import android.view.MotionEvent import android.view.View +import android.view.inputmethod.EditorInfo import android.widget.ImageButton import android.widget.LinearLayout import android.widget.TextView import androidx.recyclerview.widget.StaggeredGridLayoutManager import helium314.keyboard.keyboard.KeyboardActionListener +import helium314.keyboard.keyboard.KeyboardId +import helium314.keyboard.keyboard.KeyboardLayoutSet import helium314.keyboard.keyboard.KeyboardSwitcher +import helium314.keyboard.keyboard.MainKeyboardView +import helium314.keyboard.keyboard.PointerTracker import helium314.keyboard.keyboard.internal.KeyDrawParams import helium314.keyboard.keyboard.internal.KeyVisualAttributes import helium314.keyboard.keyboard.internal.KeyboardIconsSet @@ -37,23 +40,18 @@ class ClipboardHistoryView @JvmOverloads constructor( context: Context, attrs: AttributeSet?, defStyle: Int = R.attr.clipboardHistoryViewStyle -) : LinearLayout(context, attrs, defStyle), View.OnTouchListener, View.OnClickListener, +) : LinearLayout(context, attrs, defStyle), View.OnClickListener, ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener, View.OnLongClickListener { private val clipboardLayoutParams = ClipboardLayoutParams(context.resources) private val pinIconId: Int - private val functionalKeyBackgroundId: Int private val keyBackgroundId: Int - private val spacebarBackground: Drawable private var initialized = false private lateinit var clipboardRecyclerView: ClipboardHistoryRecyclerView private lateinit var placeholderView: TextView - private lateinit var alphabetKey: TextView private val toolbarKeys = mutableListOf() private lateinit var clipboardAdapter: ClipboardAdapter - private lateinit var spacebar: View - private lateinit var deleteKey: ImageButton var keyboardActionListener: KeyboardActionListener? = null var clipboardHistoryManager: ClipboardHistoryManager? = null @@ -65,8 +63,6 @@ class ClipboardHistoryView @JvmOverloads constructor( clipboardViewAttr.recycle() val keyboardViewAttr = context.obtainStyledAttributes(attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView) keyBackgroundId = keyboardViewAttr.getResourceId(R.styleable.KeyboardView_keyBackground, 0) - functionalKeyBackgroundId = keyboardViewAttr.getResourceId(R.styleable.KeyboardView_functionalKeyBackground, keyBackgroundId) - spacebarBackground = Settings.getInstance().current.mColors.selectAndColorDrawable(keyboardViewAttr, ColorType.SPACE_BAR_BACKGROUND) keyboardViewAttr.recycle() val keyboardAttr = context.obtainStyledAttributes(attrs, R.styleable.Keyboard, defStyle, R.style.SuggestionStripView) // todo (maybe): setting the correct color only works because the activated state is inverted @@ -84,7 +80,6 @@ class ClipboardHistoryView @JvmOverloads constructor( // The main keyboard expands to the entire this {@link KeyboardView}. val width = ResourceUtils.getKeyboardWidth(res, Settings.getInstance().current) + paddingLeft + paddingRight val height = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current) + paddingTop + paddingBottom - findViewById(R.id.action_bar)?.layoutParams?.width = width setMeasuredDimension(width, height) } @@ -105,25 +100,9 @@ class ClipboardHistoryView @JvmOverloads constructor( clipboardLayoutParams.setListProperties(this) placeholderView = this@ClipboardHistoryView.placeholderView } - alphabetKey = findViewById(R.id.key_alphabet) - alphabetKey.setBackgroundResource(functionalKeyBackgroundId) - alphabetKey.tag = KeyCode.ALPHA - alphabetKey.setOnTouchListener(this) - alphabetKey.setOnClickListener(this) - deleteKey = findViewById(R.id.key_delete) - deleteKey.setBackgroundResource(functionalKeyBackgroundId) - deleteKey.tag = KeyCode.DELETE - deleteKey.setOnTouchListener(this) - deleteKey.setOnClickListener(this) - spacebar = findViewById(R.id.key_space) - spacebar.background = spacebarBackground - spacebar.tag = Constants.CODE_SPACE - spacebar.setOnTouchListener(this) - spacebar.setOnClickListener(this) val clipboardStrip = KeyboardSwitcher.getInstance().clipboardStrip toolbarKeys.forEach { clipboardStrip.addView(it) - it.setOnTouchListener(this@ClipboardHistoryView) it.setOnClickListener(this@ClipboardHistoryView) it.setOnLongClickListener(this@ClipboardHistoryView) colors.setColor(it, ColorType.TOOL_BAR_KEY) @@ -132,24 +111,6 @@ class ClipboardHistoryView @JvmOverloads constructor( initialized = true } - private fun setupAlphabetKey(key: TextView, label: String, params: KeyDrawParams) { - key.apply { - text = label - typeface = params.mTypeface - Settings.getInstance().current.mColors.setBackground(this, ColorType.FUNCTIONAL_KEY_BACKGROUND) - setTextColor(params.mFunctionalTextColor) - setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mLabelSize.toFloat()) - } - } - - private fun setupDeleteKey(key: ImageButton, icon: Drawable?) { - key.apply { - setImageDrawable(icon) - Settings.getInstance().current.mColors.setBackground(this, ColorType.FUNCTIONAL_KEY_BACKGROUND) - Settings.getInstance().current.mColors.setColor(this, ColorType.KEY_ICON) - } - } - private fun setupClipKey(params: KeyDrawParams) { clipboardAdapter.apply { itemBackgroundId = keyBackgroundId @@ -165,6 +126,15 @@ class ClipboardHistoryView @JvmOverloads constructor( toolbarKeys.forEach { it.layoutParams = toolbarKeyLayoutParams } } + private fun setupBottomRowKeyboard(editorInfo: EditorInfo, listener: KeyboardActionListener) { + val keyboardView = findViewById(R.id.bottom_row_keyboard) + keyboardView.setKeyboardActionListener(listener) + PointerTracker.switchTo(keyboardView) + val kls = KeyboardLayoutSet.Builder.buildEmojiClipBottomRow(context, editorInfo) + val keyboard = kls.getKeyboard(KeyboardId.ELEMENT_CLIPBOARD_BOTTOM_ROW) + keyboardView.setKeyboard(keyboard) + } + fun setHardwareAcceleratedDrawingEnabled(enabled: Boolean) { if (!enabled) return // TODO: Should use LAYER_TYPE_SOFTWARE when hardware acceleration is off? @@ -173,9 +143,9 @@ class ClipboardHistoryView @JvmOverloads constructor( fun startClipboardHistory( historyManager: ClipboardHistoryManager, - switchToAlphaLabel: String, keyVisualAttr: KeyVisualAttributes?, - iconSet: KeyboardIconsSet + editorInfo: EditorInfo, + keyboardActionListener: KeyboardActionListener ) { initialize() setupToolbarKeys() @@ -183,15 +153,11 @@ class ClipboardHistoryView @JvmOverloads constructor( historyManager.setHistoryChangeListener(this) clipboardHistoryManager = historyManager clipboardAdapter.clipboardHistoryManager = historyManager - findViewById(R.id.action_bar).apply { - clipboardLayoutParams.setActionBarProperties(this) - } val params = KeyDrawParams() - params.updateParams(clipboardLayoutParams.actionBarContentHeight, keyVisualAttr) - setupAlphabetKey(alphabetKey, switchToAlphaLabel, params) - setupDeleteKey(deleteKey, iconSet.getIconDrawable(KeyboardIconsSet.NAME_DELETE_KEY)) + params.updateParams(clipboardLayoutParams.bottomRowKeyboardHeight, keyVisualAttr) setupClipKey(params) + setupBottomRowKeyboard(editorInfo, keyboardActionListener) placeholderView.apply { typeface = params.mTypeface @@ -212,27 +178,7 @@ class ClipboardHistoryView @JvmOverloads constructor( clipboardAdapter.clipboardHistoryManager = null } - // the touch & click thing is used to provide haptic and audio feedback if enabled - override fun onTouch(view: View, event: MotionEvent): Boolean { - if (event.actionMasked != MotionEvent.ACTION_DOWN) { - return false - } - when (view) { - alphabetKey, spacebar, deleteKey -> keyboardActionListener?.onPressKey(view.tag as Int, 0, true) - } - // It's important to return false here. Otherwise, {@link #onClick} and touch-down visual - // feedback stop working. - return false - } - override fun onClick(view: View) { - when (view) { - alphabetKey, spacebar, deleteKey -> { - keyboardActionListener?.onCodeInput(view.tag as Int, - Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false) - keyboardActionListener?.onReleaseKey(view.tag as Int, false) - } - } val tag = view.tag if (tag is ToolbarKey) { val code = getCodeForToolbarKey(tag) diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardLayoutParams.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardLayoutParams.kt index 07e477cd4..12b32eea7 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardLayoutParams.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardLayoutParams.kt @@ -5,8 +5,8 @@ package helium314.keyboard.keyboard.clipboard import android.content.res.Resources import android.view.View import android.widget.FrameLayout -import android.widget.LinearLayout import androidx.recyclerview.widget.RecyclerView +import helium314.keyboard.keyboard.internal.KeyboardParams import helium314.keyboard.latin.R import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.ResourceUtils @@ -15,20 +15,15 @@ class ClipboardLayoutParams(res: Resources) { private val keyVerticalGap: Int private val keyHorizontalGap: Int - private val topPadding: Int - private val bottomPadding: Int private val listHeight: Int - private val actionBarHeight: Int - - companion object { - private const val DEFAULT_KEYBOARD_ROWS = 4 - } + val bottomRowKeyboardHeight: Int init { - val defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current) - val defaultKeyboardWidth = ResourceUtils.getKeyboardWidth(res, Settings.getInstance().current) + val sv = Settings.getInstance().current + val defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, sv) + val defaultKeyboardWidth = ResourceUtils.getKeyboardWidth(res, sv) - if (Settings.getInstance().current.mNarrowKeyGaps) { + if (sv.mNarrowKeyGaps) { keyVerticalGap = res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow, defaultKeyboardHeight, defaultKeyboardHeight).toInt() keyHorizontalGap = res.getFraction(R.fraction.config_key_horizontal_gap_holo_narrow, @@ -39,14 +34,16 @@ class ClipboardLayoutParams(res: Resources) { keyHorizontalGap = res.getFraction(R.fraction.config_key_horizontal_gap_holo, defaultKeyboardWidth, defaultKeyboardWidth).toInt() } - bottomPadding = (res.getFraction(R.fraction.config_keyboard_bottom_padding_holo, - defaultKeyboardHeight, defaultKeyboardHeight) * Settings.getInstance().current.mBottomPaddingScale).toInt() - topPadding = res.getFraction(R.fraction.config_keyboard_top_padding_holo, + val bottomPadding = (res.getFraction(R.fraction.config_keyboard_bottom_padding_holo, + defaultKeyboardHeight, defaultKeyboardHeight) * sv.mBottomPaddingScale).toInt() + val topPadding = res.getFraction(R.fraction.config_keyboard_top_padding_holo, defaultKeyboardHeight, defaultKeyboardHeight).toInt() - val rowCount = DEFAULT_KEYBOARD_ROWS + if (Settings.getInstance().current.mShowsNumberRow) 1 else 0 - actionBarHeight = (defaultKeyboardHeight - bottomPadding - topPadding) / rowCount - keyVerticalGap / 2 - listHeight = defaultKeyboardHeight - actionBarHeight - bottomPadding + val rowCount = KeyboardParams.DEFAULT_KEYBOARD_ROWS + if (sv.mShowsNumberRow) 1 else 0 + bottomRowKeyboardHeight = (defaultKeyboardHeight - bottomPadding - topPadding) / rowCount - keyVerticalGap / 2 + // height calculation is not good enough, probably also because keyboard top padding might be off by a pixel (see KeyboardParser) + val offset = 1.25f * res.displayMetrics.density * sv.mKeyboardHeightScale + listHeight = defaultKeyboardHeight - bottomRowKeyboardHeight - bottomPadding + offset.toInt() } fun setListProperties(recycler: RecyclerView) { @@ -56,14 +53,6 @@ class ClipboardLayoutParams(res: Resources) { } } - fun setActionBarProperties(layout: LinearLayout) { - (layout.layoutParams as LinearLayout.LayoutParams).apply { - height = actionBarHeight - width = ResourceUtils.getKeyboardWidth(layout.resources, Settings.getInstance().current) - layout.layoutParams = this - } - } - fun setItemProperties(view: View) { (view.layoutParams as RecyclerView.LayoutParams).apply { topMargin = keyHorizontalGap / 2 @@ -73,7 +62,4 @@ class ClipboardLayoutParams(res: Resources) { view.layoutParams = this } } - - val actionBarContentHeight - get() = actionBarHeight } \ No newline at end of file diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiLayoutParams.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiLayoutParams.java deleted file mode 100644 index 095f996f8..000000000 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiLayoutParams.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * modified - * SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only - */ - -package helium314.keyboard.keyboard.emoji; - -import android.content.res.Resources; -import android.view.View; -import android.widget.LinearLayout; - -import androidx.recyclerview.widget.RecyclerView; -import helium314.keyboard.latin.R; -import helium314.keyboard.latin.settings.Settings; -import helium314.keyboard.latin.settings.SettingsValues; -import helium314.keyboard.latin.utils.ResourceUtils; - -final class EmojiLayoutParams { - private static final int DEFAULT_KEYBOARD_ROWS = 4; - - public final int mEmojiListHeight; - private final int mEmojiListBottomMargin; - public final int mEmojiKeyboardHeight; - private final int mEmojiCategoryPageIdViewHeight; - public final int mEmojiActionBarHeight; - public final int mKeyVerticalGap; - private final int mKeyHorizontalGap; - private final int mBottomPadding; - private final int mTopPadding; - - public EmojiLayoutParams(final Resources res) { - final SettingsValues settingsValues = Settings.getInstance().getCurrent(); - final int defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues); - final int defaultKeyboardWidth = ResourceUtils.getKeyboardWidth(res, settingsValues); - if (settingsValues.mNarrowKeyGaps) { - mKeyVerticalGap = (int) res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow, - defaultKeyboardHeight, defaultKeyboardHeight); - mKeyHorizontalGap = (int) (res.getFraction(R.fraction.config_key_horizontal_gap_holo_narrow, - defaultKeyboardWidth, defaultKeyboardWidth)); - } else { - mKeyVerticalGap = (int) res.getFraction(R.fraction.config_key_vertical_gap_holo, - defaultKeyboardHeight, defaultKeyboardHeight); - mKeyHorizontalGap = (int) (res.getFraction(R.fraction.config_key_horizontal_gap_holo, - defaultKeyboardWidth, defaultKeyboardWidth)); - } - final float defaultBottomPadding = res.getFraction(R.fraction.config_keyboard_bottom_padding_holo, defaultKeyboardHeight, defaultKeyboardHeight); - mBottomPadding = (int) (defaultBottomPadding * settingsValues.mBottomPaddingScale); - final int paddingScaleOffset = (int) (mBottomPadding - defaultBottomPadding); - mTopPadding = (int) res.getFraction(R.fraction.config_keyboard_top_padding_holo, defaultKeyboardHeight, defaultKeyboardHeight); - mEmojiCategoryPageIdViewHeight = (int) (res.getDimension(R.dimen.config_emoji_category_page_id_height)); - final int baseheight = defaultKeyboardHeight - mBottomPadding - mTopPadding + mKeyVerticalGap; - final int rows = DEFAULT_KEYBOARD_ROWS + (settingsValues.mShowsNumberRow ? 1 : 0); // for proper size considering number row - mEmojiActionBarHeight = baseheight / rows - (mKeyVerticalGap - mBottomPadding) / 2 + paddingScaleOffset / 2; - mEmojiListHeight = defaultKeyboardHeight - mEmojiActionBarHeight - mEmojiCategoryPageIdViewHeight; - mEmojiListBottomMargin = 0; - mEmojiKeyboardHeight = mEmojiListHeight - mEmojiListBottomMargin - 1; - } - - public void setEmojiListProperties(final RecyclerView vp) { - final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) vp.getLayoutParams(); - lp.height = mEmojiKeyboardHeight; - lp.bottomMargin = mEmojiListBottomMargin; - vp.setLayoutParams(lp); - } - - public void setCategoryPageIdViewProperties(final View v) { - final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) v.getLayoutParams(); - lp.height = mEmojiCategoryPageIdViewHeight; - v.setLayoutParams(lp); - } - - public int getActionBarHeight() { - return mEmojiActionBarHeight - mBottomPadding; - } - - public void setActionBarProperties(final LinearLayout ll) { - final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) ll.getLayoutParams(); - lp.height = getActionBarHeight(); - lp.width = ResourceUtils.getKeyboardWidth(ll.getResources(), Settings.getInstance().getCurrent()); - ll.setLayoutParams(lp); - } - - public void setKeyProperties(final View v) { - final LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) v.getLayoutParams(); - lp.leftMargin = mKeyHorizontalGap / 2; - lp.rightMargin = mKeyHorizontalGap / 2; - v.setLayoutParams(lp); - } -} diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiLayoutParams.kt b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiLayoutParams.kt new file mode 100644 index 000000000..eef79bbdc --- /dev/null +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiLayoutParams.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * modified + * SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only + */ +package helium314.keyboard.keyboard.emoji + +import android.content.res.Resources +import android.view.View +import android.widget.LinearLayout +import androidx.recyclerview.widget.RecyclerView +import helium314.keyboard.keyboard.internal.KeyboardParams +import helium314.keyboard.latin.R +import helium314.keyboard.latin.settings.Settings +import helium314.keyboard.latin.utils.ResourceUtils + +internal class EmojiLayoutParams(res: Resources) { + private val emojiListBottomMargin: Int + val emojiKeyboardHeight: Int + private val emojiCategoryPageIdViewHeight: Int + val bottomRowKeyboardHeight: Int + + init { + val sv = Settings.getInstance().current + val defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, sv) + + val keyVerticalGap = if (sv.mNarrowKeyGaps) { + res.getFraction(R.fraction.config_key_vertical_gap_holo_narrow, + defaultKeyboardHeight, defaultKeyboardHeight).toInt() + } else { + res.getFraction(R.fraction.config_key_vertical_gap_holo, + defaultKeyboardHeight, defaultKeyboardHeight).toInt() + } + val bottomPadding = (res.getFraction(R.fraction.config_keyboard_bottom_padding_holo, + defaultKeyboardHeight, defaultKeyboardHeight) * sv.mBottomPaddingScale).toInt() + val topPadding = res.getFraction(R.fraction.config_keyboard_top_padding_holo, + defaultKeyboardHeight, defaultKeyboardHeight).toInt() + + val rowCount = KeyboardParams.DEFAULT_KEYBOARD_ROWS + if (sv.mShowsNumberRow) 1 else 0 + bottomRowKeyboardHeight = (defaultKeyboardHeight - bottomPadding - topPadding) / rowCount - keyVerticalGap / 2 + + val pageIdHeight = res.getDimension(R.dimen.config_emoji_category_page_id_height) + emojiCategoryPageIdViewHeight = pageIdHeight.toInt() + val offset = 1.25f * res.displayMetrics.density * sv.mKeyboardHeightScale // like ClipboardLayoutParams + val emojiListHeight = defaultKeyboardHeight - bottomRowKeyboardHeight - bottomPadding + (offset.toInt()) + emojiListBottomMargin = 0 + emojiKeyboardHeight = emojiListHeight - emojiCategoryPageIdViewHeight - emojiListBottomMargin + } + + fun setEmojiListProperties(vp: RecyclerView) { + val lp = vp.layoutParams as LinearLayout.LayoutParams + lp.height = emojiKeyboardHeight + lp.bottomMargin = emojiListBottomMargin + vp.layoutParams = lp + } + + fun setCategoryPageIdViewProperties(v: View) { + val lp = v.layoutParams as LinearLayout.LayoutParams + lp.height = emojiCategoryPageIdViewHeight + v.layoutParams = lp + } +} diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java index 7fdcdb07a..a475e4be3 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java @@ -10,35 +10,33 @@ import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; -import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; +import android.view.inputmethod.EditorInfo; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.TextView; import androidx.annotation.NonNull; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import helium314.keyboard.keyboard.Key; +import helium314.keyboard.keyboard.Keyboard; import helium314.keyboard.keyboard.KeyboardActionListener; +import helium314.keyboard.keyboard.KeyboardId; import helium314.keyboard.keyboard.KeyboardLayoutSet; import helium314.keyboard.keyboard.KeyboardSwitcher; import helium314.keyboard.keyboard.KeyboardView; +import helium314.keyboard.keyboard.MainKeyboardView; +import helium314.keyboard.keyboard.PointerTracker; import helium314.keyboard.keyboard.internal.KeyDrawParams; import helium314.keyboard.keyboard.internal.KeyVisualAttributes; -import helium314.keyboard.keyboard.internal.KeyboardIconsSet; import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode; import helium314.keyboard.latin.AudioAndHapticFeedbackManager; import helium314.keyboard.latin.R; import helium314.keyboard.latin.RichInputMethodSubtype; import helium314.keyboard.latin.common.ColorType; import helium314.keyboard.latin.common.Colors; -import helium314.keyboard.latin.common.Constants; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.utils.DeviceProtectedUtils; import helium314.keyboard.latin.utils.ResourceUtils; @@ -59,10 +57,8 @@ * Because of the above reasons, this class doesn't extend {@link KeyboardView}. */ public final class EmojiPalettesView extends LinearLayout - implements View.OnClickListener, View.OnTouchListener, OnKeyEventListener { + implements View.OnClickListener, OnKeyEventListener { private boolean initialized = false; - private final int mFunctionalKeyBackgroundId; - private final Drawable mSpacebarBackground; // keep the indicator in case emoji view is changed to tabs / viewpager private final boolean mCategoryIndicatorEnabled; private final int mCategoryIndicatorDrawableResId; @@ -71,14 +67,8 @@ public final class EmojiPalettesView extends LinearLayout private final Colors mColors; private EmojiPalettesAdapter mEmojiPalettesAdapter; private final EmojiLayoutParams mEmojiLayoutParams; - private final DeleteKeyOnTouchListener mDeleteKeyOnTouchListener; private final LinearLayoutManager mEmojiLayoutManager; - private ImageButton mDeleteKey; - private TextView mAlphabetKeyLeft; - private View mSpacebar; - // TODO: Remove this workaround. - private View mSpacebarIcon; private LinearLayout mTabStrip; private RecyclerView mEmojiRecyclerView; private EmojiCategoryPageIndicatorView mEmojiCategoryPageIndicatorView; @@ -95,21 +85,13 @@ public EmojiPalettesView(final Context context, final AttributeSet attrs) { 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); mColors = Settings.getInstance().getCurrent().mColors; - mSpacebarBackground = mColors.selectAndColorDrawable(keyboardViewAttr, ColorType.SPACE_BAR_BACKGROUND); - keyboardViewAttr.recycle(); final KeyboardLayoutSet.Builder builder = new KeyboardLayoutSet.Builder(context, null); final Resources res = context.getResources(); mEmojiLayoutParams = new EmojiLayoutParams(res); builder.setSubtype(RichInputMethodSubtype.getEmojiSubtype()); builder.setKeyboardGeometry(ResourceUtils.getKeyboardWidth(res, Settings.getInstance().getCurrent()), - mEmojiLayoutParams.mEmojiKeyboardHeight); + mEmojiLayoutParams.getEmojiKeyboardHeight()); final KeyboardLayoutSet layoutSet = builder.build(); final TypedArray emojiPalettesViewAttr = context.obtainStyledAttributes(attrs, R.styleable.EmojiPalettesView, defStyle, R.style.EmojiPalettesView); @@ -124,7 +106,6 @@ public EmojiPalettesView(final Context context, final AttributeSet attrs, final mCategoryPageIndicatorColor = emojiPalettesViewAttr.getColor( // todo: remove this and related attr R.styleable.EmojiPalettesView_categoryPageIndicatorColor, 0); emojiPalettesViewAttr.recycle(); - mDeleteKeyOnTouchListener = new DeleteKeyOnTouchListener(); mEmojiLayoutManager = new LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false); } @@ -222,73 +203,10 @@ public void onScrolled(@NonNull @NotNull RecyclerView recyclerView, int dx, int setCurrentCategoryAndPageId(mEmojiCategory.getCurrentCategoryId(), mEmojiCategory.getCurrentCategoryPageId(), true); - // deleteKey depends only on OnTouchListener. - mDeleteKey = findViewById(R.id.key_delete); - mDeleteKey.setBackgroundResource(mFunctionalKeyBackgroundId); - mColors.setColor(mDeleteKey, ColorType.KEY_ICON); - mDeleteKey.setTag(KeyCode.DELETE); - mDeleteKey.setOnTouchListener(mDeleteKeyOnTouchListener); - - // {@link #mAlphabetKeyLeft} 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 = findViewById(R.id.key_alphabet); - mAlphabetKeyLeft.setBackgroundResource(mFunctionalKeyBackgroundId); - mAlphabetKeyLeft.setTag(KeyCode.ALPHA); - mAlphabetKeyLeft.setOnTouchListener(this); - mAlphabetKeyLeft.setOnClickListener(this); - mSpacebar = findViewById(R.id.key_space); - mSpacebar.setBackground(mSpacebarBackground); - mSpacebar.setTag(Constants.CODE_SPACE); - mSpacebar.setOnTouchListener(this); - mSpacebar.setOnClickListener(this); - - mEmojiLayoutParams.setKeyProperties(mSpacebar); - mSpacebarIcon = findViewById(R.id.key_space_icon); - - mColors.setBackground(mAlphabetKeyLeft, ColorType.FUNCTIONAL_KEY_BACKGROUND); - mColors.setBackground(mDeleteKey, ColorType.FUNCTIONAL_KEY_BACKGROUND); - mColors.setBackground(mSpacebar, ColorType.SPACE_BAR_BACKGROUND); mEmojiCategoryPageIndicatorView.setColors(mColors.get(ColorType.EMOJI_CATEGORY_SELECTED), mColors.get(ColorType.STRIP_BACKGROUND)); initialized = true; } - @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); - } - - /** - * 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 @@ -305,12 +223,6 @@ public void onClick(View v) { updateEmojiCategoryPageIdView(); } } - if (!(tag instanceof Integer)) { - return; - } - final int code = (Integer) tag; - mKeyboardActionListener.onCodeInput(code, NOT_A_COORDINATE, NOT_A_COORDINATE, false); - mKeyboardActionListener.onReleaseKey(code, false); } /** @@ -350,29 +262,28 @@ public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { 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) { + public void startEmojiPalettes(final KeyVisualAttributes keyVisualAttr, + final EditorInfo editorInfo, final KeyboardActionListener keyboardActionListener) { initialize(); - mDeleteKey.setImageDrawable(iconSet.getIconDrawable(KeyboardIconsSet.NAME_DELETE_KEY)); - mEmojiLayoutParams.setActionBarProperties(findViewById(R.id.action_bar)); + + setupBottomRowKeyboard(editorInfo, keyboardActionListener); final KeyDrawParams params = new KeyDrawParams(); - params.updateParams(mEmojiLayoutParams.getActionBarHeight(), keyVisualAttr); - setupAlphabetKey(mAlphabetKeyLeft, switchToAlphaLabel, params); + params.updateParams(mEmojiLayoutParams.getBottomRowKeyboardHeight(), keyVisualAttr); if (mEmojiRecyclerView.getAdapter() == null) { mEmojiRecyclerView.setAdapter(mEmojiPalettesAdapter); setCurrentCategoryAndPageId(mEmojiCategory.getCurrentCategoryId(), mEmojiCategory.getCurrentCategoryPageId(), true); } } + private void setupBottomRowKeyboard(final EditorInfo editorInfo, final KeyboardActionListener keyboardActionListener) { + MainKeyboardView keyboardView = findViewById(R.id.bottom_row_keyboard); + keyboardView.setKeyboardActionListener(keyboardActionListener); + PointerTracker.switchTo(keyboardView); + final KeyboardLayoutSet kls = KeyboardLayoutSet.Builder.buildEmojiClipBottomRow(getContext(), editorInfo); + final Keyboard keyboard = kls.getKeyboard(KeyboardId.ELEMENT_EMOJI_BOTTOM_ROW); + keyboardView.setKeyboard(keyboard); + } + public void stopEmojiPalettes() { if (!initialized) return; mEmojiPalettesAdapter.releaseCurrentKey(true); @@ -382,7 +293,6 @@ public void stopEmojiPalettes() { public void setKeyboardActionListener(final KeyboardActionListener listener) { mKeyboardActionListener = listener; - mDeleteKeyOnTouchListener.setKeyboardActionListener(listener); } private void updateEmojiCategoryPageIdView() { @@ -421,53 +331,6 @@ private void setCurrentCategoryAndPageId(final int categoryId, final int categor Settings.getInstance().getCurrent().mColors.setColor((ImageView) current, ColorType.EMOJI_CATEGORY_SELECTED); } - private static class DeleteKeyOnTouchListener implements OnTouchListener { - private KeyboardActionListener mKeyboardActionListener = - KeyboardActionListener.EMPTY_LISTENER; - - public void setKeyboardActionListener(final KeyboardActionListener listener) { - mKeyboardActionListener = listener; - } - - @SuppressLint("ClickableViewAccessibility") - @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(KeyCode.DELETE, 0, true); - v.setPressed(true /* pressed */); - } - - private void onTouchUp(final View v) { - mKeyboardActionListener.onCodeInput(KeyCode.DELETE, NOT_A_COORDINATE, NOT_A_COORDINATE, false); - mKeyboardActionListener.onReleaseKey(KeyCode.DELETE, false); - v.setPressed(false /* pressed */); - } - - private void onTouchCanceled(final View v) { - v.setPressed(false); - } - } - public void clearKeyboardCache() { mEmojiCategory.clearKeyboardCache(); } diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java index 0ce97791a..ca1f950eb 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java @@ -31,7 +31,7 @@ public class KeyboardParams { private static final int DEFAULT_KEYBOARD_COLUMNS = 10; - private static final int DEFAULT_KEYBOARD_ROWS = 4; + public static final int DEFAULT_KEYBOARD_ROWS = 4; public KeyboardId mId; public int mThemeId; diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt index 39337dbed..d347f1077 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt @@ -26,6 +26,7 @@ import helium314.keyboard.latin.utils.getCustomLayoutFiles import helium314.keyboard.latin.utils.replaceFirst import helium314.keyboard.latin.utils.splitAt import helium314.keyboard.latin.utils.sumOf +import kotlin.math.roundToInt /** * Abstract parser class that handles creation of keyboard from [KeyData] arranged in rows, @@ -50,8 +51,23 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co val baseKeys = RawKeyboardParser.parseLayout(params, context) val keysInRows = createRows(baseKeys) - // rescale height if we have anything but the usual 4 rows - val heightRescale = if (keysInRows.size != 4) 4f / keysInRows.size else 1f + val heightRescale: Float + if (params.mId.isEmojiClipBottomRow) { + heightRescale = 4f + // params rescale is not perfect, especially mTopPadding may cause 1 pixel offsets because it's already been converted to int once + if (Settings.getInstance().current.mShowsNumberRow) { + params.mOccupiedHeight /= 5 + params.mBaseHeight /= 5 + params.mTopPadding = (params.mTopPadding / 5.0).roundToInt() + } else { + params.mOccupiedHeight /= 4 + params.mBaseHeight /= 4 + params.mTopPadding = (params.mTopPadding / 4.0).roundToInt() + } + } else { + // rescale height if we have anything but the usual 4 rows + heightRescale = if (keysInRows.size != 4) 4f / keysInRows.size else 1f + } if (heightRescale != 1f) { keysInRows.forEach { row -> row.forEach { it.mHeight *= heightRescale } } } @@ -314,3 +330,5 @@ const val LAYOUT_NUMBER = "number" const val LAYOUT_PHONE = "phone" const val LAYOUT_PHONE_SYMBOLS = "phone_symbols" const val LAYOUT_NUMBER_ROW = "number_row" +const val LAYOUT_EMOJI_BOTTOM_ROW = "emoji_bottom_row" +const val LAYOUT_CLIPBOARD_BOTTOM_ROW = "clip_bottom_row" diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt index 248d80fd4..80cafd7f0 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/RawKeyboardParser.kt @@ -37,7 +37,8 @@ object RawKeyboardParser { private val rawLayoutCache = hashMapOf MutableList>>() val symbolAndNumberLayouts = listOf(LAYOUT_SYMBOLS, LAYOUT_SYMBOLS_SHIFTED, LAYOUT_SYMBOLS_ARABIC, - LAYOUT_NUMBER, LAYOUT_NUMPAD, LAYOUT_NUMPAD_LANDSCAPE, LAYOUT_PHONE, LAYOUT_PHONE_SYMBOLS, LAYOUT_NUMBER_ROW) + LAYOUT_NUMBER, LAYOUT_NUMPAD, LAYOUT_NUMPAD_LANDSCAPE, LAYOUT_PHONE, LAYOUT_PHONE_SYMBOLS, + LAYOUT_NUMBER_ROW, LAYOUT_EMOJI_BOTTOM_ROW, LAYOUT_CLIPBOARD_BOTTOM_ROW) fun clearCache() = rawLayoutCache.clear() @@ -137,6 +138,8 @@ object RawKeyboardParser { KeyboardId.ELEMENT_NUMBER -> LAYOUT_NUMBER KeyboardId.ELEMENT_PHONE -> LAYOUT_PHONE KeyboardId.ELEMENT_PHONE_SYMBOLS -> LAYOUT_PHONE_SYMBOLS + KeyboardId.ELEMENT_EMOJI_BOTTOM_ROW -> LAYOUT_EMOJI_BOTTOM_ROW + KeyboardId.ELEMENT_CLIPBOARD_BOTTOM_ROW -> LAYOUT_CLIPBOARD_BOTTOM_ROW else -> params.mId.mSubtype.keyboardLayoutSetName.substringBeforeLast("+") } diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt index d9075a0ec..6688797df 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt @@ -110,7 +110,7 @@ sealed interface KeyData : AbstractKeyData { } private fun getSpaceLabel(params: KeyboardParams): String = - if (params.mId.isAlphaOrSymbolKeyboard) + if (params.mId.isAlphaOrSymbolKeyboard || params.mId.isEmojiClipBottomRow) "!icon/space_key|!code/key_space" else "!icon/space_key_for_number_layout|!code/key_space" diff --git a/app/src/main/res/layout/action_bar.xml b/app/src/main/res/layout/action_bar.xml deleted file mode 100644 index 00c5455c6..000000000 --- a/app/src/main/res/layout/action_bar.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/clipboard_history_view.xml b/app/src/main/res/layout/clipboard_history_view.xml index f8ef75a61..75b7b1664 100644 --- a/app/src/main/res/layout/clipboard_history_view.xml +++ b/app/src/main/res/layout/clipboard_history_view.xml @@ -34,6 +34,9 @@ - + - \ No newline at end of file + diff --git a/app/src/main/res/layout/emoji_palettes_view.xml b/app/src/main/res/layout/emoji_palettes_view.xml index 4aeee8771..ecf75b6ba 100644 --- a/app/src/main/res/layout/emoji_palettes_view.xml +++ b/app/src/main/res/layout/emoji_palettes_view.xml @@ -24,6 +24,9 @@ android:id="@+id/emoji_category_page_id_view" android:layout_width="match_parent" android:layout_height="2dip" /> - + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8d1cf5e3b..f3dbc1e0d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -533,6 +533,10 @@ disposition rather than other common dispositions for Latin languages. [CHAR LIM Numpad (landscape) Number row + + Emoji bottom row + + Clipboard bottom row Set background image