forked from oyvindberg/tui-scala
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ParagraphExample.scala
126 lines (108 loc) · 3.97 KB
/
ParagraphExample.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package tuiexamples
import tui._
import tui.crossterm.CrosstermJni
import tui.widgets.{BlockWidget, ParagraphWidget}
import java.time.{Duration, Instant}
import scala.math.Ordering.Implicits._
object ParagraphExample {
case class App(var scroll: Int = 0) {
def on_tick(): Unit = {
scroll += 1
scroll %= 10
}
}
def main(args: Array[String]): Unit = withTerminal { (jni, terminal) =>
// create app and run it
val tick_rate = Duration.ofMillis(250)
val app = App()
run_app(terminal, app, tick_rate, jni)
}
def run_app(
terminal: Terminal,
app: App,
tick_rate: Duration,
jni: CrosstermJni
): Unit = {
var last_tick = Instant.now()
def elapsed = java.time.Duration.between(last_tick, java.time.Instant.now())
def timeout = {
val timeout = tick_rate.minus(elapsed)
new tui.crossterm.Duration(timeout.toSeconds, timeout.getNano)
}
while (true) {
terminal.draw(f => ui(f, app))
if (jni.poll(timeout)) {
jni.read() match {
case key: tui.crossterm.Event.Key =>
key.keyEvent.code match {
case char: tui.crossterm.KeyCode.Char if char.c() == 'q' => return
case _ => ()
}
case _ => ()
}
}
if (elapsed >= tick_rate) {
app.on_tick()
last_tick = Instant.now()
}
}
}
def ui(f: Frame, app: App): Unit = {
// Words made "loooong" to demonstrate line breaking.
val s = "Veeeeeeeeeeeeeeeery loooooooooooooooooong striiiiiiiiiiiiiiiiiiiiiiiiiing. "
val long_line = s.repeat(f.size.width / s.length + 4) + "\n"
val block = BlockWidget(style = Style(bg = Some(Color.White), fg = Some(Color.Black)))
f.renderWidget(block, f.size)
val chunks = Layout(
direction = Direction.Vertical,
margin = Margin(5),
constraints = Array(Constraint.Percentage(25), Constraint.Percentage(25), Constraint.Percentage(25), Constraint.Percentage(25))
).split(f.size)
val text = Text.fromSpans(
Spans.nostyle("This is a line "),
Spans.styled("This is a line ", Style.DEFAULT.fg(Color.Red)),
Spans.styled("This is a line", Style.DEFAULT.bg(Color.Blue)),
Spans.styled("This is a longer line", Style.DEFAULT.addModifier(Modifier.CROSSED_OUT)),
Spans.styled(long_line, Style.DEFAULT.bg(Color.Green)),
Spans.styled("This is a line", Style.DEFAULT.fg(Color.Green).addModifier(Modifier.ITALIC))
)
def create_block(title: String): BlockWidget =
BlockWidget(
borders = Borders.ALL,
style = Style(bg = Some(Color.White), fg = Some(Color.Black)),
title = Some(Spans.from(Span.styled(title, Style.DEFAULT.addModifier(Modifier.BOLD))))
)
val paragraph0 = ParagraphWidget(
text = text,
style = Style(bg = Some(Color.White), fg = Some(Color.Black)),
block = Some(create_block("Left, no wrap")),
alignment = Alignment.Left
)
f.renderWidget(paragraph0, chunks(0))
val paragraph1 = ParagraphWidget(
text = text,
style = Style(bg = Some(Color.White), fg = Some(Color.Black)),
block = Some(create_block("Left, wrap")),
alignment = Alignment.Left,
wrap = Some(ParagraphWidget.Wrap(trim = true))
)
f.renderWidget(paragraph1, chunks(1))
val paragraph2 = ParagraphWidget(
text = text,
style = Style(bg = Some(Color.White), fg = Some(Color.Black)),
block = Some(create_block("Center, wrap")),
alignment = Alignment.Center,
wrap = Some(ParagraphWidget.Wrap(trim = true)),
scroll = (app.scroll, 0)
)
f.renderWidget(paragraph2, chunks(2))
val paragraph3 = ParagraphWidget(
text = text,
style = Style(bg = Some(Color.White), fg = Some(Color.Black)),
block = Some(create_block("Right, wrap")),
alignment = Alignment.Right,
wrap = Some(ParagraphWidget.Wrap(trim = true))
)
f.renderWidget(paragraph3, chunks(3))
}
}