https://kotlinlang.org logo
#compose
Title
# compose
p

pavi2410

06/10/2020, 2:52 PM
I made a Text editor using VisualTransformation. It shows line numbers on the side. It was really tricky for me to write the offset translator, but Kotlin makes it super easy.
v

Vinay Gaba

06/10/2020, 3:20 PM
Looks neat!
l

Leland Richardson [G]

06/10/2020, 5:35 PM
neat - can you share the code for this?
p

pavi2410

06/10/2020, 6:15 PM
I need to do a little cleanup to make it readable. I will post it ASAP
👍 2
Copy code
@Composable
fun CodeEditor(value: TextFieldValue, onValueChange: (TextFieldValue) -> Unit) {
    TextField(
        textStyle = currentTextStyle().copy(
            fontFamily = FontFamily.Monospace,
            fontSize = 16.sp
        ),
        value = value,
        onValueChange = onValueChange,
        visualTransformation = CodeVisualTransformation()
    )
}

class CodeVisualTransformation : VisualTransformation {
    override fun filter(text: AnnotatedString): TransformedText {

        val transformedText = text.text
            .split("\n")
            .mapIndexed { i, t -> String.format("%2d %s", i + 1, t) }
            .joinToString("\n")

        val gutterSize = 3 // "%2d "

        val codeOffsetTranslator = object : OffsetMap {
            override fun originalToTransformed(offset: Int): Int =
                gutterSize + offset + text.text.take(offset).count { it == '\n' } * gutterSize

            override fun transformedToOriginal(offset: Int): Int =
                offset - gutterSize - transformedText.take(offset).count { it == '\n' } * gutterSize
        }

        val lineNumStyle = SpanStyle(color = Color.LightGray, fontSize = 12.sp)

        val transformedTextStyled = with(AnnotatedString.Builder(transformedText)) {

            """^.{2} """.toRegex(RegexOption.MULTILINE).findAll(transformedText).forEach {
                addStyle(lineNumStyle, it.range.first, it.range.last)
            }

            toAnnotatedString()
        }

        return TransformedText(transformedTextStyled, codeOffsetTranslator)
    }
}
8 Views