Skip to content

Commit 7ac8bc9

Browse files
authored
Merge pull request #178 from Merkost/capitalizing_settings
Sentences capitalization improving
2 parents c36f678 + 073ea38 commit 7ac8bc9

File tree

3 files changed

+32
-112
lines changed

3 files changed

+32
-112
lines changed

app/src/main/kotlin/com/simplemobiletools/keyboard/helpers/Constants.kt

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,10 @@
11
package com.simplemobiletools.keyboard.helpers
22

3-
import android.content.Context
4-
import com.simplemobiletools.keyboard.extensions.config
5-
import com.simplemobiletools.keyboard.helpers.MyKeyboard.Companion.KEYCODE_SPACE
63

74
enum class ShiftState {
85
OFF,
96
ON_ONE_CHAR,
107
ON_PERMANENT;
11-
12-
companion object {
13-
private val endOfSentenceChars: List<Char> = listOf('.', '?', '!')
14-
15-
fun getDefaultShiftState(context: Context): ShiftState {
16-
return when (context.config.enableSentencesCapitalization) {
17-
true -> ON_ONE_CHAR
18-
else -> OFF
19-
}
20-
}
21-
22-
fun getShiftStateForText(context: Context, newText: String?): ShiftState {
23-
if (!context.config.enableSentencesCapitalization) {
24-
return OFF
25-
}
26-
27-
val twoLastSymbols = newText?.takeLast(2)
28-
return when {
29-
shouldCapitalizeSentence(previousChar = twoLastSymbols?.getOrNull(0), currentChar = twoLastSymbols?.getOrNull(1)) -> {
30-
ON_ONE_CHAR
31-
}
32-
else -> {
33-
OFF
34-
}
35-
}
36-
}
37-
38-
fun getCapitalizationOnDelete(context: Context, text: CharSequence?): ShiftState {
39-
if (!context.config.enableSentencesCapitalization) {
40-
return OFF
41-
}
42-
43-
return if (text.isNullOrEmpty() || shouldCapitalizeSentence(currentChar = text.last(), previousChar = text.getOrNull(text.lastIndex - 1))) {
44-
ON_ONE_CHAR
45-
} else {
46-
OFF
47-
}
48-
}
49-
50-
private fun shouldCapitalizeSentence(previousChar: Char?, currentChar: Char?): Boolean {
51-
if (previousChar == null || currentChar == null) {
52-
return false
53-
}
54-
55-
return currentChar.code == KEYCODE_SPACE && endOfSentenceChars.contains(previousChar)
56-
}
57-
}
588
}
599

6010
// limit the count of alternative characters that show up at long pressing a key

app/src/main/kotlin/com/simplemobiletools/keyboard/helpers/MyKeyboard.kt

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,7 @@ class MyKeyboard {
242242
fun isInside(x: Int, y: Int): Boolean {
243243
val leftEdge = edgeFlags and EDGE_LEFT > 0
244244
val rightEdge = edgeFlags and EDGE_RIGHT > 0
245-
return (
246-
(x >= this.x || leftEdge && x <= this.x + width) &&
247-
(x < this.x + width || rightEdge && x >= this.x) &&
248-
(y >= this.y && y <= this.y + height) &&
249-
(y < this.y + height && y >= this.y)
250-
)
245+
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))
251246
}
252247
}
253248

@@ -258,14 +253,13 @@ class MyKeyboard {
258253
* @param enterKeyType determines what icon should we show on Enter key
259254
*/
260255
@JvmOverloads
261-
constructor(context: Context, @XmlRes xmlLayoutResId: Int, enterKeyType: Int, shiftState: ShiftState = ShiftState.OFF) {
256+
constructor(context: Context, @XmlRes xmlLayoutResId: Int, enterKeyType: Int) {
262257
mDisplayWidth = context.resources.displayMetrics.widthPixels
263258
mDefaultHorizontalGap = 0
264259
mDefaultWidth = mDisplayWidth / 10
265260
mDefaultHeight = mDefaultWidth
266261
mKeyboardHeightMultiplier = getKeyboardHeightMultiplier(context.config.keyboardHeightMultiplier)
267262
mKeys = ArrayList()
268-
mShiftState = shiftState
269263
mEnterKeyType = enterKeyType
270264
loadKeyboard(context, context.resources.getXml(xmlLayoutResId))
271265
}
@@ -278,8 +272,7 @@ class MyKeyboard {
278272
* @param characters the list of characters to display on the keyboard. One key will be created for each character.
279273
* @param keyWidth the width of the popup key, make sure it is the same as the key itself
280274
*/
281-
constructor(context: Context, layoutTemplateResId: Int, characters: CharSequence, keyWidth: Int) :
282-
this(context, layoutTemplateResId, 0) {
275+
constructor(context: Context, layoutTemplateResId: Int, characters: CharSequence, keyWidth: Int) : this(context, layoutTemplateResId, 0) {
283276
var x = 0
284277
var y = 0
285278
var column = 0

app/src/main/kotlin/com/simplemobiletools/keyboard/services/SimpleKeyboardIME.kt

Lines changed: 29 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ package com.simplemobiletools.keyboard.services
22

33
import android.content.SharedPreferences
44
import android.inputmethodservice.InputMethodService
5-
import android.text.InputType
6-
import android.text.InputType.TYPE_CLASS_DATETIME
7-
import android.text.InputType.TYPE_CLASS_NUMBER
8-
import android.text.InputType.TYPE_CLASS_PHONE
9-
import android.text.InputType.TYPE_MASK_CLASS
5+
import android.text.InputType.*
106
import android.text.TextUtils
117
import android.view.KeyEvent
128
import android.view.View
@@ -20,8 +16,7 @@ import com.simplemobiletools.keyboard.R
2016
import com.simplemobiletools.keyboard.extensions.config
2117
import com.simplemobiletools.keyboard.helpers.*
2218
import com.simplemobiletools.keyboard.views.MyKeyboardView
23-
import kotlinx.android.synthetic.main.keyboard_view_keyboard.view.keyboard_holder
24-
import kotlinx.android.synthetic.main.keyboard_view_keyboard.view.keyboard_view
19+
import kotlinx.android.synthetic.main.keyboard_view_keyboard.view.*
2520

2621
// based on https://www.androidauthority.com/lets-build-custom-keyboard-android-832362/
2722
class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionListener, SharedPreferences.OnSharedPreferenceChangeListener {
@@ -36,7 +31,8 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
3631
private var keyboardView: MyKeyboardView? = null
3732
private var lastShiftPressTS = 0L
3833
private var keyboardMode = KEYBOARD_LETTERS
39-
private var inputTypeClass = InputType.TYPE_CLASS_TEXT
34+
private var inputTypeClass = TYPE_CLASS_TEXT
35+
private var inputTypeClassVariation = TYPE_CLASS_TEXT
4036
private var enterKeyType = IME_ACTION_NONE
4137
private var switchToLetters = false
4238

@@ -64,23 +60,31 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
6460
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
6561
super.onStartInput(attribute, restarting)
6662
inputTypeClass = attribute!!.inputType and TYPE_MASK_CLASS
63+
inputTypeClassVariation = attribute.inputType and TYPE_MASK_VARIATION
64+
6765
enterKeyType = attribute.imeOptions and (IME_MASK_ACTION or IME_FLAG_NO_ENTER_ACTION)
6866
keyboard = createNewKeyboard()
6967
keyboardView?.setKeyboard(keyboard!!)
7068
keyboardView?.setEditorInfo(attribute)
71-
updateShiftKeyState()
69+
updateShiftKeyState(null)
7270
}
7371

74-
private fun updateShiftKeyState() {
75-
if (keyboardMode == KEYBOARD_LETTERS) {
76-
val editorInfo = currentInputEditorInfo
77-
if (editorInfo != null && editorInfo.inputType != InputType.TYPE_NULL && keyboard?.mShiftState != ShiftState.ON_PERMANENT) {
78-
if (currentInputConnection.getCursorCapsMode(editorInfo.inputType) != 0) {
79-
keyboard?.setShifted(ShiftState.ON_ONE_CHAR)
80-
keyboardView?.invalidateAllKeys()
81-
}
72+
private fun updateShiftKeyState(code: Int?) {
73+
if (code == MyKeyboard.KEYCODE_SHIFT) {
74+
return
75+
}
76+
77+
val editorInfo = currentInputEditorInfo
78+
if (config.enableSentencesCapitalization && editorInfo != null && editorInfo.inputType != TYPE_NULL) {
79+
if (currentInputConnection.getCursorCapsMode(editorInfo.inputType) != 0) {
80+
keyboard?.setShifted(ShiftState.ON_ONE_CHAR)
81+
keyboardView?.invalidateAllKeys()
82+
return
8283
}
8384
}
85+
86+
keyboard?.setShifted(ShiftState.OFF)
87+
keyboardView?.invalidateAllKeys()
8488
}
8589

8690
override fun onKey(code: Int) {
@@ -95,22 +99,14 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
9599

96100
when (code) {
97101
MyKeyboard.KEYCODE_DELETE -> {
98-
99-
if (keyboard!!.mShiftState != ShiftState.ON_PERMANENT) {
100-
val extractedText = inputConnection.getTextBeforeCursor(3, 0)?.dropLast(1)
101-
keyboard!!.setShifted(ShiftState.getCapitalizationOnDelete(context = this, text = extractedText))
102-
}
103-
104102
val selectedText = inputConnection.getSelectedText(0)
105103
if (TextUtils.isEmpty(selectedText)) {
106104
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
107105
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL))
108106
} else {
109107
inputConnection.commitText("", 1)
110108
}
111-
keyboardView!!.invalidateAllKeys()
112109
}
113-
114110
MyKeyboard.KEYCODE_SHIFT -> {
115111
if (keyboardMode == KEYBOARD_LETTERS) {
116112
when {
@@ -134,22 +130,15 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
134130
}
135131
keyboardView!!.invalidateAllKeys()
136132
}
137-
138133
MyKeyboard.KEYCODE_ENTER -> {
139134
val imeOptionsActionId = getImeOptionsActionId()
140135
if (imeOptionsActionId != IME_ACTION_NONE) {
141136
inputConnection.performEditorAction(imeOptionsActionId)
142137
} else {
143138
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER))
144139
inputConnection.sendKeyEvent(KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER))
145-
146-
if (config.enableSentencesCapitalization) {
147-
keyboard!!.setShifted(ShiftState.ON_ONE_CHAR)
148-
keyboardView!!.invalidateAllKeys()
149-
}
150140
}
151141
}
152-
153142
MyKeyboard.KEYCODE_MODE_CHANGE -> {
154143
val keyboardXml = if (keyboardMode == KEYBOARD_LETTERS) {
155144
keyboardMode = KEYBOARD_SYMBOLS
@@ -161,11 +150,9 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
161150
keyboard = MyKeyboard(this, keyboardXml, enterKeyType)
162151
keyboardView!!.setKeyboard(keyboard!!)
163152
}
164-
165153
MyKeyboard.KEYCODE_EMOJI -> {
166154
keyboardView?.openEmojiPalette()
167155
}
168-
169156
else -> {
170157
var codeChar = code.toChar()
171158
val originalText = inputConnection.getExtractedText(ExtractedTextRequest(), 0)?.text ?: return
@@ -177,7 +164,7 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
177164
// If the keyboard is set to symbols and the user presses space, we usually should switch back to the letters keyboard.
178165
// However, avoid doing that in cases when the EditText for example requires numbers as the input.
179166
// We can detect that by the text not changing on pressing Space.
180-
if (keyboardMode != KEYBOARD_LETTERS && code == MyKeyboard.KEYCODE_SPACE) {
167+
if (keyboardMode != KEYBOARD_LETTERS && inputTypeClass == TYPE_CLASS_TEXT && code == MyKeyboard.KEYCODE_SPACE) {
181168
inputConnection.commitText(codeChar.toString(), 1)
182169
val newText = inputConnection.getExtractedText(ExtractedTextRequest(), 0)?.text
183170
if (originalText != newText) {
@@ -186,31 +173,23 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
186173
} else {
187174
inputConnection.commitText(codeChar.toString(), 1)
188175
}
189-
190-
if (keyboardMode == KEYBOARD_LETTERS && keyboard!!.mShiftState != ShiftState.ON_PERMANENT) {
191-
keyboard!!.setShifted(ShiftState.getShiftStateForText(this, newText = "$originalText$codeChar"))
192-
keyboardView!!.invalidateAllKeys()
193-
}
194-
195176
}
196177
}
197178

198-
if (code != MyKeyboard.KEYCODE_SHIFT && config.enableSentencesCapitalization) {
199-
updateShiftKeyState()
179+
if (keyboard!!.mShiftState != ShiftState.ON_PERMANENT) {
180+
updateShiftKeyState(code)
200181
}
201182
}
202183

203184
override fun onActionUp() {
204185
if (switchToLetters) {
205186
// TODO: Change keyboardMode to enum class
206187
keyboardMode = KEYBOARD_LETTERS
207-
val text = currentInputConnection?.getExtractedText(ExtractedTextRequest(), 0)?.text
208-
val newShiftState = ShiftState.getShiftStateForText(this, text?.toString().orEmpty())
209188

210-
keyboard = MyKeyboard(this, getKeyboardLayoutXML(), enterKeyType, shiftState = newShiftState)
189+
keyboard = MyKeyboard(this, getKeyboardLayoutXML(), enterKeyType)
211190

212191
val editorInfo = currentInputEditorInfo
213-
if (editorInfo != null && editorInfo.inputType != InputType.TYPE_NULL && keyboard?.mShiftState != ShiftState.ON_PERMANENT) {
192+
if (editorInfo != null && editorInfo.inputType != TYPE_NULL && keyboard?.mShiftState != ShiftState.ON_PERMANENT) {
214193
if (currentInputConnection.getCursorCapsMode(editorInfo.inputType) != 0) {
215194
keyboard?.setShifted(ShiftState.ON_ONE_CHAR)
216195
}
@@ -245,25 +224,23 @@ class SimpleKeyboardIME : InputMethodService(), MyKeyboardView.OnKeyboardActionL
245224
keyboardMode = KEYBOARD_NUMBERS
246225
R.xml.keys_numbers
247226
}
248-
249227
TYPE_CLASS_PHONE -> {
250228
keyboardMode = KEYBOARD_PHONE
251229
R.xml.keys_phone
252230
}
253-
254231
TYPE_CLASS_DATETIME -> {
255232
keyboardMode = KEYBOARD_SYMBOLS
256233
R.xml.keys_symbols
257234
}
258-
259235
else -> {
260236
keyboardMode = KEYBOARD_LETTERS
261237
getKeyboardLayoutXML()
262238
}
263239
}
264-
265240
return MyKeyboard(
266-
context = this, xmlLayoutResId = keyboardXml, enterKeyType = enterKeyType, shiftState = ShiftState.getDefaultShiftState(this)
241+
context = this,
242+
xmlLayoutResId = keyboardXml,
243+
enterKeyType = enterKeyType,
267244
)
268245
}
269246

0 commit comments

Comments
 (0)