mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-06-24 10:00:53 +00:00
Merge branch 'main' into settings_new
This commit is contained in:
commit
ed48d5096a
51 changed files with 1126 additions and 226 deletions
34
app/src/main/assets/layouts/arabic_hijai.txt
Normal file
34
app/src/main/assets/layouts/arabic_hijai.txt
Normal file
|
@ -0,0 +1,34 @@
|
|||
ز
|
||||
ر
|
||||
ذ
|
||||
د
|
||||
خ
|
||||
ح
|
||||
ج
|
||||
ث
|
||||
ت
|
||||
ب
|
||||
ا
|
||||
|
||||
ك
|
||||
ق
|
||||
ف
|
||||
غ
|
||||
ع
|
||||
ظ
|
||||
ط
|
||||
ض
|
||||
ص
|
||||
ش
|
||||
س
|
||||
|
||||
ء
|
||||
ى
|
||||
ي
|
||||
ؤ
|
||||
و
|
||||
ة
|
||||
ﻩ
|
||||
ن
|
||||
م
|
||||
ل
|
|
@ -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": "শ"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
]
|
||||
]
|
|
@ -16,7 +16,7 @@
|
|||
ী ঈ
|
||||
া আ অ
|
||||
্ ঁ
|
||||
ঁ ় ৺ ঽ ৗ ঌ ৡ ৠ ৱ ৢ ৣ ৄ ৰ
|
||||
ঁ !autoColumnOrder!6 ় ৄ ঽ ৢ ৱ ৣ ৗ ৠ ৺ ঌ ৰ ৡ
|
||||
ব ভ
|
||||
ক খ
|
||||
ত থ ৎ
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,10 +450,10 @@ 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);
|
||||
paint.setTypeface(mTypeface == null ? Typeface.DEFAULT_BOLD : mTypeface);
|
||||
blendAlpha(paint, params.mAnimAlpha);
|
||||
final float labelCharHeight = TypefaceUtils.getReferenceCharHeight(paint);
|
||||
final float labelCharWidth = TypefaceUtils.getReferenceCharWidth(paint);
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -1076,6 +1076,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
if (mInHorizontalSwipe || mInVerticalSwipe) {
|
||||
mInHorizontalSwipe = false;
|
||||
mInVerticalSwipe = false;
|
||||
sListener.onEndSpaceSwipe();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -65,10 +68,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()
|
||||
|
@ -156,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)
|
||||
|
||||
|
@ -167,8 +167,24 @@ 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")
|
||||
toolbarKeys.forEach { it.isEnabled = false; it.isEnabled = true }
|
||||
}
|
||||
|
||||
fun stopClipboardHistory() {
|
||||
|
@ -233,4 +249,8 @@ class ClipboardHistoryView @JvmOverloads constructor(
|
|||
clipboardAdapter.notifyItemChanged(to)
|
||||
if (to < from) clipboardRecyclerView.smoothScrollToPosition(to)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(prefs: SharedPreferences?, key: String?) {
|
||||
setToolbarButtonsActivatedStateOnPrefChange(KeyboardSwitcher.getInstance().clipboardStrip, key)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) } }
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
@ -195,12 +199,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 +214,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 +222,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)
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -409,7 +417,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 +432,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 +445,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 +564,7 @@ class AllColors(private val colorMap: EnumMap<ColorType, Int>, 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,14 +629,14 @@ 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))
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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:
|
||||
|
@ -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.
|
||||
|
|
|
@ -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<Preference>("load_gesture_library")?.setOnPreferenceClickListener { onClickLoadLibrary() }
|
||||
findPreference<Preference>("backup_restore")?.setOnPreferenceClickListener { showBackupRestoreDialog() }
|
||||
|
||||
|
@ -560,10 +563,37 @@ class AdvancedSettingsFragment : SubScreenFragment() {
|
|||
})
|
||||
}
|
||||
|
||||
private fun setupLanguageSwipeDistanceSettings() {
|
||||
val prefs = sharedPreferences
|
||||
findPreference<SeekBarDialogPreference>(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())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,6 +105,11 @@ 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)
|
||||
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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -112,6 +112,11 @@ 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_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";
|
||||
public static final String PREF_SPACE_VERTICAL_SWIPE = "vertical_space_swipe";
|
||||
public static final String PREF_DELETE_SWIPE = "delete_swipe";
|
||||
|
@ -142,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";
|
||||
|
@ -151,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";
|
||||
|
@ -447,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);
|
||||
}
|
||||
|
@ -499,6 +518,18 @@ 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 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.
|
||||
|
|
|
@ -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;
|
||||
|
@ -80,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;
|
||||
|
@ -113,6 +115,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;
|
||||
|
@ -120,6 +123,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
|
||||
|
@ -171,6 +176,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);
|
||||
|
@ -227,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);
|
||||
|
@ -262,7 +269,8 @@ 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);
|
||||
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);
|
||||
|
@ -273,6 +281,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() {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,7 +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.serialization.encodeToString
|
||||
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
|
||||
|
@ -38,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) {
|
||||
|
@ -60,7 +81,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
|
||||
|
|
|
@ -377,6 +377,7 @@
|
|||
<string name="prefs_long_press_symbol_for_numpad">নম্বর প্যাডের জন্য প্রতীক বোতামে দীর্ঘ চাপ</string>
|
||||
<string name="var_toolbar_direction">টুলবারের পরিবর্তনশীল দিক</string>
|
||||
<string name="var_toolbar_direction_summary">ডান থেকে বাম কিবোর্ড নির্বাচন করলে দিক বিপরীত হবে</string>
|
||||
<string name="prefs_language_swipe_distance">ভাষা পরিবর্তন অভিস্পর্শের দূরত্ব</string>
|
||||
<string name="subtype_generic_student"><xliff:g id="LANGUAGE_NAME" example="Russian">%s</xliff:g> (শিক্ষার্থী)</string>
|
||||
<string name="language_switch_key_behavior">ভাষা পরিবর্তন বোতামের আচরণ</string>
|
||||
<string name="pinned_toolbar_keys">পিন করে রাখা টুলবার বোতাম নির্বাচন</string>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<dimen name="config_popup_keys_keyboard_slide_allowance">53.76dp</dimen>
|
||||
|
||||
<fraction name="config_keyboard_top_padding_holo">2.727%p</fraction>
|
||||
<fraction name="config_keyboard_bottom_padding_holo">0.0%p</fraction>
|
||||
<fraction name="config_keyboard_bottom_padding_holo">2.5%p</fraction>
|
||||
<fraction name="config_key_vertical_gap_holo">5.368%p</fraction>
|
||||
<fraction name="config_key_horizontal_gap_holo">1.020%p</fraction>
|
||||
<fraction name="config_key_vertical_gap_holo_narrow">4.85%p</fraction>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<dimen name="config_popup_keys_keyboard_key_height">81.9dp</dimen>
|
||||
|
||||
<fraction name="config_keyboard_top_padding_holo">2.727%p</fraction>
|
||||
<fraction name="config_keyboard_bottom_padding_holo">0.0%p</fraction>
|
||||
<fraction name="config_keyboard_bottom_padding_holo">2.0%p</fraction>
|
||||
<fraction name="config_key_vertical_gap_holo">4.5%p</fraction>
|
||||
<fraction name="config_key_horizontal_gap_holo">0.9%p</fraction>
|
||||
<fraction name="config_key_vertical_gap_holo_narrow">4.5%p</fraction>
|
||||
|
|
|
@ -79,8 +79,8 @@
|
|||
<integer name="config_touch_noise_threshold_time">40</integer>
|
||||
|
||||
<!-- Common keyboard configuration. -->
|
||||
<fraction name="config_keyboard_left_padding">0%p</fraction>
|
||||
<fraction name="config_keyboard_right_padding">0%p</fraction>
|
||||
<fraction name="config_keyboard_left_padding">8%p</fraction>
|
||||
<fraction name="config_keyboard_right_padding">8%p</fraction>
|
||||
<dimen name="config_keyboard_vertical_correction">0.0dp</dimen>
|
||||
|
||||
<!-- Common key top visual configuration. -->
|
||||
|
|
|
@ -86,6 +86,9 @@
|
|||
<!-- Description for Arabic (PC) subtype. -->
|
||||
<string name="subtype_arabic_pc" translatable="false">%s (PC)</string>
|
||||
|
||||
<!-- Description for Arabic (Hija'i) subtype. -->
|
||||
<string name="subtype_arabic_hijai" translatable="false">%s (Hija\'i)</string>
|
||||
|
||||
<!-- Description for Hebrew 2 subtype. -->
|
||||
<string name="subtype_hebrew_1452_2" translatable="false">%s (1452-2)</string>
|
||||
|
||||
|
|
|
@ -239,6 +239,8 @@
|
|||
<string name="localized_number_row">Localize number row</string>
|
||||
<!-- Description of the settings to localize number row -->
|
||||
<string name="localized_number_row_summary">Prefer localized over latin numbers</string>
|
||||
<!-- Title of the setting to enable number row hints -->
|
||||
<string name="number_row_hints">Show hints on number row</string>
|
||||
<!-- Title of the setting to show key hints -->
|
||||
<string name="show_hints">Show key hints</string>
|
||||
<!-- Description of the settings to show hints -->
|
||||
|
@ -311,6 +313,16 @@
|
|||
<string name="prefs_keyboard_height_scale">Keyboard height scale</string>
|
||||
<!-- Title of the setting for setting bottom padding height -->
|
||||
<string name="prefs_bottom_padding_scale">Bottom padding scale</string>
|
||||
<!-- Title of the setting for setting bottom padding height in landscape mode -->
|
||||
<string name="prefs_bottom_padding_scale_landscape">Bottom padding scale (landscape)</string>
|
||||
<!-- Title of the setting for adjusting font size on the keyboard -->
|
||||
<!-- Title of the setting for setting side padding -->
|
||||
<string name="prefs_side_padding_scale">Side padding scale</string>
|
||||
<!-- Title of the setting for setting side padding in landscape mode -->
|
||||
<string name="prefs_side_padding_scale_landscape">Side padding scale (landscape)</string>
|
||||
<string name="prefs_font_scale">Keyboard font scale</string>
|
||||
<!-- Title of the setting for adjusting font size in emoji view -->
|
||||
<string name="prefs_emoji_font_scale">Emoji view font scale</string>
|
||||
<!-- Title of the setting for customizing space bar text -->
|
||||
<string name="prefs_space_bar_text">Custom text on space bar</string>
|
||||
<!-- Title of the setting for adding / removing custom font file -->
|
||||
|
@ -946,6 +958,8 @@ New dictionary:
|
|||
<string name="var_toolbar_direction">Variable toolbar direction</string>
|
||||
<!-- Description of the variable toolbar direction setting -->
|
||||
<string name="var_toolbar_direction_summary">Reverse direction when a right-to-left keyboard subtype is selected</string>
|
||||
<!-- Title of the settings for adjusting the language swipe gesture distance -->
|
||||
<string name="prefs_language_swipe_distance">Switch language swipe distance</string>
|
||||
<!-- Title of the setting to customize toolbar key codes -->
|
||||
<string name="customize_toolbar_key_codes">Customize toolbar key codes</string>
|
||||
<!-- Confirmation message when resetting all custom toolbar key codes -->
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
>
|
||||
<item name="keyboardTopPadding">0%p</item>
|
||||
<item name="keyboardBottomPadding">0%p</item>
|
||||
<item name="keyboardLeftPadding">0%p</item>
|
||||
<item name="keyboardRightPadding">0%p</item>
|
||||
<item name="horizontalGap">0%p</item>
|
||||
<item name="horizontalGapNarrow">0%p</item>
|
||||
<item name="touchPositionCorrectionData">@null</item>
|
||||
|
|
|
@ -81,6 +81,8 @@
|
|||
>
|
||||
<item name="keyboardTopPadding">0%p</item>
|
||||
<item name="keyboardBottomPadding">0%p</item>
|
||||
<item name="keyboardLeftPadding">0%p</item>
|
||||
<item name="keyboardRightPadding">0%p</item>
|
||||
<item name="horizontalGap">0%p</item>
|
||||
<item name="horizontalGapNarrow">0%p</item>
|
||||
<item name="touchPositionCorrectionData">@null</item>
|
||||
|
|
|
@ -90,6 +90,8 @@
|
|||
>
|
||||
<item name="keyboardTopPadding">0%p</item>
|
||||
<item name="keyboardBottomPadding">0%p</item>
|
||||
<item name="keyboardLeftPadding">0%p</item>
|
||||
<item name="keyboardRightPadding">0%p</item>
|
||||
<item name="horizontalGap">0%p</item>
|
||||
<item name="horizontalGapNarrow">0%p</item>
|
||||
<item name="touchPositionCorrectionData">@null</item>
|
||||
|
|
|
@ -178,6 +178,15 @@
|
|||
android:imeSubtypeExtraValue="KeyboardLayoutSet=arabic_pc,NoShiftKey,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_arabic_hijai"
|
||||
android:subtypeId="0x590dde42"
|
||||
android:imeSubtypeLocale="ar"
|
||||
android:languageTag="ar"
|
||||
android:imeSubtypeMode="keyboard"
|
||||
android:imeSubtypeExtraValue="KeyboardLayoutSet=arabic_hijai,NoShiftKey,SupportTouchPositionCorrection,EmojiCapable"
|
||||
android:isAsciiCapable="false"
|
||||
/>
|
||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||
android:label="@string/subtype_generic"
|
||||
android:subtypeId="0x70b0f974"
|
||||
|
|
|
@ -43,6 +43,13 @@
|
|||
android:title="@string/show_vertical_space_swipe"
|
||||
latin:singleLineTitle="false" />
|
||||
|
||||
<helium314.keyboard.latin.settings.SeekBarDialogPreference
|
||||
android:key="language_swipe_distance"
|
||||
android:title="@string/prefs_language_swipe_distance"
|
||||
latin:minValue="2"
|
||||
latin:maxValue="18"
|
||||
latin:stepValue="1" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="delete_swipe"
|
||||
android:title="@string/delete_swipe"
|
||||
|
|
|
@ -111,6 +111,27 @@
|
|||
latin:minValue="0"
|
||||
latin:maxValue="500" /> <!-- percentage -->
|
||||
|
||||
<helium314.keyboard.latin.settings.SeekBarDialogPreference
|
||||
android:key="bottom_padding_scale_landscape"
|
||||
android:title="@string/prefs_bottom_padding_scale_landscape"
|
||||
latin:defaultValue="0"
|
||||
latin:minValue="0"
|
||||
latin:maxValue="500" /> <!-- percentage -->
|
||||
|
||||
<helium314.keyboard.latin.settings.SeekBarDialogPreference
|
||||
android:key="side_padding_scale"
|
||||
android:title="@string/prefs_side_padding_scale"
|
||||
latin:defaultValue="0"
|
||||
latin:minValue="0"
|
||||
latin:maxValue="300" /> <!-- percentage -->
|
||||
|
||||
<helium314.keyboard.latin.settings.SeekBarDialogPreference
|
||||
android:key="side_padding_scale_landscape"
|
||||
android:title="@string/prefs_side_padding_scale_landscape"
|
||||
latin:defaultValue="0"
|
||||
latin:minValue="0"
|
||||
latin:maxValue="300" /> <!-- percentage -->
|
||||
|
||||
<EditTextPreference
|
||||
android:key="space_bar_text"
|
||||
android:title="@string/prefs_space_bar_text"
|
||||
|
@ -123,6 +144,18 @@
|
|||
android:defaultValue=""
|
||||
android:persistent="true" />
|
||||
|
||||
<helium314.keyboard.latin.settings.SeekBarDialogPreference
|
||||
android:key="font_scale"
|
||||
android:title="@string/prefs_font_scale"
|
||||
latin:minValue="50"
|
||||
latin:maxValue="150" /> <!-- percentage -->
|
||||
|
||||
<helium314.keyboard.latin.settings.SeekBarDialogPreference
|
||||
android:key="emoji_font_scale"
|
||||
android:title="@string/prefs_emoji_font_scale"
|
||||
latin:minValue="50"
|
||||
latin:maxValue="150" /> <!-- percentage -->
|
||||
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||
|
|
|
@ -85,6 +85,12 @@
|
|||
android:defaultValue="true"
|
||||
android:persistent="true" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="show_number_row_hints"
|
||||
android:title="@string/number_row_hints"
|
||||
android:defaultValue="false"
|
||||
android:persistent="true" />
|
||||
|
||||
<SwitchPreference
|
||||
android:key="show_language_switch_key"
|
||||
android:title="@string/show_language_switch_key"
|
||||
|
|
|
@ -613,6 +613,57 @@ 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)
|
||||
}
|
||||
|
||||
@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
|
||||
|
@ -646,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)
|
||||
|
@ -751,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) ""
|
||||
|
@ -969,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")
|
||||
|
|
|
@ -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?
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue