Im looking for some advice around `VisualTransform...
# compose
z
Im looking for some advice around
VisualTransformation
& formatting duration input! 🧵
Im looking to format numerical input as "hhmmss" as the user is typing. Typing 1, 3, 5 should result in "1:35", whereas 1, 3 should just be "13". I take it VisualTransformation is the place to go, but Ive been unable to wrap my head around it enough to get it working - it seems to me that since the offset differs between "1:35" [1 -> 2] and "13:35" [2 -> 3], Ill probably need to also account for that in my calculations. Any advice would be greatly appreciated!
d
In my opinion I do not see how to do this on the fly.
Not sure you have enough information until you can determine they are done typing and have moved on.
Or you could float the colon in front of the cursor? 🤔
Yeah cursor position might be key here?
Type 1st number then place colon and if the cursor moves in front of the colon then you have all you need.
Or enforce a strict syntax
digit digit : digit digit
@Zoltan Demant How’s that sound?
z
I think I can get the formatting working quite easily, since youre always typing in reverse .. the general rule still applies that every 2 characters should include a
:
separator .. 1,3,5 becomes "1:35" and 1,3,5,6 becomes "13:56" etc. It feels odd typing that way though, and I think its due to the cursor position moving left through the input as youre typing instead of always being at the end; theoretically that should be an easy fix? I can share some code around it tomorrow. As for including a colon right from the get go, wouldnt that be hard to accomplish as well? Id be down to experiment with it, but I dont really know how to implement it right now! Perhaps Im just all too new to the offset mapping..
My early draft for formatting works. Still havent gotten OffsetMapping to do its thing, for every "missed" offset-mapping, the cursor moves left due to the appended ":"; and moving back through the cursor jumps at the wrong place, again due to the offset-mapping not being correct.
Copy code
VisualTransformation { annotatedString ->
    val trimmed = if (annotatedString.text.length > 5) annotatedString.text.take(5) else annotatedString.text
    var out = ""
    var separators = 0

    trimmed.forEachIndexed { index, c ->
        out += c

        if (index % 2 == 0 && index + 1 < trimmed.length) {
            out += ':'
            separators++
        }
    }
}
I managed to solve this. If anyone is interested in the code, let me know!
d
@Zoltan Demant I am interested, could you make a small gist on github?
z
Here you go 🙂