Add multiinput scenario
- InputView using viewcommands and has event for text change. - Experimental way to handle tab navigation in a layout views. - New viewcommands for tab navigation and moving cursor. - Mouse click takes focus in AbstractView if no view command binding. - MultiInputViewScenario now shows tab navigation. - Fixes #917
This commit is contained in:
@@ -196,6 +196,7 @@ public class TerminalUI implements ViewService {
|
|||||||
view.setViewService(getViewService());
|
view.setViewService(getViewService());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void setFocus(@Nullable View view) {
|
public void setFocus(@Nullable View view) {
|
||||||
if (focus != null) {
|
if (focus != null) {
|
||||||
focus.focus(focus, false);
|
focus.focus(focus, false);
|
||||||
|
|||||||
@@ -164,6 +164,7 @@ public abstract class AbstractView extends AbstractControl implements View {
|
|||||||
int mouse = event.mouse();
|
int mouse = event.mouse();
|
||||||
View view = null;
|
View view = null;
|
||||||
boolean consumed = false;
|
boolean consumed = false;
|
||||||
|
// mouse binding may consume and focus
|
||||||
MouseBindingValue mouseBindingValue = getMouseBindings().get(mouse);
|
MouseBindingValue mouseBindingValue = getMouseBindings().get(mouse);
|
||||||
if (mouseBindingValue != null) {
|
if (mouseBindingValue != null) {
|
||||||
if (mouseBindingValue.mousePredicate().test(event)) {
|
if (mouseBindingValue.mousePredicate().test(event)) {
|
||||||
@@ -171,6 +172,10 @@ public abstract class AbstractView extends AbstractControl implements View {
|
|||||||
consumed = dispatchMouseRunCommand(event, mouseBindingValue);
|
consumed = dispatchMouseRunCommand(event, mouseBindingValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// click in bounds focuses
|
||||||
|
if (view == null && getRect().contains(event.x(), event.y())) {
|
||||||
|
view = this;
|
||||||
|
}
|
||||||
return MouseHandler.resultOf(args.event(), consumed, view, this);
|
return MouseHandler.resultOf(args.event(), consumed, view, this);
|
||||||
};
|
};
|
||||||
return handler;
|
return handler;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.util.Map.Entry;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import org.springframework.shell.component.view.event.KeyEvent.Key;
|
||||||
import org.springframework.shell.component.view.event.KeyHandler;
|
import org.springframework.shell.component.view.event.KeyHandler;
|
||||||
import org.springframework.shell.component.view.event.MouseHandler;
|
import org.springframework.shell.component.view.event.MouseHandler;
|
||||||
import org.springframework.shell.component.view.event.MouseHandler.MouseHandlerResult;
|
import org.springframework.shell.component.view.event.MouseHandler.MouseHandlerResult;
|
||||||
@@ -214,17 +215,53 @@ public class GridView extends BoxView {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void nextView() {
|
||||||
|
View toFocus = null;
|
||||||
|
boolean found = false;
|
||||||
|
for (GridItem i : gridItems) {
|
||||||
|
if (!i.visible) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (toFocus == null) {
|
||||||
|
toFocus = i.view;
|
||||||
|
}
|
||||||
|
if (found) {
|
||||||
|
toFocus = i.view;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i.view.hasFocus()) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (toFocus != null) {
|
||||||
|
getViewService().setFocus(toFocus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initInternal() {
|
||||||
|
registerViewCommand(ViewCommand.NEXT_VIEW, () -> nextView());
|
||||||
|
|
||||||
|
registerKeyBinding(Key.Tab, ViewCommand.NEXT_VIEW);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyHandler getKeyHandler() {
|
public KeyHandler getKeyHandler() {
|
||||||
log.trace("getKeyHandler()");
|
log.trace("getKeyHandler()");
|
||||||
|
KeyHandler handler = null;
|
||||||
for (GridItem i : gridItems) {
|
for (GridItem i : gridItems) {
|
||||||
if (i.view.hasFocus()) {
|
if (i.view.hasFocus()) {
|
||||||
return i.view.getKeyHandler();
|
handler = i.view.getKeyHandler();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (handler != null) {
|
||||||
|
return handler.thenIfNotConsumed(super.getKeyHandler());
|
||||||
|
}
|
||||||
return super.getKeyHandler();
|
return super.getKeyHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasFocus() {
|
public boolean hasFocus() {
|
||||||
for (GridItem i : gridItems) {
|
for (GridItem i : gridItems) {
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ package org.springframework.shell.component.view.control;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import org.springframework.shell.component.message.ShellMessageBuilder;
|
import org.springframework.shell.component.message.ShellMessageBuilder;
|
||||||
import org.springframework.shell.component.view.event.KeyEvent;
|
import org.springframework.shell.component.view.event.KeyEvent;
|
||||||
import org.springframework.shell.component.view.event.KeyEvent.Key;
|
import org.springframework.shell.component.view.event.KeyEvent.Key;
|
||||||
@@ -33,20 +36,28 @@ import org.springframework.shell.geom.Rectangle;
|
|||||||
*/
|
*/
|
||||||
public class InputView extends BoxView {
|
public class InputView extends BoxView {
|
||||||
|
|
||||||
|
private final Logger log = LoggerFactory.getLogger(InputView.class);
|
||||||
private final ArrayList<String> text = new ArrayList<>();
|
private final ArrayList<String> text = new ArrayList<>();
|
||||||
private int cursorIndex = 0;
|
private int cursorIndex = 0;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initInternal() {
|
protected void initInternal() {
|
||||||
registerKeyBinding(Key.CursorLeft, event -> left());
|
registerViewCommand(ViewCommand.ACCEPT, () -> done());
|
||||||
registerKeyBinding(Key.CursorRight, event -> right());
|
registerViewCommand(ViewCommand.LEFT, () -> left());
|
||||||
registerKeyBinding(Key.Delete, () -> delete());
|
registerViewCommand(ViewCommand.RIGHT, () -> right());
|
||||||
registerKeyBinding(Key.Backspace, () -> backspace());
|
registerViewCommand(ViewCommand.DELETE_CHAR_LEFT, () -> deleteCharLeft());
|
||||||
registerKeyBinding(Key.Enter, () -> done());
|
registerViewCommand(ViewCommand.DELETE_CHAR_RIGHT, () -> deleteCharRight());
|
||||||
|
|
||||||
|
registerKeyBinding(Key.Enter, ViewCommand.ACCEPT);
|
||||||
|
registerKeyBinding(Key.CursorLeft, ViewCommand.LEFT);
|
||||||
|
registerKeyBinding(Key.CursorRight, ViewCommand.RIGHT);
|
||||||
|
registerKeyBinding(Key.Backspace, ViewCommand.DELETE_CHAR_LEFT);
|
||||||
|
registerKeyBinding(Key.Delete, ViewCommand.DELETE_CHAR_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public KeyHandler getKeyHandler() {
|
public KeyHandler getKeyHandler() {
|
||||||
|
log.trace("getKeyHandler()");
|
||||||
KeyHandler handler = args -> {
|
KeyHandler handler = args -> {
|
||||||
KeyEvent event = args.event();
|
KeyEvent event = args.event();
|
||||||
boolean consumed = false;
|
boolean consumed = false;
|
||||||
@@ -68,9 +79,11 @@ public class InputView extends BoxView {
|
|||||||
Rectangle rect = getInnerRect();
|
Rectangle rect = getInnerRect();
|
||||||
String s = getInputText();
|
String s = getInputText();
|
||||||
screen.writerBuilder().build().text(s, rect.x(), rect.y());
|
screen.writerBuilder().build().text(s, rect.x(), rect.y());
|
||||||
screen.setShowCursor(hasFocus());
|
if (hasFocus()) {
|
||||||
int cPos = cursorPosition();
|
screen.setShowCursor(true);
|
||||||
screen.setCursorPosition(new Position(rect.x() + cPos, rect.y()));
|
int cPos = cursorPosition();
|
||||||
|
screen.setCursorPosition(new Position(rect.x() + cPos, rect.y()));
|
||||||
|
}
|
||||||
super.drawInternal(screen);
|
super.drawInternal(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,21 +100,34 @@ public class InputView extends BoxView {
|
|||||||
return text.stream().limit(cursorIndex).mapToInt(text -> text.length()).sum();
|
return text.stream().limit(cursorIndex).mapToInt(text -> text.length()).sum();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void add(String data) {
|
private void dispatchTextChange(String oldText, String newText) {
|
||||||
text.add(cursorIndex, data);
|
dispatch(ShellMessageBuilder.ofView(this, InputViewTextChangeEvent.of(this, oldText, newText)));
|
||||||
moveCursor(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void backspace() {
|
private void add(String data) {
|
||||||
|
String oldText = text.stream().collect(Collectors.joining());
|
||||||
|
text.add(cursorIndex, data);
|
||||||
|
moveCursor(1);
|
||||||
|
String newText = text.stream().collect(Collectors.joining());
|
||||||
|
dispatchTextChange(oldText, newText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteCharLeft() {
|
||||||
if (cursorIndex > 0) {
|
if (cursorIndex > 0) {
|
||||||
|
String oldText = text.stream().collect(Collectors.joining());
|
||||||
text.remove(cursorIndex - 1);
|
text.remove(cursorIndex - 1);
|
||||||
|
String newText = text.stream().collect(Collectors.joining());
|
||||||
|
dispatchTextChange(oldText, newText);
|
||||||
}
|
}
|
||||||
left();
|
left();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void delete() {
|
private void deleteCharRight() {
|
||||||
if (cursorIndex < text.size()) {
|
if (cursorIndex < text.size()) {
|
||||||
|
String oldText = text.stream().collect(Collectors.joining());
|
||||||
text.remove(cursorIndex);
|
text.remove(cursorIndex);
|
||||||
|
String newText = text.stream().collect(Collectors.joining());
|
||||||
|
dispatchTextChange(oldText, newText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,4 +150,18 @@ public class InputView extends BoxView {
|
|||||||
dispatch(ShellMessageBuilder.ofView(this, ViewDoneEvent.of(this)));
|
dispatch(ShellMessageBuilder.ofView(this, ViewDoneEvent.of(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record InputViewTextChangeEventArgs(String oldText, String newText) implements ViewEventArgs {
|
||||||
|
|
||||||
|
public static InputViewTextChangeEventArgs of(String oldText, String newText) {
|
||||||
|
return new InputViewTextChangeEventArgs(oldText, newText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public record InputViewTextChangeEvent(View view, InputViewTextChangeEventArgs args) implements ViewEvent {
|
||||||
|
|
||||||
|
public static InputViewTextChangeEvent of(View view, String oldText, String newText) {
|
||||||
|
return new InputViewTextChangeEvent(view, InputViewTextChangeEventArgs.of(oldText, newText));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,4 +39,36 @@ public final class ViewCommand {
|
|||||||
*/
|
*/
|
||||||
public static String LINE_DOWN = "LineDown";
|
public static String LINE_DOWN = "LineDown";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move focus to the next view.
|
||||||
|
*
|
||||||
|
* For example using tab to navigate into next input field.
|
||||||
|
*/
|
||||||
|
public static String NEXT_VIEW = "NextView";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accepts a current state.
|
||||||
|
*/
|
||||||
|
public static String ACCEPT = "Accept";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the character on the left.
|
||||||
|
*/
|
||||||
|
public static String DELETE_CHAR_LEFT = "DeleteCharLeft";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the character on the right.
|
||||||
|
*/
|
||||||
|
public static String DELETE_CHAR_RIGHT = "DeleteCharRight";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the selection left by one.
|
||||||
|
*/
|
||||||
|
public static String LEFT = "Left";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves the selection righ by one.
|
||||||
|
*/
|
||||||
|
public static String RIGHT = "Right";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.shell.component.view.control;
|
package org.springframework.shell.component.view.control;
|
||||||
|
|
||||||
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides services for a {@link View} like handling modals.
|
* Provides services for a {@link View} like handling modals.
|
||||||
*
|
*
|
||||||
@@ -26,4 +28,5 @@ public interface ViewService {
|
|||||||
|
|
||||||
void setModal(View view);
|
void setModal(View view);
|
||||||
|
|
||||||
|
void setFocus(@Nullable View view);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class AbstractViewTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected MouseHandlerResult handleMouseClick(View view, int x, int y) {
|
protected MouseHandlerResult handleMouseClick(View view, int x, int y) {
|
||||||
MouseEvent click = mouseClick(0, 2);
|
MouseEvent click = mouseClick(x, y);
|
||||||
return handleMouseClick(view, click);
|
return handleMouseClick(view, click);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.shell.component.view.control;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.shell.component.view.event.MouseHandler.MouseHandlerResult;
|
||||||
|
import org.springframework.shell.component.view.screen.Screen;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
class BaseViewTests extends AbstractViewTests {
|
||||||
|
|
||||||
|
TestView view;
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Mouse {
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
view = new TestView();
|
||||||
|
configure(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void clickInBounds() {
|
||||||
|
view.setRect(0, 0, 80, 24);
|
||||||
|
MouseHandlerResult result = handleMouseClick(view, 0, 0);
|
||||||
|
assertThat(result).isNotNull().satisfies(r -> {
|
||||||
|
assertThat(r.consumed()).isFalse();
|
||||||
|
assertThat(r.focus()).isEqualTo(view);
|
||||||
|
assertThat(r.capture()).isEqualTo(view);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void clickOutOfBounds() {
|
||||||
|
view.setRect(0, 0, 80, 24);
|
||||||
|
MouseHandlerResult result = handleMouseClick(view, 100, 100);
|
||||||
|
assertThat(result).isNotNull().satisfies(r -> {
|
||||||
|
assertThat(r.consumed()).isFalse();
|
||||||
|
assertThat(r.focus()).isNull();
|
||||||
|
assertThat(r.capture()).isEqualTo(view);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestView extends AbstractView {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawInternal(Screen screen) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -37,6 +37,30 @@ class InputViewTests extends AbstractViewTests {
|
|||||||
|
|
||||||
InputView view;
|
InputView view;
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
class Visual {
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setup() {
|
||||||
|
view = new InputView();
|
||||||
|
configure(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void haveOneRow() {
|
||||||
|
view.setShowBorder(false);
|
||||||
|
view.setRect(0, 0, 80, 1);
|
||||||
|
view.focus(view, true);
|
||||||
|
|
||||||
|
dispatchEvent(view, KeyEvent.of('1'));
|
||||||
|
view.draw(screen24x80);
|
||||||
|
|
||||||
|
assertThat(forScreen(screen24x80)).hasHorizontalText("1", 0, 0, 1);
|
||||||
|
assertThat(forScreen(screen24x80)).hasCursorInPosition(1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
class Input {
|
class Input {
|
||||||
|
|
||||||
@@ -50,6 +74,7 @@ class InputViewTests extends AbstractViewTests {
|
|||||||
void shouldShowPlainText() {
|
void shouldShowPlainText() {
|
||||||
view.setShowBorder(true);
|
view.setShowBorder(true);
|
||||||
view.setRect(0, 0, 80, 24);
|
view.setRect(0, 0, 80, 24);
|
||||||
|
view.focus(view, true);
|
||||||
|
|
||||||
dispatchEvent(view, KeyEvent.of('1'));
|
dispatchEvent(view, KeyEvent.of('1'));
|
||||||
view.draw(screen24x80);
|
view.draw(screen24x80);
|
||||||
@@ -62,6 +87,7 @@ class InputViewTests extends AbstractViewTests {
|
|||||||
void shouldShowUnicode() {
|
void shouldShowUnicode() {
|
||||||
view.setShowBorder(true);
|
view.setShowBorder(true);
|
||||||
view.setRect(0, 0, 80, 24);
|
view.setRect(0, 0, 80, 24);
|
||||||
|
view.focus(view, true);
|
||||||
|
|
||||||
dispatchEvent(view, KeyEvent.of('★'));
|
dispatchEvent(view, KeyEvent.of('★'));
|
||||||
view.draw(screen24x80);
|
view.draw(screen24x80);
|
||||||
@@ -74,6 +100,7 @@ class InputViewTests extends AbstractViewTests {
|
|||||||
void shouldShowUnicodeEmoji() {
|
void shouldShowUnicodeEmoji() {
|
||||||
view.setShowBorder(true);
|
view.setShowBorder(true);
|
||||||
view.setRect(0, 0, 80, 24);
|
view.setRect(0, 0, 80, 24);
|
||||||
|
view.focus(view, true);
|
||||||
|
|
||||||
dispatchEvent(view, KeyEvent.of("😂"));
|
dispatchEvent(view, KeyEvent.of("😂"));
|
||||||
view.draw(screen24x80);
|
view.draw(screen24x80);
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
*** xref:tui/views/button.adoc[]
|
*** xref:tui/views/button.adoc[]
|
||||||
*** xref:tui/views/dialog.adoc[]
|
*** xref:tui/views/dialog.adoc[]
|
||||||
*** xref:tui/views/grid.adoc[]
|
*** xref:tui/views/grid.adoc[]
|
||||||
|
*** xref:tui/views/input.adoc[]
|
||||||
*** xref:tui/views/list.adoc[]
|
*** xref:tui/views/list.adoc[]
|
||||||
*** xref:tui/views/menu.adoc[]
|
*** xref:tui/views/menu.adoc[]
|
||||||
*** xref:tui/views/menubar.adoc[]
|
*** xref:tui/views/menubar.adoc[]
|
||||||
|
|||||||
66
spring-shell-docs/modules/ROOT/pages/tui/views/input.adoc
Normal file
66
spring-shell-docs/modules/ROOT/pages/tui/views/input.adoc
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
= InputView
|
||||||
|
:page-section-summary-toc: 1
|
||||||
|
|
||||||
|
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
|
||||||
|
|
||||||
|
_InputView_ is a base implementation providing functionality to draw and modify
|
||||||
|
text in a bounded _Rectancle_.
|
||||||
|
|
||||||
|
[source, java, indent=0]
|
||||||
|
----
|
||||||
|
include::{snippets}/InputViewSnippets.java[tag=sample]
|
||||||
|
----
|
||||||
|
|
||||||
|
== Default Bindings
|
||||||
|
Default _view commands_ are:
|
||||||
|
|
||||||
|
.ViewCommands
|
||||||
|
|===
|
||||||
|
|Command |Description
|
||||||
|
|
||||||
|
|LEFT
|
||||||
|
|Cursor moves left
|
||||||
|
|
||||||
|
|RIGHT
|
||||||
|
|Cursor moves right
|
||||||
|
|
||||||
|
|DELETE_CHAR_LEFT
|
||||||
|
|Delete character left
|
||||||
|
|
||||||
|
|DELETE_CHAR_RIGHT
|
||||||
|
|Delete character right
|
||||||
|
|
||||||
|
|===
|
||||||
|
|
||||||
|
Default _key bindigs_ are:
|
||||||
|
|
||||||
|
.Key
|
||||||
|
|===
|
||||||
|
|Command |Description
|
||||||
|
|
||||||
|
|CursorLeft
|
||||||
|
|Bound ViewCommand LEFT
|
||||||
|
|
||||||
|
|CursorRight
|
||||||
|
|Bound ViewCommand RIGHT
|
||||||
|
|
||||||
|
|Backspace
|
||||||
|
|Bound ViewCommand DELETE_CHAR_LEFT
|
||||||
|
|
||||||
|
|Delete
|
||||||
|
|Bound ViewCommand DELETE_CHAR_RIGHT
|
||||||
|
|
||||||
|
|===
|
||||||
|
|
||||||
|
== Events
|
||||||
|
|
||||||
|
Events are sent depending on a used list type.
|
||||||
|
|
||||||
|
.InputView Events
|
||||||
|
|===
|
||||||
|
|Event |Description
|
||||||
|
|
||||||
|
|InputViewTextChangeEvent
|
||||||
|
|Input text has changed
|
||||||
|
|
||||||
|
|===
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.shell.docs;
|
||||||
|
|
||||||
|
import org.springframework.shell.component.view.control.InputView;
|
||||||
|
|
||||||
|
class InputViewSnippets {
|
||||||
|
|
||||||
|
class Dump1 {
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
void dump1() {
|
||||||
|
// tag::sample[]
|
||||||
|
InputView input = new InputView();
|
||||||
|
String text = input.getInputText();
|
||||||
|
// end::sample[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springframework.shell.samples.catalog.scenario.other;
|
||||||
|
|
||||||
|
import org.springframework.shell.component.view.control.GridView;
|
||||||
|
import org.springframework.shell.component.view.control.InputView;
|
||||||
|
import org.springframework.shell.component.view.control.View;
|
||||||
|
import org.springframework.shell.component.view.screen.Color;
|
||||||
|
import org.springframework.shell.samples.catalog.scenario.AbstractScenario;
|
||||||
|
import org.springframework.shell.samples.catalog.scenario.Scenario;
|
||||||
|
import org.springframework.shell.samples.catalog.scenario.ScenarioComponent;;
|
||||||
|
|
||||||
|
@ScenarioComponent(name = "Multi inputview", description = "Multi InputView sample", category = { Scenario.CATEGORY_OTHER })
|
||||||
|
public class MultiInputViewScenario extends AbstractScenario {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View build() {
|
||||||
|
GridView grid = new GridView();
|
||||||
|
configure(grid);
|
||||||
|
grid.setRowSize(1, 1, 1);
|
||||||
|
grid.setColumnSize(0);
|
||||||
|
|
||||||
|
InputView input1 = new InputView();
|
||||||
|
input1.setBackgroundColor(Color.GREEN);
|
||||||
|
configure(input1);
|
||||||
|
|
||||||
|
InputView input2 = new InputView();
|
||||||
|
input2.setBackgroundColor(Color.BLUE);
|
||||||
|
configure(input2);
|
||||||
|
|
||||||
|
InputView input3 = new InputView();
|
||||||
|
input3.setBackgroundColor(Color.RED);
|
||||||
|
configure(input3);
|
||||||
|
|
||||||
|
grid.addItem(input1, 0, 0, 1, 1, 0, 0);
|
||||||
|
grid.addItem(input2, 1, 0, 1, 1, 0, 0);
|
||||||
|
grid.addItem(input3, 2, 0, 1, 1, 0, 0);
|
||||||
|
|
||||||
|
return grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user