Fixed cursor at 0

This commit is contained in:
Sad Ellie 2023-05-31 21:44:11 +03:00
parent 225c35c35e
commit 9f6ba87f57
2 changed files with 84 additions and 10 deletions

View File

@ -34,21 +34,24 @@ class ExpressionTransformer(private val formatterSymbols: FormatterSymbols) : Vi
} }
inner class ExpressionMapping( inner class ExpressionMapping(
private val unformatted: String, private val original: String,
private val formatted: String private val transformed: String
) : OffsetMapping { ) : OffsetMapping {
// Called when entering text (on each text change) // Called when entering text (on each text change)
// Basically moves cursor to the right position // Basically moves cursor to the right position
// //
// original input is "1000" and cursor is placed at the end "1000|" // original input is "1000" and cursor is placed at the end "1000|"
// the formatted is "1,000" where cursor should be? - "1,000|" // the transformed is "1,000" where cursor should be? - "1,000|"
override fun originalToTransformed(offset: Int): Int { override fun originalToTransformed(offset: Int): Int {
val unformattedSubstr = unformatted.take(offset) if (offset <= 0) return 0
if (offset >= original.length) return transformed.length
val unformattedSubstr = original.take(offset)
var buffer = "" var buffer = ""
var groupings = 0 var groupings = 0
run { run {
formatted.forEach { transformed.forEach {
when (it) { when (it) {
formatterSymbols.grouping.first() -> groupings++ formatterSymbols.grouping.first() -> groupings++
formatterSymbols.fractional.first() -> buffer += "." formatterSymbols.fractional.first() -> buffer += "."
@ -58,18 +61,21 @@ class ExpressionTransformer(private val formatterSymbols: FormatterSymbols) : Vi
} }
} }
return formatted.fixCursor(buffer.length + groupings, formatterSymbols.grouping) return transformed.fixCursor(buffer.length + groupings, formatterSymbols.grouping)
} }
// Called when clicking formatted text // Called when clicking transformed text
// Snaps cursor to the right position // Snaps cursor to the right position
// //
// the formatted is "1,000" and cursor is placed at the end "1,000|" // the transformed is "1,000" and cursor is placed at the end "1,000|"
// original input is "1000" where cursor should be? - "1000|" // original input is "1000" where cursor should be? - "1000|"
override fun transformedToOriginal(offset: Int): Int { override fun transformedToOriginal(offset: Int): Int {
if (offset <= 0) return 0
if (offset >= transformed.length) return original.length
val grouping = formatterSymbols.grouping.first() val grouping = formatterSymbols.grouping.first()
val fixedCursor = formatted.fixCursor(offset, formatterSymbols.grouping) val fixedCursor = transformed.fixCursor(offset, formatterSymbols.grouping)
val addedSymbols = formatted.take(fixedCursor).count { it == grouping } val addedSymbols = transformed.take(fixedCursor).count { it == grouping }
return fixedCursor - addedSymbols return fixedCursor - addedSymbols
} }
} }

View File

@ -0,0 +1,68 @@
/*
* Unitto is a unit converter for Android
* Copyright (c) 2023 Elshan Agaev
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sadellie.unitto.core.ui
import com.sadellie.unitto.core.ui.common.textfield.ExpressionTransformer
import com.sadellie.unitto.core.ui.common.textfield.FormatterSymbols
import org.junit.Assert.assertEquals
import org.junit.Test
class ExpressionTransformerTest {
private val expr = ExpressionTransformer(FormatterSymbols.Comma)
private fun origToTrans(orig: String, trans: String, offset: Int): Int =
expr.ExpressionMapping(orig, trans).originalToTransformed(offset)
private fun transToOrig(trans: String, orig: String, offset: Int): Int =
expr.ExpressionMapping(orig, trans).transformedToOriginal(offset)
@Test
fun `test 1234`() {
// at the start
assertEquals(0, origToTrans("1,234", "1234", 0))
assertEquals(0, transToOrig("1,234", "1234", 0))
// somewhere in inside, no offset needed
assertEquals(1, origToTrans("1234", "1,234", 1))
assertEquals(1, transToOrig("1,234", "1234", 1))
// somewhere in inside, offset needed
assertEquals(1, transToOrig("1,234", "1234", 2))
// at the end
assertEquals(5, origToTrans("1234", "1,234", 4))
assertEquals(4, transToOrig("1,234", "1234", 5))
}
@Test
fun `test 123`() {
// at the start
assertEquals(0, origToTrans("123", "123", 0))
assertEquals(0, transToOrig("123", "123", 0))
// somewhere in inside
assertEquals(1, origToTrans("123", "123", 1))
assertEquals(1, transToOrig("123", "123", 1))
// at the end
assertEquals(3, origToTrans("123", "123", 3))
assertEquals(3, transToOrig("123", "123", 3))
}
}