diff --git a/CHANGELOG.md b/CHANGELOG.md
index 72f7757a..c98f44ed 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,8 +6,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
### Added
+- Optional key to quickly switch keyboard language ([#62])
- Added apostrophe as a pop-up character on the dot key ([#356])
+### Changed
+- The space bar now shows the currently selected language ([#62])
+- Space bar cursor control now activates immediately on swipe ([#129])
+
## [1.7.0] - 2025-12-16
### Added
- Option to disable the emoji key ([#234])
@@ -116,9 +121,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Initial release
[#47]: https://github.com/FossifyOrg/Keyboard/issues/47
+[#62]: https://github.com/FossifyOrg/Keyboard/issues/62
[#78]: https://github.com/FossifyOrg/Keyboard/issues/78
[#100]: https://github.com/FossifyOrg/Keyboard/issues/100
[#117]: https://github.com/FossifyOrg/Keyboard/issues/117
+[#129]: https://github.com/FossifyOrg/Keyboard/issues/129
[#133]: https://github.com/FossifyOrg/Keyboard/issues/133
[#134]: https://github.com/FossifyOrg/Keyboard/issues/134
[#136]: https://github.com/FossifyOrg/Keyboard/issues/136
diff --git a/app/detekt-baseline.xml b/app/detekt-baseline.xml
index 7c17b114..78d5f011 100644
--- a/app/detekt-baseline.xml
+++ b/app/detekt-baseline.xml
@@ -8,8 +8,7 @@
ComplexCondition:MyKeyboardView.kt$MyKeyboardView$(show && keyboardViewBinding?.clipboardValue!!.alpha == 0f) || (!show && keyboardViewBinding?.clipboardValue!!.alpha == 1f)
ComplexCondition:MyKeyboardView.kt$MyKeyboardView$key.label.isNotEmpty() && key.code != KEYCODE_MODE_CHANGE && key.code != KEYCODE_SYMBOLS_MODE_CHANGE && key.code != KEYCODE_SHIFT
ComplexCondition:MyKeyboardView.kt$MyKeyboardView$mBuffer == null || mKeyboardChanged && (mBuffer!!.width != width || mBuffer!!.height != height)
- CyclomaticComplexMethod:Context.kt$fun Context.getKeyboardLanguageText(language: Int): String
- CyclomaticComplexMethod:Context.kt$fun Context.setupKeyboardDialogStuff( windowToken: IBinder, view: View, dialog: AlertDialog.Builder, titleId: Int = 0, titleText: String = "", cancelOnTouchOutside: Boolean = true, callback: ((alertDialog: AlertDialog) -> Unit)? = null )
+ CyclomaticComplexMethod:ContextExt.kt$fun Context.setupKeyboardDialogStuff( windowToken: IBinder, view: View, dialog: AlertDialog.Builder, titleId: Int = 0, titleText: String = "", cancelOnTouchOutside: Boolean = true, callback: ((alertDialog: AlertDialog) -> Unit)? = null )
CyclomaticComplexMethod:MyKeyboard.kt$MyKeyboard$@SuppressLint("UseCompatLoadingForDrawables") private fun loadKeyboard(context: Context, parser: XmlResourceParser)
CyclomaticComplexMethod:MyKeyboardView.kt$MyKeyboardView$@SuppressLint("UseCompatLoadingForDrawables") private fun onBufferDraw()
CyclomaticComplexMethod:MyKeyboardView.kt$MyKeyboardView$override fun onTouchEvent(me: MotionEvent): Boolean
@@ -54,7 +53,6 @@
MaxLineLength:ClipsActivityAdapter.kt$ClipsActivityAdapter$override fun onCreateViewHolder(parent: ViewGroup, viewType: Int)
MaxLineLength:ClipsKeyboardAdapter.kt$ClipsKeyboardAdapter$layerDrawable.findDrawableByLayerId(R.id.clipboard_background_stroke).applyColorFilter(context.getStrokeColor())
MaxLineLength:Config.kt$Config$set(lastExportedClipsFolder) = prefs.edit().putString(LAST_EXPORTED_CLIPS_FOLDER, lastExportedClipsFolder).apply()
- MaxLineLength:Context.kt$fun
MaxLineLength:EmojisAdapter.kt$EmojisAdapter.EmojiCategoryViewHolder$inner
MaxLineLength:ExportClipsDialog.kt$ExportClipsDialog$exportClipsFilename.setText("${activity.getString(R.string.app_launcher_name)}_${activity.getCurrentFormattedDateTime()}")
MaxLineLength:ExportClipsDialog.kt$ExportClipsDialog$val activity: BaseSimpleActivity
@@ -93,7 +91,7 @@
MaxLineLength:SimpleKeyboardIME.kt$SimpleKeyboardIME$layerDrawable.findDrawableByLayerId(R.id.clipboard_background_shape).applyColorFilter(getProperBackgroundColor())
MaxLineLength:SimpleKeyboardIME.kt$SimpleKeyboardIME$override
MaxLineLength:SwitchLanguageDialog.kt$SwitchLanguageDialog$addView(radioButton, RadioGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT))
- NestedBlockDepth:Context.kt$fun Context.setupKeyboardDialogStuff( windowToken: IBinder, view: View, dialog: AlertDialog.Builder, titleId: Int = 0, titleText: String = "", cancelOnTouchOutside: Boolean = true, callback: ((alertDialog: AlertDialog) -> Unit)? = null )
+ NestedBlockDepth:ContextExt.kt$fun Context.setupKeyboardDialogStuff( windowToken: IBinder, view: View, dialog: AlertDialog.Builder, titleId: Int = 0, titleText: String = "", cancelOnTouchOutside: Boolean = true, callback: ((alertDialog: AlertDialog) -> Unit)? = null )
NestedBlockDepth:MyKeyboard.kt$MyKeyboard$@SuppressLint("UseCompatLoadingForDrawables") private fun loadKeyboard(context: Context, parser: XmlResourceParser)
NestedBlockDepth:MyKeyboardView.kt$MyKeyboardView$@SuppressLint("UseCompatLoadingForDrawables") private fun onBufferDraw()
NestedBlockDepth:MyKeyboardView.kt$MyKeyboardView$override fun onTouchEvent(me: MotionEvent): Boolean
diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml
index dbec9dcf..c835a2db 100644
--- a/app/lint-baseline.xml
+++ b/app/lint-baseline.xml
@@ -8,7 +8,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -36,29 +36,40 @@
errorLine1="distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip"
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
+
+
+
+
@@ -76,7 +87,7 @@
+
+
+
+
@@ -756,6 +778,17 @@
column="29"/>
+
+
+
+
@@ -774,7 +807,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -785,7 +818,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -796,7 +829,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -807,7 +840,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -818,7 +851,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -829,7 +862,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -840,7 +873,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -851,7 +884,7 @@
errorLine2=" ~~~~~~~~~~~~">
@@ -862,7 +895,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -873,7 +906,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -884,7 +917,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -895,7 +928,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -906,7 +939,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -917,7 +950,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -928,7 +961,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -939,7 +972,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -950,7 +983,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -961,7 +994,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -972,7 +1005,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -983,7 +1016,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~">
@@ -994,7 +1027,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1005,7 +1038,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1016,7 +1049,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1027,7 +1060,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1038,7 +1071,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
@@ -1049,7 +1082,7 @@
errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~">
diff --git a/app/src/main/kotlin/org/fossify/keyboard/activities/SettingsActivity.kt b/app/src/main/kotlin/org/fossify/keyboard/activities/SettingsActivity.kt
index 08c0eb45..5133024c 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/activities/SettingsActivity.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/activities/SettingsActivity.kt
@@ -60,6 +60,7 @@ class SettingsActivity : SimpleActivity() {
setupKeyboardLanguage()
setupKeyboardHeightMultiplier()
setupShowEmojiKey()
+ setupShowLanguageSwitchKey()
setupShowClipboardContent()
setupSentencesCapitalization()
setupShowNumbersRow()
@@ -243,11 +244,29 @@ class SettingsActivity : SimpleActivity() {
settingsShowEmojiKeyHolder.setOnClickListener {
settingsShowEmojiKey.toggle()
config.showEmojiKey = settingsShowEmojiKey.isChecked
+ if (settingsShowEmojiKey.isChecked) {
+ config.showLanguageSwitchKey = false
+ settingsShowLanguageSwitchKey.isChecked = false
+ }
}
settingsShowEmojiKey.isChecked = config.showEmojiKey
}
}
+ private fun setupShowLanguageSwitchKey() {
+ binding.apply {
+ settingsShowLanguageSwitchKeyHolder.setOnClickListener {
+ settingsShowLanguageSwitchKey.toggle()
+ config.showLanguageSwitchKey = settingsShowLanguageSwitchKey.isChecked
+ if (settingsShowLanguageSwitchKey.isChecked) {
+ config.showEmojiKey = false
+ settingsShowEmojiKey.isChecked = false
+ }
+ }
+ settingsShowLanguageSwitchKey.isChecked = config.showLanguageSwitchKey
+ }
+ }
+
private fun setupShowNumbersRow() {
binding.apply {
settingsShowNumbersRow.isChecked = config.showNumbersRow
diff --git a/app/src/main/kotlin/org/fossify/keyboard/extensions/Context.kt b/app/src/main/kotlin/org/fossify/keyboard/extensions/ContextExt.kt
similarity index 50%
rename from app/src/main/kotlin/org/fossify/keyboard/extensions/Context.kt
rename to app/src/main/kotlin/org/fossify/keyboard/extensions/ContextExt.kt
index e35433ec..563c8692 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/extensions/Context.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/extensions/ContextExt.kt
@@ -3,7 +3,6 @@ package org.fossify.keyboard.extensions
import android.app.KeyguardManager
import android.content.ClipboardManager
import android.content.Context
-import android.graphics.Color
import android.inputmethodservice.InputMethodService
import android.os.IBinder
import android.os.UserManager
@@ -21,15 +20,12 @@ import androidx.core.content.res.ResourcesCompat
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import org.fossify.commons.databinding.DialogTitleBinding
import org.fossify.commons.extensions.baseConfig
-import org.fossify.commons.extensions.darkenColor
import org.fossify.commons.extensions.getColoredDrawableWithColor
import org.fossify.commons.extensions.getProperBackgroundColor
import org.fossify.commons.extensions.getProperPrimaryColor
import org.fossify.commons.extensions.getProperTextColor
import org.fossify.commons.extensions.isBlackAndWhiteTheme
import org.fossify.commons.extensions.isDynamicTheme
-import org.fossify.commons.extensions.isSystemInDarkMode
-import org.fossify.commons.extensions.lightenColor
import org.fossify.commons.extensions.updateTextColors
import org.fossify.commons.helpers.isNougatPlus
import org.fossify.commons.models.RadioItem
@@ -38,49 +34,6 @@ import org.fossify.keyboard.R
import org.fossify.keyboard.databases.ClipsDatabase
import org.fossify.keyboard.helpers.Config
import org.fossify.keyboard.helpers.INPUT_METHOD_SUBTYPE_VOICE
-import org.fossify.keyboard.helpers.LANGUAGE_ARABIC
-import org.fossify.keyboard.helpers.LANGUAGE_BELARUSIAN_CYRL
-import org.fossify.keyboard.helpers.LANGUAGE_BELARUSIAN_LATN
-import org.fossify.keyboard.helpers.LANGUAGE_BENGALI
-import org.fossify.keyboard.helpers.LANGUAGE_BULGARIAN
-import org.fossify.keyboard.helpers.LANGUAGE_CENTRAL_KURDISH
-import org.fossify.keyboard.helpers.LANGUAGE_CHUVASH
-import org.fossify.keyboard.helpers.LANGUAGE_CZECH_QWERTY
-import org.fossify.keyboard.helpers.LANGUAGE_CZECH_QWERTZ
-import org.fossify.keyboard.helpers.LANGUAGE_DANISH
-import org.fossify.keyboard.helpers.LANGUAGE_DUTCH
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_ASSET
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_COLEMAK
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_COLEMAKDH
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_DVORAK
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_NIRO
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_QWERTZ
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_SOUL
-import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_WORKMAN
-import org.fossify.keyboard.helpers.LANGUAGE_ESPERANTO
-import org.fossify.keyboard.helpers.LANGUAGE_FRENCH_AZERTY
-import org.fossify.keyboard.helpers.LANGUAGE_FRENCH_BEPO
-import org.fossify.keyboard.helpers.LANGUAGE_GERMAN
-import org.fossify.keyboard.helpers.LANGUAGE_GERMAN_QWERTZ
-import org.fossify.keyboard.helpers.LANGUAGE_GREEK
-import org.fossify.keyboard.helpers.LANGUAGE_HEBREW
-import org.fossify.keyboard.helpers.LANGUAGE_ITALIAN
-import org.fossify.keyboard.helpers.LANGUAGE_KABYLE_AZERTY
-import org.fossify.keyboard.helpers.LANGUAGE_LATVIAN
-import org.fossify.keyboard.helpers.LANGUAGE_LITHUANIAN
-import org.fossify.keyboard.helpers.LANGUAGE_NORWEGIAN
-import org.fossify.keyboard.helpers.LANGUAGE_POLISH
-import org.fossify.keyboard.helpers.LANGUAGE_PORTUGUESE
-import org.fossify.keyboard.helpers.LANGUAGE_PORTUGUESE_HCESAR
-import org.fossify.keyboard.helpers.LANGUAGE_ROMANIAN
-import org.fossify.keyboard.helpers.LANGUAGE_RUSSIAN
-import org.fossify.keyboard.helpers.LANGUAGE_SLOVENIAN
-import org.fossify.keyboard.helpers.LANGUAGE_SPANISH
-import org.fossify.keyboard.helpers.LANGUAGE_SWEDISH
-import org.fossify.keyboard.helpers.LANGUAGE_TURKISH
-import org.fossify.keyboard.helpers.LANGUAGE_TURKISH_Q
-import org.fossify.keyboard.helpers.LANGUAGE_UKRAINIAN
-import org.fossify.keyboard.helpers.LANGUAGE_VIETNAMESE_TELEX
import org.fossify.keyboard.interfaces.ClipsDao
val Context.config: Config get() = Config.newInstance(applicationContext.safeStorageContext)
@@ -115,43 +68,6 @@ fun Context.getCurrentClip(): String? {
return clipboardManager.primaryClip?.getItemAt(0)?.text?.toString()
}
-fun Context.getKeyboardBackgroundColor(): Int {
- val color = if (isDynamicTheme()) {
- resources.getColor(R.color.you_keyboard_background_color, theme)
- } else {
- getProperBackgroundColor().darkenColor(2)
- }
-
- // use darker background color when key borders are enabled
- if (config.showKeyBorders) {
- val darkerColor = color.darkenColor(2)
- return if (darkerColor == Color.WHITE) {
- resources.getColor(R.color.md_grey_200, theme)
- } else {
- darkerColor
- }
- }
-
- return color
-}
-
-fun Context.getStrokeColor(): Int {
- return if (isDynamicTheme()) {
- if (isSystemInDarkMode()) {
- resources.getColor(R.color.md_grey_800, theme)
- } else {
- resources.getColor(R.color.md_grey_400, theme)
- }
- } else {
- val lighterColor = safeStorageContext.getProperBackgroundColor().lightenColor()
- if (lighterColor == Color.WHITE || lighterColor == Color.BLACK) {
- resources.getColor(R.color.divider_grey, theme)
- } else {
- lighterColor
- }
- }
-}
-
fun Context.getKeyboardDialogBuilder() = if (safeStorageContext.isDynamicTheme()) {
MaterialAlertDialogBuilder(this, R.style.MyKeyboard_Alert)
} else {
@@ -273,68 +189,9 @@ fun Context.setupKeyboardDialogStuff(
}
}
-fun Context.getKeyboardLanguagesRadioItems(): ArrayList {
- val selectedLanguagesRadioItems = arrayListOf()
-
- for (lang in config.selectedLanguages) {
- selectedLanguagesRadioItems.add(RadioItem(lang, getKeyboardLanguageText(lang)))
- }
-
- return selectedLanguagesRadioItems
- .sortedBy { it.title }
- .toMutableList() as ArrayList
-}
-
-fun Context.getKeyboardLanguageText(language: Int): String {
- return when (language) {
- LANGUAGE_ARABIC -> getString(R.string.translation_arabic)
- LANGUAGE_BELARUSIAN_CYRL -> "${getString(R.string.translation_belarusian)} (Cyrillic)"
- LANGUAGE_BELARUSIAN_LATN -> "${getString(R.string.translation_belarusian)} (Latin)"
- LANGUAGE_BENGALI -> getString(R.string.translation_bengali)
- LANGUAGE_BULGARIAN -> getString(R.string.translation_bulgarian)
- LANGUAGE_CENTRAL_KURDISH -> getString(R.string.translation_central_kurdish)
- LANGUAGE_CHUVASH -> getString(R.string.translation_chuvash)
- LANGUAGE_CZECH_QWERTY -> "${getString(R.string.translation_czech)} (QWERTY)"
- LANGUAGE_CZECH_QWERTZ -> "${getString(R.string.translation_czech)} (QWERTZ)"
- LANGUAGE_DANISH -> getString(R.string.translation_danish)
- LANGUAGE_DUTCH -> getString(R.string.translation_dutch)
- LANGUAGE_ENGLISH_ASSET -> "${getString(R.string.translation_english)} (Asset)"
- LANGUAGE_ENGLISH_COLEMAK -> "${getString(R.string.translation_english)} (Colemak)"
- LANGUAGE_ENGLISH_COLEMAKDH -> "${getString(R.string.translation_english)} (Colemak-DH)"
- LANGUAGE_ENGLISH_DVORAK -> "${getString(R.string.translation_english)} (DVORAK)"
- LANGUAGE_ENGLISH_NIRO -> "${getString(R.string.translation_english)} (Niro)"
- LANGUAGE_ENGLISH_QWERTZ -> "${getString(R.string.translation_english)} (QWERTZ)"
- LANGUAGE_ENGLISH_SOUL -> "${getString(R.string.translation_english)} (Soul)"
- LANGUAGE_ENGLISH_WORKMAN -> "${getString(R.string.translation_english)} (Workman)"
- LANGUAGE_ESPERANTO -> getString(R.string.translation_esperanto)
- LANGUAGE_FRENCH_AZERTY -> "${getString(R.string.translation_french)} (AZERTY)"
- LANGUAGE_FRENCH_BEPO -> "${getString(R.string.translation_french)} (BEPO)"
- LANGUAGE_GERMAN -> getString(R.string.translation_german)
- LANGUAGE_GERMAN_QWERTZ -> "${getString(R.string.translation_german)} (QWERTZ)"
- LANGUAGE_GREEK -> getString(R.string.translation_greek)
- LANGUAGE_HEBREW -> getString(R.string.translation_hebrew)
- LANGUAGE_ITALIAN -> getString(R.string.translation_italian)
- LANGUAGE_KABYLE_AZERTY -> "${getString(R.string.translation_kabyle)} (AZERTY)"
- LANGUAGE_LATVIAN -> getString(R.string.translation_latvian)
- LANGUAGE_LITHUANIAN -> getString(R.string.translation_lithuanian)
- LANGUAGE_NORWEGIAN -> getString(R.string.translation_norwegian)
- LANGUAGE_POLISH -> getString(R.string.translation_polish)
- LANGUAGE_PORTUGUESE -> getString(R.string.translation_portuguese)
- LANGUAGE_PORTUGUESE_HCESAR -> "${getString(R.string.translation_portuguese)} (HCESAR)"
- LANGUAGE_ROMANIAN -> getString(R.string.translation_romanian)
- LANGUAGE_RUSSIAN -> getString(R.string.translation_russian)
- LANGUAGE_SLOVENIAN -> getString(R.string.translation_slovenian)
- LANGUAGE_SPANISH -> getString(R.string.translation_spanish)
- LANGUAGE_SWEDISH -> getString(R.string.translation_swedish)
- LANGUAGE_TURKISH -> getString(R.string.translation_turkish)
- LANGUAGE_TURKISH_Q -> "${getString(R.string.translation_turkish)} (Q)"
- LANGUAGE_UKRAINIAN -> getString(R.string.translation_ukrainian)
- LANGUAGE_VIETNAMESE_TELEX -> "${getString(R.string.translation_vietnamese)} (Telex)"
- else -> "${getString(R.string.translation_english)} (QWERTY)"
- }
-}
-
-fun Context.getVoiceInputMethods(imm: InputMethodManager = inputMethodManager): List> {
+fun Context.getVoiceInputMethods(
+ imm: InputMethodManager = inputMethodManager
+): List> {
return imm.enabledInputMethodList.flatMap { im ->
imm.getEnabledInputMethodSubtypeList(im, true)
.filter { it.mode == INPUT_METHOD_SUBTYPE_VOICE }
diff --git a/app/src/main/kotlin/org/fossify/keyboard/extensions/KeyboardLanguageExt.kt b/app/src/main/kotlin/org/fossify/keyboard/extensions/KeyboardLanguageExt.kt
new file mode 100644
index 00000000..d7aa20cf
--- /dev/null
+++ b/app/src/main/kotlin/org/fossify/keyboard/extensions/KeyboardLanguageExt.kt
@@ -0,0 +1,112 @@
+package org.fossify.keyboard.extensions
+
+import android.annotation.SuppressLint
+import android.content.Context
+import org.fossify.commons.models.RadioItem
+import org.fossify.keyboard.R
+import org.fossify.keyboard.helpers.LANGUAGE_ARABIC
+import org.fossify.keyboard.helpers.LANGUAGE_BELARUSIAN_CYRL
+import org.fossify.keyboard.helpers.LANGUAGE_BELARUSIAN_LATN
+import org.fossify.keyboard.helpers.LANGUAGE_BENGALI
+import org.fossify.keyboard.helpers.LANGUAGE_BULGARIAN
+import org.fossify.keyboard.helpers.LANGUAGE_CENTRAL_KURDISH
+import org.fossify.keyboard.helpers.LANGUAGE_CHUVASH
+import org.fossify.keyboard.helpers.LANGUAGE_CZECH_QWERTY
+import org.fossify.keyboard.helpers.LANGUAGE_CZECH_QWERTZ
+import org.fossify.keyboard.helpers.LANGUAGE_DANISH
+import org.fossify.keyboard.helpers.LANGUAGE_DUTCH
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_ASSET
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_COLEMAK
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_COLEMAKDH
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_DVORAK
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_NIRO
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_QWERTZ
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_SOUL
+import org.fossify.keyboard.helpers.LANGUAGE_ENGLISH_WORKMAN
+import org.fossify.keyboard.helpers.LANGUAGE_ESPERANTO
+import org.fossify.keyboard.helpers.LANGUAGE_FRENCH_AZERTY
+import org.fossify.keyboard.helpers.LANGUAGE_FRENCH_BEPO
+import org.fossify.keyboard.helpers.LANGUAGE_GERMAN
+import org.fossify.keyboard.helpers.LANGUAGE_GERMAN_QWERTZ
+import org.fossify.keyboard.helpers.LANGUAGE_GREEK
+import org.fossify.keyboard.helpers.LANGUAGE_HEBREW
+import org.fossify.keyboard.helpers.LANGUAGE_ITALIAN
+import org.fossify.keyboard.helpers.LANGUAGE_KABYLE_AZERTY
+import org.fossify.keyboard.helpers.LANGUAGE_LATVIAN
+import org.fossify.keyboard.helpers.LANGUAGE_LITHUANIAN
+import org.fossify.keyboard.helpers.LANGUAGE_NORWEGIAN
+import org.fossify.keyboard.helpers.LANGUAGE_POLISH
+import org.fossify.keyboard.helpers.LANGUAGE_PORTUGUESE
+import org.fossify.keyboard.helpers.LANGUAGE_PORTUGUESE_HCESAR
+import org.fossify.keyboard.helpers.LANGUAGE_ROMANIAN
+import org.fossify.keyboard.helpers.LANGUAGE_RUSSIAN
+import org.fossify.keyboard.helpers.LANGUAGE_SLOVENIAN
+import org.fossify.keyboard.helpers.LANGUAGE_SPANISH
+import org.fossify.keyboard.helpers.LANGUAGE_SWEDISH
+import org.fossify.keyboard.helpers.LANGUAGE_TURKISH
+import org.fossify.keyboard.helpers.LANGUAGE_TURKISH_Q
+import org.fossify.keyboard.helpers.LANGUAGE_UKRAINIAN
+import org.fossify.keyboard.helpers.LANGUAGE_VIETNAMESE_TELEX
+
+fun Context.getSelectedLanguagesSorted(): List {
+ return config.selectedLanguages
+ .map { it to getKeyboardLanguageText(it) }
+ .sortedBy { it.second }
+ .map { it.first }
+}
+
+fun Context.getKeyboardLanguagesRadioItems(): ArrayList {
+ return getSelectedLanguagesSorted()
+ .map { RadioItem(it, getKeyboardLanguageText(it)) }
+ .toMutableList() as ArrayList
+}
+
+@Suppress("CyclomaticComplexMethod")
+fun Context.getKeyboardLanguageText(language: Int): String {
+ return when (language) {
+ LANGUAGE_ARABIC -> getString(R.string.translation_arabic)
+ LANGUAGE_BELARUSIAN_CYRL -> "${getString(R.string.translation_belarusian)} (Cyrillic)"
+ LANGUAGE_BELARUSIAN_LATN -> "${getString(R.string.translation_belarusian)} (Latin)"
+ LANGUAGE_BENGALI -> getString(R.string.translation_bengali)
+ LANGUAGE_BULGARIAN -> getString(R.string.translation_bulgarian)
+ LANGUAGE_CENTRAL_KURDISH -> getString(R.string.translation_central_kurdish)
+ LANGUAGE_CHUVASH -> getString(R.string.translation_chuvash)
+ LANGUAGE_CZECH_QWERTY -> "${getString(R.string.translation_czech)} (QWERTY)"
+ LANGUAGE_CZECH_QWERTZ -> "${getString(R.string.translation_czech)} (QWERTZ)"
+ LANGUAGE_DANISH -> getString(R.string.translation_danish)
+ LANGUAGE_DUTCH -> getString(R.string.translation_dutch)
+ LANGUAGE_ENGLISH_ASSET -> "${getString(R.string.translation_english)} (Asset)"
+ LANGUAGE_ENGLISH_COLEMAK -> "${getString(R.string.translation_english)} (Colemak)"
+ LANGUAGE_ENGLISH_COLEMAKDH -> "${getString(R.string.translation_english)} (Colemak-DH)"
+ LANGUAGE_ENGLISH_DVORAK -> "${getString(R.string.translation_english)} (DVORAK)"
+ LANGUAGE_ENGLISH_NIRO -> "${getString(R.string.translation_english)} (Niro)"
+ LANGUAGE_ENGLISH_QWERTZ -> "${getString(R.string.translation_english)} (QWERTZ)"
+ LANGUAGE_ENGLISH_SOUL -> "${getString(R.string.translation_english)} (Soul)"
+ LANGUAGE_ENGLISH_WORKMAN -> "${getString(R.string.translation_english)} (Workman)"
+ LANGUAGE_ESPERANTO -> getString(R.string.translation_esperanto)
+ LANGUAGE_FRENCH_AZERTY -> "${getString(R.string.translation_french)} (AZERTY)"
+ LANGUAGE_FRENCH_BEPO -> "${getString(R.string.translation_french)} (BEPO)"
+ LANGUAGE_GERMAN -> getString(R.string.translation_german)
+ LANGUAGE_GERMAN_QWERTZ -> "${getString(R.string.translation_german)} (QWERTZ)"
+ LANGUAGE_GREEK -> getString(R.string.translation_greek)
+ LANGUAGE_HEBREW -> getString(R.string.translation_hebrew)
+ LANGUAGE_ITALIAN -> getString(R.string.translation_italian)
+ LANGUAGE_KABYLE_AZERTY -> "${getString(R.string.translation_kabyle)} (AZERTY)"
+ LANGUAGE_LATVIAN -> getString(R.string.translation_latvian)
+ LANGUAGE_LITHUANIAN -> getString(R.string.translation_lithuanian)
+ LANGUAGE_NORWEGIAN -> getString(R.string.translation_norwegian)
+ LANGUAGE_POLISH -> getString(R.string.translation_polish)
+ LANGUAGE_PORTUGUESE -> getString(R.string.translation_portuguese)
+ LANGUAGE_PORTUGUESE_HCESAR -> "${getString(R.string.translation_portuguese)} (HCESAR)"
+ LANGUAGE_ROMANIAN -> getString(R.string.translation_romanian)
+ LANGUAGE_RUSSIAN -> getString(R.string.translation_russian)
+ LANGUAGE_SLOVENIAN -> getString(R.string.translation_slovenian)
+ LANGUAGE_SPANISH -> getString(R.string.translation_spanish)
+ LANGUAGE_SWEDISH -> getString(R.string.translation_swedish)
+ LANGUAGE_TURKISH -> getString(R.string.translation_turkish)
+ LANGUAGE_TURKISH_Q -> "${getString(R.string.translation_turkish)} (Q)"
+ LANGUAGE_UKRAINIAN -> getString(R.string.translation_ukrainian)
+ LANGUAGE_VIETNAMESE_TELEX -> "${getString(R.string.translation_vietnamese)} (Telex)"
+ else -> "${getString(R.string.translation_english)} (QWERTY)"
+ }
+}
diff --git a/app/src/main/kotlin/org/fossify/keyboard/extensions/KeyboardThemeExt.kt b/app/src/main/kotlin/org/fossify/keyboard/extensions/KeyboardThemeExt.kt
new file mode 100644
index 00000000..3a0abb89
--- /dev/null
+++ b/app/src/main/kotlin/org/fossify/keyboard/extensions/KeyboardThemeExt.kt
@@ -0,0 +1,47 @@
+package org.fossify.keyboard.extensions
+
+import android.content.Context
+import android.graphics.Color
+import org.fossify.commons.extensions.darkenColor
+import org.fossify.commons.extensions.getProperBackgroundColor
+import org.fossify.commons.extensions.isDynamicTheme
+import org.fossify.commons.extensions.isSystemInDarkMode
+import org.fossify.commons.extensions.lightenColor
+import org.fossify.keyboard.R
+
+fun Context.getKeyboardBackgroundColor(): Int {
+ val color = if (isDynamicTheme()) {
+ resources.getColor(R.color.you_keyboard_background_color, theme)
+ } else {
+ getProperBackgroundColor().darkenColor(2)
+ }
+
+ // use darker background color when key borders are enabled
+ if (config.showKeyBorders) {
+ val darkerColor = color.darkenColor(2)
+ return if (darkerColor == Color.WHITE) {
+ resources.getColor(R.color.md_grey_200, theme)
+ } else {
+ darkerColor
+ }
+ }
+
+ return color
+}
+
+fun Context.getStrokeColor(): Int {
+ return if (isDynamicTheme()) {
+ if (isSystemInDarkMode()) {
+ resources.getColor(R.color.md_grey_800, theme)
+ } else {
+ resources.getColor(R.color.md_grey_400, theme)
+ }
+ } else {
+ val lighterColor = safeStorageContext.getProperBackgroundColor().lightenColor()
+ if (lighterColor == Color.WHITE || lighterColor == Color.BLACK) {
+ resources.getColor(R.color.divider_grey, theme)
+ } else {
+ lighterColor
+ }
+ }
+}
diff --git a/app/src/main/kotlin/org/fossify/keyboard/helpers/Config.kt b/app/src/main/kotlin/org/fossify/keyboard/helpers/Config.kt
index 9d5499e4..58b8f510 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/helpers/Config.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/helpers/Config.kt
@@ -27,6 +27,10 @@ class Config(context: Context) : BaseConfig(context) {
get() = prefs.getBoolean(SHOW_EMOJI_KEY, true)
set(showEmojiKey) = prefs.edit().putBoolean(SHOW_EMOJI_KEY, showEmojiKey).apply()
+ var showLanguageSwitchKey: Boolean
+ get() = prefs.getBoolean(SHOW_LANGUAGE_SWITCH_KEY, false)
+ set(showLanguageSwitchKey) = prefs.edit().putBoolean(SHOW_LANGUAGE_SWITCH_KEY, showLanguageSwitchKey).apply()
+
var showKeyBorders: Boolean
get() = prefs.getBoolean(SHOW_KEY_BORDERS, true)
set(showKeyBorders) = prefs.edit().putBoolean(SHOW_KEY_BORDERS, showKeyBorders).apply()
diff --git a/app/src/main/kotlin/org/fossify/keyboard/helpers/Constants.kt b/app/src/main/kotlin/org/fossify/keyboard/helpers/Constants.kt
index dfa1c6ea..b60629ec 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/helpers/Constants.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/helpers/Constants.kt
@@ -16,6 +16,7 @@ const val SHOW_POPUP_ON_KEYPRESS = "show_popup_on_keypress"
const val SHOW_KEY_BORDERS = "show_key_borders"
const val SENTENCES_CAPITALIZATION = "sentences_capitalization"
const val SHOW_EMOJI_KEY = "show_emoji_key"
+const val SHOW_LANGUAGE_SWITCH_KEY = "show_language_switch_key"
const val LAST_EXPORTED_CLIPS_FOLDER = "last_exported_clips_folder"
const val KEYBOARD_LANGUAGE = "keyboard_language"
const val HEIGHT_PERCENTAGE = "height_percentage"
diff --git a/app/src/main/kotlin/org/fossify/keyboard/helpers/MyKeyboard.kt b/app/src/main/kotlin/org/fossify/keyboard/helpers/MyKeyboard.kt
index 0e85f200..592e7d30 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/helpers/MyKeyboard.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/helpers/MyKeyboard.kt
@@ -66,7 +66,7 @@ class MyKeyboard {
const val KEYCODE_ENTER = -4
const val KEYCODE_DELETE = -5
const val KEYCODE_SPACE = 32
- const val KEYCODE_EMOJI = -6
+ const val KEYCODE_EMOJI_OR_LANGUAGE = -6
fun getDimensionOrFraction(a: TypedArray, index: Int, base: Int, defValue: Int): Int {
val value = a.peekValue(index) ?: return defValue
@@ -237,7 +237,9 @@ class MyKeyboard {
KEYCODE_ENTER -> context.getString(R.string.keycode_enter)
KEYCODE_DELETE -> context.getString(R.string.keycode_delete)
KEYCODE_SPACE -> context.getString(R.string.keycode_space)
- KEYCODE_EMOJI -> context.getString(R.string.emojis)
+ KEYCODE_EMOJI_OR_LANGUAGE -> context.getString(
+ if (context.config.showEmojiKey) R.string.emojis else R.string.keyboard_language
+ )
else -> label
}
}
diff --git a/app/src/main/kotlin/org/fossify/keyboard/services/SimpleKeyboardIME.kt b/app/src/main/kotlin/org/fossify/keyboard/services/SimpleKeyboardIME.kt
index e46d3e74..02b2cee9 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/services/SimpleKeyboardIME.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/services/SimpleKeyboardIME.kt
@@ -28,6 +28,7 @@ import androidx.autofill.inline.common.ImageViewStyle
import androidx.autofill.inline.common.TextViewStyle
import androidx.autofill.inline.common.ViewStyle
import androidx.autofill.inline.v1.InlineSuggestionUi
+import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
@@ -39,6 +40,8 @@ import org.fossify.keyboard.R
import org.fossify.keyboard.databinding.KeyboardViewKeyboardBinding
import org.fossify.keyboard.extensions.config
import org.fossify.keyboard.extensions.getKeyboardBackgroundColor
+import org.fossify.keyboard.extensions.getKeyboardLanguageText
+import org.fossify.keyboard.extensions.getSelectedLanguagesSorted
import org.fossify.keyboard.extensions.getStrokeColor
import org.fossify.keyboard.extensions.safeStorageContext
import org.fossify.keyboard.helpers.*
@@ -251,8 +254,18 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared
keyboardView!!.setKeyboard(keyboard!!)
}
- MyKeyboard.KEYCODE_EMOJI -> {
- keyboardView?.openEmojiPalette()
+ MyKeyboard.KEYCODE_EMOJI_OR_LANGUAGE -> {
+ if (config.showEmojiKey) {
+ keyboardView?.openEmojiPalette()
+ } else if (config.showLanguageSwitchKey) {
+ val sortedLanguages = getSelectedLanguagesSorted()
+ if (sortedLanguages.size > 1) {
+ val currentIndex = sortedLanguages.indexOf(config.keyboardLanguage)
+ val nextIndex = (currentIndex + 1) % sortedLanguages.size
+ config.keyboardLanguage = sortedLanguages[nextIndex]
+ reloadKeyboard()
+ }
+ }
}
else -> {
@@ -581,30 +594,47 @@ class SimpleKeyboardIME : InputMethodService(), OnKeyboardActionListener, Shared
return Icon.createWithData(byteArray, 0, byteArray.size)
}
- private fun adjustForEmojiButton(keyboard: MyKeyboard): MyKeyboard {
- if (!config.showEmojiKey && this.keyboardMode == KEYBOARD_LETTERS) {
- keyboard.mKeys?.let { keys ->
- val emojiKeyIndex = keys.indexOfFirst { it.code == MyKeyboard.KEYCODE_EMOJI }
- val spaceKeyIndex = keys.indexOfFirst { it.code == MyKeyboard.KEYCODE_SPACE }
-
- if (emojiKeyIndex != -1 && spaceKeyIndex != -1) {
- val emojiKey = keys[emojiKeyIndex]
- val spaceKey = keys[spaceKeyIndex]
+ private fun constructKeyboard(keyboardXml: Int, enterKeyType: Int): MyKeyboard {
+ val keyboard = MyKeyboard(this, keyboardXml, enterKeyType)
+ return adjustBottomRow(keyboard)
+ }
- spaceKey.width += emojiKey.width + emojiKey.gap
- spaceKey.x = emojiKey.x
+ // hacky, but good enough for now
+ private fun adjustBottomRow(keyboard: MyKeyboard): MyKeyboard {
+ keyboard.mKeys?.let { keys ->
+ val spaceKeyIndex = keys.indexOfFirst { it.code == MyKeyboard.KEYCODE_SPACE }
+ if (spaceKeyIndex != -1) {
+ val spaceKey = keys[spaceKeyIndex]
+ spaceKey.label = spaceKey.label.ifEmpty {
+ getKeyboardLanguageText(config.keyboardLanguage)
+ }
+ }
- val mutableKeys = keys.toMutableList()
- mutableKeys.removeAt(emojiKeyIndex)
- keyboard.mKeys = mutableKeys
+ if (keyboardMode != KEYBOARD_LETTERS) return keyboard
+ val emojiKeyIndex = keys.indexOfFirst { it.code == MyKeyboard.KEYCODE_EMOJI_OR_LANGUAGE }
+ if (emojiKeyIndex != -1 && spaceKeyIndex != -1) {
+ val emojiKey = keys[emojiKeyIndex]
+ val spaceKey = keys[spaceKeyIndex]
+ emojiKey.secondaryIcon = null
+ when {
+ config.showEmojiKey -> {
+ // no-op
+ }
+ config.showLanguageSwitchKey -> {
+ emojiKey.icon = ResourcesCompat.getDrawable(resources, R.drawable.ic_language_outlined, theme)
+ }
+ else -> {
+ // both emoji and language keys are disabled
+ spaceKey.width += emojiKey.width + emojiKey.gap
+ spaceKey.x = emojiKey.x
+
+ val mutableKeys = keys.toMutableList()
+ mutableKeys.removeAt(emojiKeyIndex)
+ keyboard.mKeys = mutableKeys
+ }
}
}
}
return keyboard
}
-
- private fun constructKeyboard(keyboardXml: Int, enterKeyType: Int): MyKeyboard {
- val keyboard = MyKeyboard(this, keyboardXml, enterKeyType)
- return adjustForEmojiButton(keyboard)
- }
}
diff --git a/app/src/main/kotlin/org/fossify/keyboard/views/MyKeyboardView.kt b/app/src/main/kotlin/org/fossify/keyboard/views/MyKeyboardView.kt
index 534bc7c7..1918e787 100644
--- a/app/src/main/kotlin/org/fossify/keyboard/views/MyKeyboardView.kt
+++ b/app/src/main/kotlin/org/fossify/keyboard/views/MyKeyboardView.kt
@@ -64,6 +64,7 @@ import org.fossify.commons.extensions.lightenColor
import org.fossify.commons.extensions.performHapticFeedback
import org.fossify.commons.extensions.removeUnderlines
import org.fossify.commons.extensions.toast
+import org.fossify.commons.helpers.HIGHER_ALPHA
import org.fossify.commons.helpers.ensureBackgroundThread
import org.fossify.commons.helpers.isOreoMr1Plus
import org.fossify.commons.helpers.isPiePlus
@@ -95,7 +96,7 @@ import org.fossify.keyboard.helpers.LANGUAGE_VN_TELEX
import org.fossify.keyboard.helpers.MAX_KEYS_PER_MINI_ROW
import org.fossify.keyboard.helpers.MyKeyboard
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_DELETE
-import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_EMOJI
+import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_EMOJI_OR_LANGUAGE
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_ENTER
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_MODE_CHANGE
import org.fossify.keyboard.helpers.MyKeyboard.Companion.KEYCODE_SHIFT
@@ -140,6 +141,7 @@ class MyKeyboardView @JvmOverloads constructor(
private var mLabelTextSize = 0
private var mKeyTextSize = 0
+ private var mSpaceBarTextSize = 0
private var mTextColor = 0
private var mBackgroundColor = 0
@@ -190,7 +192,7 @@ class MyKeyboardView @JvmOverloads constructor(
private var mRepeatKeyIndex = NOT_A_KEY
private var mPopupLayout = 0
private var mAbortKey = false
- private var mIsLongPressingSpace = false
+ private var mCursorControlActive = false
private var mLastSpaceMoveX = 0
private var mPopupMaxMoveDistance = 0f
private var mTopSmallNumberSize = 0f
@@ -264,6 +266,7 @@ class MyKeyboardView @JvmOverloads constructor(
mKeyBackground = resources.getDrawable(R.drawable.keyboard_key_selector, context.theme)
mVerticalCorrection = resources.getDimension(R.dimen.vertical_correction).toInt()
mLabelTextSize = resources.getDimension(R.dimen.label_text_size).toInt()
+ mSpaceBarTextSize = resources.getDimension(R.dimen.space_bar_text_size).toInt()
mPreviewHeight = resources.getDimension(R.dimen.key_height).toInt()
mSpaceMoveThreshold = resources.getDimension(R.dimen.medium_margin).toInt()
@@ -305,7 +308,7 @@ class MyKeyboardView @JvmOverloads constructor(
override fun handleMessage(msg: Message) {
when (msg.what) {
MSG_REMOVE_PREVIEW -> mPreviewText!!.visibility = INVISIBLE
- MSG_REPEAT -> if (repeatKey(false)) {
+ MSG_REPEAT -> if (repeatKey()) {
val repeat = Message.obtain(this, MSG_REPEAT)
sendMessageDelayed(repeat, REPEAT_INTERVAL.toLong())
}
@@ -685,19 +688,23 @@ class MyKeyboardView @JvmOverloads constructor(
for (i in 0 until keyCount) {
val key = keys[i]
val code = key.code
+ val label = adjustCase(key.label)?.toString()
setupKeyBackground(key, code, canvas)
- val textColor = if (key.pressed) {
- mTextColor.adjustAlpha(0.5f)
- } else {
- mTextColor
+ val textColor = when {
+ key.pressed -> mTextColor.adjustAlpha(0.5f)
+ code == KEYCODE_SPACE && label.orEmpty().length > 1 -> mTextColor.adjustAlpha(HIGHER_ALPHA)
+ else -> mTextColor
}
// Switch the character to uppercase if shift is pressed
- val label = adjustCase(key.label)?.toString()
if (label?.isNotEmpty() == true) {
// For characters, use large font. For labels like "Done", use small font.
- if (label.length > 1) {
+ if (code == KEYCODE_SPACE && key.label.length > 1) {
+ // Use smaller font size for current language label on space bar
+ paint.textSize = mSpaceBarTextSize.toFloat()
+ paint.typeface = Typeface.DEFAULT
+ } else if (label.length > 1) {
paint.textSize = mLabelTextSize.toFloat()
paint.typeface = Typeface.DEFAULT_BOLD
} else {
@@ -758,7 +765,7 @@ class MyKeyboardView @JvmOverloads constructor(
val contrastColor = mPrimaryColor.getContrastColor()
key.icon!!.applyColorFilter(contrastColor)
key.secondaryIcon?.applyColorFilter(contrastColor.adjustAlpha(0.6f))
- } else if (code == KEYCODE_DELETE || code == KEYCODE_SHIFT || code == KEYCODE_EMOJI) {
+ } else if (code == KEYCODE_DELETE || code == KEYCODE_SHIFT || code == KEYCODE_EMOJI_OR_LANGUAGE) {
key.icon!!.applyColorFilter(textColor)
key.secondaryIcon?.applyColorFilter(
if (key.pressed) {
@@ -830,7 +837,7 @@ class MyKeyboardView @JvmOverloads constructor(
private fun setupKeyBackground(key: MyKeyboard.Key, keyCode: Int, canvas: Canvas) {
val keyBackground = when {
- keyCode == KEYCODE_SPACE && key.label.isBlank() -> getSpaceKeyBackground()
+ keyCode == KEYCODE_SPACE && key.label.length > 1 -> getSpaceKeyBackground()
keyCode == KEYCODE_ENTER -> getEnterKeyBackground()
else -> mKeyBackground
}
@@ -1019,6 +1026,7 @@ class MyKeyboardView @JvmOverloads constructor(
}
val key = keys[keyIndex]
+ if (key.code == KEYCODE_SPACE) return // no popup for the language label
if (key.icon != null) {
mPreviewText!!.setCompoundDrawables(null, null, null, key.icon)
} else {
@@ -1169,10 +1177,25 @@ class MyKeyboardView @JvmOverloads constructor(
* handle the call.
*/
private fun onLongPress(popupKey: MyKeyboard.Key, me: MotionEvent): Boolean {
- if (popupKey.code == KEYCODE_EMOJI) {
+ if (popupKey.code == KEYCODE_SPACE) {
+ return if (!mCursorControlActive) {
+ setCurrentKeyPressed(false)
+ mRepeatKeyIndex = NOT_A_KEY
+ mHandler?.removeMessages(MSG_REPEAT)
+ vibrateIfNeeded()
+ SwitchLanguageDialog(this) {
+ mOnKeyboardActionListener?.reloadKeyboard()
+ }
+ true
+ } else false
+ } else if (popupKey.code == KEYCODE_EMOJI_OR_LANGUAGE) {
setCurrentKeyPressed(false)
- SwitchLanguageDialog(this) {
- mOnKeyboardActionListener?.reloadKeyboard()
+ if (context.config.showEmojiKey) {
+ openEmojiPalette()
+ } else {
+ SwitchLanguageDialog(this) {
+ mOnKeyboardActionListener?.reloadKeyboard()
+ }
}
return true
} else {
@@ -1415,11 +1438,12 @@ class MyKeyboardView @JvmOverloads constructor(
val msg = mHandler!!.obtainMessage(MSG_REPEAT)
mHandler!!.sendMessageDelayed(msg, REPEAT_START_DELAY.toLong())
- // if the user long presses Space, move the cursor after swipine left/right
+ // if the user long presses space bar, move the cursor after swiping left/right
if (mKeys[mCurrentKey].code == KEYCODE_SPACE) {
mLastSpaceMoveX = -1
+ mCursorControlActive = false
} else {
- repeatKey(true)
+ repeatKey()
}
// Delivering the key could have caused an abort
@@ -1463,7 +1487,9 @@ class MyKeyboardView @JvmOverloads constructor(
}
}
- if (mIsLongPressingSpace) {
+ // activate cursor control immediately on sufficient movement
+ val currentKey = mKeys.getOrNull(mCurrentKey)
+ if (currentKey?.code == KEYCODE_SPACE && mLastSpaceMoveX != 0) {
if (mLastSpaceMoveX == -1) {
mLastSpaceMoveX = mLastX
}
@@ -1474,16 +1500,20 @@ class MyKeyboardView @JvmOverloads constructor(
mOnKeyboardActionListener?.moveCursorLeft()
}
mLastSpaceMoveX = mLastX
+ if (!mCursorControlActive) mHandler?.removeMessages(MSG_LONGPRESS)
+ mCursorControlActive = true
} else if (diff > mSpaceMoveThreshold) {
for (i in 0 until diff / mSpaceMoveThreshold) {
mOnKeyboardActionListener?.moveCursorRight()
}
mLastSpaceMoveX = mLastX
+ if (!mCursorControlActive) mHandler?.removeMessages(MSG_LONGPRESS)
+ mCursorControlActive = true
}
} else if (!continueLongPress) {
- // Cancel old longpress
+ // Cancel old long-press
mHandler!!.removeMessages(MSG_LONGPRESS)
- // Start new longpress if key has changed
+ // Start new long-press if key has changed
if (keyIndex != NOT_A_KEY) {
val msg = mHandler!!.obtainMessage(MSG_LONGPRESS, me)
mHandler!!.sendMessageDelayed(msg, LONGPRESS_TIMEOUT.toLong())
@@ -1523,17 +1553,17 @@ class MyKeyboardView @JvmOverloads constructor(
// If we're not on a repeating key (which sends on a DOWN event)
if (mRepeatKeyIndex == NOT_A_KEY && !mMiniKeyboardOnScreen && !mAbortKey) {
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime)
- } else if (currentKeyCode == KEYCODE_SPACE && !mIsLongPressingSpace) {
+ } else if (currentKeyCode == KEYCODE_SPACE && !mCursorControlActive) {
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime)
}
mRepeatKeyIndex = NOT_A_KEY
mOnKeyboardActionListener!!.onActionUp()
- mIsLongPressingSpace = false
+ mCursorControlActive = false
}
MotionEvent.ACTION_CANCEL -> {
- mIsLongPressingSpace = false
+ mCursorControlActive = false
mLastSpaceMoveX = 0
removeMessages()
dismissPopupKeyboard()
@@ -1548,15 +1578,9 @@ class MyKeyboardView @JvmOverloads constructor(
return true
}
- private fun repeatKey(initialCall: Boolean): Boolean {
+ private fun repeatKey(): Boolean {
val key = mKeys[mRepeatKeyIndex]
- if (!initialCall && key.code == KEYCODE_SPACE) {
- if (!mIsLongPressingSpace) {
- vibrateIfNeeded()
- }
-
- mIsLongPressingSpace = true
- } else {
+ if (key.code != KEYCODE_SPACE) {
detectAndSendKey(mCurrentKey, key.x, key.y, mLastTapTime)
}
return true
diff --git a/app/src/main/res/drawable-v31/keyboard_space_background_material.xml b/app/src/main/res/drawable-v31/keyboard_space_background_material.xml
index 64f29b9b..91b55f81 100644
--- a/app/src/main/res/drawable-v31/keyboard_space_background_material.xml
+++ b/app/src/main/res/drawable-v31/keyboard_space_background_material.xml
@@ -2,20 +2,20 @@
-
-
-
+
-
-
+
-
-
-
+
-
-
+
diff --git a/app/src/main/res/drawable/keyboard_enter_background.xml b/app/src/main/res/drawable/keyboard_enter_background.xml
index 2be68134..23e3f1ed 100644
--- a/app/src/main/res/drawable/keyboard_enter_background.xml
+++ b/app/src/main/res/drawable/keyboard_enter_background.xml
@@ -2,13 +2,13 @@
-
+ android:bottom="@dimen/medium_margin"
+ android:left="@dimen/tiny_margin"
+ android:right="@dimen/tiny_margin"
+ android:top="@dimen/medium_margin">
-
+
diff --git a/app/src/main/res/drawable/keyboard_space_background.xml b/app/src/main/res/drawable/keyboard_space_background.xml
index 1953af34..6bd13adb 100644
--- a/app/src/main/res/drawable/keyboard_space_background.xml
+++ b/app/src/main/res/drawable/keyboard_space_background.xml
@@ -2,20 +2,20 @@
-
-
-
+
-
-
+
-
-
-
+
-
-
+
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index 82850b41..80e300b1 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -252,6 +252,21 @@
+
+
+
+
+
+
16sp
30sp
13sp
+ 13sp
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 10499b1d..70541f0d 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -37,6 +37,7 @@
Show numbers on a separate row
Start sentences with a capital letter
Show emoji key
+ Show language switch key
Emojis
Recently used