Merge pull request #178 from Merkost/capitalizing_settings
Sentences capitalization improving
This commit is contained in:
commit
7ac8bc9c3b
|
@ -1,60 +1,10 @@
|
|||
package com.simplemobiletools.keyboard.helpers
|
||||
|
||||
import android.content.Context
|
||||
import com.simplemobiletools.keyboard.extensions.config
|
||||
import com.simplemobiletools.keyboard.helpers.MyKeyboard.Companion.KEYCODE_SPACE
|
||||
|
||||
enum class ShiftState {
|
||||
OFF,
|
||||
ON_ONE_CHAR,
|
||||
ON_PERMANENT;
|
||||
|
||||
companion object {
|
||||
private val endOfSentenceChars: List<Char> = listOf('.', '?', '!')
|
||||
|
||||
fun getDefaultShiftState(context: Context): ShiftState {
|
||||
return when (context.config.enableSentencesCapitalization) {
|
||||
true -> ON_ONE_CHAR
|
||||
else -> OFF
|
||||
}
|
||||
}
|
||||
|
||||
fun getShiftStateForText(context: Context, newText: String?): ShiftState {
|
||||
if (!context.config.enableSentencesCapitalization) {
|
||||
return OFF
|
||||
}
|
||||
|
||||
val twoLastSymbols = newText?.takeLast(2)
|
||||
return when {
|
||||
shouldCapitalizeSentence(previousChar = twoLastSymbols?.getOrNull(0), currentChar = twoLastSymbols?.getOrNull(1)) -> {
|
||||
ON_ONE_CHAR
|
||||
}
|
||||
else -> {
|
||||
OFF
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getCapitalizationOnDelete(context: Context, text: CharSequence?): ShiftState {
|
||||
if (!context.config.enableSentencesCapitalization) {
|
||||
return OFF
|
||||
}
|
||||
|
||||
return if (text.isNullOrEmpty() || shouldCapitalizeSentence(currentChar = text.last(), previousChar = text.getOrNull(text.lastIndex - 1))) {
|
||||
ON_ONE_CHAR
|
||||
} else {
|
||||
OFF
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldCapitalizeSentence(previousChar: Char?, currentChar: Char?): Boolean {
|
||||
if (previousChar == null || currentChar == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
return currentChar.code == KEYCODE_SPACE && endOfSentenceChars.contains(previousChar)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// limit the count of alternative characters that show up at long pressing a key
|
||||
|
|
|
@ -242,12 +242,7 @@ class MyKeyboard {
|
|||
fun isInside(x: Int, y: Int): Boolean {
|
||||
val leftEdge = edgeFlags and EDGE_LEFT > 0
|
||||
val rightEdge = edgeFlags and EDGE_RIGHT > 0
|
||||
return (
|
||||
(x >= this.x || leftEdge && x <= this.x + width) &&
|
||||
(x < this.x + width || rightEdge && x >= this.x) &&
|
||||
(y >= this.y && y <= this.y + height) &&
|
||||
(y < this.y + height && y >= this.y)
|
||||
)
|
||||
return ((x >= this.x || leftEdge && x <= this.x + width) && (x < this.x + width || rightEdge && x >= this.x) && (y >= this.y && y <= this.y + height) && (y < this.y + height && y >= this.y))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -258,14 +253,13 @@ class MyKeyboard {
|
|||
* @param enterKeyType determines what icon should we show on Enter key
|
||||
*/
|
||||
@JvmOverloads
|
||||
constructor(context: Context, @XmlRes xmlLayoutResId: Int, enterKeyType: Int, shiftState: ShiftState = ShiftState.OFF) {
|
||||
constructor(context: Context, @XmlRes xmlLayoutResId: Int, enterKeyType: Int) {
|
||||
mDisplayWidth = context.resources.displayMetrics.widthPixels
|
||||
mDefaultHorizontalGap = 0
|
||||
mDefaultWidth = mDisplayWidth / 10
|
||||
mDefaultHeight = mDefaultWidth
|
||||
mKeyboardHeightMultiplier = getKeyboardHeightMultiplier(context.config.keyboardHeightMultiplier)
|
||||
mKeys = ArrayList()
|
||||
mShiftState = shiftState
|
||||
mEnterKeyType = enterKeyType
|
||||
loadKeyboard(context, context.resources.getXml(xmlLayoutResId))
|
||||
}
|
||||
|
@ -278,8 +272,7 @@ class MyKeyboard {
|
|||
* @param characters the list of characters to display on the keyboard. One key will be created for each character.
|
||||
* @param keyWidth the width of the popup key, make sure it is the same as the key itself
|
||||
*/
|
||||
constructor(context: Context, layoutTemplateResId: Int, characters: CharSequence, keyWidth: Int) :
|
||||
this(context, layoutTemplateResId, 0) {
|
||||
constructor(context: Context, layoutTemplateResId: Int, characters: CharSequence, keyWidth: Int) : this(context, layoutTemplateResId, 0) {
|
||||
var x = 0
|
||||
var y = 0
|
||||
var column = 0
|
||||
|
|
|
@ -2,11 +2,7 @@ package com.simplemobiletools.keyboard.services
|
|||
|
||||
import android.content.SharedPreferences
|
||||
import android.inputmethodservice.InputMethodService
|
||||
import android.text.InputType
|
||||
import android.text.InputType.TYPE_CLASS_DATETIME
|
||||
import android.text.InputType.TYPE_CLASS_NUMBER
|
||||
import android.text.InputType.TYPE_CLASS_PHONE
|
||||
import android.text.InputType.TYPE_MASK_CLASS
|
||||
import android.text.InputType.*
|
||||
import android.text.TextUtils
|
||||
import android.view.KeyEvent
|
||||
import android.view.View
|
||||
|
@ -20,8 +16,7 @@ import com.simplemobiletools.keyboard.R
|
|||
import com.simplemobiletools.keyboard.extensions.config
|
||||
import com.simplemobiletools.keyboard.helpers.*
|
||||
import com.simplemobiletools.keyboard.views.MyKeyboardView
|
||||
import kotlinx.android.synthetic.main.keyboard_view_keyboard.view.keyboard_holder
|
||||
import kotlinx.android.synthetic.main.keyboard_view_keyboard.view.keyboard_view
|
||||
import kotlinx.android.synthetic.main.keyboard_view_keyboard.view.*
|
||||
|
||||
// based on https://www.androidauthority.com/lets-build-custom-keyboard-android-832362/
|
||||
class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionListener, SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
|
@ -36,7 +31,8 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
private var keyboardView: MyKeyboardView? = null
|
||||
private var lastShiftPressTS = 0L
|
||||
private var keyboardMode = KEYBOARD_LETTERS
|
||||
private var inputTypeClass = InputType.TYPE_CLASS_TEXT
|
||||
private var inputTypeClass = TYPE_CLASS_TEXT
|
||||
private var inputTypeClassVariation = TYPE_CLASS_TEXT
|
||||
private var enterKeyType = IME_ACTION_NONE
|
||||
private var switchToLetters = false
|
||||
|
||||
|
@ -64,23 +60,31 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
|
||||
super.onStartInput(attribute, restarting)
|
||||
inputTypeClass = attribute!!.inputType and TYPE_MASK_CLASS
|
||||
inputTypeClassVariation = attribute.inputType and TYPE_MASK_VARIATION
|
||||
|
||||
enterKeyType = attribute.imeOptions and (IME_MASK_ACTION or IME_FLAG_NO_ENTER_ACTION)
|
||||
keyboard = createNewKeyboard()
|
||||
keyboardView?.setKeyboard(keyboard!!)
|
||||
keyboardView?.setEditorInfo(attribute)
|
||||
updateShiftKeyState()
|
||||
updateShiftKeyState(null)
|
||||
}
|
||||
|
||||
private fun updateShiftKeyState() {
|
||||
if (keyboardMode == KEYBOARD_LETTERS) {
|
||||
val editorInfo = currentInputEditorInfo
|
||||
if (editorInfo != null && editorInfo.inputType != InputType.TYPE_NULL && keyboard?.mShiftState != ShiftState.ON_PERMANENT) {
|
||||
if (currentInputConnection.getCursorCapsMode(editorInfo.inputType) != 0) {
|
||||
keyboard?.setShifted(ShiftState.ON_ONE_CHAR)
|
||||
keyboardView?.invalidateAllKeys()
|
||||
}
|
||||
private fun updateShiftKeyState(code: Int?) {
|
||||
if (code == MyKeyboard.KEYCODE_SHIFT) {
|
||||
return
|
||||
}
|
||||
|
||||
val editorInfo = currentInputEditorInfo
|
||||
if (config.enableSentencesCapitalization && editorInfo != null && editorInfo.inputType != TYPE_NULL) {
|
||||
if (currentInputConnection.getCursorCapsMode(editorInfo.inputType) != 0) {
|
||||
keyboard?.setShifted(ShiftState.ON_ONE_CHAR)
|
||||
keyboardView?.invalidateAllKeys()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
keyboard?.setShifted(ShiftState.OFF)
|
||||
keyboardView?.invalidateAllKeys()
|
||||
}
|
||||
|
||||
override fun onKey(code: Int) {
|
||||
|
@ -95,12 +99,6 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
|
||||
when (code) {
|
||||
MyKeyboard.KEYCODE_DELETE -> {
|
||||
|
||||
if (keyboard!!.mShiftState != ShiftState.ON_PERMANENT) {
|
||||
val extractedText = inputConnection.getTextBeforeCursor(3, 0)?.dropLast(1)
|
||||
keyboard!!.setShifted(ShiftState.getCapitalizationOnDelete(context = this, text = extractedText))
|
||||
}
|
||||
|
||||
val selectedText = inputConnection.getSelectedText(0)
|
||||
if (TextUtils.isEmpty(selectedText)) {
|
||||
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
|
||||
|
@ -108,9 +106,7 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
} else {
|
||||
inputConnection.commitText("", 1)
|
||||
}
|
||||
keyboardView!!.invalidateAllKeys()
|
||||
}
|
||||
|
||||
MyKeyboard.KEYCODE_SHIFT -> {
|
||||
if (keyboardMode == KEYBOARD_LETTERS) {
|
||||
when {
|
||||
|
@ -134,7 +130,6 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
}
|
||||
keyboardView!!.invalidateAllKeys()
|
||||
}
|
||||
|
||||
MyKeyboard.KEYCODE_ENTER -> {
|
||||
val imeOptionsActionId = getImeOptionsActionId()
|
||||
if (imeOptionsActionId != IME_ACTION_NONE) {
|
||||
|
@ -142,14 +137,8 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
} else {
|
||||
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER))
|
||||
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER))
|
||||
|
||||
if (config.enableSentencesCapitalization) {
|
||||
keyboard!!.setShifted(ShiftState.ON_ONE_CHAR)
|
||||
keyboardView!!.invalidateAllKeys()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MyKeyboard.KEYCODE_MODE_CHANGE -> {
|
||||
val keyboardXml = if (keyboardMode == KEYBOARD_LETTERS) {
|
||||
keyboardMode = KEYBOARD_SYMBOLS
|
||||
|
@ -161,11 +150,9 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
keyboard = MyKeyboard(this, keyboardXml, enterKeyType)
|
||||
keyboardView!!.setKeyboard(keyboard!!)
|
||||
}
|
||||
|
||||
MyKeyboard.KEYCODE_EMOJI -> {
|
||||
keyboardView?.openEmojiPalette()
|
||||
}
|
||||
|
||||
else -> {
|
||||
var codeChar = code.toChar()
|
||||
val originalText = inputConnection.getExtractedText(ExtractedTextRequest(), 0)?.text ?: return
|
||||
|
@ -177,7 +164,7 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
// If the keyboard is set to symbols and the user presses space, we usually should switch back to the letters keyboard.
|
||||
// However, avoid doing that in cases when the EditText for example requires numbers as the input.
|
||||
// We can detect that by the text not changing on pressing Space.
|
||||
if (keyboardMode != KEYBOARD_LETTERS && code == MyKeyboard.KEYCODE_SPACE) {
|
||||
if (keyboardMode != KEYBOARD_LETTERS && inputTypeClass == TYPE_CLASS_TEXT && code == MyKeyboard.KEYCODE_SPACE) {
|
||||
inputConnection.commitText(codeChar.toString(), 1)
|
||||
val newText = inputConnection.getExtractedText(ExtractedTextRequest(), 0)?.text
|
||||
if (originalText != newText) {
|
||||
|
@ -186,17 +173,11 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
} else {
|
||||
inputConnection.commitText(codeChar.toString(), 1)
|
||||
}
|
||||
|
||||
if (keyboardMode == KEYBOARD_LETTERS && keyboard!!.mShiftState != ShiftState.ON_PERMANENT) {
|
||||
keyboard!!.setShifted(ShiftState.getShiftStateForText(this, newText = "$originalText$codeChar"))
|
||||
keyboardView!!.invalidateAllKeys()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (code != MyKeyboard.KEYCODE_SHIFT && config.enableSentencesCapitalization) {
|
||||
updateShiftKeyState()
|
||||
if (keyboard!!.mShiftState != ShiftState.ON_PERMANENT) {
|
||||
updateShiftKeyState(code)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,13 +185,11 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
if (switchToLetters) {
|
||||
// TODO: Change keyboardMode to enum class
|
||||
keyboardMode = KEYBOARD_LETTERS
|
||||
val text = currentInputConnection?.getExtractedText(ExtractedTextRequest(), 0)?.text
|
||||
val newShiftState = ShiftState.getShiftStateForText(this, text?.toString().orEmpty())
|
||||
|
||||
keyboard = MyKeyboard(this, getKeyboardLayoutXML(), enterKeyType, shiftState = newShiftState)
|
||||
keyboard = MyKeyboard(this, getKeyboardLayoutXML(), enterKeyType)
|
||||
|
||||
val editorInfo = currentInputEditorInfo
|
||||
if (editorInfo != null && editorInfo.inputType != InputType.TYPE_NULL && keyboard?.mShiftState != ShiftState.ON_PERMANENT) {
|
||||
if (editorInfo != null && editorInfo.inputType != TYPE_NULL && keyboard?.mShiftState != ShiftState.ON_PERMANENT) {
|
||||
if (currentInputConnection.getCursorCapsMode(editorInfo.inputType) != 0) {
|
||||
keyboard?.setShifted(ShiftState.ON_ONE_CHAR)
|
||||
}
|
||||
|
@ -245,25 +224,23 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
|
|||
keyboardMode = KEYBOARD_NUMBERS
|
||||
R.xml.keys_numbers
|
||||
}
|
||||
|
||||
TYPE_CLASS_PHONE -> {
|
||||
keyboardMode = KEYBOARD_PHONE
|
||||
R.xml.keys_phone
|
||||
}
|
||||
|
||||
TYPE_CLASS_DATETIME -> {
|
||||
keyboardMode = KEYBOARD_SYMBOLS
|
||||
R.xml.keys_symbols
|
||||
}
|
||||
|
||||
else -> {
|
||||
keyboardMode = KEYBOARD_LETTERS
|
||||
getKeyboardLayoutXML()
|
||||
}
|
||||
}
|
||||
|
||||
return MyKeyboard(
|
||||
context = this, xmlLayoutResId = keyboardXml, enterKeyType = enterKeyType, shiftState = ShiftState.getDefaultShiftState(this)
|
||||
context = this,
|
||||
xmlLayoutResId = keyboardXml,
|
||||
enterKeyType = enterKeyType,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue