Fix InputView position and deletion

- Fixes #856
This commit is contained in:
Janne Valkealahti
2023-08-22 15:05:20 +03:00
parent 29417d495b
commit b271c4493c
3 changed files with 63 additions and 10 deletions

View File

@@ -67,8 +67,8 @@ public class InputView extends BoxView {
String s = getInputText();
screen.writerBuilder().build().text(s, rect.x(), rect.y());
screen.setShowCursor(hasFocus());
int sum = text.stream().limit(cursorIndex).mapToInt(text -> text.length()).sum();
screen.setCursorPosition(new Position(rect.x() + sum, rect.y()));
int cPos = cursorPosition();
screen.setCursorPosition(new Position(rect.x() + cPos, rect.y()));
super.drawInternal(screen);
}
@@ -81,8 +81,12 @@ public class InputView extends BoxView {
return text.stream().collect(Collectors.joining());
}
private int cursorPosition() {
return text.stream().limit(cursorIndex).mapToInt(text -> text.length()).sum();
}
private void add(String data) {
text.add(data);
text.add(cursorIndex, data);
moveCursor(1);
}
@@ -94,7 +98,9 @@ public class InputView extends BoxView {
}
private void delete() {
text.remove(cursorIndex);
if (cursorIndex < text.size()) {
text.remove(cursorIndex);
}
}
private void moveCursor(int index) {

View File

@@ -132,6 +132,10 @@ public class AbstractViewTests {
return getField(object, field, String.class);
}
protected static int getIntField(Object object, String field) {
return getField(object, field, int.class);
}
protected static Runnable getRunnableField(Object object, String field) {
return getField(object, field, Runnable.class);
}
@@ -141,4 +145,13 @@ public class AbstractViewTests {
return (T) ReflectionTestUtils.getField(object, field);
}
protected static int callIntMethod(Object object, String method) {
return callMethod(int.class, object, method);
}
@SuppressWarnings("unchecked")
protected static <T> T callMethod(Class<T> type, Object object, String method, Object... args) {
return (T) ReflectionTestUtils.invokeMethod(object, method, args);
}
}

View File

@@ -28,6 +28,7 @@ import static org.assertj.core.api.Assertions.assertThat;
class InputViewTests extends AbstractViewTests {
private static final String CURSOR_INDEX_FIELD = "cursorIndex";
private static final String CURSOR_POSITION_METHOD = "cursorPosition";
@Nested
class Input {
@@ -135,16 +136,49 @@ class InputViewTests extends AbstractViewTests {
configure(view);
}
int cursorIndex() {
return (Integer) ReflectionTestUtils.getField(view, CURSOR_INDEX_FIELD);
}
@Test
void addEmojiAndBackspace() {
handleKey(view, "😂");
assertThat(cursorIndex()).isEqualTo(1);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(1);
handleKey(view, Key.Backspace);
assertThat(cursorIndex()).isEqualTo(0);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(0);
}
@Test
void deleteFromLastPosition() {
handleKey(view, Key.Delete);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(0);
handleKey(view, Key.a);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(1);
}
}
@Nested
class MoveAndMods {
InputView view;
@BeforeEach
void setup() {
view = new InputView();
configure(view);
}
@Test
void shouldAddToCursorPosition() {
assertThat(callIntMethod(view, CURSOR_POSITION_METHOD)).isEqualTo(0);
handleKey(view, Key.a);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(1);
assertThat(view.getInputText()).isEqualTo("a");
assertThat(callIntMethod(view, CURSOR_POSITION_METHOD)).isEqualTo(1);
handleKey(view, Key.CursorLeft);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(0);
handleKey(view, Key.b);
assertThat(getIntField(view, CURSOR_INDEX_FIELD)).isEqualTo(1);
assertThat(view.getInputText()).isEqualTo("ba");
}
}