Skip to content

Commit 8065bf8

Browse files
committed
Update the method of dealing with Console
1 parent 8c85b67 commit 8065bf8

File tree

3 files changed

+64
-20
lines changed

3 files changed

+64
-20
lines changed

src/main/kotlin/ConsoleHandler.kt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
11
import androidx.compose.ui.text.AnnotatedString
2+
import androidx.compose.ui.text.input.TextFieldValue
23
import androidx.compose.ui.text.withStyle
34

45
object ConsoleHandler {
56
private lateinit var builder: AnnotatedString.Builder
67

7-
fun processInput(text: String): AnnotatedString {
8-
if (::builder.isInitialized)
9-
if (State.console.prevText == text ||
10-
!identicalLinesExceptLastLineAreEqual(text, State.console.prevText) || isAtTheBeginningOfLinesExceptOne(State.console.prevText, text)
11-
) {
12-
return builder.toAnnotatedString()
13-
}
8+
fun shouldNotChange(newText: String) = ::builder.isInitialized && (
9+
State.console.prevText == newText ||
10+
!identicalLinesExceptLastLineAreEqual(newText, State.console.prevText) ||
11+
isAtTheBeginningOfLinesExceptOne(State.console.prevText, newText)
12+
)
13+
14+
fun processInput(textFieldValue: TextFieldValue): AnnotatedString {
15+
val text = textFieldValue.text
16+
17+
if (shouldNotChange(text))
18+
return builder.toAnnotatedString()
1419

1520
if (text[text.lastIndex] == '\n') {
1621
val rawUserLine = State.console.prevText.substring(State.console.prevText.lastIndexOf('\n') + 1)

src/main/kotlin/ConsoleState.kt

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import androidx.compose.runtime.getValue
22
import androidx.compose.runtime.mutableStateOf
33
import androidx.compose.runtime.setValue
4+
import androidx.compose.ui.text.TextRange
5+
import androidx.compose.ui.text.input.TextFieldValue
46
import kotlinx.coroutines.delay
57
import kotlinx.coroutines.flow.flow
68

@@ -21,7 +23,7 @@ class ConsoleState {
2123
|
2224
""".trimMargin(marginPrefix = "|")
2325

24-
var text by mutableStateOf(initialText)
26+
var textFieldValue by mutableStateOf(TextFieldValue(initialText, selection = TextRange(initialText.length)))
2527
private set
2628

2729
var prevText by mutableStateOf(initialText)
@@ -35,10 +37,29 @@ class ConsoleState {
3537
colorChangeIndexList[478] = appConfig.theme.color.front
3638
}
3739

38-
@JvmName("setConsoleText")
39-
fun setText(newText: String) {
40-
if (newText.count { it == '\n' } >= text.count { it == '\n' })
41-
text = newText
40+
@JvmName("setConsoleTextFieldValue")
41+
fun setTextFieldValue(textFieldValue: TextFieldValue) {
42+
if (textFieldValue.text.count { it == '\n' } >= this.textFieldValue.text.count { it == '\n' }) {
43+
this.textFieldValue = textFieldValue
44+
}
45+
}
46+
47+
fun setText(newText: String, jumpToEnd: Boolean) {
48+
if (newText.count { it == '\n' } >= this.textFieldValue.text.count { it == '\n' }) {
49+
this.textFieldValue = textFieldValue.copy(
50+
text = newText,
51+
selection = if (jumpToEnd) TextRange(newText.length) else this.textFieldValue.selection
52+
)
53+
}
54+
}
55+
56+
fun setTextRange(selection: TextRange) {
57+
this.textFieldValue.text.length.let { length ->
58+
if (selection.max <= length)
59+
textFieldValue = textFieldValue.copy(textFieldValue.text, selection)
60+
else if (selection.min <= length)
61+
textFieldValue = textFieldValue.copy(textFieldValue.text, TextRange(selection.min, length))
62+
}
4263
}
4364

4465
@JvmName("setConsolePrevText")
@@ -47,7 +68,7 @@ class ConsoleState {
4768
}
4869

4970
fun clean() {
50-
text = initialText
71+
textFieldValue = textFieldValue.copy(initialText)
5172
prevText = initialText
5273
}
5374

@@ -56,7 +77,7 @@ class ConsoleState {
5677
printQueue += it
5778
}
5879
colorCode?.let {
59-
colorChangeIndexList[this.text.length] = it
80+
colorChangeIndexList[this.textFieldValue.text.length] = it
6081
}
6182
}
6283

src/main/kotlin/compose/Console.kt

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package compose
22

33
import ConsoleHandler.processInput
4+
import ConsoleHandler.shouldNotChange
45
import ConsoleState
56
import State
7+
import androidx.compose.foundation.text.KeyboardOptions
68
import androidx.compose.material.TextField
79
import androidx.compose.material.TextFieldDefaults
810
import androidx.compose.runtime.Composable
@@ -11,10 +13,15 @@ import androidx.compose.runtime.rememberCoroutineScope
1113
import androidx.compose.ui.Modifier
1214
import androidx.compose.ui.graphics.Color
1315
import androidx.compose.ui.graphics.RectangleShape
16+
import androidx.compose.ui.text.TextRange
1417
import androidx.compose.ui.text.TextStyle
1518
import androidx.compose.ui.text.font.FontFamily
1619
import androidx.compose.ui.text.font.FontStyle
20+
import androidx.compose.ui.text.input.ImeAction
21+
import androidx.compose.ui.text.input.KeyboardCapitalization
22+
import androidx.compose.ui.text.input.KeyboardType
1723
import androidx.compose.ui.text.input.OffsetMapping
24+
import androidx.compose.ui.text.input.TextFieldValue
1825
import androidx.compose.ui.text.input.TransformedText
1926
import androidx.compose.ui.unit.em
2027
import androidx.compose.ui.unit.sp
@@ -65,8 +72,8 @@ fun Console(modifier: Modifier, state: ConsoleState = remember { State.console }
6572
)
6673

6774
TextField(
68-
modifier = modifier,
69-
value = state.text,
75+
modifier = modifier.HandleKeyEvents(),
76+
value = state.textFieldValue,
7077
singleLine = false,
7178
maxLines = Int.MAX_VALUE,
7279
colors = colors,
@@ -81,18 +88,29 @@ fun Console(modifier: Modifier, state: ConsoleState = remember { State.console }
8188
isError = false,
8289
visualTransformation = {
8390
TransformedText(
84-
processInput(state.text),
91+
processInput(state.textFieldValue),
8592
OffsetMapping.Identity
8693
)
8794
},
88-
onValueChange = {
89-
state.setText(processInput(it).toString())
95+
onValueChange = { value: TextFieldValue ->
96+
if (!shouldNotChange(value.text)) {
97+
val result = processInput(value).toString()
98+
state.setTextFieldValue(
99+
TextFieldValue(result, TextRange(result.length))
100+
)
101+
}
90102
},
103+
keyboardOptions = KeyboardOptions(
104+
capitalization = KeyboardCapitalization.None,
105+
autoCorrect = true,
106+
keyboardType = KeyboardType.Text,
107+
imeAction = ImeAction.Send,
108+
),
91109
)
92110

93111
coroutineScope.launch {
94112
state.printMessageFlow().collect {
95-
state.setText(processInput(state.text + it).toString())
113+
state.setText(processInput(TextFieldValue(state.textFieldValue.text + it)).toString(), true)
96114
}
97115
}
98116
}

0 commit comments

Comments
 (0)