Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 24 additions & 16 deletions app/src/main/java/be/scri/helpers/KeyboardBase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ class KeyboardBase {
const val KEYCODE_DELETE = -5
const val KEYCODE_SPACE = 32
const val SCALING_CONSTANT = 150
const val KEYCODE_TAB = -30
const val KEYCODE_CAPS_LOCK = -50
const val KEYCODE_LEFT_ARROW = -55
const val KEYCODE_RIGHT_ARROW = -56
const val SHIFT_OFF = 0
const val SHIFT_ON = 1
const val SHIFT_LOCKED = 2

fun getDimensionOrFraction(
a: TypedArray,
Expand Down Expand Up @@ -132,9 +139,11 @@ class KeyboardBase {
Configuration.ORIENTATION_LANDSCAPE -> {
res.getDimension(R.dimen.key_height_landscape).toInt()
}

Configuration.ORIENTATION_PORTRAIT -> {
res.getDimension(R.dimen.key_height).toInt()
}

else -> {
res.getDimension(R.dimen.key_height).toInt()
}
Expand Down Expand Up @@ -269,9 +278,10 @@ class KeyboardBase {
label = a.getText(R.styleable.KeyboardBase_Key_keyLabel) ?: ""
topSmallNumber = a.getString(R.styleable.KeyboardBase_Key_topSmallNumber) ?: ""

if (label.isNotEmpty() && code != KEYCODE_MODE_CHANGE && code != KEYCODE_SHIFT) {
if (label.isNotEmpty() && code == 0) {
code = label[0].code
}

a.recycle()
}

Expand Down Expand Up @@ -318,18 +328,7 @@ class KeyboardBase {
@XmlRes xmlLayoutResId: Int,
enterKeyType: Int,
) {
mDisplayWidth =
when (context.resources.configuration.orientation) {
Configuration.ORIENTATION_LANDSCAPE -> {
context.resources.displayMetrics.widthPixels - SCALING_CONSTANT
}
Configuration.ORIENTATION_PORTRAIT -> {
context.resources.displayMetrics.widthPixels
}
else -> {
context.resources.displayMetrics.widthPixels
}
}
mDisplayWidth = context.resources.displayMetrics.widthPixels
mDefaultHorizontalGap = 0
mDefaultWidth = mDisplayWidth / WIDTH_DIVIDER
mDefaultHeight = mDefaultWidth
Expand Down Expand Up @@ -387,11 +386,14 @@ class KeyboardBase {
}

fun setShifted(shiftState: Int): Boolean {
if (this.mShiftState != shiftState) {
this.mShiftState = shiftState
if (mShiftState != shiftState) {
mShiftState =
when (shiftState) {
SHIFT_ON_PERMANENT -> SHIFT_LOCKED
else -> shiftState and 0x1
}
return true
}

return false
}

Expand Down Expand Up @@ -432,6 +434,7 @@ class KeyboardBase {
currentRow = createRowFromXml(res, parser)
mRows.add(currentRow)
}

TAG_KEY -> {
inKey = true
key = createKeyFromXml(res, currentRow!!, x, y, parser)
Expand All @@ -441,21 +444,26 @@ class KeyboardBase {
when (mEnterKeyType) {
EditorInfo.IME_ACTION_SEARCH ->
R.drawable.ic_search_vector

EditorInfo.IME_ACTION_NEXT,
EditorInfo.IME_ACTION_GO,
->
R.drawable.ic_arrow_right_vector

EditorInfo.IME_ACTION_SEND ->
R.drawable.ic_send_vector

MyCustomActions.IME_ACTION_COMMAND ->
R.drawable.play_button

else ->
R.drawable.ic_enter_vector
}
key.icon = context.resources.getDrawable(enterResourceId, context.theme)
}
currentRow.mKeys.add(key)
}

TAG_KEYBOARD -> {
parseKeyboardAttributes(res, parser)
}
Expand Down
204 changes: 126 additions & 78 deletions app/src/main/java/be/scri/services/EnglishKeyboardIME.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,19 @@ import be.scri.helpers.KeyboardBase
import be.scri.views.KeyboardView

class EnglishKeyboardIME : GeneralKeyboardIME("English") {
companion object {
private const val SMALLEST_SCREEN_WIDTH_TABLET = 600
private const val MAX_TEXT_LENGTH = 1000
private const val COMMIT_TEXT_CURSOR_POSITION = 1
}

private fun isTablet(): Boolean = resources.configuration.smallestScreenWidthDp >= SMALLEST_SCREEN_WIDTH_TABLET

override fun getKeyboardLayoutXML(): Int =
if (getEnablePeriodAndCommaABC()) {
R.xml.keys_letters_english
} else {
R.xml.keys_letters_english_without_period_and_comma
when {
isTablet() -> R.xml.keys_letters_english_tablet
getEnablePeriodAndCommaABC() -> R.xml.keys_letters_english
else -> R.xml.keys_letters_english_without_period_and_comma
}

override val keyboardLetters = 0
Expand All @@ -37,6 +45,9 @@ class EnglishKeyboardIME : GeneralKeyboardIME("English") {
override var hasTextBeforeCursor = false
override lateinit var binding: KeyboardViewCommandOptionsBinding

// Key handling logic extracted to a separate class
private val keyHandler = KeyHandler(this)

override fun onCreateInputView(): View {
binding = KeyboardViewCommandOptionsBinding.inflate(layoutInflater)
setupCommandBarTheme(binding)
Expand All @@ -57,101 +68,138 @@ class EnglishKeyboardIME : GeneralKeyboardIME("English") {
}

override fun onKey(code: Int) {
val inputConnection = currentInputConnection
if (keyboard == null || inputConnection == null) {
return
}
if (code != KeyboardBase.KEYCODE_SHIFT) {
lastShiftPressTS = 0
}
keyHandler.handleKey(code)
}

when (code) {
KeyboardBase.KEYCODE_DELETE -> {
handleKeycodeDelete()
keyboardView!!.invalidateAllKeys()
disableAutoSuggest()
override fun onCreate() {
super.onCreate()
keyboard = KeyboardBase(this, getKeyboardLayoutXML(), enterKeyType)
onCreateInputView()
setupCommandBarTheme(binding)
}

// Inner class to handle key events
inner class KeyHandler(
private val ime: EnglishKeyboardIME,
) {
fun handleKey(code: Int) {
val inputConnection = ime.currentInputConnection
if (ime.keyboard == null || inputConnection == null) {
return
}
if (code != KeyboardBase.KEYCODE_SHIFT) {
ime.lastShiftPressTS = 0
}

KeyboardBase.KEYCODE_SHIFT -> {
super.handleKeyboardLetters(keyboardMode, keyboardView)
keyboardView!!.invalidateAllKeys()
disableAutoSuggest()
when (code) {
KeyboardBase.KEYCODE_TAB -> inputConnection.commitText("\t", COMMIT_TEXT_CURSOR_POSITION)
KeyboardBase.KEYCODE_CAPS_LOCK -> handleCapsLock()
KeyboardBase.KEYCODE_DELETE -> handleDeleteKey()
KeyboardBase.KEYCODE_SHIFT -> handleShiftKey()
KeyboardBase.KEYCODE_ENTER -> handleEnterKey()
KeyboardBase.KEYCODE_MODE_CHANGE -> handleModeChangeKey()
KeyboardBase.KEYCODE_SPACE -> handleKeycodeSpace()
KeyboardBase.KEYCODE_LEFT_ARROW -> handleArrowKey(false)
KeyboardBase.KEYCODE_RIGHT_ARROW -> handleArrowKey(true)
else -> handleDefaultKey(code)
}
updateKeyboardState(code)
}

KeyboardBase.KEYCODE_ENTER -> {
disableAutoSuggest()
handleKeycodeEnter()
updateAutoSuggestText(isPlural = checkIfPluralWord, nounTypeSuggestion = nounTypeSuggestion)
private fun updateKeyboardState(code: Int) {
ime.lastWord = ime.getLastWordBeforeCursor()
Log.d("Debug", "${ime.lastWord}")
ime.autosuggestEmojis = ime.findEmojisForLastWord(ime.emojiKeywords, ime.lastWord)
ime.checkIfPluralWord = ime.findWheatherWordIsPlural(ime.pluralWords, ime.lastWord)

Log.i("MY-TAG", "${ime.checkIfPluralWord}")
Log.d("Debug", "${ime.autosuggestEmojis}")
Log.d("MY-TAG", "${ime.nounTypeSuggestion}")
ime.updateButtonText(ime.isAutoSuggestEnabled, ime.autosuggestEmojis)
if (code != KeyboardBase.KEYCODE_SHIFT) {
ime.updateShiftKeyState()
}
}

KeyboardBase.KEYCODE_MODE_CHANGE -> {
handleModeChange(keyboardMode, keyboardView, this)
disableAutoSuggest()
private fun handleCapsLock() {
ime.keyboard?.let {
val newState =
when (it.mShiftState) {
KeyboardBase.SHIFT_OFF -> KeyboardBase.SHIFT_LOCKED
else -> KeyboardBase.SHIFT_OFF
}
if (it.setShifted(newState)) {
ime.keyboardView?.invalidateAllKeys()
}
}
}

KeyboardBase.KEYCODE_SPACE -> {
handleKeycodeSpace()
private fun handleDefaultKey(code: Int) {
if (ime.currentState == ScribeState.IDLE || ime.currentState == ScribeState.SELECT_COMMAND) {
ime.handleElseCondition(code, ime.keyboardMode, binding = null)
} else {
ime.handleElseCondition(code, ime.keyboardMode, ime.keyboardBinding, commandBarState = true)
}
ime.disableAutoSuggest()
}

else -> {
if (currentState == ScribeState.IDLE || currentState == ScribeState.SELECT_COMMAND) {
handleElseCondition(code, keyboardMode, binding = null)
disableAutoSuggest()
} else {
handleElseCondition(code, keyboardMode, keyboardBinding, commandBarState = true)
disableAutoSuggest()
private fun handleDeleteKey() {
val shouldDelete =
when (ime.currentState) {
ScribeState.IDLE, ScribeState.SELECT_COMMAND -> false
else -> true
}
}
ime.handleDelete(shouldDelete, ime.keyboardBinding)
ime.keyboardView!!.invalidateAllKeys()
ime.disableAutoSuggest()
}

lastWord = getLastWordBeforeCursor()
Log.d("Debug", "$lastWord")
autosuggestEmojis = findEmojisForLastWord(emojiKeywords, lastWord)
checkIfPluralWord = findWheatherWordIsPlural(pluralWords, lastWord)

Log.i("MY-TAG", "$checkIfPluralWord")
Log.d("Debug", "$autosuggestEmojis")
Log.d("MY-TAG", "$nounTypeSuggestion")
updateButtonText(isAutoSuggestEnabled, autosuggestEmojis)
if (code != KeyboardBase.KEYCODE_SHIFT) {
super.updateShiftKeyState()
private fun handleShiftKey() {
ime.handleKeyboardLetters(ime.keyboardMode, ime.keyboardView)
ime.keyboardView!!.invalidateAllKeys()
ime.disableAutoSuggest()
}
}

fun handleKeycodeDelete() {
if (currentState == ScribeState.IDLE || currentState == ScribeState.SELECT_COMMAND) {
handleDelete(false, keyboardBinding)
} else {
handleDelete(true, keyboardBinding)
private fun handleEnterKey() {
if (ime.currentState == ScribeState.IDLE || ime.currentState == ScribeState.SELECT_COMMAND) {
ime.handleKeycodeEnter(ime.keyboardBinding, false)
} else {
ime.handleKeycodeEnter(ime.keyboardBinding, true)
ime.currentState = ScribeState.IDLE
ime.switchToCommandToolBar()
ime.updateUI()
}
ime.disableAutoSuggest()
}
}

fun handleKeycodeEnter() {
if (currentState == ScribeState.IDLE || currentState == ScribeState.SELECT_COMMAND) {
handleKeycodeEnter(keyboardBinding, false)
} else {
handleKeycodeEnter(keyboardBinding, true)
currentState = ScribeState.IDLE
switchToCommandToolBar()
updateUI()
private fun handleModeChangeKey() {
ime.handleModeChange(ime.keyboardMode, ime.keyboardView, ime)
ime.disableAutoSuggest()
}
}

fun handleKeycodeSpace() {
val code = KeyboardBase.KEYCODE_SPACE
if (currentState == ScribeState.IDLE || currentState == ScribeState.SELECT_COMMAND) {
handleElseCondition(code, keyboardMode, binding = null)
updateAutoSuggestText(isPlural = checkIfPluralWord)
} else {
handleElseCondition(code, keyboardMode, keyboardBinding, commandBarState = true)
disableAutoSuggest()
private fun handleArrowKey(isRight: Boolean) {
ime.currentInputConnection?.let { ic ->
val currentPos = ic.getTextBeforeCursor(MAX_TEXT_LENGTH, 0)?.length ?: 0
val newPos =
if (isRight) {
val textAfter = ic.getTextAfterCursor(MAX_TEXT_LENGTH, 0)?.toString() ?: ""
(currentPos + 1).coerceAtMost(currentPos + textAfter.length)
} else {
(currentPos - 1).coerceAtLeast(0)
}
ic.setSelection(newPos, newPos)
}
}
}

override fun onCreate() {
super.onCreate()
keyboard = KeyboardBase(this, getKeyboardLayoutXML(), enterKeyType)
onCreateInputView()
setupCommandBarTheme(binding)
private fun handleKeycodeSpace() {
val code = KeyboardBase.KEYCODE_SPACE
if (ime.currentState == ScribeState.IDLE || ime.currentState == ScribeState.SELECT_COMMAND) {
ime.handleElseCondition(code, ime.keyboardMode, binding = null)
ime.updateAutoSuggestText(isPlural = ime.checkIfPluralWord)
} else {
ime.handleElseCondition(code, ime.keyboardMode, ime.keyboardBinding, commandBarState = true)
ime.disableAutoSuggest()
}
}
}
}
23 changes: 15 additions & 8 deletions app/src/main/java/be/scri/views/KeyboardView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -521,14 +521,21 @@ class KeyboardView
}
}

private fun adjustCase(label: CharSequence?): CharSequence? =
label?.takeIf { it.length in 1..2 }?.let {
if (mKeyboard?.mShiftState?.let { state -> state > SHIFT_OFF } == true) {
label.toString().uppercase(Locale.getDefault())
} else {
label
}
} ?: label
private fun adjustCase(label: CharSequence?): CharSequence? {
if (label == null) return null
return when {
label.toString() in listOf("tab", "caps lock") -> label

mKeyboard?.mShiftState in
setOf(
KeyboardBase.SHIFT_LOCKED,
KeyboardBase.SHIFT_ON,
)
-> label.toString().uppercase(Locale.getDefault())

else -> label
}
}

public override fun onMeasure(
widthMeasureSpec: Int,
Expand Down
Loading
Loading