tawasuyu

sergio/humanoid

HTML 38Markdown 1TOML 10 Definitions

⎇ e3dd167a16e071c181b3d4f3bc77664f9cf053ab keyboard/src/main/java/com/rizoma/trazo/ime/KeyboardController.kt 80 lines · 2.3 KB History raw

Trazo: teclado MessagEase remasterizado (IME v0.1) e3dd167a1 · sergio ·

1package com.rizoma.trazo.ime
2
3import androidx.compose.runtime.getValue
4import androidx.compose.runtime.mutableStateOf
5import androidx.compose.runtime.setValue
6import com.rizoma.trazo.model.Layouts
7
8/** Puente con el editor real. Lo implementa el InputMethodService. */
9interface ImeHost {
10    fun commit(text: String)
11    fun backspace()
12    fun newline()
13    fun textBeforeCursor(n: Int): CharSequence
14    /** TextUtils.CAP_MODE_* combinado: !=0 si el editor quiere mayúscula aquí. */
15    fun cursorCapsMode(): Int
16}
17
18enum class ShiftState { OFF, ON, LOCK }
19enum class Layer { LETTERS, SYMBOLS }
20
21/**
22 * Toda la lógica de escritura. La UI solo dispara eventos; el estado de mayúscula
23 * y de capa son observables por Compose.
24 */
25class KeyboardController(private val host: ImeHost) {
26
27    var shift by mutableStateOf(ShiftState.ON)
28        private set
29    var layer by mutableStateOf(Layer.LETTERS)
30        private set
31
32    val keys get() = if (layer == Layer.LETTERS) Layouts.letters else Layouts.symbols
33    val shifted get() = shift != ShiftState.OFF
34
35    fun onChar(raw: Char) {
36        val out = if (shifted) raw.uppercaseChar() else raw
37        host.commit(out.toString())
38        if (shift == ShiftState.ON) shift = ShiftState.OFF // mayúscula de un solo disparo
39    }
40
41    fun onSpace() {
42        // Doble espacio tras palabra → ". " (puntua y capitaliza).
43        val before = host.textBeforeCursor(2)
44        if (before.length == 2 && before[1] == ' ' && before[0].isLetterOrDigit()) {
45            host.backspace()
46            host.commit(". ")
47        } else {
48            host.commit(" ")
49        }
50        syncAutoShift()
51    }
52
53    fun onBackspace() {
54        host.backspace()
55        syncAutoShift()
56    }
57
58    fun onEnter() {
59        host.newline()
60        syncAutoShift()
61    }
62
63    fun onShift() {
64        shift = when (shift) {
65            ShiftState.OFF -> ShiftState.ON
66            ShiftState.ON -> ShiftState.LOCK
67            ShiftState.LOCK -> ShiftState.OFF
68        }
69    }
70
71    fun toggleLayer() {
72        layer = if (layer == Layer.LETTERS) Layer.SYMBOLS else Layer.LETTERS
73    }
74
75    /** Recalcula la mayúscula automática según el contexto del editor. */
76    fun syncAutoShift() {
77        if (shift == ShiftState.LOCK) return
78        shift = if (host.cursorCapsMode() != 0) ShiftState.ON else ShiftState.OFF
79    }
80}