From f45f69f8a2639d91992bce6aa7c16a2d4b59f4c8 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 09:10:07 +0100 Subject: [PATCH 01/18] add setting for adjusting bottom padding in landscape mode fixes some issue I can't currently find slight issue: will remove the bottom padding on large tables (sw768-land), users need to get it back by switching to 100% --- .../keyboard/latin/settings/AppearanceSettingsFragment.kt | 1 + .../java/helium314/keyboard/latin/settings/Settings.java | 7 +++++++ .../helium314/keyboard/latin/settings/SettingsValues.java | 2 +- app/src/main/res/values-land/config.xml | 2 +- app/src/main/res/values-sw600dp-land/config.xml | 2 +- app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/prefs_screen_appearance.xml | 7 +++++++ 7 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt index 93d3b0f51..fa9614f31 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt @@ -105,6 +105,7 @@ class AppearanceSettingsFragment : SubScreenFragment() { setupScalePrefs(Settings.PREF_KEYBOARD_HEIGHT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) setupScalePrefs(Settings.PREF_BOTTOM_PADDING_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) + setupScalePrefs(Settings.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE, 0f) if (splitScalePref != null) { setupScalePrefs(Settings.PREF_SPLIT_SPACER_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) splitScalePref?.isVisible = splitPref?.isChecked == true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 446a3f0ca..8f67ddc11 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -112,6 +112,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_SPLIT_SPACER_SCALE = "split_spacer_scale"; public static final String PREF_KEYBOARD_HEIGHT_SCALE = "keyboard_height_scale"; public static final String PREF_BOTTOM_PADDING_SCALE = "bottom_padding_scale"; + public static final String PREF_BOTTOM_PADDING_SCALE_LANDSCAPE = "bottom_padding_scale_landscape"; public static final String PREF_SPACE_HORIZONTAL_SWIPE = "horizontal_space_swipe"; public static final String PREF_SPACE_VERTICAL_SWIPE = "vertical_space_swipe"; public static final String PREF_DELETE_SWIPE = "delete_swipe"; @@ -499,6 +500,12 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang (getCurrent().mDisplayOrientation == Configuration.ORIENTATION_PORTRAIT), gravity).apply(); } + public static float readBottomPaddingScale(final SharedPreferences prefs, final boolean landscape) { + if (landscape) + return prefs.getFloat(PREF_BOTTOM_PADDING_SCALE_LANDSCAPE, 0f); + return prefs.getFloat(PREF_BOTTOM_PADDING_SCALE, SettingsValues.DEFAULT_SIZE_SCALE); + } + public static boolean readHasHardwareKeyboard(final Configuration conf) { // The standard way of finding out whether we have a hardware keyboard. This code is taken // from InputMethodService#onEvaluateInputShown, which canonically determines this. diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index eae7b375f..0a312633b 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -262,7 +262,7 @@ public class SettingsValues { prefs.getBoolean(Settings.PREF_GESTURE_SPACE_AWARE, false) ); mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled); - mBottomPaddingScale = prefs.getFloat(Settings.PREF_BOTTOM_PADDING_SCALE, DEFAULT_SIZE_SCALE); + mBottomPaddingScale = Settings.readBottomPaddingScale(prefs, mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE); mLongPressSymbolsForNumpad = prefs.getBoolean(Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, false); mAutoShowToolbar = prefs.getBoolean(Settings.PREF_AUTO_SHOW_TOOLBAR, false); mAutoHideToolbar = readSuggestionsEnabled(prefs) && prefs.getBoolean(Settings.PREF_AUTO_HIDE_TOOLBAR, false); diff --git a/app/src/main/res/values-land/config.xml b/app/src/main/res/values-land/config.xml index cde49ee1b..e1d909847 100644 --- a/app/src/main/res/values-land/config.xml +++ b/app/src/main/res/values-land/config.xml @@ -21,7 +21,7 @@ 53.76dp 2.727%p - 0.0%p + 2.5%p 5.368%p 1.020%p 4.85%p diff --git a/app/src/main/res/values-sw600dp-land/config.xml b/app/src/main/res/values-sw600dp-land/config.xml index 9d00149e4..448b73c0e 100644 --- a/app/src/main/res/values-sw600dp-land/config.xml +++ b/app/src/main/res/values-sw600dp-land/config.xml @@ -15,7 +15,7 @@ 81.9dp 2.727%p - 0.0%p + 2.0%p 4.5%p 0.9%p 4.5%p diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 322cadd77..a5c94bdf1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -311,6 +311,8 @@ Keyboard height scale Bottom padding scale + + Bottom padding scale (landscape) Custom text on space bar diff --git a/app/src/main/res/xml/prefs_screen_appearance.xml b/app/src/main/res/xml/prefs_screen_appearance.xml index e02f3702f..1590619cf 100644 --- a/app/src/main/res/xml/prefs_screen_appearance.xml +++ b/app/src/main/res/xml/prefs_screen_appearance.xml @@ -111,6 +111,13 @@ latin:minValue="0" latin:maxValue="500" /> + + Date: Sun, 26 Jan 2025 09:27:48 +0100 Subject: [PATCH 02/18] add font scale setting (separat for emoji view, because here it feels different) fixes #1149 --- .../helium314/keyboard/keyboard/KeyboardView.java | 10 +++++++--- .../keyboard/keyboard/MainKeyboardView.java | 3 ++- .../keyboard/keyboard/internal/KeyPreviewView.java | 4 ++-- .../latin/settings/AppearanceSettingsFragment.kt | 2 ++ .../helium314/keyboard/latin/settings/Settings.java | 2 ++ .../keyboard/latin/settings/SettingsValues.java | 4 ++++ app/src/main/res/values/strings.xml | 4 ++++ app/src/main/res/xml/prefs_screen_appearance.xml | 12 ++++++++++++ 8 files changed, 35 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java index 5e39d1665..d374dac6d 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java @@ -65,6 +65,7 @@ public class KeyboardView extends View { private static final float KET_TEXT_SHADOW_RADIUS_DISABLED = -1.0f; private final Colors mColors; private float mKeyScaleForText; + protected float mFontSizeMultiplier; // The maximum key label width in the proportion to the key width. private static final float MAX_LABEL_RATIO = 0.90f; @@ -189,6 +190,9 @@ public class KeyboardView extends View { mKeyDrawParams.updateParams(scaledKeyHeight, keyboard.mKeyVisualAttributes); invalidateAllKeys(); requestLayout(); + mFontSizeMultiplier = mKeyboard.mId.isEmojiKeyboard() + ? Settings.getInstance().getCurrent().mFontSizeMultiplierEmoji + : Settings.getInstance().getCurrent().mFontSizeMultiplier; } /** @@ -384,7 +388,7 @@ public class KeyboardView extends View { final String label = key.getLabel(); if (label != null) { paint.setTypeface(mTypeface == null ? key.selectTypeface(params) : mTypeface); - paint.setTextSize(key.selectTextSize(params)); + paint.setTextSize(key.selectTextSize(params) * mFontSizeMultiplier); final float labelCharHeight = TypefaceUtils.getReferenceCharHeight(paint); final float labelCharWidth = TypefaceUtils.getReferenceCharWidth(paint); @@ -446,7 +450,7 @@ public class KeyboardView extends View { // Draw hint label. final String hintLabel = key.getHintLabel(); if (hintLabel != null && mShowsHints) { - paint.setTextSize(key.selectHintTextSize(params)); + paint.setTextSize(key.selectHintTextSize(params) * mFontSizeMultiplier); // maybe take sqrt to not have such extreme changes? paint.setColor(key.selectHintTextColor(params)); // TODO: Should add a way to specify type face for hint letters paint.setTypeface(Typeface.DEFAULT_BOLD); @@ -561,7 +565,7 @@ public class KeyboardView extends View { } else { paint.setColor(key.selectTextColor(mKeyDrawParams)); paint.setTypeface(key.selectTypeface(mKeyDrawParams)); - paint.setTextSize(key.selectTextSize(mKeyDrawParams)); + paint.setTextSize(key.selectTextSize(mKeyDrawParams) * mFontSizeMultiplier); } return paint; } diff --git a/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java index c004822b3..fddc64d57 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java @@ -164,7 +164,8 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy mBackgroundDimAlphaPaint.setColor(Color.BLACK); mBackgroundDimAlphaPaint.setAlpha(backgroundDimAlpha); mLanguageOnSpacebarTextRatio = mainKeyboardViewAttr.getFraction( - R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f); + R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f) + * Settings.getInstance().getCurrent().mFontSizeMultiplier; final Colors colors = Settings.getInstance().getCurrent().mColors; mLanguageOnSpacebarTextColor = colors.get(ColorType.SPACE_BAR_TEXT); mLanguageOnSpacebarTextShadowRadius = mainKeyboardViewAttr.getFloat( diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java index f1d75986d..94ad2cc5c 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java @@ -57,8 +57,8 @@ public class KeyPreviewView extends AppCompatTextView { setCompoundDrawables(null, null, null, null); setTextColor(drawParams.mPreviewTextColor); - setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectPreviewTextSize(drawParams)); - // wie hier machen? + setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectPreviewTextSize(drawParams) + * Settings.getInstance().getCurrent().mFontSizeMultiplier); setTypeface(mTypeface == null ? key.selectPreviewTypeface(drawParams) : mTypeface); // TODO Should take care of temporaryShiftLabel here. setTextAndScaleX(key.getPreviewLabel()); diff --git a/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt index fa9614f31..aa990648d 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt @@ -106,6 +106,8 @@ class AppearanceSettingsFragment : SubScreenFragment() { setupScalePrefs(Settings.PREF_KEYBOARD_HEIGHT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) setupScalePrefs(Settings.PREF_BOTTOM_PADDING_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) setupScalePrefs(Settings.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE, 0f) + setupScalePrefs(Settings.PREF_FONT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) + setupScalePrefs(Settings.PREF_EMOJI_FONT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) if (splitScalePref != null) { setupScalePrefs(Settings.PREF_SPLIT_SPACER_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) splitScalePref?.isVisible = splitPref?.isChecked == true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 8f67ddc11..0db33ad1f 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -113,6 +113,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_KEYBOARD_HEIGHT_SCALE = "keyboard_height_scale"; public static final String PREF_BOTTOM_PADDING_SCALE = "bottom_padding_scale"; public static final String PREF_BOTTOM_PADDING_SCALE_LANDSCAPE = "bottom_padding_scale_landscape"; + public static final String PREF_FONT_SCALE = "font_scale"; + public static final String PREF_EMOJI_FONT_SCALE = "emoji_font_scale"; public static final String PREF_SPACE_HORIZONTAL_SWIPE = "horizontal_space_swipe"; public static final String PREF_SPACE_VERTICAL_SWIPE = "vertical_space_swipe"; public static final String PREF_DELETE_SWIPE = "delete_swipe"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 0a312633b..c89761655 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -120,6 +120,8 @@ public class SettingsValues { public final boolean mAlphaAfterSymbolAndSpace; public final boolean mRemoveRedundantPopups; public final String mSpaceBarText; + public final float mFontSizeMultiplier; + public final float mFontSizeMultiplierEmoji; // From the input box @NonNull @@ -273,6 +275,8 @@ public class SettingsValues { mRemoveRedundantPopups = prefs.getBoolean(Settings.PREF_REMOVE_REDUNDANT_POPUPS, false); mSpaceBarText = prefs.getString(Settings.PREF_SPACE_BAR_TEXT, ""); mEmojiMaxSdk = prefs.getInt(Settings.PREF_EMOJI_MAX_SDK, Build.VERSION.SDK_INT); + mFontSizeMultiplier = prefs.getFloat(Settings.PREF_FONT_SCALE, DEFAULT_SIZE_SCALE); + mFontSizeMultiplierEmoji = prefs.getFloat(Settings.PREF_EMOJI_FONT_SCALE, DEFAULT_SIZE_SCALE); } public boolean isApplicationSpecifiedCompletionsOn() { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a5c94bdf1..43b0a3514 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -313,6 +313,10 @@ Bottom padding scale Bottom padding scale (landscape) + + Keyboard font scale + + Emoji view font scale Custom text on space bar diff --git a/app/src/main/res/xml/prefs_screen_appearance.xml b/app/src/main/res/xml/prefs_screen_appearance.xml index 1590619cf..d30b97aee 100644 --- a/app/src/main/res/xml/prefs_screen_appearance.xml +++ b/app/src/main/res/xml/prefs_screen_appearance.xml @@ -130,6 +130,18 @@ android:defaultValue="" android:persistent="true" /> + + + + From 5afb1e3a0c0aa4d9b4d3f915df8f1f6a2417c1a7 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 09:31:32 +0100 Subject: [PATCH 03/18] use custom font also for hint labels, fixes #1323 --- app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java index d374dac6d..ffcb9e2d6 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java @@ -453,7 +453,7 @@ public class KeyboardView extends View { paint.setTextSize(key.selectHintTextSize(params) * mFontSizeMultiplier); // maybe take sqrt to not have such extreme changes? paint.setColor(key.selectHintTextColor(params)); // TODO: Should add a way to specify type face for hint letters - paint.setTypeface(Typeface.DEFAULT_BOLD); + paint.setTypeface(mTypeface == null ? Typeface.DEFAULT_BOLD : mTypeface); blendAlpha(paint, params.mAnimAlpha); final float labelCharHeight = TypefaceUtils.getReferenceCharHeight(paint); final float labelCharWidth = TypefaceUtils.getReferenceCharWidth(paint); From 419c0d847b4ce6943cace7150c4db3b7f54eaa34 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 09:48:21 +0100 Subject: [PATCH 04/18] switch from start / stop one-handed mode key codes to a toggle code mainly so there is no awkward state-dependent key code on the toolbar key --- .../keyboard/keyboard/internal/KeyboardCodesSet.java | 10 ++++++---- .../keyboard/keyboard/internal/KeyboardState.java | 6 ++---- .../internal/keyboard_parser/floris/KeyCode.kt | 7 ++++--- .../internal/keyboard_parser/floris/TextKeyData.kt | 2 +- .../helium314/keyboard/latin/KeyboardWrapperView.kt | 5 ++--- .../helium314/keyboard/latin/common/Constants.java | 3 +-- .../keyboard/latin/inputlogic/InputLogic.java | 2 +- .../helium314/keyboard/latin/utils/ToolbarUtils.kt | 2 +- 8 files changed, 18 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardCodesSet.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardCodesSet.java index 7c21f1542..7671784e0 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardCodesSet.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardCodesSet.java @@ -52,8 +52,9 @@ public final class KeyboardCodesSet { "key_emoji", "key_unspecified", "key_clipboard", - "key_start_onehanded", - "key_stop_onehanded", + "key_toggle_onehanded", + "key_start_onehanded", // keep name to avoid breaking custom layouts + "key_stop_onehanded", // keep name to avoid breaking custom layouts "key_switch_onehanded" }; @@ -77,8 +78,9 @@ public final class KeyboardCodesSet { KeyCode.EMOJI, KeyCode.NOT_SPECIFIED, KeyCode.CLIPBOARD, - KeyCode.START_ONE_HANDED_MODE, - KeyCode.STOP_ONE_HANDED_MODE, + KeyCode.TOGGLE_ONE_HANDED_MODE, + KeyCode.TOGGLE_ONE_HANDED_MODE, + KeyCode.TOGGLE_ONE_HANDED_MODE, KeyCode.SWITCH_ONE_HANDED_MODE }; diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java index 6eae4b155..ded17bdcc 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java @@ -808,10 +808,8 @@ public final class KeyboardState { toggleNumpad(false, autoCapsFlags, recapitalizeMode, false, true); } else if (code == KeyCode.SYMBOL) { setSymbolsKeyboard(); - } else if (code == KeyCode.START_ONE_HANDED_MODE) { - setOneHandedModeEnabled(true); - } else if (code == KeyCode.STOP_ONE_HANDED_MODE) { - setOneHandedModeEnabled(false); + } else if (code == KeyCode.TOGGLE_ONE_HANDED_MODE) { + setOneHandedModeEnabled(!Settings.getInstance().getCurrent().mOneHandedModeEnabled); } else if (code == KeyCode.SWITCH_ONE_HANDED_MODE) { switchOneHandedMode(); } diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt index 8f39a39cc..55250513e 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt @@ -125,8 +125,8 @@ object KeyCode { // heliboard only codes const val SYMBOL_ALPHA = -10001 - const val START_ONE_HANDED_MODE = -10002 - const val STOP_ONE_HANDED_MODE = -10003 + const val TOGGLE_ONE_HANDED_MODE = -10002 + const val TOGGLE_ONE_HANDED_MODE_2 = -10003 // does the same as TOGGLE_ONE_HANDED_MODE (used to be start & stop) const val SWITCH_ONE_HANDED_MODE = -10004 const val SHIFT_ENTER = -10005 const val ACTION_NEXT = -10006 @@ -179,7 +179,7 @@ object KeyCode { FN, CLIPBOARD_CLEAR_HISTORY, NUMPAD, // heliboard only - SYMBOL_ALPHA, START_ONE_HANDED_MODE, STOP_ONE_HANDED_MODE, SWITCH_ONE_HANDED_MODE, SHIFT_ENTER, + SYMBOL_ALPHA, TOGGLE_ONE_HANDED_MODE, SWITCH_ONE_HANDED_MODE, SHIFT_ENTER, ACTION_NEXT, ACTION_PREVIOUS, NOT_SPECIFIED, CLIPBOARD_COPY_ALL, WORD_LEFT, WORD_RIGHT, PAGE_UP, PAGE_DOWN, META, TAB, ESCAPE, INSERT, SLEEP, MEDIA_PLAY, MEDIA_PAUSE, MEDIA_PLAY_PAUSE, MEDIA_NEXT, MEDIA_PREVIOUS, VOL_UP, VOL_DOWN, MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BACK @@ -189,6 +189,7 @@ object KeyCode { IME_UI_MODE_TEXT -> ALPHA VIEW_PHONE -> ALPHA // phone keyboard is treated like alphabet, just with different layout VIEW_PHONE2 -> SYMBOL + TOGGLE_ONE_HANDED_MODE_2 -> TOGGLE_ONE_HANDED_MODE else -> throw IllegalStateException("key code $this not yet supported") } diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt index b26d3a08b..d22cf4c24 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt @@ -127,7 +127,7 @@ sealed interface KeyData : AbstractKeyData { if (!params.mId.mLanguageSwitchKeyEnabled && !params.mId.isNumberLayout && RichInputMethodManager.canSwitchLanguage()) keys.add("!icon/language_switch_key|!code/key_language_switch") if (!params.mId.mOneHandedModeEnabled) - keys.add("!icon/start_onehanded_mode_key|!code/key_start_onehanded") + keys.add("!icon/start_onehanded_mode_key|!code/key_toggle_onehanded") if (!params.mId.mDeviceLocked) keys.add("!icon/settings_key|!code/key_settings") return keys diff --git a/app/src/main/java/helium314/keyboard/latin/KeyboardWrapperView.kt b/app/src/main/java/helium314/keyboard/latin/KeyboardWrapperView.kt index 8393e21e9..1ffbfadfd 100644 --- a/app/src/main/java/helium314/keyboard/latin/KeyboardWrapperView.kt +++ b/app/src/main/java/helium314/keyboard/latin/KeyboardWrapperView.kt @@ -84,8 +84,7 @@ class KeyboardWrapperView @JvmOverloads constructor( if (newScale == oldScale) return@setOnTouchListener true Settings.getInstance().writeOneHandedModeScale(newScale) oneHandedModeEnabled = false // intentionally putting wrong value, so KeyboardSwitcher.setOneHandedModeEnabled does actually reload - keyboardActionListener?.onCodeInput(KeyCode.START_ONE_HANDED_MODE, - Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false) + KeyboardSwitcher.getInstance().setOneHandedModeEnabled(true) } else -> x = 0f } @@ -119,7 +118,7 @@ class KeyboardWrapperView @JvmOverloads constructor( override fun onClick(view: View) { if (view === stopOneHandedModeBtn) { - keyboardActionListener?.onCodeInput(KeyCode.STOP_ONE_HANDED_MODE, + keyboardActionListener?.onCodeInput(KeyCode.TOGGLE_ONE_HANDED_MODE, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false /* isKeyRepeat */) } else if (view === switchOneHandedModeBtn) { diff --git a/app/src/main/java/helium314/keyboard/latin/common/Constants.java b/app/src/main/java/helium314/keyboard/latin/common/Constants.java index 07685cd17..ff8ef330e 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Constants.java +++ b/app/src/main/java/helium314/keyboard/latin/common/Constants.java @@ -224,8 +224,7 @@ public final class Constants { case CODE_TAB: return "tab"; case CODE_ENTER: return "enter"; case CODE_SPACE: return "space"; - case KeyCode.START_ONE_HANDED_MODE: return "startOneHandedMode"; - case KeyCode.STOP_ONE_HANDED_MODE: return "stopOneHandedMode"; + case KeyCode.TOGGLE_ONE_HANDED_MODE: return "toggleOneHandedMode"; case KeyCode.SWITCH_ONE_HANDED_MODE: return "switchOneHandedMode"; case KeyCode.NUMPAD: return "numpad"; default: diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index d3239187a..ff782ebd8 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -779,7 +779,7 @@ public final class InputLogic { // We need to switch to the shortcut IME. This is handled by LatinIME since the // input logic has no business with IME switching. case KeyCode.CAPS_LOCK, KeyCode.SYMBOL_ALPHA, KeyCode.ALPHA, KeyCode.SYMBOL, KeyCode.NUMPAD, KeyCode.EMOJI, - KeyCode.START_ONE_HANDED_MODE, KeyCode.STOP_ONE_HANDED_MODE, KeyCode.SWITCH_ONE_HANDED_MODE, + KeyCode.TOGGLE_ONE_HANDED_MODE, KeyCode.SWITCH_ONE_HANDED_MODE, KeyCode.CTRL, KeyCode.ALT, KeyCode.FN, KeyCode.META: break; default: diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt index 6cb94ff79..ee4126e82 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt @@ -60,7 +60,7 @@ fun getCodeForToolbarKey(key: ToolbarKey) = Settings.getInstance().getCustomTool COPY -> KeyCode.CLIPBOARD_COPY CUT -> KeyCode.CLIPBOARD_CUT PASTE -> KeyCode.CLIPBOARD_PASTE - ONE_HANDED -> if (Settings.getInstance().current.mOneHandedModeEnabled) KeyCode.STOP_ONE_HANDED_MODE else KeyCode.START_ONE_HANDED_MODE + ONE_HANDED -> KeyCode.TOGGLE_ONE_HANDED_MODE INCOGNITO -> KeyCode.TOGGLE_INCOGNITO_MODE AUTOCORRECT -> KeyCode.TOGGLE_AUTOCORRECT CLEAR_CLIPBOARD -> KeyCode.CLIPBOARD_CLEAR_HISTORY From 54f222c0ee7d46b47519896392b704229f83f137 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 11:25:50 +0100 Subject: [PATCH 05/18] fix weird issue with toolbar keys having wrong color for their state and remove related semi-workaround --- .../keyboard/keyboard/clipboard/ClipboardHistoryView.kt | 7 +++---- .../main/java/helium314/keyboard/latin/common/Colors.kt | 6 +++--- .../java/helium314/keyboard/latin/utils/ToolbarUtils.kt | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index 188ed3c5e..98c70f61c 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -65,10 +65,6 @@ class ClipboardHistoryView @JvmOverloads constructor( keyBackgroundId = keyboardViewAttr.getResourceId(R.styleable.KeyboardView_keyBackground, 0) keyboardViewAttr.recycle() val keyboardAttr = context.obtainStyledAttributes(attrs, R.styleable.Keyboard, defStyle, R.style.SuggestionStripView) - // todo (maybe): setting the correct color only works because the activated state is inverted - // even when state is activated, the not activated color is set - // in suggestionStripView the same thing works correctly, wtf? - // need to properly fix it (and maybe undo the inverted isActivated) when adding a toggle key getEnabledClipboardToolbarKeys(DeviceProtectedUtils.getSharedPreferences(context)) .forEach { toolbarKeys.add(createToolbarKey(context, KeyboardIconsSet.instance, it)) } keyboardAttr.recycle() @@ -169,6 +165,9 @@ class ClipboardHistoryView @JvmOverloads constructor( adapter = clipboardAdapter layoutParams.width = ResourceUtils.getKeyboardWidth(context, Settings.getInstance().current) } + + // absurd workaround so Android sets the correct color from stateList (depending on "activated") + toolbarKeys.forEach { it.isEnabled = false; it.isEnabled = true } } fun stopClipboardHistory() { diff --git a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt index 6876823c6..154cff3c2 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt @@ -626,9 +626,9 @@ private fun stateList(pressed: Int, normal: Int): ColorStateList { return ColorStateList(states, intArrayOf(pressed, normal)) } -private fun activatedStateList(normal: Int, activated: Int): ColorStateList { - val states = arrayOf(intArrayOf(-android.R.attr.state_activated), intArrayOf(android.R.attr.state_activated)) - return ColorStateList(states, intArrayOf(normal, activated)) +private fun activatedStateList(activated: Int, normal: Int): ColorStateList { + val states = arrayOf(intArrayOf(android.R.attr.state_activated), intArrayOf(-android.R.attr.state_activated)) + return ColorStateList(states, intArrayOf(activated, normal)) } enum class ColorType { diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt index ee4126e82..766265349 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt @@ -26,7 +26,6 @@ import helium314.keyboard.latin.R import helium314.keyboard.latin.databinding.ReorderDialogItemBinding import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.ToolbarKey.* -import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import java.util.EnumMap import java.util.Locale @@ -38,7 +37,7 @@ fun createToolbarKey(context: Context, iconsSet: KeyboardIconsSet, key: ToolbarK val contentDescriptionId = context.resources.getIdentifier(key.name.lowercase(), "string", context.packageName) if (contentDescriptionId != 0) button.contentDescription = context.getString(contentDescriptionId) - button.isActivated = !when (key) { + button.isActivated = when (key) { INCOGNITO -> Settings.readAlwaysIncognitoMode(DeviceProtectedUtils.getSharedPreferences(context)) ONE_HANDED -> Settings.getInstance().current.mOneHandedModeEnabled AUTOCORRECT -> Settings.getInstance().current.mAutoCorrectionEnabledPerUserSettings From 833aa321b9ac5de4324b3355e576a225d42bc866 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 11:27:40 +0100 Subject: [PATCH 06/18] rename stateList to pressedStateList for clarification --- .../helium314/keyboard/latin/common/Colors.kt | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt index 154cff3c2..e5bf3d664 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt @@ -195,12 +195,12 @@ class DynamicColors(context: Context, override val themeStyle: String, override } adjustedBackgroundStateList = if (themeStyle == STYLE_HOLO) { - stateList(accent, adjustedBackground) + pressedStateList(accent, adjustedBackground) } else if (isNight) { - if (hasKeyBorders) stateList(doubleAdjustedAccent, keyBackground) - else stateList(adjustedAccent, adjustedKeyBackground) + if (hasKeyBorders) pressedStateList(doubleAdjustedAccent, keyBackground) + else pressedStateList(adjustedAccent, adjustedKeyBackground) } else { - stateList(accent, Color.WHITE) + pressedStateList(accent, Color.WHITE) } val stripBackground = if (keyboardBackground == null && !hasKeyBorders) { @@ -210,7 +210,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override } val pressedStripElementBackground = if (keyboardBackground == null) adjustedBackground else if (isDarkColor(background)) 0x22ffffff else 0x11000000 - stripBackgroundList = stateList(pressedStripElementBackground, stripBackground) + stripBackgroundList = pressedStateList(pressedStripElementBackground, stripBackground) adjustedBackgroundFilter = if (themeStyle == STYLE_HOLO) colorFilter(adjustedBackground) @@ -218,47 +218,47 @@ class DynamicColors(context: Context, override val themeStyle: String, override if (hasKeyBorders) { backgroundStateList = - if (!isNight) stateList(adjustedFunctionalKey, background) - else stateList(adjustedKeyBackground, background) + if (!isNight) pressedStateList(adjustedFunctionalKey, background) + else pressedStateList(adjustedKeyBackground, background) keyStateList = - if (!isNight) stateList(adjustedBackground, keyBackground) - else stateList(adjustedKeyBackground, keyBackground) + if (!isNight) pressedStateList(adjustedBackground, keyBackground) + else pressedStateList(adjustedKeyBackground, keyBackground) functionalKeyStateList = - if (!isNight) stateList(doubleAdjustedFunctionalKey, functionalKey) - else stateList(functionalKey, doubleAdjustedKeyBackground) + if (!isNight) pressedStateList(doubleAdjustedFunctionalKey, functionalKey) + else pressedStateList(functionalKey, doubleAdjustedKeyBackground) actionKeyStateList = - if (!isNight) stateList(gesture, accent) - else stateList(doubleAdjustedAccent, accent) + if (!isNight) pressedStateList(gesture, accent) + else pressedStateList(doubleAdjustedAccent, accent) spaceBarStateList = - if (themeStyle == STYLE_HOLO) stateList(spaceBar, spaceBar) + if (themeStyle == STYLE_HOLO) pressedStateList(spaceBar, spaceBar) else keyStateList } else { // need to set color to background if key borders are disabled, or there will be ugly keys backgroundStateList = - if (!isNight) stateList(adjustedFunctionalKey, background) - else stateList(adjustedKeyBackground, background) + if (!isNight) pressedStateList(adjustedFunctionalKey, background) + else pressedStateList(adjustedKeyBackground, background) keyStateList = - if (!isNight) stateList(adjustedFunctionalKey, Color.TRANSPARENT) - else stateList(functionalKey, Color.TRANSPARENT) + if (!isNight) pressedStateList(adjustedFunctionalKey, Color.TRANSPARENT) + else pressedStateList(functionalKey, Color.TRANSPARENT) functionalKeyStateList = - if (themeStyle == STYLE_HOLO) stateList(functionalKey, Color.TRANSPARENT) + if (themeStyle == STYLE_HOLO) pressedStateList(functionalKey, Color.TRANSPARENT) else keyStateList actionKeyStateList = - if (themeStyle == STYLE_HOLO) stateList(accent, Color.TRANSPARENT) - else if (!isNight) stateList(gesture, accent) - else stateList(doubleAdjustedAccent, accent) + if (themeStyle == STYLE_HOLO) pressedStateList(accent, Color.TRANSPARENT) + else if (!isNight) pressedStateList(gesture, accent) + else pressedStateList(doubleAdjustedAccent, accent) spaceBarStateList = - if (!isNight) stateList(gesture, adjustedFunctionalKey) - else stateList(adjustedKeyBackground, spaceBar) + if (!isNight) pressedStateList(gesture, adjustedFunctionalKey) + else pressedStateList(adjustedKeyBackground, spaceBar) } keyTextFilter = colorFilter(keyText) @@ -409,7 +409,7 @@ class DefaultColors ( adjustedBackground = darken(background) doubleAdjustedBackground = darken(adjustedBackground) } - adjustedBackgroundStateList = stateList(doubleAdjustedBackground, adjustedBackground) + adjustedBackgroundStateList = pressedStateList(doubleAdjustedBackground, adjustedBackground) val stripBackground: Int val pressedStripElementBackground: Int @@ -424,7 +424,7 @@ class DefaultColors ( stripBackground = adjustedBackground pressedStripElementBackground = doubleAdjustedBackground } - stripBackgroundList = stateList(pressedStripElementBackground, stripBackground) + stripBackgroundList = pressedStateList(pressedStripElementBackground, stripBackground) if (themeStyle == STYLE_HOLO && keyboardBackground == null) { val darkerBackground = adjustLuminosityAndKeepAlpha(background, -0.2f) @@ -437,22 +437,22 @@ class DefaultColors ( adjustedBackgroundFilter = colorFilter(adjustedBackground) if (hasKeyBorders) { - backgroundStateList = stateList(brightenOrDarken(background, true), background) - keyStateList = if (themeStyle == STYLE_HOLO) stateList(keyBackground, keyBackground) - else stateList(brightenOrDarken(keyBackground, true), keyBackground) - functionalKeyStateList = stateList(brightenOrDarken(functionalKey, true), functionalKey) + backgroundStateList = pressedStateList(brightenOrDarken(background, true), background) + keyStateList = if (themeStyle == STYLE_HOLO) pressedStateList(keyBackground, keyBackground) + else pressedStateList(brightenOrDarken(keyBackground, true), keyBackground) + functionalKeyStateList = pressedStateList(brightenOrDarken(functionalKey, true), functionalKey) actionKeyStateList = if (themeStyle == STYLE_HOLO) functionalKeyStateList - else stateList(brightenOrDarken(accent, true), accent) - spaceBarStateList = if (themeStyle == STYLE_HOLO) stateList(spaceBar, spaceBar) - else stateList(brightenOrDarken(spaceBar, true), spaceBar) + else pressedStateList(brightenOrDarken(accent, true), accent) + spaceBarStateList = if (themeStyle == STYLE_HOLO) pressedStateList(spaceBar, spaceBar) + else pressedStateList(brightenOrDarken(spaceBar, true), spaceBar) } else { // need to set color to background if key borders are disabled, or there will be ugly keys - backgroundStateList = stateList(brightenOrDarken(background, true), background) - keyStateList = stateList(keyBackground, Color.TRANSPARENT) + backgroundStateList = pressedStateList(brightenOrDarken(background, true), background) + keyStateList = pressedStateList(keyBackground, Color.TRANSPARENT) functionalKeyStateList = keyStateList actionKeyStateList = if (themeStyle == STYLE_HOLO) functionalKeyStateList - else stateList(brightenOrDarken(accent, true), accent) - spaceBarStateList = stateList(brightenOrDarken(spaceBar, true), spaceBar) + else pressedStateList(brightenOrDarken(accent, true), accent) + spaceBarStateList = pressedStateList(brightenOrDarken(spaceBar, true), spaceBar) } keyTextFilter = colorFilter(keyText) actionKeyIconColorFilter = when { @@ -556,7 +556,7 @@ class AllColors(private val colorMap: EnumMap, override val them override fun get(color: ColorType): Int = colorMap[color] ?: color.default() override fun setColor(drawable: Drawable, color: ColorType) { - val colorStateList = stateListMap.getOrPut(color) { stateList(brightenOrDarken(get(color), true), get(color)) } + val colorStateList = stateListMap.getOrPut(color) { pressedStateList(brightenOrDarken(get(color), true), get(color)) } DrawableCompat.setTintMode(drawable, PorterDuff.Mode.MULTIPLY) DrawableCompat.setTintList(drawable, colorStateList) } @@ -621,7 +621,7 @@ private fun colorFilter(color: Int, mode: BlendModeCompat = BlendModeCompat.MODU return BlendModeColorFilterCompat.createBlendModeColorFilterCompat(color, mode)!! } -private fun stateList(pressed: Int, normal: Int): ColorStateList { +private fun pressedStateList(pressed: Int, normal: Int): ColorStateList { val states = arrayOf(intArrayOf(android.R.attr.state_pressed), intArrayOf(-android.R.attr.state_pressed)) return ColorStateList(states, intArrayOf(pressed, normal)) } From 79c9a85082dc2e3a2e881b7ab31377bd560a29f3 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 11:36:17 +0100 Subject: [PATCH 07/18] better choice of color for deactivated toolbar key --- .../java/helium314/keyboard/latin/common/Colors.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt index e5bf3d664..b9790e4a0 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt @@ -150,7 +150,11 @@ class DynamicColors(context: Context, override val themeStyle: String, override private val spaceBarStateList: ColorStateList private val adjustedBackgroundStateList: ColorStateList private val stripBackgroundList: ColorStateList - private val toolbarKeyStateList = activatedStateList(keyText, darken(darken(keyText))) + private val toolbarKeyStateList = activatedStateList( + keyText, + if (isBrightColor(keyText)) darken(darken(keyText)) + else brighten(brighten(keyText)) + ) /** darkened variant of [accent] because the accent color is always light for dynamic colors */ private val adjustedAccent: Int = darken(accent) @@ -398,7 +402,11 @@ class DefaultColors ( private val spaceBarStateList: ColorStateList private val adjustedBackgroundStateList: ColorStateList private val stripBackgroundList: ColorStateList - private val toolbarKeyStateList = activatedStateList(suggestionText, darken(darken(suggestionText))) + private val toolbarKeyStateList = activatedStateList( + suggestionText, + if (isBrightColor(suggestionText)) darken(darken(suggestionText)) + else brighten(brighten(suggestionText)) + ) private var backgroundSetupDone = false init { From 635cd5f8dad00fd9a3edb47d53d0b30334ea5c35 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 13:16:13 +0100 Subject: [PATCH 08/18] toolbar key activated state now responds to settings changes --- .../keyboard/keyboard/KeyboardSwitcher.java | 14 +++++++-- .../clipboard/ClipboardHistoryView.kt | 11 +++++-- .../suggestions/SuggestionStripView.java | 15 ++++++---- .../keyboard/latin/utils/ToolbarUtils.kt | 30 ++++++++++++++++--- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java index e676e014b..0ea114754 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardSwitcher.java @@ -8,6 +8,7 @@ package helium314.keyboard.keyboard; import android.annotation.SuppressLint; import android.content.Context; +import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Drawable; @@ -40,8 +41,10 @@ import helium314.keyboard.latin.RichInputMethodSubtype; import helium314.keyboard.latin.WordComposer; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.settings.SettingsValues; +import helium314.keyboard.latin.suggestions.SuggestionStripView; import helium314.keyboard.latin.utils.AdditionalSubtypeUtils; import helium314.keyboard.latin.utils.CapsModeUtils; +import helium314.keyboard.latin.utils.DeviceProtectedUtils; import helium314.keyboard.latin.utils.LanguageOnSpacebarUtils; import helium314.keyboard.latin.utils.Log; import helium314.keyboard.latin.utils.RecapitalizeStatus; @@ -59,7 +62,7 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { private View mEmojiTabStripView; private LinearLayout mClipboardStripView; private HorizontalScrollView mClipboardStripScrollView; - private View mSuggestionStripView; + private SuggestionStripView mSuggestionStripView; private ClipboardHistoryView mClipboardHistoryView; private TextView mFakeToastView; private LatinIME mLatinIME; @@ -325,7 +328,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { if (DEBUG_ACTION) { Log.d(TAG, "setEmojiKeyboard"); } - final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); mMainKeyboardFrame.setVisibility(View.VISIBLE); // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}. // @see #getVisibleKeyboardView() and @@ -346,7 +348,6 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { if (DEBUG_ACTION) { Log.d(TAG, "setClipboardKeyboard"); } - final Keyboard keyboard = mKeyboardLayoutSet.getKeyboard(KeyboardId.ELEMENT_ALPHABET); mMainKeyboardFrame.setVisibility(View.VISIBLE); // The visibility of {@link #mKeyboardView} must be aligned with {@link #MainKeyboardFrame}. // @see #getVisibleKeyboardView() and @@ -634,6 +635,11 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mKeyboardView.closing(); } PointerTracker.clearOldViewData(); + final SharedPreferences prefs = DeviceProtectedUtils.getSharedPreferences(displayContext); + if (mSuggestionStripView != null) + prefs.unregisterOnSharedPreferenceChangeListener(mSuggestionStripView); + if (mClipboardHistoryView != null) + prefs.unregisterOnSharedPreferenceChangeListener(mClipboardHistoryView); updateKeyboardThemeAndContextThemeWrapper(displayContext, KeyboardTheme.getKeyboardTheme(displayContext)); mCurrentInputView = (InputView)LayoutInflater.from(mThemeContext).inflate(R.layout.input_view, null); @@ -656,6 +662,8 @@ public final class KeyboardSwitcher implements KeyboardState.SwitchActions { mClipboardStripScrollView = mCurrentInputView.findViewById(R.id.clipboard_strip_scroll_view); mSuggestionStripView = mCurrentInputView.findViewById(R.id.suggestion_strip_view); + prefs.registerOnSharedPreferenceChangeListener(mSuggestionStripView); + prefs.registerOnSharedPreferenceChangeListener(mClipboardHistoryView); PointerTracker.switchTo(mKeyboardView); return mCurrentInputView; } diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index 98c70f61c..73e5959b7 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -4,6 +4,7 @@ package helium314.keyboard.keyboard.clipboard import android.annotation.SuppressLint import android.content.Context +import android.content.SharedPreferences import android.util.AttributeSet import android.util.TypedValue import android.view.View @@ -34,6 +35,7 @@ import helium314.keyboard.latin.utils.createToolbarKey import helium314.keyboard.latin.utils.getCodeForToolbarKey import helium314.keyboard.latin.utils.getCodeForToolbarKeyLongClick import helium314.keyboard.latin.utils.getEnabledClipboardToolbarKeys +import helium314.keyboard.latin.utils.setToolbarButtonsActivatedStateOnPrefChange @SuppressLint("CustomViewStyleable") class ClipboardHistoryView @JvmOverloads constructor( @@ -41,7 +43,8 @@ class ClipboardHistoryView @JvmOverloads constructor( attrs: AttributeSet?, defStyle: Int = R.attr.clipboardHistoryViewStyle ) : LinearLayout(context, attrs, defStyle), View.OnClickListener, - ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener, View.OnLongClickListener { + ClipboardHistoryManager.OnHistoryChangeListener, OnKeyEventListener, + View.OnLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener { private val clipboardLayoutParams = ClipboardLayoutParams(context) private val pinIconId: Int @@ -232,4 +235,8 @@ class ClipboardHistoryView @JvmOverloads constructor( clipboardAdapter.notifyItemChanged(to) if (to < from) clipboardRecyclerView.smoothScrollToPosition(to) } -} \ No newline at end of file + + override fun onSharedPreferenceChanged(prefs: SharedPreferences?, key: String?) { + setToolbarButtonsActivatedStateOnPrefChange(KeyboardSwitcher.getInstance().clipboardStrip, key) + } +} diff --git a/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java b/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java index 04cc9c4e3..ab99a5064 100644 --- a/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java +++ b/app/src/main/java/helium314/keyboard/latin/suggestions/SuggestionStripView.java @@ -70,7 +70,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; public final class SuggestionStripView extends RelativeLayout implements OnClickListener, - OnLongClickListener { + OnLongClickListener, SharedPreferences.OnSharedPreferenceChangeListener { public interface Listener { void pickSuggestionManually(SuggestedWordInfo word); void onCodeInput(int primaryCode, int x, int y, boolean isKeyRepeat); @@ -231,6 +231,12 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick colors.setBackground(this, ColorType.STRIP_BACKGROUND); } + @Override + public void onSharedPreferenceChanged(SharedPreferences prefs, @Nullable String key) { + ToolbarUtilsKt.setToolbarButtonsActivatedStateOnPrefChange(mPinnedKeys, key); + ToolbarUtilsKt.setToolbarButtonsActivatedStateOnPrefChange(mToolbar, key); + } + /** * A connection back to the input method. */ @@ -647,11 +653,8 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick if (code != KeyCode.UNSPECIFIED) { Log.d(TAG, "click toolbar key "+tag); mListener.onCodeInput(code, Constants.SUGGESTION_STRIP_COORDINATE, Constants.SUGGESTION_STRIP_COORDINATE, false); - if (tag == ToolbarKey.INCOGNITO || tag == ToolbarKey.AUTOCORRECT || tag == ToolbarKey.ONE_HANDED) { - if (tag == ToolbarKey.INCOGNITO) - updateKeys(); // update icon - view.setActivated(!view.isActivated()); - } + if (tag == ToolbarKey.INCOGNITO) + updateKeys(); // update expand key icon return; } } diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt index 766265349..a14a5ff65 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt @@ -6,6 +6,7 @@ import android.content.Context import android.content.DialogInterface import android.content.SharedPreferences import android.view.LayoutInflater +import android.view.ViewGroup import android.widget.EditText import android.widget.ImageButton import android.widget.ImageView @@ -16,6 +17,7 @@ import androidx.core.content.ContextCompat import androidx.core.content.edit import androidx.core.graphics.BlendModeColorFilterCompat import androidx.core.graphics.BlendModeCompat +import androidx.core.view.forEach import androidx.core.view.isGone import androidx.core.view.isVisible import androidx.core.widget.doAfterTextChanged @@ -26,6 +28,9 @@ import helium314.keyboard.latin.R import helium314.keyboard.latin.databinding.ReorderDialogItemBinding import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.ToolbarKey.* +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch import kotlinx.serialization.json.Json import java.util.EnumMap import java.util.Locale @@ -37,14 +42,31 @@ fun createToolbarKey(context: Context, iconsSet: KeyboardIconsSet, key: ToolbarK val contentDescriptionId = context.resources.getIdentifier(key.name.lowercase(), "string", context.packageName) if (contentDescriptionId != 0) button.contentDescription = context.getString(contentDescriptionId) - button.isActivated = when (key) { - INCOGNITO -> Settings.readAlwaysIncognitoMode(DeviceProtectedUtils.getSharedPreferences(context)) + setToolbarButtonActivatedState(button) + button.setImageDrawable(iconsSet.getNewDrawable(key.name, context)) + return button +} + +fun setToolbarButtonsActivatedStateOnPrefChange(buttonsGroup: ViewGroup, key: String?) { + // settings need to be updated when buttons change + if (key != Settings.PREF_AUTO_CORRECTION + && key != Settings.PREF_ALWAYS_INCOGNITO_MODE + && key?.startsWith(Settings.PREF_ONE_HANDED_MODE_PREFIX) == false) + return + + GlobalScope.launch { + delay(10) // need to wait until SettingsValues are reloaded + buttonsGroup.forEach { if (it is ImageButton) setToolbarButtonActivatedState(it) } + } +} + +private fun setToolbarButtonActivatedState(button: ImageButton) { + button.isActivated = when (button.tag) { + INCOGNITO -> Settings.readAlwaysIncognitoMode(DeviceProtectedUtils.getSharedPreferences(button.context)) ONE_HANDED -> Settings.getInstance().current.mOneHandedModeEnabled AUTOCORRECT -> Settings.getInstance().current.mAutoCorrectionEnabledPerUserSettings else -> true } - button.setImageDrawable(iconsSet.getNewDrawable(key.name, context)) - return button } fun getCodeForToolbarKey(key: ToolbarKey) = Settings.getInstance().getCustomToolbarKeyCode(key) ?: when (key) { From 92bc79b7e656a5581fd6268623bfc781b814711b Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 26 Jan 2025 17:31:23 +0100 Subject: [PATCH 09/18] Add side padding scale setting (#1309) --- .../clipboard/ClipboardHistoryView.kt | 18 ++++++++++-- .../keyboard/emoji/EmojiCategory.java | 2 ++ .../emoji/EmojiCategoryPageIndicatorView.java | 6 ++-- .../keyboard/emoji/EmojiPalettesView.java | 29 ++++++++++++++++++- .../keyboard/internal/KeyboardParams.java | 11 +++---- .../internal/keyboard_parser/EmojiParser.kt | 3 +- .../settings/AppearanceSettingsFragment.kt | 2 ++ .../keyboard/latin/settings/Settings.java | 8 +++++ .../latin/settings/SettingsValues.java | 2 ++ app/src/main/res/values/config-common.xml | 4 +-- app/src/main/res/values/strings.xml | 4 +++ app/src/main/res/values/themes-holo_base.xml | 2 ++ app/src/main/res/values/themes-lxx-base.xml | 2 ++ .../main/res/values/themes-rounded-base.xml | 2 ++ .../main/res/xml/prefs_screen_appearance.xml | 14 +++++++++ 15 files changed, 96 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt index 73e5959b7..ed31aa661 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/clipboard/ClipboardHistoryView.kt @@ -155,7 +155,8 @@ class ClipboardHistoryView @JvmOverloads constructor( val params = KeyDrawParams() params.updateParams(clipboardLayoutParams.bottomRowKeyboardHeight, keyVisualAttr) - Settings.getInstance().getCustomTypeface()?.let { params.mTypeface = it } + val settings = Settings.getInstance() + settings.getCustomTypeface()?.let { params.mTypeface = it } setupClipKey(params) setupBottomRowKeyboard(editorInfo, keyboardActionListener) @@ -166,7 +167,20 @@ class ClipboardHistoryView @JvmOverloads constructor( } clipboardRecyclerView.apply { adapter = clipboardAdapter - layoutParams.width = ResourceUtils.getKeyboardWidth(context, Settings.getInstance().current) + val keyboardWidth = ResourceUtils.getKeyboardWidth(context, settings.current) + layoutParams.width = keyboardWidth + + // set side padding + val keyboardAttr = context.obtainStyledAttributes( + null, R.styleable.Keyboard, R.attr.keyboardStyle, R.style.Keyboard); + val leftPadding = (keyboardAttr.getFraction(R.styleable.Keyboard_keyboardLeftPadding, + keyboardWidth, keyboardWidth, 0f) + * settings.current.mSidePaddingScale).toInt() + val rightPadding = (keyboardAttr.getFraction(R.styleable.Keyboard_keyboardRightPadding, + keyboardWidth, keyboardWidth, 0f) + * settings.current.mSidePaddingScale).toInt() + keyboardAttr.recycle() + setPadding(leftPadding, paddingTop, rightPadding, paddingBottom) } // absurd workaround so Android sets the correct color from stateList (depending on "activated") diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategory.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategory.java index fbdfc99ae..359cda86c 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategory.java +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategory.java @@ -173,6 +173,8 @@ final class EmojiCategory { public void clearKeyboardCache() { mCategoryKeyboardMap.clear(); + for (CategoryProperties props: mShownCategories) + props.mPageCount = -1; // reset page count in case size (number of keys per row) changed } private void addShownCategoryId(final int categoryId) { diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategoryPageIndicatorView.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategoryPageIndicatorView.java index 1a8151faf..26c13d217 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategoryPageIndicatorView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiCategoryPageIndicatorView.java @@ -18,6 +18,7 @@ public final class EmojiCategoryPageIndicatorView extends View { private int mCategoryPageSize = 0; private int mCurrentCategoryPageId = 0; private float mOffset = 0.0f; + int mWidth = 0; public EmojiCategoryPageIndicatorView(final Context context, final AttributeSet attrs) { this(context, attrs, 0); @@ -49,12 +50,13 @@ public final class EmojiCategoryPageIndicatorView extends View { return; } final float height = getHeight(); - final float width = getWidth(); + final float leftPadding = getPaddingLeft(); + final float width = mWidth - leftPadding - getPaddingRight(); final float unitWidth = width / mCategoryPageSize; final float left = Math.min(unitWidth * mCurrentCategoryPageId + mOffset * unitWidth, width - unitWidth); final float top = 0.0f; final float right = Math.min(left + unitWidth, width); final float bottom = height * BOTTOM_MARGIN_RATIO; - canvas.drawRect(left, top, right, bottom, mPaint); + canvas.drawRect(left + leftPadding, top, right + leftPadding, bottom, mPaint); } } diff --git a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java index 641243002..3c63ceb98 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/emoji/EmojiPalettesView.java @@ -38,7 +38,7 @@ import helium314.keyboard.latin.RichInputMethodSubtype; import helium314.keyboard.latin.common.ColorType; import helium314.keyboard.latin.common.Colors; import helium314.keyboard.latin.settings.Settings; -import helium314.keyboard.latin.utils.DeviceProtectedUtils; +import helium314.keyboard.latin.settings.SettingsValues; import helium314.keyboard.latin.utils.ResourceUtils; import org.jetbrains.annotations.NotNull; @@ -117,6 +117,7 @@ public final class EmojiPalettesView extends LinearLayout + getPaddingLeft() + getPaddingRight(); final int height = ResourceUtils.getKeyboardHeight(res, Settings.getInstance().getCurrent()) + getPaddingTop() + getPaddingBottom(); + mEmojiCategoryPageIndicatorView.mWidth = width; setMeasuredDimension(width, height); } @@ -272,6 +273,7 @@ public final class EmojiPalettesView extends LinearLayout mEmojiRecyclerView.setAdapter(mEmojiPalettesAdapter); setCurrentCategoryAndPageId(mEmojiCategory.getCurrentCategoryId(), mEmojiCategory.getCurrentCategoryPageId(), true); } + setupSidePadding(); } private void setupBottomRowKeyboard(final EditorInfo editorInfo, final KeyboardActionListener keyboardActionListener) { @@ -283,6 +285,31 @@ public final class EmojiPalettesView extends LinearLayout keyboardView.setKeyboard(keyboard); } + private void setupSidePadding() { + final SettingsValues sv = Settings.getInstance().getCurrent(); + final int keyboardWidth = ResourceUtils.getKeyboardWidth(getContext(), sv); + final TypedArray keyboardAttr = getContext().obtainStyledAttributes( + null, R.styleable.Keyboard, R.attr.keyboardStyle, R.style.Keyboard); + final float leftPadding = keyboardAttr.getFraction(R.styleable.Keyboard_keyboardLeftPadding, + keyboardWidth, keyboardWidth, 0f) * sv.mSidePaddingScale; + final float rightPadding = keyboardAttr.getFraction(R.styleable.Keyboard_keyboardRightPadding, + keyboardWidth, keyboardWidth, 0f) * sv.mSidePaddingScale; + keyboardAttr.recycle(); + mEmojiRecyclerView.setPadding( + (int) leftPadding, + mEmojiRecyclerView.getPaddingTop(), + (int) rightPadding, + mEmojiRecyclerView.getPaddingBottom() + ); + mEmojiCategoryPageIndicatorView.setPadding( + (int) leftPadding, + mEmojiCategoryPageIndicatorView.getPaddingTop(), + (int) rightPadding, + mEmojiCategoryPageIndicatorView.getPaddingBottom() + ); + // setting width does not do anything, so we have some workaround in EmojiCategoryPageIndicatorView + } + public void stopEmojiPalettes() { if (!initialized) return; mEmojiPalettesAdapter.releaseCurrentKey(true); diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java index fe456eb15..aa3676165 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardParams.java @@ -225,10 +225,12 @@ public class KeyboardParams { mBottomPadding = (int) (keyboardAttr.getFraction( R.styleable.Keyboard_keyboardBottomPadding, height, height, 0) * Settings.getInstance().getCurrent().mBottomPaddingScale); - mLeftPadding = (int) keyboardAttr.getFraction( - R.styleable.Keyboard_keyboardLeftPadding, width, width, 0); - mRightPadding = (int) keyboardAttr.getFraction( - R.styleable.Keyboard_keyboardRightPadding, width, width, 0); + mLeftPadding = (int) (keyboardAttr.getFraction( + R.styleable.Keyboard_keyboardLeftPadding, width, width, 0) + * Settings.getInstance().getCurrent().mSidePaddingScale); + mRightPadding = (int) (keyboardAttr.getFraction( + R.styleable.Keyboard_keyboardRightPadding, width, width, 0) + * Settings.getInstance().getCurrent().mSidePaddingScale); mBaseWidth = mOccupiedWidth - mLeftPadding - mRightPadding; final float defaultKeyWidthFactor = context.getResources().getInteger(R.integer.config_screen_metrics) > 2 ? 0.9f : 1f; @@ -238,7 +240,6 @@ public class KeyboardParams { mDefaultAbsoluteKeyWidth = (int) (mDefaultKeyWidth * mBaseWidth); mAbsolutePopupKeyWidth = (int) (alphaSymbolKeyWidth * mBaseWidth); - // todo: maybe settings should not be accessed from here? if (Settings.getInstance().getCurrent().mNarrowKeyGaps) { mRelativeHorizontalGap = keyboardAttr.getFraction( R.styleable.Keyboard_horizontalGapNarrow, 1, 1, 0); diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/EmojiParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/EmojiParser.kt index dcf9ca204..2b8262218 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/EmojiParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/EmojiParser.kt @@ -42,7 +42,8 @@ class EmojiParser(private val params: KeyboardParams, private val context: Conte // determine key width for default settings (no number row, no one-handed mode, 100% height and bottom padding scale) // this is a bit long, but ensures that emoji size stays the same, independent of these settings - val defaultKeyWidth = (ResourceUtils.getDefaultKeyboardWidth(context) - params.mLeftPadding - params.mRightPadding) * params.mDefaultKeyWidth + // we also ignore side padding for key width, and prefer fewer keys per row over narrower keys + val defaultKeyWidth = ResourceUtils.getDefaultKeyboardWidth(context) * params.mDefaultKeyWidth val keyWidth = defaultKeyWidth * sqrt(Settings.getInstance().current.mKeyboardHeightScale) val defaultKeyboardHeight = ResourceUtils.getDefaultKeyboardHeight(context.resources, false) val defaultBottomPadding = context.resources.getFraction(R.fraction.config_keyboard_bottom_padding_holo, defaultKeyboardHeight, defaultKeyboardHeight) diff --git a/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt index aa990648d..0a72a4fcc 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AppearanceSettingsFragment.kt @@ -108,6 +108,8 @@ class AppearanceSettingsFragment : SubScreenFragment() { setupScalePrefs(Settings.PREF_BOTTOM_PADDING_SCALE_LANDSCAPE, 0f) setupScalePrefs(Settings.PREF_FONT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) setupScalePrefs(Settings.PREF_EMOJI_FONT_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) + setupScalePrefs(Settings.PREF_SIDE_PADDING_SCALE, 0f) + setupScalePrefs(Settings.PREF_SIDE_PADDING_SCALE_LANDSCAPE, 0f) if (splitScalePref != null) { setupScalePrefs(Settings.PREF_SPLIT_SPACER_SCALE, SettingsValues.DEFAULT_SIZE_SCALE) splitScalePref?.isVisible = splitPref?.isChecked == true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 0db33ad1f..912384906 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -113,6 +113,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_KEYBOARD_HEIGHT_SCALE = "keyboard_height_scale"; public static final String PREF_BOTTOM_PADDING_SCALE = "bottom_padding_scale"; public static final String PREF_BOTTOM_PADDING_SCALE_LANDSCAPE = "bottom_padding_scale_landscape"; + public static final String PREF_SIDE_PADDING_SCALE = "side_padding_scale"; + public static final String PREF_SIDE_PADDING_SCALE_LANDSCAPE = "side_padding_scale_landscape"; public static final String PREF_FONT_SCALE = "font_scale"; public static final String PREF_EMOJI_FONT_SCALE = "emoji_font_scale"; public static final String PREF_SPACE_HORIZONTAL_SWIPE = "horizontal_space_swipe"; @@ -508,6 +510,12 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang return prefs.getFloat(PREF_BOTTOM_PADDING_SCALE, SettingsValues.DEFAULT_SIZE_SCALE); } + public static float readSidePaddingScale(final SharedPreferences prefs, final boolean landscape) { + if (landscape) + return prefs.getFloat(PREF_SIDE_PADDING_SCALE_LANDSCAPE, 0f); + return prefs.getFloat(PREF_SIDE_PADDING_SCALE, 0f); + } + public static boolean readHasHardwareKeyboard(final Configuration conf) { // The standard way of finding out whether we have a hardware keyboard. This code is taken // from InputMethodService#onEvaluateInputShown, which canonically determines this. diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index c89761655..2c1e494ca 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -113,6 +113,7 @@ public class SettingsValues { public final float mKeyboardHeightScale; public final boolean mUrlDetectionEnabled; public final float mBottomPaddingScale; + public final float mSidePaddingScale; public final boolean mAutoShowToolbar; public final boolean mAutoHideToolbar; public final boolean mAlphaAfterEmojiInEmojiView; @@ -265,6 +266,7 @@ public class SettingsValues { ); mSpacingAndPunctuations = new SpacingAndPunctuations(res, mUrlDetectionEnabled); mBottomPaddingScale = Settings.readBottomPaddingScale(prefs, mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE); + mSidePaddingScale = Settings.readSidePaddingScale(prefs, mDisplayOrientation == Configuration.ORIENTATION_LANDSCAPE); mLongPressSymbolsForNumpad = prefs.getBoolean(Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, false); mAutoShowToolbar = prefs.getBoolean(Settings.PREF_AUTO_SHOW_TOOLBAR, false); mAutoHideToolbar = readSuggestionsEnabled(prefs) && prefs.getBoolean(Settings.PREF_AUTO_HIDE_TOOLBAR, false); diff --git a/app/src/main/res/values/config-common.xml b/app/src/main/res/values/config-common.xml index aea0abfd9..6366b02cd 100644 --- a/app/src/main/res/values/config-common.xml +++ b/app/src/main/res/values/config-common.xml @@ -79,8 +79,8 @@ 40 - 0%p - 0%p + 8%p + 8%p 0.0dp diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 43b0a3514..35d14c3e2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -314,6 +314,10 @@ Bottom padding scale (landscape) + + Side padding scale + + Side padding scale (landscape) Keyboard font scale Emoji view font scale diff --git a/app/src/main/res/values/themes-holo_base.xml b/app/src/main/res/values/themes-holo_base.xml index 9e93ccd87..4a8c11ced 100644 --- a/app/src/main/res/values/themes-holo_base.xml +++ b/app/src/main/res/values/themes-holo_base.xml @@ -97,6 +97,8 @@ > 0%p 0%p + 0%p + 0%p 0%p 0%p @null diff --git a/app/src/main/res/values/themes-lxx-base.xml b/app/src/main/res/values/themes-lxx-base.xml index af4aea217..40897ca9a 100644 --- a/app/src/main/res/values/themes-lxx-base.xml +++ b/app/src/main/res/values/themes-lxx-base.xml @@ -81,6 +81,8 @@ > 0%p 0%p + 0%p + 0%p 0%p 0%p @null diff --git a/app/src/main/res/values/themes-rounded-base.xml b/app/src/main/res/values/themes-rounded-base.xml index f692691f4..05091c99e 100644 --- a/app/src/main/res/values/themes-rounded-base.xml +++ b/app/src/main/res/values/themes-rounded-base.xml @@ -90,6 +90,8 @@ > 0%p 0%p + 0%p + 0%p 0%p 0%p @null diff --git a/app/src/main/res/xml/prefs_screen_appearance.xml b/app/src/main/res/xml/prefs_screen_appearance.xml index d30b97aee..46b653adb 100644 --- a/app/src/main/res/xml/prefs_screen_appearance.xml +++ b/app/src/main/res/xml/prefs_screen_appearance.xml @@ -118,6 +118,20 @@ latin:minValue="0" latin:maxValue="500" /> + + + + Date: Wed, 29 Jan 2025 00:10:25 +0600 Subject: [PATCH 10/18] adjust unijoy layout for bn-BD (#1321) --- .../main/assets/layouts/bengali_unijoy.json | 602 +++++++++++++++--- .../main/assets/locale_key_texts/bn-BD.txt | 2 +- 2 files changed, 524 insertions(+), 80 deletions(-) diff --git a/app/src/main/assets/layouts/bengali_unijoy.json b/app/src/main/assets/layouts/bengali_unijoy.json index bbe534982..16eedb68c 100644 --- a/app/src/main/assets/layouts/bengali_unijoy.json +++ b/app/src/main/assets/layouts/bengali_unijoy.json @@ -1,112 +1,556 @@ [ [ - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ং" }, - "default": { "label": "ঙ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ং", + "labelFlags": 1073741824 + }, + "default": { + "label": "ঙ", + "popup": { + "main": { + "label": "ং" + }, + "relevant": [ + { + "label": "১" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "য়" }, - "default": { "label": "য" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "য়", + "labelFlags": 1073741824 + }, + "default": { + "label": "য", + "popup": { + "main": { + "label": "য়" + }, + "relevant": [ + { + "label": "২" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঢ" }, - "default": { "label": "ড" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঢ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ড", + "popup": { + "main": { + "label": "ঢ" + }, + "relevant": [ + { + "label": "৩" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ফ" }, - "default": { "label": "প" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ফ", + "labelFlags": 1073741824 + }, + "default": { + "label": "প", + "popup": { + "main": { + "label": "ফ" + }, + "relevant": [ + { + "label": "৪" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঠ" }, - "default": { "label": "ট" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঠ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ট", + "popup": { + "main": { + "label": "ঠ" + }, + "relevant": [ + { + "label": "৫" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ছ" }, - "default": { "label": "চ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ছ", + "labelFlags": 1073741824 + }, + "default": { + "label": "চ", + "popup": { + "main": { + "label": "ছ" + }, + "relevant": [ + { + "label": "৬" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঝ" }, - "default": { "label": "জ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঝ", + "labelFlags": 1073741824 + }, + "default": { + "label": "জ", + "popup": { + "main": { + "label": "ঝ" + }, + "relevant": [ + { + "label": "৭" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঞ" }, - "default": { "label": "হ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঞ", + "labelFlags": 1073741824 + }, + "default": { + "label": "হ", + "popup": { + "main": { + "label": "ঞ" + }, + "relevant": [ + { + "label": "৮" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঘ" }, - "default": { "label": "গ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঘ", + "labelFlags": 1073741824 + }, + "default": { + "label": "গ", + "popup": { + "main": { + "label": "ঘ" + }, + "relevant": [ + { + "label": "৯" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঢ়" }, - "default": { "label": "ড়" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঢ়", + "labelFlags": 1073741824 + }, + "default": { + "label": "ড়", + "popup": { + "main": { + "label": "ঢ়" + }, + "relevant": [ + { + "label": "০" + } + ] + } + } } ], [ - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঃ" }, - "default": { "label": "ৃ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঃ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ৃ", + "popup": { + "relevant": [ + { + "label": "ঋ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ূ" }, - "default": { "label": "ু" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ূ", + "popup": { + "relevant": [ + { + "label": "ঊ" + } + ] + } + }, + "default": { + "label": "ু", + "popup": { + "relevant": [ + { + "label": "উ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ী" }, - "default": { "label": "ি" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ী", + "popup": { + "relevant": [ + { + "label": "ঈ" + } + ] + } + }, + "default": { + "label": "ি", + "popup": { + "relevant": [ + { + "label": "ই" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "অ" }, - "default": { "label": "া" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "অ", + "labelFlags": 1073741824 + }, + "default": { + "label": "া", + "popup": { + "main": { + "label": "আ" + }, + "relevant": [ + { + "label": "অ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ঁ" }, - "default": { "label": "্" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ঁ", + "labelFlags": 1073741824, + "popup": { + "relevant": [ + { + "label": "!autoColumnOrder!6" + }, + { + "label": "়" + }, + { + "label": "ৄ" + }, + { + "label": "ঽ" + }, + { + "label": "ৢ" + }, + { + "label": "ৱ" + }, + { + "label": "ৣ" + }, + { + "label": "ৗ" + }, + { + "label": "ৠ" + }, + { + "label": "৺" + }, + { + "label": "ঌ" + }, + { + "label": "ৰ" + }, + { + "label": "ৡ" + } + ] + } + }, + "default": { + "label": "্", + "popup": { + "relevant": [ + { + "label": "ঁ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ভ" }, - "default": { "label": "ব" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ভ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ব", + "popup": { + "relevant": [ + { + "label": "ভ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "খ" }, - "default": { "label": "ক" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "খ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ক", + "popup": { + "relevant": [ + { + "label": "খ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "থ" }, - "default": { "label": "ত" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "থ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ত", + "popup": { + "main": { + "label": "থ" + }, + "relevant": [ + { + "label": "ৎ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ধ" }, - "default": { "label": "দ" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ধ", + "labelFlags": 1073741824 + }, + "default": { + "label": "দ", + "popup": { + "relevant": [ + { + "label": "ধ" + } + ] + } + } } ], [ - { "$": "shift_state_selector", - "manualOrLocked": { "label": "্য" }, - "default": { "label": "্র" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "্য", + "labelFlags": 1073741824 + }, + "default": { + "label": "্র", + "popup": { + "relevant": [ + { + "label": "্য" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ৌ" }, - "default": { "label": "ো" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ৌ", + "popup": { + "relevant": [ + { + "label": "ঔ" + } + ] + } + }, + "default": { + "label": "ো", + "popup": { + "relevant": [ + { + "label": "ও" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ৈ" }, - "default": { "label": "ে" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ৈ", + "popup": { + "relevant": [ + { + "label": "ঐ" + } + ] + } + }, + "default": { + "label": "ে", + "popup": { + "relevant": [ + { + "label": "এ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ল" }, - "default": { "label": "র" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ল", + "labelFlags": 1073741824 + }, + "default": { + "label": "র", + "popup": { + "main": { + "label": "ল" + }, + "relevant": [ + { + "label": "র‍্য" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ণ" }, - "default": { "label": "ন" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ণ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ন", + "popup": { + "relevant": [ + { + "label": "ণ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "ষ" }, - "default": { "label": "স" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "ষ", + "labelFlags": 1073741824 + }, + "default": { + "label": "স", + "popup": { + "relevant": [ + { + "label": "ষ" + } + ] + } + } }, - { "$": "shift_state_selector", - "manualOrLocked": { "label": "শ" }, - "default": { "label": "ম" } + { + "$": "shift_state_selector", + "manualOrLocked": { + "label": "শ", + "labelFlags": 1073741824 + }, + "default": { + "label": "ম", + "popup": { + "relevant": [ + { + "label": "শ" + } + ] + } + } } ] -] +] \ No newline at end of file diff --git a/app/src/main/assets/locale_key_texts/bn-BD.txt b/app/src/main/assets/locale_key_texts/bn-BD.txt index 6f602cf66..fe5d56d4d 100644 --- a/app/src/main/assets/locale_key_texts/bn-BD.txt +++ b/app/src/main/assets/locale_key_texts/bn-BD.txt @@ -16,7 +16,7 @@ ী ঈ া আ অ ্ ঁ -ঁ ় ৺ ঽ ৗ ঌ ৡ ৠ ৱ ৢ ৣ ৄ ৰ +ঁ !autoColumnOrder!6 ় ৄ ঽ ৢ ৱ ৣ ৗ ৠ ৺ ঌ ৰ ৡ ব ভ ক খ ত থ ৎ From 82ec37f33923034cbe53eb94e90bbbc5802e3656 Mon Sep 17 00:00:00 2001 From: Eran Leshem <1707552+eranl@users.noreply.github.com> Date: Fri, 31 Jan 2025 23:53:08 +0200 Subject: [PATCH 11/18] Optionally show popup hints on number row (#1303) --- .../keyboard_parser/KeyboardParser.kt | 10 ++++----- .../settings/PreferencesSettingsFragment.java | 21 +++++++++++++++---- .../keyboard/latin/settings/Settings.java | 1 + .../latin/settings/SettingsValues.java | 2 ++ app/src/main/res/values/strings.xml | 2 ++ .../main/res/xml/prefs_screen_preferences.xml | 6 ++++++ 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt index 5f3286767..98540dc6c 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt @@ -17,12 +17,10 @@ import helium314.keyboard.keyboard.internal.keyboard_parser.floris.TextKeyData import helium314.keyboard.latin.common.isEmoji import helium314.keyboard.latin.define.DebugFlags import helium314.keyboard.latin.settings.Settings -import helium314.keyboard.latin.utils.CUSTOM_LAYOUT_PREFIX import helium314.keyboard.latin.utils.POPUP_KEYS_LAYOUT import helium314.keyboard.latin.utils.POPUP_KEYS_NUMBER import helium314.keyboard.latin.utils.ScriptUtils import helium314.keyboard.latin.utils.ScriptUtils.script -import helium314.keyboard.latin.utils.getCustomLayoutFiles import helium314.keyboard.latin.utils.replaceFirst import helium314.keyboard.latin.utils.splitAt import helium314.keyboard.latin.utils.sumOf @@ -88,9 +86,11 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co addNumberRowOrPopupKeys(baseKeys, numberRow) if (params.mId.isAlphabetKeyboard) addSymbolPopupKeys(baseKeys) - if (params.mId.isAlphaOrSymbolKeyboard && params.mId.mNumberRowEnabled) - baseKeys.add(0, numberRow - .mapTo(mutableListOf()) { it.copy(newLabelFlags = Key.LABEL_FLAGS_DISABLE_HINT_LABEL or defaultLabelFlags) }) + if (params.mId.isAlphaOrSymbolKeyboard && params.mId.mNumberRowEnabled) { + val newLabelFlags = defaultLabelFlags or + if (Settings.getInstance().current.mShowNumberRowHints) 0 else Key.LABEL_FLAGS_DISABLE_HINT_LABEL + baseKeys.add(0, numberRow.mapTo(mutableListOf()) { it.copy(newLabelFlags = newLabelFlags) }) + } if (!params.mAllowRedundantPopupKeys) params.baseKeys = baseKeys.flatMap { it.map { it.toKeyParams(params) } } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java b/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java index d1d2a3df3..92184838d 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/PreferencesSettingsFragment.java @@ -54,6 +54,7 @@ public final class PreferencesSettingsFragment extends SubScreenFragment { setupHistoryRetentionTimeSettings(); refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings(); setLocalizedNumberRowVisibility(); + setNumberRowHintsVisibility(); findPreference(Settings.PREF_POPUP_KEYS_LABELS_ORDER).setVisible(getSharedPreferences().getBoolean(Settings.PREF_SHOW_HINTS, false)); findPreference(Settings.PREF_POPUP_KEYS_ORDER).setOnPreferenceClickListener((pref) -> { DialogUtilsKt.reorderDialog(requireContext(), Settings.PREF_POPUP_KEYS_ORDER, @@ -77,12 +78,18 @@ public final class PreferencesSettingsFragment extends SubScreenFragment { refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings(); if (key == null) return; switch (key) { - case Settings.PREF_POPUP_KEYS_ORDER, Settings.PREF_SHOW_POPUP_HINTS, Settings.PREF_SHOW_NUMBER_ROW, + case Settings.PREF_POPUP_KEYS_ORDER, Settings.PREF_SHOW_POPUP_HINTS, Settings.PREF_SHOW_NUMBER_ROW_HINTS, Settings.PREF_POPUP_KEYS_LABELS_ORDER, Settings.PREF_LANGUAGE_SWITCH_KEY, - Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY , Settings.PREF_REMOVE_REDUNDANT_POPUPS-> mReloadKeyboard = true; + Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, Settings.PREF_REMOVE_REDUNDANT_POPUPS -> mReloadKeyboard = true; + case Settings.PREF_SHOW_NUMBER_ROW -> { + setNumberRowHintsVisibility(); + mReloadKeyboard = true; + } case Settings.PREF_LOCALIZED_NUMBER_ROW -> KeyboardLayoutSet.onSystemLocaleChanged(); - case Settings.PREF_SHOW_HINTS - -> findPreference(Settings.PREF_POPUP_KEYS_LABELS_ORDER).setVisible(prefs.getBoolean(Settings.PREF_SHOW_HINTS, false)); + case Settings.PREF_SHOW_HINTS -> { + findPreference(Settings.PREF_POPUP_KEYS_LABELS_ORDER).setVisible(prefs.getBoolean(Settings.PREF_SHOW_HINTS, false)); + setNumberRowHintsVisibility(); + } } } @@ -108,6 +115,12 @@ public final class PreferencesSettingsFragment extends SubScreenFragment { pref.setVisible(false); } + private void setNumberRowHintsVisibility() { + var prefs = getSharedPreferences(); + setPreferenceVisible(Settings.PREF_SHOW_NUMBER_ROW_HINTS, prefs.getBoolean(Settings.PREF_SHOW_HINTS, false) + && prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, false)); + } + private void refreshEnablingsOfKeypressSoundAndVibrationAndHistRetentionSettings() { final SharedPreferences prefs = getSharedPreferences(); final Resources res = getResources(); diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 912384906..d8effb21b 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -147,6 +147,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_SHOW_NUMBER_ROW = "show_number_row"; public static final String PREF_LOCALIZED_NUMBER_ROW = "localized_number_row"; + public static final String PREF_SHOW_NUMBER_ROW_HINTS = "show_number_row_hints"; public static final String PREF_CUSTOM_CURRENCY_KEY = "custom_currency_key"; public static final String PREF_SHOW_HINTS = "show_hints"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 2c1e494ca..acee04aa3 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -70,6 +70,7 @@ public class SettingsValues { private final boolean mShowsLanguageSwitchKey; public final boolean mShowsNumberRow; public final boolean mLocalizedNumberRow; + public final boolean mShowNumberRowHints; public final boolean mShowsHints; public final boolean mShowsPopupHints; public final boolean mSpaceForLangChange; @@ -174,6 +175,7 @@ public class SettingsValues { mShowsLanguageSwitchKey = prefs.getBoolean(Settings.PREF_SHOW_LANGUAGE_SWITCH_KEY, false); // only relevant for default functional key layout mShowsNumberRow = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW, false); mLocalizedNumberRow = prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, true); + mShowNumberRowHints = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW_HINTS, false); mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, true); mShowsPopupHints = prefs.getBoolean(Settings.PREF_SHOW_POPUP_HINTS, false); mSpaceForLangChange = prefs.getBoolean(Settings.PREF_SPACE_TO_CHANGE_LANG, true); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 35d14c3e2..9607ac2f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -239,6 +239,8 @@ Localize number row Prefer localized over latin numbers + + Show hints on number row Show key hints diff --git a/app/src/main/res/xml/prefs_screen_preferences.xml b/app/src/main/res/xml/prefs_screen_preferences.xml index 915d8a5b9..858016f8b 100644 --- a/app/src/main/res/xml/prefs_screen_preferences.xml +++ b/app/src/main/res/xml/prefs_screen_preferences.xml @@ -85,6 +85,12 @@ android:defaultValue="true" android:persistent="true" /> + + Date: Mon, 3 Feb 2025 02:46:11 +0600 Subject: [PATCH 12/18] Improve behavior for language swipe cycling (#1319) --------- Co-authored-by: Helium314 --- .../keyboard/KeyboardActionListener.java | 3 ++ .../keyboard/KeyboardActionListenerImpl.kt | 25 ++++++++++++++-- .../keyboard/keyboard/PointerTracker.java | 1 + .../settings/AdvancedSettingsFragment.kt | 30 +++++++++++++++++++ .../keyboard/latin/settings/Settings.java | 13 ++++++++ .../latin/settings/SettingsValues.java | 2 ++ app/src/main/res/values-bn/strings.xml | 1 + app/src/main/res/values/strings.xml | 2 ++ .../main/res/xml/prefs_screen_advanced.xml | 7 +++++ 9 files changed, 82 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java index 224337f34..fb177e806 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListener.java @@ -97,6 +97,7 @@ public interface KeyboardActionListener { */ boolean onHorizontalSpaceSwipe(int steps); boolean onVerticalSpaceSwipe(int steps); + void onEndSpaceSwipe(); boolean toggleNumpad(boolean withSliding, boolean forceReturnToAlpha); void onMoveDeletePointer(int steps); @@ -148,6 +149,8 @@ public interface KeyboardActionListener { return false; } @Override + public void onEndSpaceSwipe() {} + @Override public void onMoveDeletePointer(int steps) {} @Override public void onUpWithDeletePointerActive() {} diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt index faf9b963b..47ed38340 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt @@ -1,6 +1,7 @@ package helium314.keyboard.keyboard import android.view.KeyEvent +import android.view.inputmethod.InputMethodSubtype import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode import helium314.keyboard.latin.LatinIME import helium314.keyboard.latin.RichInputMethodManager @@ -19,6 +20,10 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp private val settings = Settings.getInstance() private var metaState = 0 // is this enough, or are there threading issues with the different PointerTrackers? + // language slide state + private var initialSubtype: InputMethodSubtype? = null + private var subtypeSwitchCount = 0 + // todo: maybe keep meta state presses to KeyboardActionListenerImpl, and avoid calls to press/release key private fun adjustMetaState(code: Int, remove: Boolean) { val metaCode = when (code) { @@ -84,6 +89,11 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp else -> false } + override fun onEndSpaceSwipe(){ + initialSubtype = null + subtypeSwitchCount = 0 + } + override fun toggleNumpad(withSliding: Boolean, forceReturnToAlpha: Boolean): Boolean { KeyboardSwitcher.getInstance().toggleNumpad(withSliding, latinIME.currentAutoCapsState, latinIME.currentRecapitalizeState, forceReturnToAlpha) return true @@ -124,7 +134,7 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp } private fun onLanguageSlide(steps: Int): Boolean { - if (abs(steps) < 4) return false + if (abs(steps) < settings.current.mLanguageSwipeDistance) return false val subtypes = RichInputMethodManager.getInstance().getMyEnabledInputMethodSubtypeList(false) if (subtypes.size <= 1) { // only allow if we have more than one subtype return false @@ -135,7 +145,18 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp wantedIndex %= subtypes.size if (wantedIndex < 0) wantedIndex += subtypes.size - KeyboardSwitcher.getInstance().switchToSubtype(subtypes[wantedIndex]) + val newSubtype = subtypes[wantedIndex] + + // do not switch if we would switch to the initial subtype after cycling all other subtypes + if (initialSubtype == null) + initialSubtype = current + if (initialSubtype == newSubtype) { + if ((subtypeSwitchCount > 0 && steps > 0) || ((subtypeSwitchCount < 0 && steps < 0))) + return true + } + if (steps > 0) subtypeSwitchCount++ else subtypeSwitchCount-- + + KeyboardSwitcher.getInstance().switchToSubtype(newSubtype) return true } diff --git a/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java b/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java index f47dc3ea6..7dcd62213 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java +++ b/app/src/main/java/helium314/keyboard/keyboard/PointerTracker.java @@ -1076,6 +1076,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, if (mInHorizontalSwipe || mInVerticalSwipe) { mInHorizontalSwipe = false; mInVerticalSwipe = false; + sListener.onEndSpaceSwipe(); return; } } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt index 946bf1aa2..c2dc11101 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/AdvancedSettingsFragment.kt @@ -25,6 +25,7 @@ import androidx.preference.PreferenceManager import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import helium314.keyboard.dictionarypack.DictionaryPackConstants +import helium314.keyboard.keyboard.KeyboardActionListener import helium314.keyboard.latin.utils.ChecksumCalculator import helium314.keyboard.keyboard.KeyboardLayoutSet import helium314.keyboard.keyboard.KeyboardSwitcher @@ -125,6 +126,8 @@ class AdvancedSettingsFragment : SubScreenFragment() { } setupKeyLongpressTimeoutSettings() setupEmojiSdkSetting() + setupLanguageSwipeDistanceSettings() + updateLangSwipeDistanceVisibility(sharedPreferences) findPreference("load_gesture_library")?.setOnPreferenceClickListener { onClickLoadLibrary() } findPreference("backup_restore")?.setOnPreferenceClickListener { showBackupRestoreDialog() } @@ -560,10 +563,37 @@ class AdvancedSettingsFragment : SubScreenFragment() { }) } + private fun setupLanguageSwipeDistanceSettings() { + val prefs = sharedPreferences + findPreference(Settings.PREF_LANGUAGE_SWIPE_DISTANCE)?.setInterface(object : ValueProxy { + override fun writeValue(value: Int, key: String) = prefs.edit().putInt(key, value).apply() + + override fun writeDefaultValue(key: String) = prefs.edit().remove(key).apply() + + override fun readValue(key: String) = Settings.readLanguageSwipeDistance(prefs, resources) + + override fun readDefaultValue(key: String) = Settings.readDefaultLanguageSwipeDistance(resources) + + override fun getValueText(value: Int) = value.toString() + + override fun feedbackValue(value: Int) {} + }) + } + + private fun updateLangSwipeDistanceVisibility(prefs: SharedPreferences) { + val horizontalSpaceSwipe = Settings.readHorizontalSpaceSwipe(prefs) + val verticalSpaceSwipe = Settings.readVerticalSpaceSwipe(prefs) + val visibility = horizontalSpaceSwipe == KeyboardActionListener.SWIPE_SWITCH_LANGUAGE + || verticalSpaceSwipe == KeyboardActionListener.SWIPE_SWITCH_LANGUAGE + setPreferenceVisible(Settings.PREF_LANGUAGE_SWIPE_DISTANCE, visibility) + } + override fun onSharedPreferenceChanged(prefs: SharedPreferences, key: String?) { when (key) { Settings.PREF_SHOW_SETUP_WIZARD_ICON -> SystemBroadcastReceiver.toggleAppIcon(requireContext()) Settings.PREF_MORE_POPUP_KEYS -> KeyboardLayoutSet.onSystemLocaleChanged() + Settings.PREF_SPACE_HORIZONTAL_SWIPE -> updateLangSwipeDistanceVisibility(prefs) + Settings.PREF_SPACE_VERTICAL_SWIPE -> updateLangSwipeDistanceVisibility(prefs) Settings.PREF_EMOJI_MAX_SDK -> KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext()) } } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index d8effb21b..32507b8dd 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -157,6 +157,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_MORE_POPUP_KEYS = "more_popup_keys"; public static final String PREF_SPACE_TO_CHANGE_LANG = "prefs_long_press_keyboard_to_change_lang"; + public static final String PREF_LANGUAGE_SWIPE_DISTANCE = "language_swipe_distance"; public static final String PREF_ENABLE_CLIPBOARD_HISTORY = "enable_clipboard_history"; public static final String PREF_CLIPBOARD_HISTORY_RETENTION_TIME = "clipboard_history_retention_time"; @@ -453,6 +454,18 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang }; } + public static int readLanguageSwipeDistance(final SharedPreferences prefs, + final Resources res) { + final int sensitivity = prefs.getInt( + PREF_LANGUAGE_SWIPE_DISTANCE, UNDEFINED_PREFERENCE_VALUE_INT); + return (sensitivity != UNDEFINED_PREFERENCE_VALUE_INT) ? sensitivity + : readDefaultLanguageSwipeDistance(res); + } + + public static int readDefaultLanguageSwipeDistance(final Resources res) { + return 5; + } + public static boolean readDeleteSwipeEnabled(final SharedPreferences prefs) { return prefs.getBoolean(PREF_DELETE_SWIPE, true); } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index acee04aa3..c42825e22 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -81,6 +81,7 @@ public class SettingsValues { public final boolean mBlockPotentiallyOffensive; public final int mSpaceSwipeHorizontal; public final int mSpaceSwipeVertical; + public final int mLanguageSwipeDistance; public final boolean mDeleteSwipeEnabled; public final boolean mAutospaceAfterPunctuationEnabled; public final boolean mClipboardHistoryEnabled; @@ -232,6 +233,7 @@ public class SettingsValues { mDisplayOrientation = res.getConfiguration().orientation; mSpaceSwipeHorizontal = Settings.readHorizontalSpaceSwipe(prefs); mSpaceSwipeVertical = Settings.readVerticalSpaceSwipe(prefs); + mLanguageSwipeDistance = Settings.readLanguageSwipeDistance(prefs, res); mDeleteSwipeEnabled = Settings.readDeleteSwipeEnabled(prefs); mAutospaceAfterPunctuationEnabled = Settings.readAutospaceAfterPunctuationEnabled(prefs); mClipboardHistoryEnabled = Settings.readClipboardHistoryEnabled(prefs); diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index e435e95b6..bdee0e28d 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -377,6 +377,7 @@ নম্বর প্যাডের জন্য প্রতীক বোতামে দীর্ঘ চাপ টুলবারের পরিবর্তনশীল দিক ডান থেকে বাম কিবোর্ড নির্বাচন করলে দিক বিপরীত হবে + ভাষা পরিবর্তন অভিস্পর্শের দূরত্ব %s (শিক্ষার্থী) ভাষা পরিবর্তন বোতামের আচরণ পিন করে রাখা টুলবার বোতাম নির্বাচন diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9607ac2f4..d98108329 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -958,6 +958,8 @@ New dictionary: Variable toolbar direction Reverse direction when a right-to-left keyboard subtype is selected + + Switch language swipe distance Customize toolbar key codes diff --git a/app/src/main/res/xml/prefs_screen_advanced.xml b/app/src/main/res/xml/prefs_screen_advanced.xml index 2ecddb6c9..35474182c 100644 --- a/app/src/main/res/xml/prefs_screen_advanced.xml +++ b/app/src/main/res/xml/prefs_screen_advanced.xml @@ -43,6 +43,13 @@ android:title="@string/show_vertical_space_swipe" latin:singleLineTitle="false" /> + + Date: Sun, 2 Feb 2025 21:50:33 +0100 Subject: [PATCH 13/18] clarify that some parts of the contribution guidelines are (strongly) recommended, but not necessary --- .github/PULL_REQUEST_TEMPLATE.md | 13 ++++--- CONTRIBUTING.md | 65 ++++++++++++++++++++++++-------- layouts.md | 4 +- 3 files changed, 59 insertions(+), 23 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1a09875c8..cede865ca 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,18 +1,19 @@ -See the contributing readme for more detailed guideline, please understand and accept them: https://github.com/Helium314/HeliBoard/blob/main/CONTRIBUTING.md -tl;dr (you should still read the full list though): -* make sure it's wanted +See the contributing readme for more detailed guidelines: https://github.com/Helium314/HeliBoard/blob/main/CONTRIBUTING.md#guidelines +tl;dr: +necessary; * a single thing only * describe it properly +recommended: +* make changes optional * re-use existing mechanisms / code * low performance impact * make it a draft if you still want to work on it -* no translations or dictionaries A good description and small scope ("single thing") massively help with reviewing. Don't be surprised when your PR gets closes if you clearly / repeatedly violate these parts of the guidelines. Further * When the PR contains "fixes" , the related issue will be linked and automatically closed if the PR is merged (also works for other words like "fix", "resolve", "resolves", "closes", ...) -* If you add a keyboard layout, make sure you also read https://github.com/Helium314/HeliBoard/blob/main/layouts.md#adding-new-layouts--languages -* Please avoid force-pushing when doing changes unless you have a good reason. This way it's not possible to see which parts have changed since the previous state. +* If you add a keyboard layout, best read https://github.com/Helium314/HeliBoard/blob/main/layouts.md#adding-new-layouts--languages +* Please avoid force-pushing when doing requested changes. This way it's not possible to see which parts have changed since the previous state. \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 93ed9feb0..5983acefd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,31 +6,64 @@ Once everything is up correctly, you're ready to go! If you have difficulties implementing some functionality, you're welcome to ask for help. No one will write the code for you, but often other contributors can give you very useful hints. +# About the Code + +HeliBoard is based on AOSP keyboard, and in many places still contains mostly the original code. There are some extensions, and some parts have been replaced completely. +When working on this app, you will likely notice its rather large size, and quite different code styles and often ancient comments and _TODO_s, where the latter are typically untouched since AOSP times. +Unfortunately a lot of the old code is hard to read or to fully understand with all of its intended (and unintended) consequences. + +Some hints for finding what you're looking for: +* Layouts: stored in `layouts` folder in assets, interpreted by `KeyboardParser` and `TextKeyData` + * Popups: either on layouts, or in `locale_key_texts` (mostly letter variations for specific languages that are not dependent on layout) +* Touch and swipe input handling: `PointerTracker` +* Handling of key inputs: `InputLogic` +* Suggestions: `DictionaryFacilitatorImpl`, `Suggest`, `InputLogic`, and `SuggestionStripView` (in order from creation to display) +* Forwarding entered text / keys to the app / text field: `RichInputConnection` +* Receiving events and information from the app / text field: `LatinIME` + # Guidelines -HeliBoard is a complex application, when contributing, you must take a step back and make sure your contribution: -- **Is actually wanted**. Best check related open issues before you start working on a PR. Issues with the [labels](https://github.com/Helium314/HeliBoard/labels) [_PR_](https://github.com/Helium314/HeliBoard/labels/PR) and [_contributor needed_](https://github.com/Helium314/HeliBoard/issues?q=label%3A%22contributor%20needed%22) (even closed ones) are accepted, but still it would be good if you announced that you are working on it, so we can discuss how changes are best implemented. - If there is no accepted issue related to your intended contribution, it's a good idea to open a new one (and of course getting one of "PR" or "contributor needed" labels) to avoid disappointment of the contribution not being accepted. For small changes or fixing obvious bugs this step is not necessary. -- **Is only about a single thing**. Mixing unrelated or semi-related contributions into a single PR is hard to review and can get messy. -- **Is finished or a draft**. When you keep changing the PR without reviewer's feedback, any attempt to review it is doomed and a waste of time. Better mark it as a draft in this case. -- **Has a proper description**. What your contribution does is usually less obvious to reviewers than for yourself. A good description helps _a lot_ for understanding what is going on, and for separating wanted from unintended changes in behavior. Therefore the changes should be as described, not more and not less. -- **Uses already in-place mechanism and take advantage of them**. In other terms, does not reinvent the wheel or uses shortcuts that could alter the consistency of the existing code. The contribution should only add as little complexity as necessary, the code is overly complicated already 😶. -- **Has a low footprint**. Some parts of the code are executed very frequently, and the keyboard should stay responsive even on older devices. -- **Does not bring any non-free code or proprietary binary blobs**. This also applies to code/binaries with unknown licenses. Make sure you do not introduce any closed-source library from Google. - If your contribution contains code that is not your own, provide a link to the source. -- **Does not increase app size too much**. Just code changes or adding icons is not in issue, but e.g. large dependencies or adding more default dictionaries will not be accepted. -- **Complies with the user privacy principle HeliBoard follows**. +## Recommended -A good description and small scope ("single thing") massively help with reviewing. Don't be surprised when your PR gets closes if you clearly / repeatedly violate these parts of the guidelines. -If possible try to keep your changes contained, i.e. in few places as opposed to sprinkling them over many parts of the code. This helps with both review and maintainability of the app. +If you want to contribute, it's a good idea to make sure your idea is actually wanted in HeliBoard. +Best check related issues before you start working on a PR. If the issue has the [labels](https://github.com/Helium314/HeliBoard/labels) [_PR_](https://github.com/Helium314/HeliBoard/labels/PR) or [_contributor needed_](https://github.com/Helium314/HeliBoard/issues?q=label%3A%22contributor%20needed%22) (even closed ones), contributions are wanted. If you don't find a related issue, it's recommended to open one, but ultimately it's your choice. +Asking before starting a PR may help you for getting pointers to potentially relevant code, and deciding how to implement your desired changes. -Please leave dependency upgrades to the maintainers, unless it's an actual security issue. +HeliBoard is a complex application and used by users with a large variety of opinions on how things should be. +When contributing to the app, please: +* Be careful when modifying core components, as it's easy to trigger unintended consequences +* When introducing a feature or change that might not be wanted by everyone, make it optional +* Keep code simple where possible. Complex code is harder to review and to maintain, so the complexity should also add a clear benefit +* Avoid noticeable performance impact. Some parts of the code are executed very frequently, and the keyboard should stay responsive even on older devices. +* Try making use of in-place mechanisms instead of re-inventing the wheel. Your contribution should only add as much complexity as necessary, the code is overly complicated already 😶. +* Keep your changes to few places, as opposed to sprinkling them over many parts of the code. This helps with keeping down complexity during review, and with maintainability of the app. +* Make a draft PR when you intend to still work on it. Submitting an unfinished PR can be a good idea when you're not sure how to best continue and would like some comments. -# Adding Layouts +Further things to consider (though irrelevant for most PRs): +* APK size: + * Large increases should be discussed first, and will only be added when it's considered worth the increase for a majority of users. It might be possible to avoid size increase by importing optional parts, like it's done for dictionaries. + * Small increases like when adding code or layouts are never an issue +* Do not add proprietary code or binary blobs. If it turns out to be necessary for a feature you want to add, it might be acceptable when the user opts in and imports those parts, like it's done for glide typing. +* Privacy: Only relevant when adding some form of communication with other apps. Internet permission will not be added. +* If your contribution contains code that is not your own, provide a link to the source + * This is especially relevant to be sure the code's license is compatible to HeliBoard's GPL3 + +## Necessary + +Some parts of the guidelines are necessary to fulfill for facilitating code review. It doesn't need to be perfect from the start, but consider it for your future PRs when you're reminded of these guidelines. Note that the larger / more complex your PR is, the more relevant these guidelines are. +Your PR should: +- **Be only about a single thing**. Mixing unrelated or semi-related contributions into a single PR is hard to review and can get messy. As a general rule: if one part doesn't need the other one(s), it should be separate PRs. If one feature builds on top of another one, but the base is usable on its own, do a PR for the base and then a follow-up once it's merged. +- **Have a proper description**. A good description helps _a lot_ for understanding what you intend to achieve with the changes, and for understanding the code. This is relevant for separating wanted from unintended changes in behavior during review. +- **No translations**. Translations should be done using [Weblate](https://translate.codeberg.org/projects/heliboard/). Exception is when you add new resource strings, those can be added right away. + +Please leave dependency upgrades to the maintainers, unless you state a good reason why they should be done now. + +# Adding / Adjusting Layouts See [layouts.md](layouts.md#adding-new-layouts--languages) for how to add new layouts to the app. Please stay in line with other layouts regarding the popup keys. When editing existing layouts, please consider that people should should still get what they're used to. In case of doubt it might be better to add a new layout instead of overhauling existing layouts. +`locale_key_texts` files should only contain letters that are actually part of the language, with exception of the optional `more_popups_<...>.txt` files. # Update Emojis diff --git a/layouts.md b/layouts.md index f58119413..2af0f5624 100644 --- a/layouts.md +++ b/layouts.md @@ -1,9 +1,11 @@ -A compilation of information about the layout formats usable in this app. +# A compilation of information about the layout formats usable in this app. There are two distinct formats: * the _simple_ format is a text file with one key label per line, and two consecutive line breaks indicating a switch to the next row, [example](app/src/main/assets/layouts/qwerty.txt) * the _json_ format taken from [FlorisBoard](https://github.com/florisboard/florisboard/blob/master/CONTRIBUTING.md#adding-the-layout), but only "normal" keys are supported (i.e. no action keys and similar), [example](app/src/main/assets/layouts/azerty.json) +You can add both directly in the app, see the related [FAQ](https://github.com/Helium314/HeliBoard/wiki/Customization#layouts). + ## General notes Adding too many keys or too long texts will make the keyboard look awkward or broken, and even crash the app under some specific conditions (popup keys are especially prone for this). There are some sanity checks when adding a layout to avoid such issues, but they do not cover all possible cases. From ad3086183d25246e8d6d312ee6ddc31a92d4d670 Mon Sep 17 00:00:00 2001 From: QuantumSoul Date: Sun, 2 Feb 2025 21:52:07 +0100 Subject: [PATCH 14/18] Arabic Hija'i Layout (#1329) --------- Co-authored-by: Helium314 --- app/src/main/assets/layouts/arabic_hijai.txt | 34 ++++++++++++++++++++ app/src/main/res/values/donottranslate.xml | 3 ++ app/src/main/res/xml/method.xml | 9 ++++++ 3 files changed, 46 insertions(+) create mode 100644 app/src/main/assets/layouts/arabic_hijai.txt diff --git a/app/src/main/assets/layouts/arabic_hijai.txt b/app/src/main/assets/layouts/arabic_hijai.txt new file mode 100644 index 000000000..acc3a007d --- /dev/null +++ b/app/src/main/assets/layouts/arabic_hijai.txt @@ -0,0 +1,34 @@ +ز +ر +ذ +د +خ +ح +ج +ث +ت +ب +ا + +ك +ق +ف +غ +ع +ظ +ط +ض +ص +ش +س + +ء +ى +ي +ؤ +و +ة +ﻩ +ن +م +ل diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index da960d9c3..bc2565a93 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -86,6 +86,9 @@ %s (PC) + + %s (Hija\'i) + %s (1452-2) diff --git a/app/src/main/res/xml/method.xml b/app/src/main/res/xml/method.xml index ba0013c9c..7bc82787c 100644 --- a/app/src/main/res/xml/method.xml +++ b/app/src/main/res/xml/method.xml @@ -178,6 +178,15 @@ android:imeSubtypeExtraValue="KeyboardLayoutSet=arabic_pc,NoShiftKey,EmojiCapable" android:isAsciiCapable="false" /> + Date: Mon, 3 Feb 2025 00:11:34 +0100 Subject: [PATCH 15/18] improve detection of emojis when deleting --- .../keyboard/latin/common/StringUtils.kt | 19 +++++++++++++++---- .../keyboard/latin/StringUtilsTest.kt | 11 +++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/common/StringUtils.kt b/app/src/main/java/helium314/keyboard/latin/common/StringUtils.kt index 69e8243db..98e5bebab 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/StringUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/StringUtils.kt @@ -62,21 +62,32 @@ fun getFullEmojiAtEnd(s: CharSequence): String { while (offset > 0) { val codepoint = text.codePointBefore(offset) // stop if codepoint can't be emoji - if (!mightBeEmoji(codepoint)) return "" + if (!mightBeEmoji(codepoint)) + return text.substring(offset) offset -= Character.charCount(codepoint) - // todo: if codepoint in 0x1F3FB..0x1F3FF -> combine with other emojis in front, but only if they actually combine - // why isn't this done with zwj like everything else? skin tones can be emojis by themselves... if (offset > 0 && text[offset - 1].code == KeyCode.ZWJ) { + // todo: this appends ZWJ in weird cases like text, ZWJ, emoji + // and detects single ZWJ as emoji (at least irrelevant for current use of getFullEmojiAtEnd) offset -= 1 continue } + + if (codepoint in 0x1F3FB..0x1F3FF) { + // Skin tones are not added with ZWJ, but just appended. This is not nice as they can be emojis on their own, + // but that's how it is done. Assume that an emoji before the skin tone will get merged (usually correct in practice) + val codepointBefore = text.codePointBefore(offset) + if (isEmoji(codepointBefore)) { + offset -= Character.charCount(codepointBefore) + continue + } + } // check the whole text after offset val textToCheck = text.substring(offset) if (isEmoji(textToCheck)) { return textToCheck } } - return "" + return text.substring(offset) } /** split the string on the first of consecutive space only, further consecutive spaces are added to the next split */ diff --git a/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt b/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt index 518b6ffe1..e2bf6adbf 100644 --- a/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt @@ -42,6 +42,8 @@ class StringUtilsTest { } @Test fun detectEmojisAtEnd() { + assertEquals("", getFullEmojiAtEnd("\uD83C\uDF83 ")) + assertEquals("", getFullEmojiAtEnd("a")) assertEquals("\uD83C\uDF83", getFullEmojiAtEnd("\uD83C\uDF83")) assertEquals("ℹ️", getFullEmojiAtEnd("ℹ️")) assertEquals("ℹ️", getFullEmojiAtEnd("ℹ️ℹ️")) @@ -51,6 +53,15 @@ class StringUtilsTest { assertEquals("\uD83C\uDFF3️\u200D\uD83C\uDF08", getFullEmojiAtEnd("\uD83C\uDFF3️\u200D\uD83C\uDF08")) assertEquals("\uD83C\uDFF3️\u200D\uD83C\uDF08", getFullEmojiAtEnd("\uD83C\uDFF4\u200D☠️\uD83C\uDFF3️\u200D\uD83C\uDF08")) assertEquals("\uD83C\uDFF3️\u200D⚧️", getFullEmojiAtEnd("hello there🏳️‍⚧️")) + assertEquals("\uD83D\uDD75\uD83C\uDFFC", getFullEmojiAtEnd(" 🕵🏼")) + assertEquals("\uD83D\uDD75\uD83C\uDFFC", getFullEmojiAtEnd("🕵🏼")) + assertEquals("\uD83C\uDFFC", getFullEmojiAtEnd(" \uD83C\uDFFC")) + // fails, but unlikely enough that we leave it unfixed + //assertEquals("\uD83C\uDFFC", getFullEmojiAtEnd("\uD83C\uDF84\uD83C\uDFFC")) + // below also fail, because ZWJ handling is not suitable for some unusual cases + //assertEquals("", getFullEmojiAtEnd("\u200D")) + //assertEquals("", getFullEmojiAtEnd("a\u200D")) + //assertEquals("\uD83D\uDE22", getFullEmojiAtEnd(" \u200D\uD83D\uDE22")) } // todo: add tests for emoji detection? From f2a46cfa9a84c32660e12e6db007822aae8737db Mon Sep 17 00:00:00 2001 From: Helium314 Date: Mon, 3 Feb 2025 00:20:48 +0100 Subject: [PATCH 16/18] disable undo-like functionality for textInput, fixes #1019 --- .../keyboard/latin/inputlogic/InputLogic.java | 7 ++++- .../keyboard/latin/InputLogicTest.kt | 29 +++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index ff782ebd8..a2f4fdb38 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -1212,7 +1212,12 @@ public final class InputLogic { } return; } - if (mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) { + // todo: this is currently disabled, as it causes inconsistencies with textInput, depending whether the end + // is part of a word (where we start composing) or not (where we end in code below) + // see https://github.com/Helium314/HeliBoard/issues/1019 + // with better emoji detection on backspace (getFullEmojiAtEnd), this functionality might not be necessary + // -> enable again if there are issues, otherwise delete the code, together with mEnteredText + if (false && mEnteredText != null && mConnection.sameAsTextBeforeCursor(mEnteredText)) { // Cancel multi-character input: remove the text we just entered. // This is triggered on backspace after a key that inputs multiple characters, // like the smiley key or the .com key. diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index 08cf13fdc..41cf69de5 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -613,6 +613,35 @@ class InputLogicTest { assertEquals("{\"label\": \"c", text) } + @Test fun `text input and delete`() { + reset() + input("hello") + assertEquals("hello", text) + functionalKeyPress(KeyCode.DELETE) + assertEquals("hell", text) + + reset() + input("hello ") + assertEquals("hello ", text) + functionalKeyPress(KeyCode.DELETE) + assertEquals("hello", text) + } + + @Test fun `emoji text input and delete`() { + reset() + input("🕵🏼") + functionalKeyPress(KeyCode.DELETE) + assertEquals("", text) + + reset() + input("\uD83D\uDD75\uD83C\uDFFC") + input(' ') + assertEquals("🕵🏼 ", text) + functionalKeyPress(KeyCode.DELETE) + functionalKeyPress(KeyCode.DELETE) + assertEquals("", text) + } + // ------- helper functions --------- // should be called before every test, so the same state is guaranteed From 7c77f4d1c4e62d607892a5cc9d18d77bbd5da304 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Mon, 3 Feb 2025 20:44:30 +0100 Subject: [PATCH 17/18] add tests related to #210 --- .../keyboard/latin/InputLogicTest.kt | 42 ++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index 41cf69de5..9aa488f66 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -642,6 +642,28 @@ class InputLogicTest { assertEquals("", text) } + @Test fun `revert autocorrect on delete`() { + reset() + chainInput("hullo") + getAutocorrectedWithSpaceAfter("hello", "hullo") + functionalKeyPress(KeyCode.DELETE) + assertEquals("hullo", text) + + // todo: now we want some way to disable revert on backspace, either per setting or something else + // need to avoid getting into the mLastComposedWord.canRevertCommit() part of handleBackspaceEvent + } + + @Test fun `remove glide typing word on delete`() { + reset() + glideTypingInput("hello") + assertEquals("hello", text) + functionalKeyPress(KeyCode.DELETE) + assertEquals("", text) + + // todo: now we want some way to disable delete-all on backspace, either per setting or something else + // need to avoid getting into the mWordComposer.isBatchMode() part of handleBackspaceEvent + } + // ------- helper functions --------- // should be called before every test, so the same state is guaranteed @@ -675,6 +697,7 @@ class InputLogicTest { if (currentScript != ScriptUtils.SCRIPT_HANGUL // check fails if hangul combiner merges symbols && !(codePoint == Constants.CODE_SPACE && oldBefore.lastOrNull() == ' ') // check fails when 2 spaces are converted into a period + && !latinIME.mInputLogic.mSuggestedWords.mWillAutoCorrect // autocorrect obviously creates inconsistencies ) { if (phantomSpaceToInsert.isEmpty()) assertEquals(oldBefore + insert, textBeforeCursor) @@ -780,6 +803,22 @@ class InputLogicTest { checkConnectionConsistency() } + // only works when autocorrect is on, separator after word is required + private fun getAutocorrectedWithSpaceAfter(suggestion: String, typedWord: String?) { + val info = SuggestedWordInfo(suggestion, "", 0, 0, null, 0, 0) + val typedInfo = SuggestedWordInfo(typedWord, "", 0, 0, null, 0, 0) + val sw = SuggestedWords(ArrayList(listOf(typedInfo, info)), null, typedInfo, false, true, false, 0, 0) + latinIME.mInputLogic.setSuggestedWords(sw) + input(' ') + checkConnectionConsistency() + } + + private fun glideTypingInput(word: String) { + val info = SuggestedWordInfo(word, "", 0, 0, null, 0, 0) + val sw = SuggestedWords(ArrayList(listOf(info)), null, info, true, false, false, 0, 0) + latinIME.mInputLogic.onUpdateTailBatchInputCompleted(settingsValues, sw, KeyboardSwitcher.getInstance()) + } + private fun checkConnectionConsistency() { // RichInputConnection only has composing text up to cursor, but InputConnection has full composing text val expectedConnectionComposingText = if (composingStart == -1 || composingEnd == -1) "" @@ -998,11 +1037,12 @@ private val ic = object : InputConnection { it.selectionEnd = selectionEnd } } + // only effect is flashing, so whatever... + override fun commitCorrection(p0: CorrectionInfo?): Boolean = true // implement only when necessary override fun getCursorCapsMode(p0: Int): Int = TODO("Not yet implemented") override fun deleteSurroundingTextInCodePoints(p0: Int, p1: Int): Boolean = TODO("Not yet implemented") override fun commitCompletion(p0: CompletionInfo?): Boolean = TODO("Not yet implemented") - override fun commitCorrection(p0: CorrectionInfo?): Boolean = TODO("Not yet implemented") override fun performEditorAction(p0: Int): Boolean = TODO("Not yet implemented") override fun performContextMenuAction(p0: Int): Boolean = TODO("Not yet implemented") override fun clearMetaKeyStates(p0: Int): Boolean = TODO("Not yet implemented") From c0b3e767417a8e2758c1d1c86b583e7ec8addb65 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Thu, 6 Feb 2025 22:46:24 +0100 Subject: [PATCH 18/18] use backspace key event instead of deleteSurroundingText when a browser claims it does not have text before the cursor fixes #1337 --- .../helium314/keyboard/latin/inputlogic/InputLogic.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index a2f4fdb38..c4ad7c0e5 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -1302,7 +1302,13 @@ public final class InputLogic { // broken apps expect something to happen in this case so that they can // catch it and have their broken interface react. If you need the keyboard // to do this, you're doing it wrong -- please fix your app. - mConnection.deleteTextBeforeCursor(1); + // To make this more interesting, web browsers, and apps that are basically + // browsers under the hood, in too many cases don't understand "deleteSurroundingText". + // So we try to send a backspace keypress instead. + if ((getCurrentInputEditorInfo().inputType & InputType.TYPE_MASK_VARIATION) + == InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT) + sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL); + else mConnection.deleteTextBeforeCursor(1); // TODO: Add a new StatsUtils method onBackspaceWhenNoText() return; }