Improve main views (#321)

* views now have the same height
* add one-handed mode width setting
* key text and emojis scale more adequately with keyboard height and one-handed mode width
* slightly adjust landscape config to match better with portrait
This commit is contained in:
Helium314 2023-12-18 17:30:53 +01:00 committed by GitHub
parent e78618fd6a
commit 0b55a92e02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 184 additions and 68 deletions

View file

@ -316,9 +316,7 @@ public class Key implements Comparable<Key> {
mHorizontalGap = Math.round(horizontalGapFloat); mHorizontalGap = Math.round(horizontalGapFloat);
mVerticalGap = Math.round(keyParams.mKeyboardParams.mVerticalGap); mVerticalGap = Math.round(keyParams.mKeyboardParams.mVerticalGap);
mWidth = Math.round(keyParams.mFullWidth - horizontalGapFloat); mWidth = Math.round(keyParams.mFullWidth - horizontalGapFloat);
// todo (later): height better should be rounded, but this may end up shifting all keys up by one pixel, // height is always rounded down, because rounding up may make the keyboard too high to fit, leading to issues
// increasing the keyboard height by one pixel, but not for emoji keyboard -> the 1 pixel shift feels very wrong
// how to do it properly? check again when keyboard height is same for all views!
mHeight = (int) (keyParams.mFullHeight - keyParams.mKeyboardParams.mVerticalGap); mHeight = (int) (keyParams.mFullHeight - keyParams.mKeyboardParams.mVerticalGap);
if (!isSpacer() && (mWidth == 0 || mHeight == 0)) { if (!isSpacer() && (mWidth == 0 || mHeight == 0)) {
throw new IllegalStateException("key needs positive width and height"); throw new IllegalStateException("key needs positive width and height");
@ -326,7 +324,7 @@ public class Key implements Comparable<Key> {
// Horizontal gap is divided equally to both sides of the key. // Horizontal gap is divided equally to both sides of the key.
mX = Math.round(keyParams.xPos + horizontalGapFloat / 2); mX = Math.round(keyParams.xPos + horizontalGapFloat / 2);
mY = Math.round(keyParams.yPos); mY = Math.round(keyParams.yPos);
mHitBox.set(Math.round(keyParams.xPos), (int) keyParams.yPos, Math.round(keyParams.xPos + keyParams.mFullWidth) + 1, mHitBox.set(Math.round(keyParams.xPos), Math.round(keyParams.yPos), Math.round(keyParams.xPos + keyParams.mFullWidth) + 1,
Math.round(keyParams.yPos + keyParams.mFullHeight)); Math.round(keyParams.yPos + keyParams.mFullHeight));
mHashCode = computeHashCode(this); mHashCode = computeHashCode(this);
} }

View file

@ -183,6 +183,10 @@ public final class KeyboardId {
|| mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS; || mElementId == ELEMENT_PHONE || mElementId == ELEMENT_PHONE_SYMBOLS;
} }
public boolean isEmojiKeyboard() {
return mElementId >= ELEMENT_EMOJI_RECENTS && mElementId <= ELEMENT_EMOJI_CATEGORY16;
}
public int imeAction() { public int imeAction() {
return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo); return InputTypeUtils.getImeOptionsActionIdFromEditorInfo(mEditorInfo);
} }

View file

@ -36,6 +36,7 @@ import org.dslul.openboard.inputmethod.latin.common.Colors;
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 org.dslul.openboard.inputmethod.latin.settings.SettingsValues;
import org.dslul.openboard.inputmethod.latin.suggestions.MoreSuggestionsView; import org.dslul.openboard.inputmethod.latin.suggestions.MoreSuggestionsView;
import org.dslul.openboard.inputmethod.latin.utils.TypefaceUtils; import org.dslul.openboard.inputmethod.latin.utils.TypefaceUtils;
@ -95,6 +96,7 @@ public class KeyboardView extends View {
private final Rect mKeyBackgroundPadding = new Rect(); private final Rect mKeyBackgroundPadding = new Rect();
private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f; private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f;
private final Colors mColors; private final Colors mColors;
private float mKeyScaleForText;
// The maximum key label width in the proportion to the key width. // The maximum key label width in the proportion to the key width.
private static final float MAX_LABEL_RATIO = 0.90f; private static final float MAX_LABEL_RATIO = 0.90f;
@ -203,9 +205,15 @@ public class KeyboardView extends View {
*/ */
public void setKeyboard(@NonNull final Keyboard keyboard) { public void setKeyboard(@NonNull final Keyboard keyboard) {
mKeyboard = keyboard; mKeyboard = keyboard;
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; final SettingsValues sv = Settings.getInstance().getCurrent();
mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes); // scale should not depend on mOneHandedModeScale for emoji and clipboard, because those views are not affected by one-handed mode (yet)
mKeyDrawParams.updateParams(keyHeight, keyboard.mKeyVisualAttributes); 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);
mKeyDrawParams.updateParams(scaledKeyHeight, mKeyVisualAttributes);
mKeyDrawParams.updateParams(scaledKeyHeight, keyboard.mKeyVisualAttributes);
invalidateAllKeys(); invalidateAllKeys();
requestLayout(); requestLayout();
} }
@ -346,7 +354,7 @@ public class KeyboardView extends View {
canvas.translate(keyDrawX, keyDrawY); canvas.translate(keyDrawX, keyDrawY);
final KeyVisualAttributes attr = key.getVisualAttributes(); final KeyVisualAttributes attr = key.getVisualAttributes();
final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(key.getHeight(), attr); final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams((int) (key.getHeight() * mKeyScaleForText), attr);
params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE; params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
if (!key.isSpacer()) { if (!key.isSpacer()) {
@ -413,7 +421,8 @@ public class KeyboardView extends View {
if (key.isAlignLabelOffCenter() && mShowsHints) { if (key.isAlignLabelOffCenter() && mShowsHints) {
// The label is placed off center of the key. Currently used only on "phone number" layout // The label is placed off center of the key. Currently used only on "phone number" layout
// to have letter hints shown nicely. We don't want to align it off center if hints are off. // to have letter hints shown nicely. We don't want to align it off center if hints are off.
labelX = centerX + params.mLabelOffCenterRatio * labelCharWidth; // use a non-negative number to avoid label starting left of the letter for high keyboard scale on holo phone layout
labelX = Math.max(0f, centerX + params.mLabelOffCenterRatio * labelCharWidth);
paint.setTextAlign(Align.LEFT); paint.setTextAlign(Align.LEFT);
} else { } else {
labelX = centerX; labelX = centerX;
@ -474,6 +483,11 @@ public class KeyboardView extends View {
hintBaseline = centerY + labelCharHeight / 2.0f; hintBaseline = centerY + labelCharHeight / 2.0f;
} }
paint.setTextAlign(Align.LEFT); paint.setTextAlign(Align.LEFT);
// shrink hint label before it's off the key
// looks bad, but still better than the alternative
final float ratio = Math.min(1.0f, (keyWidth - hintX) * 0.95f / TypefaceUtils.getStringWidth(hintLabel, paint));
final float autoSize = paint.getTextSize() * ratio;
paint.setTextSize(autoSize);
} else if (key.hasShiftedLetterHint()) { } else if (key.hasShiftedLetterHint()) {
// The hint label is placed at top-right corner of the key. Used mainly on tablet. // The hint label is placed at top-right corner of the key. Used mainly on tablet.
hintX = keyWidth - mKeyShiftedLetterHintPadding - labelCharWidth / 2.0f; hintX = keyWidth - mKeyShiftedLetterHintPadding - labelCharWidth / 2.0f;

View file

@ -61,7 +61,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
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.getDefaultKeyboardWidth(res) + paddingLeft + paddingRight)
val height = (ResourceUtils.getDefaultKeyboardHeight(res) val height = (ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current)
+ res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height) + res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
+ paddingTop + paddingBottom) + paddingTop + paddingBottom)
setMeasuredDimension(width, height) setMeasuredDimension(width, height)

View file

@ -25,7 +25,7 @@ class ClipboardLayoutParams(res: Resources) {
} }
init { init {
val defaultKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res) val defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().current)
val suggestionStripHeight = res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height) val suggestionStripHeight = res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
val defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res) val defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res)

View file

@ -13,6 +13,7 @@ import android.widget.LinearLayout;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
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.settings.SettingsValues;
import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils; import org.dslul.openboard.inputmethod.latin.utils.ResourceUtils;
final class EmojiLayoutParams { final class EmojiLayoutParams {
@ -29,9 +30,10 @@ final class EmojiLayoutParams {
private final int mTopPadding; private final int mTopPadding;
public EmojiLayoutParams(final Resources res) { public EmojiLayoutParams(final Resources res) {
final int defaultKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(res); final SettingsValues settingsValues = Settings.getInstance().getCurrent();
final int defaultKeyboardHeight = ResourceUtils.getKeyboardHeight(res, settingsValues);
final int defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res); final int defaultKeyboardWidth = ResourceUtils.getDefaultKeyboardWidth(res);
if (Settings.getInstance().getCurrent().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);
mKeyHorizontalGap = (int) (res.getFraction(R.fraction.config_key_horizontal_gap_holo_narrow, mKeyHorizontalGap = (int) (res.getFraction(R.fraction.config_key_horizontal_gap_holo_narrow,
@ -42,13 +44,14 @@ final class EmojiLayoutParams {
mKeyHorizontalGap = (int) (res.getFraction(R.fraction.config_key_horizontal_gap_holo, mKeyHorizontalGap = (int) (res.getFraction(R.fraction.config_key_horizontal_gap_holo,
defaultKeyboardWidth, defaultKeyboardWidth)); defaultKeyboardWidth, defaultKeyboardWidth));
} }
mBottomPadding = (int) (res.getFraction(R.fraction.config_keyboard_bottom_padding_holo, final float defaultBottomPadding = res.getFraction(R.fraction.config_keyboard_bottom_padding_holo, defaultKeyboardHeight, defaultKeyboardHeight);
defaultKeyboardHeight, defaultKeyboardHeight) * Settings.getInstance().getCurrent().mBottomPaddingScale); mBottomPadding = (int) (defaultBottomPadding * settingsValues.mBottomPaddingScale);
mTopPadding = (int) res.getFraction(R.fraction.config_keyboard_top_padding_holo, final int paddingScaleOffset = (int) (mBottomPadding - defaultBottomPadding);
defaultKeyboardHeight, defaultKeyboardHeight); 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)); mEmojiCategoryPageIdViewHeight = (int) (res.getDimension(R.dimen.config_emoji_category_page_id_height));
final int baseheight = defaultKeyboardHeight - mBottomPadding - mTopPadding + mKeyVerticalGap; final int baseheight = defaultKeyboardHeight - mBottomPadding - mTopPadding + mKeyVerticalGap;
mEmojiActionBarHeight = baseheight / DEFAULT_KEYBOARD_ROWS - (mKeyVerticalGap - mBottomPadding) / 2; 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; mEmojiListHeight = defaultKeyboardHeight - mEmojiActionBarHeight - mEmojiCategoryPageIdViewHeight;
mEmojiListBottomMargin = 0; mEmojiListBottomMargin = 0;
mEmojiKeyboardHeight = mEmojiListHeight - mEmojiListBottomMargin - 1; mEmojiKeyboardHeight = mEmojiListHeight - mEmojiListBottomMargin - 1;

View file

@ -135,7 +135,7 @@ public final class EmojiPalettesView extends LinearLayout
// 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.getDefaultKeyboardWidth(res)
+ getPaddingLeft() + getPaddingRight(); + getPaddingLeft() + getPaddingRight();
final int height = ResourceUtils.getDefaultKeyboardHeight(res) final int height = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().getCurrent())
+ res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height) + res.getDimensionPixelSize(R.dimen.config_suggestions_strip_height)
+ getPaddingTop() + getPaddingBottom(); + getPaddingTop() + getPaddingBottom();
setMeasuredDimension(width, height); setMeasuredDimension(width, height);

View file

@ -140,7 +140,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> { fun loadFromXml(xmlId: Int, id: KeyboardId): KeyboardBuilder<KP> {
if (Settings.getInstance().current.mUseNewKeyboardParsing) { if (Settings.getInstance().current.mUseNewKeyboardParsing) {
if (id.mElementId >= KeyboardId.ELEMENT_EMOJI_RECENTS && id.mElementId <= KeyboardId.ELEMENT_EMOJI_CATEGORY16) { if (id.isEmojiKeyboard) {
mParams.mId = id mParams.mId = id
readAttributes(R.xml.kbd_emoji_category1) // all the same anyway, gridRows are ignored readAttributes(R.xml.kbd_emoji_category1) // all the same anyway, gridRows are ignored
keysInRows = EmojiParser(mParams, mContext).parse(Settings.getInstance().current.mIsSplitKeyboardEnabled) keysInRows = EmojiParser(mParams, mContext).parse(Settings.getInstance().current.mIsSplitKeyboardEnabled)
@ -222,10 +222,7 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
Log.d(TAG, "setting size and position for ${it.mLabel}, ${it.mCode}: x ${currentX.toInt()}, w ${it.mFullWidth.toInt()}") Log.d(TAG, "setting size and position for ${it.mLabel}, ${it.mCode}: x ${currentX.toInt()}, w ${it.mFullWidth.toInt()}")
currentX += it.mFullWidth currentX += it.mFullWidth
} }
// need to truncate to int here, otherwise it may end up one pixel lower than original currentY += row.first().mFullHeight
// though actually not truncating would be more correct... but that's already an y / height issue somewhere in Key
// todo (later): round, and do the change together with the some thing in Key(KeyParams keyParams)
currentY += row.first().mFullHeight.toInt()
} }
} }
@ -371,8 +368,13 @@ open class KeyboardBuilder<KP : KeyboardParams>(protected val mContext: Context,
mParams.removeRedundantMoreKeys() mParams.removeRedundantMoreKeys()
// {@link #parseGridRows(XmlPullParser,boolean)} may populate keyboard rows higher than // {@link #parseGridRows(XmlPullParser,boolean)} may populate keyboard rows higher than
// previously expected. // previously expected.
// todo (low priority): mCurrentY may end up too high with the new parser and 4 row keyboards in landscape mode
// -> why is this happening?
// but anyway, since the height is resized correctly already, we don't need to adjust the
// occupied height, except for the scrollable emoji keyoards
if (!mParams.mId.isEmojiKeyboard) return
val actualHeight = mCurrentY - mParams.mVerticalGap + mParams.mBottomPadding val actualHeight = mCurrentY - mParams.mVerticalGap + mParams.mBottomPadding
mParams.mOccupiedHeight = Math.max(mParams.mOccupiedHeight, actualHeight) mParams.mOccupiedHeight = mParams.mOccupiedHeight.coerceAtLeast(actualHeight)
} }
private fun addKeysToParams() { private fun addKeysToParams() {

View file

@ -10,6 +10,9 @@ import org.dslul.openboard.inputmethod.keyboard.internal.KeyboardParams
import org.dslul.openboard.inputmethod.latin.R 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 kotlin.math.round
import kotlin.math.sqrt
class EmojiParser(private val params: KeyboardParams, private val context: Context) { class EmojiParser(private val params: KeyboardParams, private val context: Context) {
@ -60,10 +63,18 @@ 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()
val widthScale = getWidthScale()
// extra scale for height only, to undo the effect of number row increasing absolute key height
// todo: with this things look ok, but number row still slightly affects emoji size (which it should not)
val numScale = if (Settings.getInstance().current.mShowsNumberRow) 1.25f else 1f
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.setDimensionsFromRelativeSize(currentX, currentY)
currentX += keyParams.mFullWidth // exact value seems to be not really relevant, but keeping 0 doesn't work keyParams.mFullHeight /= numScale
keyParams.mFullWidth *= widthScale
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
// repeat(spacerNumKeys) { row.add(KeyParams.newSpacer(params, params.mDefaultRelativeKeyWidth)) } // repeat(spacerNumKeys) { row.add(KeyParams.newSpacer(params, params.mDefaultRelativeKeyWidth)) }
@ -72,6 +83,16 @@ 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 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>? {

View file

@ -70,20 +70,14 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
} }
// rescale height if we have more than 4 rows (todo: there is some default row count in params that could be used) // rescale height if we have more than 4 rows (todo: there is some default row count in params that could be used)
val heightRescale = if (keysInRows.size > 4) 4f / keysInRows.size else 1f val heightRescale = if (keysInRows.size > 4) 4f / keysInRows.size else 1f
if (params.mId.mNumberRowEnabled && params.mId.mElementId <= KeyboardId.ELEMENT_SYMBOLS_SHIFTED)
keysInRows.add(0, getNumberRow()) // todo: maybe this should be in createAlphaSymbolRows, but first need to decide height stuff below
if (heightRescale != 1f) { if (heightRescale != 1f) {
// rescale all keys, so number row doesn't look weird (this is done like in current parsing)
// todo: in symbols view, number row is not rescaled
// so the symbols keyboard is higher than the normal one
// not a new issue, but should be solved in this migration
// how? possibly scale all keyboards to height of main alphabet? (consider suggestion strip)
keysInRows.forEach { row -> row.forEach { it.mRelativeHeight *= heightRescale } } keysInRows.forEach { row -> row.forEach { it.mRelativeHeight *= heightRescale } }
} }
return keysInRows return keysInRows
} }
// todo: get rid if the bottom-to-top thing, feels weird (then number row could also be added first)
private fun createAlphaSymbolRows(baseKeys: MutableList<List<KeyData>>): ArrayList<ArrayList<KeyParams>> { private fun createAlphaSymbolRows(baseKeys: MutableList<List<KeyData>>): ArrayList<ArrayList<KeyParams>> {
// number row related modifications of baseKeys // number row related modifications of baseKeys
if (!params.mId.mNumberRowEnabled && params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS) { if (!params.mId.mNumberRowEnabled && params.mId.mElementId == KeyboardId.ELEMENT_SYMBOLS) {
@ -97,7 +91,7 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
) { ) {
// add number to the first 10 keys in first row // add number to the first 10 keys in first row
// setting the correct moreKeys is handled in PopupSet // setting the correct moreKeys is handled in PopupSet
// not for korean/lao/thai layouts, todo: should be decided in the layout, not in the parser // not for korean/lao/thai layouts, todo: should be decided in the layout / layoutInfos, not in the parser
baseKeys.first().take(10).forEachIndexed { index, keyData -> keyData.popup.numberIndex = index } baseKeys.first().take(10).forEachIndexed { index, keyData -> keyData.popup.numberIndex = index }
if (DebugFlags.DEBUG_ENABLED && baseKeys.first().size < 10) { if (DebugFlags.DEBUG_ENABLED && baseKeys.first().size < 10) {
val message = "first row only has ${baseKeys.first().size} keys: ${baseKeys.first().map { it.label }}" val message = "first row only has ${baseKeys.first().size} keys: ${baseKeys.first().map { it.label }}"
@ -192,6 +186,8 @@ abstract class KeyboardParser(private val params: KeyboardParams, private val co
functionalKeysRight.forEach { paramsRow.add(it) } functionalKeysRight.forEach { paramsRow.add(it) }
keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top keysInRows.add(0, paramsRow) // we're doing it backwards, so add on top
} }
if (params.mId.mNumberRowEnabled)
keysInRows.add(0, getNumberRow())
resizeLastNormalRowIfNecessaryForAlignment(keysInRows) resizeLastNormalRowIfNecessaryForAlignment(keysInRows)
return keysInRows return keysInRows
} }

View file

@ -4,9 +4,11 @@ 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.graphics.Color 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.View import android.view.View
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.ImageButton import android.widget.ImageButton
@ -14,6 +16,8 @@ import org.dslul.openboard.inputmethod.keyboard.KeyboardActionListener
import org.dslul.openboard.inputmethod.latin.common.BackgroundType import org.dslul.openboard.inputmethod.latin.common.BackgroundType
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
import org.dslul.openboard.inputmethod.latin.utils.DeviceProtectedUtils
import kotlin.math.abs
class KeyboardWrapperView @JvmOverloads constructor( class KeyboardWrapperView @JvmOverloads constructor(
context: Context, context: Context,
@ -26,8 +30,10 @@ 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 keyboardView: View
private lateinit var resizeOneHandedModeBtn: ImageButton
private val iconStopOneHandedModeId: Int private val iconStopOneHandedModeId: Int
private val iconSwitchOneHandedModeId: Int private val iconSwitchOneHandedModeId: Int
private val iconResizeOneHandedModeId: Int
var oneHandedModeEnabled = false var oneHandedModeEnabled = false
set(enabled) { set(enabled) {
@ -44,6 +50,7 @@ class KeyboardWrapperView @JvmOverloads constructor(
} }
@SuppressLint("ClickableViewAccessibility")
override fun onFinishInflate() { override fun onFinishInflate() {
super.onFinishInflate() super.onFinishInflate()
stopOneHandedModeBtn = findViewById(R.id.btn_stop_one_handed_mode) stopOneHandedModeBtn = findViewById(R.id.btn_stop_one_handed_mode)
@ -52,11 +59,41 @@ class KeyboardWrapperView @JvmOverloads constructor(
switchOneHandedModeBtn = findViewById(R.id.btn_switch_one_handed_mode) switchOneHandedModeBtn = findViewById(R.id.btn_switch_one_handed_mode)
switchOneHandedModeBtn.setImageResource(iconSwitchOneHandedModeId) switchOneHandedModeBtn.setImageResource(iconSwitchOneHandedModeId)
switchOneHandedModeBtn.visibility = GONE switchOneHandedModeBtn.visibility = GONE
resizeOneHandedModeBtn = findViewById(R.id.btn_resize_one_handed_mode)
resizeOneHandedModeBtn.setImageResource(iconResizeOneHandedModeId)
resizeOneHandedModeBtn.visibility = GONE
keyboardView = findViewById(R.id.keyboard_view) keyboardView = findViewById(R.id.keyboard_view)
stopOneHandedModeBtn.setOnClickListener(this) stopOneHandedModeBtn.setOnClickListener(this)
switchOneHandedModeBtn.setOnClickListener(this) switchOneHandedModeBtn.setOnClickListener(this)
var x = 0f
resizeOneHandedModeBtn.setOnTouchListener { _, motionEvent ->
when (motionEvent.action) {
MotionEvent.ACTION_DOWN -> x = motionEvent.rawX
MotionEvent.ACTION_MOVE -> {
// performance is not great because settings are reloaded and keyboard is redrawn
// on every move, but it's good enough
val sign = -switchOneHandedModeBtn.scaleX
// factor 2 to make it more sensitive (maybe could be tuned a little)
val changePercent = 2 * sign * (x - motionEvent.rawX) / context.resources.displayMetrics.density
if (abs(changePercent) < 1) return@setOnTouchListener true
x = motionEvent.rawX
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
val oldScale = Settings.readOneHandedModeScale(prefs, Settings.getInstance().current.mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT)
val newScale = (oldScale + changePercent / 100f).coerceAtMost(2.5f).coerceAtLeast(0.5f)
if (newScale == oldScale) return@setOnTouchListener true
Settings.getInstance().writeOneHandedModeScale(newScale)
prefs.edit().putFloat(Settings.PREF_ONE_HANDED_SCALE, newScale).apply()
oneHandedModeEnabled = false // intentionally putting wrong value, so KeyboardSwitcher.setOneHandedModeEnabled does actually reload
keyboardActionListener?.onCodeInput(Constants.CODE_START_ONE_HANDED_MODE,
Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
}
else -> x = 0f
}
true
}
val colors = Settings.getInstance().current.mColors val colors = Settings.getInstance().current.mColors
stopOneHandedModeBtn.colorFilter = colors.keyTextFilter stopOneHandedModeBtn.colorFilter = colors.keyTextFilter
switchOneHandedModeBtn.colorFilter = colors.keyTextFilter switchOneHandedModeBtn.colorFilter = colors.keyTextFilter
@ -74,6 +111,7 @@ class KeyboardWrapperView @JvmOverloads constructor(
private fun updateViewsVisibility() { private fun updateViewsVisibility() {
stopOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE stopOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE
switchOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE switchOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE
resizeOneHandedModeBtn.visibility = if (oneHandedModeEnabled) VISIBLE else GONE
} }
@SuppressLint("RtlHardcoded") @SuppressLint("RtlHardcoded")
@ -114,21 +152,17 @@ class KeyboardWrapperView @JvmOverloads constructor(
val scale = Settings.getInstance().current.mKeyboardHeightScale val scale = Settings.getInstance().current.mKeyboardHeightScale
// scale one-handed mode button height if keyboard height scale is < 80% // scale one-handed mode button height if keyboard height scale is < 80%
// more relevant: also change the distance, so the buttons are actually visible
val heightScale = if (scale < 0.8f) scale + 0.2f else 1f val heightScale = if (scale < 0.8f) scale + 0.2f else 1f
val buttonsLeft = if (isLeftGravity) keyboardView.measuredWidth else 0 val buttonsLeft = if (isLeftGravity) keyboardView.measuredWidth else 0
stopOneHandedModeBtn.layout( val buttonXLeft = buttonsLeft + (spareWidth - stopOneHandedModeBtn.measuredWidth) / 2
buttonsLeft + (spareWidth - stopOneHandedModeBtn.measuredWidth) / 2, val buttonXRight = buttonsLeft + (spareWidth + stopOneHandedModeBtn.measuredWidth) / 2
(heightScale * stopOneHandedModeBtn.measuredHeight / 2).toInt(), val buttonHeight = (heightScale * stopOneHandedModeBtn.measuredHeight).toInt()
buttonsLeft + (spareWidth + stopOneHandedModeBtn.measuredWidth) / 2, fun View.setLayout(yPosition: Int) {
(heightScale * 3 * stopOneHandedModeBtn.measuredHeight / 2).toInt() layout(buttonXLeft, yPosition - buttonHeight / 2, buttonXRight, yPosition + buttonHeight / 2)
) }
switchOneHandedModeBtn.layout( stopOneHandedModeBtn.setLayout((keyboardView.measuredHeight * 0.2f).toInt())
buttonsLeft + (spareWidth - switchOneHandedModeBtn.measuredWidth) / 2, switchOneHandedModeBtn.setLayout((keyboardView.measuredHeight * 0.5f).toInt())
(heightScale * 2 * stopOneHandedModeBtn.measuredHeight).toInt(), resizeOneHandedModeBtn.setLayout((keyboardView.measuredHeight * 0.8f).toInt())
buttonsLeft + (spareWidth + switchOneHandedModeBtn.measuredWidth) / 2,
(heightScale * (2 * stopOneHandedModeBtn.measuredHeight + switchOneHandedModeBtn.measuredHeight)).toInt()
)
} }
init { init {
@ -136,6 +170,7 @@ class KeyboardWrapperView @JvmOverloads constructor(
val keyboardAttr = context.obtainStyledAttributes(attrs, R.styleable.Keyboard, defStyle, R.style.Keyboard) val keyboardAttr = context.obtainStyledAttributes(attrs, R.styleable.Keyboard, defStyle, R.style.Keyboard)
iconStopOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconStopOneHandedMode, 0) iconStopOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconStopOneHandedMode, 0)
iconSwitchOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconSwitchOneHandedMode, 0) iconSwitchOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconSwitchOneHandedMode, 0)
iconResizeOneHandedModeId = keyboardAttr.getResourceId(R.styleable.Keyboard_iconResizeOneHandedMode, 0)
keyboardAttr.recycle() keyboardAttr.recycle()
} }
} }

View file

@ -78,7 +78,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment {
@Override @Override
public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) { public void onSharedPreferenceChanged(final SharedPreferences prefs, final String key) {
refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings(); refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings();
if (Settings.PREF_SHOW_POPUP_HINTS.equals(key) || Settings.PREF_HINT_LABEL_FROM_FIRST_MORE_KEY.equals(key)) if (Settings.PREF_SHOW_POPUP_HINTS.equals(key) || Settings.PREF_HINT_LABEL_FROM_FIRST_MORE_KEY.equals(key) || Settings.PREF_SHOW_NUMBER_ROW.equals(key))
mReloadKeyboard = true; mReloadKeyboard = true;
if (key.equals(Settings.PREF_LOCALIZED_NUMBER_ROW)) if (key.equals(Settings.PREF_LOCALIZED_NUMBER_ROW))
KeyboardLayoutSet.onSystemLocaleChanged(); KeyboardLayoutSet.onSystemLocaleChanged();

View file

@ -105,8 +105,9 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon"; public static final String PREF_SHOW_SETUP_WIZARD_ICON = "pref_show_setup_wizard_icon";
public static final String PREF_USE_NEW_KEYBOARD_PARSING = "pref_use_new_keyboard_parsing2"; // todo: remove later public static final String PREF_USE_NEW_KEYBOARD_PARSING = "pref_use_new_keyboard_parsing2"; // todo: remove later
public static final String PREF_ONE_HANDED_MODE = "pref_one_handed_mode_enabled"; public static final String PREF_ONE_HANDED_MODE = "pref_one_handed_mode_enabled_p_";
public static final String PREF_ONE_HANDED_GRAVITY = "pref_one_handed_mode_gravity"; public static final String PREF_ONE_HANDED_GRAVITY = "pref_one_handed_mode_gravity_p_";
public static final String PREF_ONE_HANDED_SCALE = "pref_one_handed_mode_scale_p_";
public static final String PREF_SHOW_NUMBER_ROW = "pref_show_number_row"; public static final String PREF_SHOW_NUMBER_ROW = "pref_show_number_row";
public static final String PREF_LOCALIZED_NUMBER_ROW = "pref_localized_number_row"; public static final String PREF_LOCALIZED_NUMBER_ROW = "pref_localized_number_row";
@ -393,21 +394,29 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false); return prefs.getBoolean(PREF_SHOW_SETUP_WIZARD_ICON, false);
} }
public static boolean readOneHandedModeEnabled(final SharedPreferences prefs) { public static boolean readOneHandedModeEnabled(final SharedPreferences prefs, final boolean portrait) {
return prefs.getBoolean(PREF_ONE_HANDED_MODE, false); return prefs.getBoolean(PREF_ONE_HANDED_MODE + portrait, false);
} }
public void writeOneHandedModeEnabled(final boolean enabled) { public void writeOneHandedModeEnabled(final boolean enabled) {
mPrefs.edit().putBoolean(PREF_ONE_HANDED_MODE, enabled).apply(); mPrefs.edit().putBoolean(PREF_ONE_HANDED_MODE + (getCurrent().mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT), enabled).apply();
}
public static float readOneHandedModeScale(final SharedPreferences prefs, final boolean portrait) {
return prefs.getFloat(PREF_ONE_HANDED_SCALE + portrait, 1f);
}
public void writeOneHandedModeScale(final Float scale) {
mPrefs.edit().putFloat(PREF_ONE_HANDED_SCALE + (getCurrent().mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT), scale).apply();
} }
@SuppressLint("RtlHardcoded") @SuppressLint("RtlHardcoded")
public static int readOneHandedModeGravity(final SharedPreferences prefs) { public static int readOneHandedModeGravity(final SharedPreferences prefs, final boolean portrait) {
return prefs.getInt(PREF_ONE_HANDED_GRAVITY, Gravity.LEFT); return prefs.getInt(PREF_ONE_HANDED_GRAVITY + portrait, Gravity.LEFT);
} }
public void writeOneHandedModeGravity(final int gravity) { public void writeOneHandedModeGravity(final int gravity) {
mPrefs.edit().putInt(PREF_ONE_HANDED_GRAVITY, gravity).apply(); mPrefs.edit().putInt(PREF_ONE_HANDED_GRAVITY + (getCurrent().mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT), gravity).apply();
} }
public static boolean readHasHardwareKeyboard(final Configuration conf) { public static boolean readHasHardwareKeyboard(final Configuration conf) {

View file

@ -81,6 +81,7 @@ public class SettingsValues {
public final long mClipboardHistoryRetentionTime; public final long mClipboardHistoryRetentionTime;
public final boolean mOneHandedModeEnabled; public final boolean mOneHandedModeEnabled;
public final int mOneHandedModeGravity; public final int mOneHandedModeGravity;
public final float mOneHandedModeScale;
public final boolean mNarrowKeyGaps; public final boolean mNarrowKeyGaps;
public final int mShowMoreKeys; public final int mShowMoreKeys;
public final List<Locale> mSecondaryLocales; public final List<Locale> mSecondaryLocales;
@ -217,8 +218,15 @@ public class SettingsValues {
mAutospaceAfterPunctuationEnabled = Settings.readAutospaceAfterPunctuationEnabled(prefs); mAutospaceAfterPunctuationEnabled = Settings.readAutospaceAfterPunctuationEnabled(prefs);
mClipboardHistoryEnabled = Settings.readClipboardHistoryEnabled(prefs); mClipboardHistoryEnabled = Settings.readClipboardHistoryEnabled(prefs);
mClipboardHistoryRetentionTime = Settings.readClipboardHistoryRetentionTime(prefs, res); mClipboardHistoryRetentionTime = Settings.readClipboardHistoryRetentionTime(prefs, res);
mOneHandedModeEnabled = Settings.readOneHandedModeEnabled(prefs);
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs); mOneHandedModeEnabled = Settings.readOneHandedModeEnabled(prefs, mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT);
mOneHandedModeGravity = Settings.readOneHandedModeGravity(prefs, mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT);
if (mOneHandedModeEnabled) {
final float baseScale = res.getFraction(R.fraction.config_one_handed_mode_width, 1, 1);
final float extraScale = Settings.readOneHandedModeScale(prefs, mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT);
mOneHandedModeScale = 1 - (1 - baseScale) * extraScale;
} else
mOneHandedModeScale = 1f;
final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs); final InputMethodSubtype selectedSubtype = SubtypeSettingsKt.getSelectedSubtype(prefs);
mSecondaryLocales = Settings.getSecondaryLocales(prefs, selectedSubtype.getLocale()); mSecondaryLocales = Settings.getSecondaryLocales(prefs, selectedSubtype.getLocale());
mShowMoreKeys = selectedSubtype.isAsciiCapable() mShowMoreKeys = selectedSubtype.isAsciiCapable()

View file

@ -176,8 +176,7 @@ public final class ResourceUtils {
public static int getKeyboardWidth(final Resources res, final SettingsValues settingsValues) { public static int getKeyboardWidth(final Resources res, final SettingsValues settingsValues) {
final int defaultKeyboardWidth = getDefaultKeyboardWidth(res); final int defaultKeyboardWidth = getDefaultKeyboardWidth(res);
if (settingsValues.mOneHandedModeEnabled) { if (settingsValues.mOneHandedModeEnabled) {
return (int) res.getFraction(R.fraction.config_one_handed_mode_width, return (int) (settingsValues.mOneHandedModeScale * defaultKeyboardWidth);
defaultKeyboardWidth, defaultKeyboardWidth);
} }
return defaultKeyboardWidth; return defaultKeyboardWidth;
} }
@ -188,14 +187,14 @@ public final class ResourceUtils {
} }
public static int getKeyboardHeight(final Resources res, final SettingsValues settingsValues) { public static int getKeyboardHeight(final Resources res, final SettingsValues settingsValues) {
final int defaultKeyboardHeight = getDefaultKeyboardHeight(res); final int defaultKeyboardHeight = getDefaultKeyboardHeight(res, settingsValues.mShowsNumberRow);
// mKeyboardHeightScale Ranges from [.5,1.5], from xml/prefs_screen_appearance.xml // mKeyboardHeightScale Ranges from [.5,1.5], from xml/prefs_screen_appearance.xml
return (int)(defaultKeyboardHeight * settingsValues.mKeyboardHeightScale); return (int)(defaultKeyboardHeight * settingsValues.mKeyboardHeightScale);
} }
public static int getDefaultKeyboardHeight(final Resources res) { private 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); 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(
R.fraction.config_max_keyboard_height, dm.heightPixels, dm.heightPixels); R.fraction.config_max_keyboard_height, dm.heightPixels, dm.heightPixels);
float minKeyboardHeight = res.getFraction( float minKeyboardHeight = res.getFraction(

View file

@ -0,0 +1,15 @@
<!--
icon available in Android Studio
modified
SPDX-License-Identifier: Apache-2.0
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
android:width="24dp"
android:viewportHeight="24"
android:viewportWidth="24">
<group android:rotation="90" android:pivotX="12" android:pivotY="12" >
<path android:fillColor="#FFF"
android:pathData="M13,6.99l3,0l-4,-3.99l-4,3.99l3,0l0,10.02l-3,0l4,3.99l4,-3.99l-3,0z"/>
</group>
</vector>

View file

@ -52,6 +52,14 @@
android:scaleType="fitCenter" android:scaleType="fitCenter"
style="?attr/suggestionWordStyle" /> style="?attr/suggestionWordStyle" />
<ImageButton
android:id="@+id/btn_resize_one_handed_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
android:scaleType="fitCenter"
style="?attr/suggestionWordStyle" />
</org.dslul.openboard.inputmethod.latin.KeyboardWrapperView> </org.dslul.openboard.inputmethod.latin.KeyboardWrapperView>
</LinearLayout> </LinearLayout>

View file

@ -24,8 +24,8 @@
<fraction name="config_keyboard_bottom_padding_holo">0.0%p</fraction> <fraction name="config_keyboard_bottom_padding_holo">0.0%p</fraction>
<fraction name="config_key_vertical_gap_holo">5.368%p</fraction> <fraction name="config_key_vertical_gap_holo">5.368%p</fraction>
<fraction name="config_key_horizontal_gap_holo">1.020%p</fraction> <fraction name="config_key_horizontal_gap_holo">1.020%p</fraction>
<fraction name="config_key_vertical_gap_holo_narrow">5.368%p</fraction> <fraction name="config_key_vertical_gap_holo_narrow">4.85%p</fraction>
<fraction name="config_key_horizontal_gap_holo_narrow">1.020%p</fraction> <fraction name="config_key_horizontal_gap_holo_narrow">0.920%p</fraction>
<!-- config_more_keys_keyboard_key_height x -0.5 --> <!-- config_more_keys_keyboard_key_height x -0.5 -->
<dimen name="config_more_keys_keyboard_vertical_correction_holo">-22.4dp</dimen> <dimen name="config_more_keys_keyboard_vertical_correction_holo">-22.4dp</dimen>
<dimen name="config_key_preview_offset_holo">1.6dp</dimen> <dimen name="config_key_preview_offset_holo">1.6dp</dimen>
@ -67,9 +67,9 @@
<!-- Emoji keyboard --> <!-- Emoji keyboard -->
<fraction name="config_emoji_keyboard_key_width">8.33%p</fraction> <fraction name="config_emoji_keyboard_key_width">8.33%p</fraction>
<fraction name="config_emoji_keyboard_row_height">40%p</fraction> <fraction name="config_emoji_keyboard_row_height">41%p</fraction>
<fraction name="config_emoji_keyboard_key_letter_size">70%p</fraction> <fraction name="config_emoji_keyboard_key_letter_size">78%p</fraction>
<fraction name="config_emoji_keyboard_key_label_size">70%p</fraction> <fraction name="config_emoji_keyboard_key_label_size">78%p</fraction>
<integer name="config_emoji_keyboard_max_recents_key_count">32</integer> <integer name="config_emoji_keyboard_max_recents_key_count">32</integer>
<!-- Clipboard keyboard --> <!-- Clipboard keyboard -->

View file

@ -271,6 +271,7 @@
<attr name="iconStartOneHandedMode" format="reference" /> <attr name="iconStartOneHandedMode" format="reference" />
<attr name="iconStopOneHandedMode" format="reference" /> <attr name="iconStopOneHandedMode" format="reference" />
<attr name="iconSwitchOneHandedMode" format="reference" /> <attr name="iconSwitchOneHandedMode" format="reference" />
<attr name="iconResizeOneHandedMode" format="reference" />
<attr name="iconNumpadKey" format="reference" /> <attr name="iconNumpadKey" format="reference" />
<attr name="iconToolbarKey" format="reference" /> <attr name="iconToolbarKey" format="reference" />
<attr name="iconSelectAll" format="reference" /> <attr name="iconSelectAll" format="reference" />

View file

@ -32,6 +32,7 @@
<item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_holo</item> <item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_holo</item>
<item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_holo</item> <item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_holo</item>
<item name="iconSwitchOneHandedMode">@drawable/sym_keyboard_switch_onehanded_holo</item> <item name="iconSwitchOneHandedMode">@drawable/sym_keyboard_switch_onehanded_holo</item>
<item name="iconResizeOneHandedMode">@drawable/ic_arrow_horizontal</item>
<item name="iconNumpadKey">@drawable/sym_keyboard_numpad_key_holo</item> <item name="iconNumpadKey">@drawable/sym_keyboard_numpad_key_holo</item>
<item name="iconToolbarKey">@drawable/ic_arrow_right</item> <item name="iconToolbarKey">@drawable/ic_arrow_right</item>
<item name="iconSelectAll">@drawable/ic_select_all</item> <item name="iconSelectAll">@drawable/ic_select_all</item>

View file

@ -37,6 +37,7 @@
<item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_lxx</item> <item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_lxx</item>
<item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_lxx</item> <item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_lxx</item>
<item name="iconSwitchOneHandedMode">@drawable/ic_arrow_left</item> <item name="iconSwitchOneHandedMode">@drawable/ic_arrow_left</item>
<item name="iconResizeOneHandedMode">@drawable/ic_arrow_horizontal</item>
<item name="iconNumpadKey">@drawable/sym_keyboard_numpad_key_lxx</item> <item name="iconNumpadKey">@drawable/sym_keyboard_numpad_key_lxx</item>
<item name="iconToolbarKey">@drawable/ic_arrow_right</item> <item name="iconToolbarKey">@drawable/ic_arrow_right</item>
<item name="iconSelectAll">@drawable/ic_select_all</item> <item name="iconSelectAll">@drawable/ic_select_all</item>

View file

@ -36,6 +36,7 @@
<item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_rounded</item> <item name="iconStartOneHandedMode">@drawable/sym_keyboard_start_onehanded_rounded</item>
<item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_rounded</item> <item name="iconStopOneHandedMode">@drawable/sym_keyboard_stop_onehanded_rounded</item>
<item name="iconSwitchOneHandedMode">@drawable/ic_arrow_left_rounded</item> <item name="iconSwitchOneHandedMode">@drawable/ic_arrow_left_rounded</item>
<item name="iconResizeOneHandedMode">@drawable/ic_arrow_horizontal</item>
<item name="iconNumpadKey">@drawable/sym_keyboard_numpad_key_lxx</item> <item name="iconNumpadKey">@drawable/sym_keyboard_numpad_key_lxx</item>
<item name="iconToolbarKey">@drawable/ic_arrow_right_rounded</item> <item name="iconToolbarKey">@drawable/ic_arrow_right_rounded</item>
<item name="iconSelectAll">@drawable/ic_select_all_rounded</item> <item name="iconSelectAll">@drawable/ic_select_all_rounded</item>