Update docs

This commit is contained in:
Janne Valkealahti
2023-10-06 13:40:48 +01:00
parent 6dd038830f
commit 89a829cfef
33 changed files with 479 additions and 103 deletions

View File

@@ -52,11 +52,19 @@
*** xref:using-shell-components-ui-confirmation.adoc[] *** xref:using-shell-components-ui-confirmation.adoc[]
*** xref:using-shell-components-ui-singleselect.adoc[] *** xref:using-shell-components-ui-singleselect.adoc[]
*** xref:using-shell-components-ui-multiselect.adoc[] *** xref:using-shell-components-ui-multiselect.adoc[]
* xref:using-shell-tui.adoc[] * xref:tui/index.adoc[]
** xref:using-shell-tui-intro.adoc[] ** xref:tui/intro/index.adoc[]
** xref:using-shell-tui-views.adoc[] ** xref:tui/views/index.adoc[]
*** xref:using-shell-tui-views-box.adoc[] *** xref:tui/views/box.adoc[]
*** xref:using-shell-tui-views-list.adoc[] *** xref:tui/views/button.adoc[]
*** xref:tui/views/dialog.adoc[]
*** xref:tui/views/list.adoc[]
*** xref:tui/views/menu.adoc[]
*** xref:tui/views/menubar.adoc[]
** xref:tui/events/index.adoc[]
*** xref:tui/events/eventloop.adoc[]
*** xref:tui/events/key.adoc[]
*** xref:tui/events/mouse.adoc[]
* xref:using-shell-customization.adoc[] * xref:using-shell-customization.adoc[]
** xref:using-shell-customization-styling.adoc[] ** xref:using-shell-customization-styling.adoc[]
** xref:using-shell-customization-logging.adoc[] ** xref:using-shell-customization-logging.adoc[]
@@ -77,11 +85,6 @@
*** xref:appendices-techical-intro-theming.adoc[] *** xref:appendices-techical-intro-theming.adoc[]
*** xref:appendices-techical-intro-searchalgorithm.adoc[] *** xref:appendices-techical-intro-searchalgorithm.adoc[]
** xref:appendices-debugging.adoc[] ** xref:appendices-debugging.adoc[]
** xref:appendices-tui.adoc[] ** xref:appendices/tui/index.adoc[]
*** xref:appendices-tui-control.adoc[] *** xref:appendices/tui/viewdev.adoc[]
*** xref:appendices-tui-view.adoc[] *** xref:appendices/tui/catalog.adoc[]
*** xref:appendices-tui-eventloop.adoc[]
*** xref:appendices-tui-screen.adoc[]
*** xref:appendices-tui-keyhandling.adoc[]
*** xref:appendices-tui-mousehandling.adoc[]
*** xref:appendices-tui-catalog.adoc[]

View File

@@ -1,7 +0,0 @@
[#appendix-tui-control]
= Control
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
_Control_ draws something into a screen with a given bounds.

View File

@@ -1,7 +0,0 @@
[#appendix-tui-eventloop]
= EventLoop
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
_EventLoop_ is a central system handling eventing in a framework.

View File

@@ -1,7 +0,0 @@
[#appendix-tui-keyhandling]
= Key Handling
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
Handles incoming key events.

View File

@@ -1,7 +0,0 @@
[#appendix-tui-mousehandling]
= Mouse Handling
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
Handles incoming mouse events.

View File

@@ -1,8 +0,0 @@
[#appendix-tui-screen]
= Screen
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
_Screen_ is an abstraction providing higher level concept to draw something
into a terminal.

View File

@@ -1,7 +0,0 @@
[#appendix-tui-view]
= View
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
_View_ extends _Control_ providing integration into event loop.

View File

@@ -2,7 +2,7 @@
= Catalog App = Catalog App
:page-section-summary-toc: 1 :page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs] ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
Catalog application is showing various ways how Terminal UI Framework can be used. Catalog application is showing various ways how Terminal UI Framework can be used.
In this section we discuss how this application works. It can be considered to be In this section we discuss how this application works. It can be considered to be
@@ -12,4 +12,13 @@ to follow best practices.
[[create-scenario]] [[create-scenario]]
== Create Scenario == Create Scenario
Every `Scenario` essentially is a sample code of a `View` as that's what catalog Every `Scenario` essentially is a sample code of a `View` as that's what catalog
app demonstrates. app demonstrates. In the sample app create a new scenario class under
_scenario_ package and implement it as something shown below.
[source, java, indent=0]
----
include::{snippets}/CatalogSnippets.java[tag=samplescenario]
----
NOTE: You need to define all fields, `name`, `description` and `category`
with _@ScenarioComponent_.

View File

@@ -0,0 +1,11 @@
[#appendix-tui-eventloop]
= View Development
:page-section-summary-toc: 1
While a _view_ just need to implement `View` it's usually convenient to just
use `BoxView` as a parent.
== Register Bindings
In an `AbstractView` use variants of _registerKeyBinding_, _registerHotKeyBinding_
and _registerMouseBinding_.

View File

@@ -0,0 +1,23 @@
[[tui-events-eventloop]]
= EventLoop
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
`EventLoop` is a central place where all eventing will be orchestrated for
a lifecycle of a component. Orchestration is usually needed around timings
of redraws and and component state updates.
Everything in an event loop is represented as a Spring Message.
[source, java, indent=0]
----
include::{snippets}/EventLoopSnippets.java[tag=plainevents]
----
Selecting key events use a build-in filtering method _keyEvents()_.
[source, java, indent=0]
----
include::{snippets}/EventLoopSnippets.java[tag=keyevents]
----

View File

@@ -0,0 +1,7 @@
[[tui-events]]
= Events
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../test/java/org/springframework/shell/docs]
This section contains information about eventing.

View File

@@ -0,0 +1,7 @@
[[tui-events-key]]
= Key Handling
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
tbd

View File

@@ -0,0 +1,7 @@
[[tui-events-mouse]]
= Mouse Handling
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
tbd

View File

@@ -0,0 +1,14 @@
[[tui]]
= Terminal UI
:page-section-summary-toc: 1
NOTE: Feature is experimental and subject to breaking changes until foundation
and related concepts around framework are getting more stable.
_Terminal UI Framework_ is a toolkit to build rich console apps. This section is
for those using existing features as is. If you're planning to go deeper possibly
creating your own components xref:appendices/tui/index.adoc[Terminal UI Appendix]
provides more detailed documentation.
TIP: xref:appendices/tui/catalog.adoc[Catalog Sample App] is a good place to
study a real application.

View File

@@ -1,8 +1,8 @@
[[using-shell-tui-intro]] [[tui-introduction]]
= Introduction = Introduction
:page-section-summary-toc: 1 :page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs] ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
Lets start with a simple app which prints "hello world" in a view. Lets start with a simple app which prints "hello world" in a view.
[source, java, indent=0] [source, java, indent=0]
@@ -12,3 +12,8 @@ include::{snippets}/TerminalUiSnippets.java[tag=snippet1]
There is not much to see here other than `TerminalUI` is a class handling There is not much to see here other than `TerminalUI` is a class handling
all logic aroung views and uses `View` as it's root view. all logic aroung views and uses `View` as it's root view.
[source, java, indent=0]
----
include::{snippets}/TerminalUiSnippets.java[tag=snippet2]
----

View File

@@ -0,0 +1,14 @@
[[tui-views-box]]
= BoxView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
_BoxView_ is a base implementation providing functionality to draw into a
bounded _Rectancle_. Only direct use of it is its `drawFunction` which
allows to do simple things without implementing a full custom `View`.
[source, java, indent=0]
----
include::{snippets}/BoxViewSnippets.java[tag=sample]
----

View File

@@ -0,0 +1,8 @@
[[tui-views-button]]
= ButtonView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
_ButtonView_ is a base implementation providing functionality to draw a button.
Inherits xref:tui/views/box.adoc[].

View File

@@ -0,0 +1,8 @@
[[tui-views-dialog]]
= DialogView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
_DialogView_ is a base implementation providing functionality to draw a dialog.
Inherits xref:tui/views/box.adoc[].

View File

@@ -0,0 +1,7 @@
[[tui-views]]
= Views
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../test/java/org/springframework/shell/docs]
Framework provides a build-in views which are documented below.

View File

@@ -0,0 +1,84 @@
[[tui-views-list]]
= ListView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
_ListView_ is a base implementation providing functionality to draw a list of
_items_. Inherits xref:tui/views/box.adoc[].
_ListView<T>_ is typed as its _item_ and can take any object. Further _item_
processing happens in a _CellFactory_. For conveniance there is a support
for generic higher level list feature showing checked states as normal
_check_ and _radio_ types. Essentially what you can have is a list of
items which are shown as is, shown where any items can have a checked
state or only one item can have a checked state.
[source, java, indent=0]
----
include::{snippets}/ListViewSnippets.java[tag=snippet1]
----
Default _item style_ is nocheck but can be changed.
Supports `NOCHECK``, `CHECK`` and `RADIO``
[source, java, indent=0]
----
include::{snippets}/ListViewSnippets.java[tag=snippet2]
----
== Default Bindings
Default _view commands_ are:
[[tui-views-list-viewcommands]]
.ViewCommands
|===
|Command |Description
|LINE_UP
|Selection moves up. Bound to _CursorUp_ and _WheelUp_.
|LINE_DOWN
|Selection moves down. Bound to _CursorDown_ and _WheelDown_.
|===
_Enter_ is choosing an active item. _Space_ is changing selection state.
== Events
Events are sent depending on a used list type.
[[tui-views-list-events]]
.ListView Events
|===
|Event |Description
|ListViewOpenSelectedItemEvent
|Active item is requested to get opened.
|ListViewSelectedItemChangedEvent
|Active item is changed.
|===
== Customisation
How individual cells are shown depends on a _CellFactory_. Default implementation
simply shows _item_ using its `toString()` method.
It can be customised by modifying a used _CellFactory_.
[source, java, indent=0]
----
include::{snippets}/ListViewSnippets.java[tag=listcell]
----
And set it as a factory:
[source, java, indent=0]
----
include::{snippets}/ListViewSnippets.java[tag=uselistcell]
----

View File

@@ -0,0 +1,8 @@
[[tui-views-menu]]
= MenuView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
_MenuView_ is a base implementation providing functionality to draw a menu.
Inherits xref:tui/views/box.adoc[].

View File

@@ -0,0 +1,8 @@
[[tui-views-menubar]]
= MenuBarView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../../../../src/test/java/org/springframework/shell/docs]
_MenuBarView_ is a base implementation providing functionality to draw a menu bar.
Inherits xref:tui/views/box.adoc[].

View File

@@ -1,8 +0,0 @@
[[using-shell-tui-views-box]]
= BoxView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
_BoxView_ is a base implementation providing functionality to draw into a
bounded _Rectancle_.

View File

@@ -1,7 +0,0 @@
[[using-shell-tui-views-list]]
= ListView
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
_ListView_ is a base implementation providing functionality to draw list of items.

View File

@@ -1,11 +0,0 @@
[[using-shell-tui-views]]
= Views
:page-section-summary-toc: 1
ifndef::snippets[:snippets: ../../test/java/org/springframework/shell/docs]
Framework provides a build-in views which are documented below.
TIP: To learn more about views, see xref:appendices-tui-view.adoc[View].

View File

@@ -1,15 +0,0 @@
[[using-shell-tui]]
= Terminal UI
:page-section-summary-toc: 1
NOTE: Feature is experimental and subject to breaking changes until foundation
and related concepts around framework are getting more stable.
_Terminal UI Framework_ is a toolkit to build rich console apps. This section is
for those using existing features as is. If you're planning to go deeper possibly
creating your own components xref:appendices-tui.adoc[Terminal UI] provides more detailed
documentation.
TIP: Catalog sample is a good place to study a real application xref:appendices-tui-catalog.adoc[Catalog App].

View File

@@ -10,6 +10,7 @@ dependencies {
management platform(project(":spring-shell-management")) management platform(project(":spring-shell-management"))
implementation project(':spring-shell-starters:spring-shell-starter') implementation project(':spring-shell-starters:spring-shell-starter')
implementation project(':spring-shell-starters:spring-shell-starter-test') implementation project(':spring-shell-starters:spring-shell-starter-test')
implementation project(':spring-shell-samples:spring-shell-sample-catalog')
testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.awaitility:awaitility' testImplementation 'org.awaitility:awaitility'
} }

View File

@@ -0,0 +1,36 @@
/*
* 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.BoxView;
class BoxViewSnippets {
class Dump1 {
void dump1() {
// tag::sample[]
BoxView view = new BoxView();
view.setDrawFunction((screen, rect) -> {
screen.writerBuilder().build()
.text("hi", 0, 0);
return rect;
});
// end::sample[]
}
}
}

View File

@@ -0,0 +1,40 @@
/*
* 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.BoxView;
import org.springframework.shell.component.view.control.View;
import org.springframework.shell.samples.catalog.scenario.AbstractScenario;
import org.springframework.shell.samples.catalog.scenario.Scenario;
import org.springframework.shell.samples.catalog.scenario.ScenarioComponent;
class CatalogSnippets {
// tag::samplescenario[]
@ScenarioComponent(
name = "Scenario name",
description = "Scenario short description",
category = { Scenario.CATEGORY_OTHER })
public class SampleScenario extends AbstractScenario {
@Override
public View build() {
return new BoxView();
}
}
// end::samplescenario[]
}

View File

@@ -0,0 +1,63 @@
/*
* 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.jline.terminal.Terminal;
import reactor.core.publisher.Flux;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.shell.component.view.TerminalUI;
import org.springframework.shell.component.view.event.EventLoop;
class EventLoopSnippets {
class Dump1 {
@Autowired
Terminal terminal;
void events() {
// tag::plainevents[]
TerminalUI ui = new TerminalUI(terminal);
EventLoop eventLoop = ui.getEventLoop();
Flux<? extends Message<?>> events = eventLoop.events();
events.subscribe();
// end::plainevents[]
}
void keyEvents() {
// tag::keyevents[]
TerminalUI ui = new TerminalUI(terminal);
EventLoop eventLoop = ui.getEventLoop();
eventLoop.keyEvents()
.doOnNext(event -> {
// do something with key event
})
.subscribe();
// end::keyevents[]
}
void onDestroy() {
// tag::ondestroy[]
TerminalUI ui = new TerminalUI(terminal);
EventLoop eventLoop = ui.getEventLoop();
eventLoop.onDestroy(eventLoop.events().subscribe());
// end::ondestroy[]
}
}
}

View File

@@ -0,0 +1,76 @@
/*
* 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 java.util.List;
import org.springframework.shell.component.view.control.ListView;
import org.springframework.shell.component.view.control.ListView.ItemStyle;
import org.springframework.shell.component.view.control.cell.AbstractListCell;
import org.springframework.shell.component.view.geom.Rectangle;
import org.springframework.shell.component.view.screen.Screen;
import org.springframework.shell.component.view.screen.Screen.Writer;
public class ListViewSnippets {
class Dump1 {
void dump1() {
// tag::snippet1[]
ListView<String> view = new ListView<>();
view.setItems(List.of("item1", "item2"));
// end::snippet1[]
}
@SuppressWarnings("unused")
void dump2() {
// tag::snippet2[]
ListView<String> view = new ListView<>(ItemStyle.CHECKED);
// end::snippet2[]
}
}
// tag::listcell[]
record ExampleData(String name) {
};
static class ExampleListCell extends AbstractListCell<ExampleData> {
public ExampleListCell(ExampleData item) {
super(item);
}
@Override
public void draw(Screen screen) {
Rectangle rect = getRect();
Writer writer = screen.writerBuilder().style(getStyle()).build();
writer.text(getItem().name(), rect.x(), rect.y());
writer.background(rect, getBackgroundColor());
}
}
// end::listcell[]
class Dump2 {
void dump1() {
// tag::uselistcell[]
ListView<ExampleData> view = new ListView<>();
view.setCellFactory((list, item) -> new ExampleListCell(item));
// end::uselistcell[]
}
}
}

View File

@@ -25,13 +25,13 @@ import org.springframework.shell.component.view.geom.VerticalAlign;
class TerminalUiSnippets { class TerminalUiSnippets {
class Sample { class Sample1 {
// tag::snippet1[] // tag::snippet1[]
@Autowired @Autowired
Terminal terminal; Terminal terminal;
void build() { void sample() {
TerminalUI ui = new TerminalUI(terminal); TerminalUI ui = new TerminalUI(terminal);
BoxView view = new BoxView(); BoxView view = new BoxView();
view.setDrawFunction((screen, rect) -> { view.setDrawFunction((screen, rect) -> {
@@ -46,4 +46,25 @@ class TerminalUiSnippets {
// end::snippet1[] // end::snippet1[]
} }
class Sample2 {
// tag::snippet2[]
@Autowired
Terminal terminal;
void sample() {
TerminalUI ui = new TerminalUI(terminal);
BoxView view = new BoxView();
view.setDrawFunction((screen, rect) -> {
screen.writerBuilder()
.build()
.text("Hello World", rect, HorizontalAlign.CENTER, VerticalAlign.CENTER);
return rect;
});
ui.setRoot(view, false);
ui.run();
}
// end::snippet2[]
}
} }