mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-21 22:59:10 +00:00
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:
parent
e78618fd6a
commit
0b55a92e02
22 changed files with 184 additions and 68 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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>? {
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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(
|
||||||
|
|
15
app/src/main/res/drawable/ic_arrow_horizontal.xml
Normal file
15
app/src/main/res/drawable/ic_arrow_horizontal.xml
Normal 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>
|
|
@ -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>
|
||||||
|
|
|
@ -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 -->
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Reference in a new issue