Skip to content

Commit

Permalink
Support view commands in view
Browse files Browse the repository at this point in the history
- Setup facilities in view system to register commands
  with a Runnable to get dispatched into an event loop.
- As first commands, setup ListView with lineDown and
  lineUp.
- Expose needed functions into View itself.
- Relates #867
  • Loading branch information
jvalkeal committed Sep 21, 2023
1 parent af519b5 commit d58293e
Show file tree
Hide file tree
Showing 5 changed files with 130 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Predicate;

Expand Down Expand Up @@ -55,6 +56,7 @@ public abstract class AbstractView extends AbstractControl implements View {
private int layer;
private EventLoop eventLoop;
private ViewService viewService;
private final Map<String, Runnable> commands = new HashMap<>();
private Map<Integer, KeyBindingValue> keyBindings = new HashMap<>();
private Map<Integer, KeyBindingValue> hotKeyBindings = new HashMap<>();
private Map<Integer, MouseBindingValue> mouseBindings = new HashMap<>();
Expand Down Expand Up @@ -173,7 +175,7 @@ public KeyHandler getKeyHandler() {
if (key != null) {
KeyBindingValue keyBindingValue = getKeyBindings().get(key);
if (keyBindingValue != null) {
consumed = dispatchRunCommand(event, keyBindingValue);
consumed = dispatchKeyRunCommand(event, keyBindingValue);
}

}
Expand All @@ -192,7 +194,7 @@ public KeyHandler getHotKeyHandler() {
if (key != null) {
KeyBindingValue keyBindingValue = getHotKeyBindings().get(key);
if (keyBindingValue != null) {
consumed = dispatchRunCommand(event, keyBindingValue);
consumed = dispatchKeyRunCommand(event, keyBindingValue);
}

}
Expand Down Expand Up @@ -257,6 +259,15 @@ protected ViewService getViewService() {
return viewService;
}

protected void registerViewCommand(String command, Runnable runnable) {
commands.put(command, runnable);
}

@Override
public Set<String> getViewCommands() {
return commands.keySet();
}

protected void registerKeyBinding(Integer keyType, String keyCommand) {
registerKeyBinding(keyType, keyCommand, null, null);
}
Expand Down Expand Up @@ -395,20 +406,43 @@ protected boolean dispatchRunnable(Runnable runnable) {
return true;
}

protected boolean dispatchRunCommand(KeyEvent event, KeyBindingValue command) {
@Override
public boolean runViewCommand(String command) {
if (eventLoop == null) {
return false;
}
if (command != null) {
Runnable runnable = commands.get(command);
if (runnable != null) {
Message<Runnable> message = ShellMessageBuilder
.withPayload(runnable)
.setEventType(EventLoop.Type.TASK)
.build();
dispatch(message);
return true;
}
}
return false;
}

protected boolean dispatchKeyRunCommand(KeyEvent event, KeyBindingValue keyBindingValue) {
if (eventLoop == null) {
return false;
}
Runnable runnable = command.keyRunnable();
if (runnable != null) {
String keyCommand = keyBindingValue.keyCommand();
if (runViewCommand(keyCommand)) {
return true;
}
Runnable keyRunnable = keyBindingValue.keyRunnable();
if (keyRunnable != null) {
Message<Runnable> message = ShellMessageBuilder
.withPayload(runnable)
.withPayload(keyRunnable)
.setEventType(EventLoop.Type.TASK)
.build();
dispatch(message);
return true;
}
KeyBindingConsumer keyConsumer = command.keyConsumer();
KeyBindingConsumer keyConsumer = keyBindingValue.keyConsumer();
if (keyConsumer != null) {
Message<KeyBindingConsumerArgs> message = ShellMessageBuilder
.withPayload(new KeyBindingConsumerArgs(keyConsumer, event))
Expand All @@ -420,20 +454,24 @@ protected boolean dispatchRunCommand(KeyEvent event, KeyBindingValue command) {
return false;
}

protected boolean dispatchMouseRunCommand(MouseEvent event, MouseBindingValue command) {
protected boolean dispatchMouseRunCommand(MouseEvent event, MouseBindingValue mouseBindingValue) {
if (eventLoop == null) {
return false;
}
Runnable runnable = command.mouseRunnable();
if (runnable != null) {
String mouseCommand = mouseBindingValue.mouseCommand();
if (runViewCommand(mouseCommand)) {
return true;
}
Runnable mouseRunnable = mouseBindingValue.mouseRunnable();
if (mouseRunnable != null) {
Message<Runnable> message = ShellMessageBuilder
.withPayload(runnable)
.withPayload(mouseRunnable)
.setEventType(EventLoop.Type.TASK)
.build();
dispatch(message);
return true;
}
MouseBindingConsumer mouseConsumer = command.mouseConsumer();
MouseBindingConsumer mouseConsumer = mouseBindingValue.mouseConsumer();
if (mouseConsumer != null) {
Message<MouseBindingConsumerArgs> message = ShellMessageBuilder
.withPayload(new MouseBindingConsumerArgs(mouseConsumer, event))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
/**
* {@code ListView} is a {@link View} showing items in a vertical list.
*
* <p>Supported view commands:
* <ul>
* <li>{@link ViewCommand#LINE_UP} - Move active line upwards.
* <li>{@link ViewCommand#LINE_DOWN} - Move active line downwards.
* </ul>
*
* @author Janne Valkealahti
*/
public class ListView<T> extends BoxView {
Expand Down Expand Up @@ -94,13 +100,16 @@ public ListView(@Nullable List<T> items, ItemStyle itemStyle) {

@Override
protected void initInternal() {
registerKeyBinding(Key.CursorUp, () -> up());
registerKeyBinding(Key.CursorDown, () -> down());
registerViewCommand(ViewCommand.LINE_UP, () -> up());
registerViewCommand(ViewCommand.LINE_DOWN, () -> down());

registerKeyBinding(Key.CursorUp, ViewCommand.LINE_UP);
registerKeyBinding(Key.CursorDown, ViewCommand.LINE_DOWN);
registerKeyBinding(Key.Enter, () -> enter());
registerKeyBinding(Key.Space, () -> space());

registerMouseBinding(MouseEvent.Type.Wheel | MouseEvent.Button.WheelUp, () -> up());
registerMouseBinding(MouseEvent.Type.Wheel | MouseEvent.Button.WheelDown, () -> down());
registerMouseBinding(MouseEvent.Type.Wheel | MouseEvent.Button.WheelUp, ViewCommand.LINE_UP);
registerMouseBinding(MouseEvent.Type.Wheel | MouseEvent.Button.WheelDown, ViewCommand.LINE_DOWN);
registerMouseBinding(MouseEvent.Type.Released | MouseEvent.Button.Button1, event -> click(event));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package org.springframework.shell.component.view.control;

import java.util.Set;

import org.springframework.lang.Nullable;
import org.springframework.shell.component.view.event.EventLoop;
import org.springframework.shell.component.view.event.KeyHandler;
Expand Down Expand Up @@ -87,4 +89,20 @@ public interface View extends Control {
*/
void setEventLoop(@Nullable EventLoop eventLoop);

/**
* Get supported commands.
*
* @return supported commands
* @see ViewCommand
*/
Set<String> getViewCommands();

/**
* Run command.
*
* @param command the command to run
* @return true if command was succesfully dispatched
* @see ViewCommand
*/
boolean runViewCommand(String command);
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,17 @@
public final class ViewCommand {

/**
* Move line up. Generic use in something where selection needs to be moved up.
* Move line up.
*
* For example where selection needs to be moved up.
*/
public static String LINE_UP = "LineUp";

/**
* Move line down. Generic use in something where selection needs to be moved
* down.
* Move line down.
*
* For example where selection needs to be moved down.
*/
public static String LINE_DOWN = "LineDown";

/**
* Open selected item. In a some sort of view where something can be selected
* and that active selected should be opened.
*/
public static String OPEN_SELECTED_ITEM = "OpenSelectedItem";

public static String SELECT = "Select";
public static String LEFT = "Left";
public static String RIGHT = "Right";
public static String SELECTION_CHANGED = "SelectionChanged";

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import java.time.Duration;
import java.util.Arrays;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Flux;
Expand Down Expand Up @@ -474,4 +475,46 @@ public void draw(Screen screen) {

}

@Nested
class ViewCommands {

@BeforeEach
void setup() {
view = new ListView<>();
configure(view);
view.setRect(0, 0, 80, 24);
view.setItems(Arrays.asList("item1", "item2"));
}

@Test
void supports() {
assertThat(view.getViewCommands()).contains(ViewCommand.LINE_DOWN, ViewCommand.LINE_UP);
}

@Test
void lineDown() {
StepVerifier verifier = StepVerifier.create(eventLoop.events())
.expectNextCount(1)
.thenCancel()
.verifyLater();
view.runViewCommand(ViewCommand.LINE_DOWN);
verifier.verify(Duration.ofSeconds(1));
assertThat(getIntField(view, START_FIELD)).isEqualTo(0);
assertThat(getIntField(view, POSITION_FIELD)).isEqualTo(1);
}

@Test
void lineUp() {
StepVerifier verifier = StepVerifier.create(eventLoop.events())
.expectNextCount(1)
.thenCancel()
.verifyLater();
view.runViewCommand(ViewCommand.LINE_UP);
verifier.verify(Duration.ofSeconds(1));
assertThat(getIntField(view, START_FIELD)).isEqualTo(0);
assertThat(getIntField(view, POSITION_FIELD)).isEqualTo(1);
}

}

}

0 comments on commit d58293e

Please sign in to comment.