aboutsummaryrefslogtreecommitdiff
path: root/demo
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2026-10-04 20:02:15 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2026-10-04 20:02:15 +0200
commit2e31cbeb70d93bb0f5512064f181990db189d1f6 (patch)
tree049f137715b692bcac0fd402fcbf04ef703523f0 /demo
downloadhare-termbox2-2e31cbeb70d93bb0f5512064f181990db189d1f6.tar.gz
hare-termbox2-2e31cbeb70d93bb0f5512064f181990db189d1f6.zip
Initial commit
Diffstat (limited to 'demo')
-rw-r--r--demo/colors16/color16.ha65
-rw-r--r--demo/fullcolor/fullcolor.ha59
-rw-r--r--demo/hjkl/hjkl.ha190
-rw-r--r--demo/size/size.ha35
4 files changed, 349 insertions, 0 deletions
diff --git a/demo/colors16/color16.ha b/demo/colors16/color16.ha
new file mode 100644
index 0000000..3121b93
--- /dev/null
+++ b/demo/colors16/color16.ha
@@ -0,0 +1,65 @@
1use fmt;
2use tb = termbox2;
3
4fn paint_cell(x: size, y: size, c: tb::uattr) void =
5 tb::set_cell(x: int, y: int, ' ', tb::COLOR.DEFAULT, c)!;
6
7fn show_colors() size = {
8 let colors = [
9 tb::COLOR.BLACK,
10 tb::COLOR.RED,
11 tb::COLOR.GREEN,
12 tb::COLOR.YELLOW,
13 tb::COLOR.BLUE,
14 tb::COLOR.MAGENTA,
15 tb::COLOR.CYAN,
16 tb::COLOR.WHITE,
17 ];
18
19 tb::print(0, 0, tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
20 "8 regular colors:")!;
21 tb::print(0, 2, tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
22 "8 bright colors:")!;
23 for (let i: size = 0; i < len(colors); i += 1) {
24 // 8 regular colors.
25 paint_cell(i, 1, colors[i]);
26
27 // 8 bright colors.
28 paint_cell(i, 3, colors[i] | tb::ATTRIBUTE.BRIGHT);
29 };
30
31 return 4;
32};
33
34export fn main() int = {
35 let e = tb::init();
36 if (e is tb::err)
37 fmt::fatalf(tb::strerror(e as tb::err));
38 defer tb::shutdown()!;
39
40 let w = tb::width()!;
41 let h = tb::height()!;
42 tb::print(0, (h - 1): int, tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
43 "Press any key to exit")!;
44
45 show_colors();
46
47 for (true) {
48 let e = tb::present();
49 if (e is tb::err)
50 fmt::fatalf(tb::strerror(e as tb::err));
51 match (tb::poll_event()) {
52 case let e: tb::err => {
53 if (e == tb::ERR.NO_EVENT)
54 continue
55 else
56 tb::print(0, h:int -1,
57 tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
58 "Unexpected error {}!", tb::strerror(e))!;
59 };
60 case tb::key_event => break;
61 case (tb::mouse_event | tb::resize_event) => continue;
62 };
63 };
64 return 0;
65};
diff --git a/demo/fullcolor/fullcolor.ha b/demo/fullcolor/fullcolor.ha
new file mode 100644
index 0000000..5d46c7c
--- /dev/null
+++ b/demo/fullcolor/fullcolor.ha
@@ -0,0 +1,59 @@
1use fmt;
2use tb = termbox2;
3
4fn paint_cell(x: size, y: size, c: tb::uattr) void =
5 tb::set_cell(x: int, y: int, ' ', tb::COLOR.DEFAULT, c)!;
6
7fn show_colors(wmin: size, hmin: size, wmax: size, hmax: size) void = {
8 tb::set_output_mode(tb::OUTPUT.TRUECOLOR)!;
9 tb::print(wmin: int, hmin: int, tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
10 "Color palette sample:")!;
11 hmin = hmin + 1;
12
13 let nsamples = (wmax - wmin +1) * (hmax - hmin + 1);
14 let step = 0xffffff / nsamples;
15 for (let y = hmin; y < hmax; y += 1) {
16 for (let x = wmin; x < wmax; x += 1) {
17 let c: tb::uattr = ((y - hmin) * wmax + (x - wmin)) * step;
18 paint_cell(x, y, c);
19 };
20 };
21};
22
23export fn main() int = {
24 let e = tb::init();
25 if (e is tb::err)
26 fmt::fatalf(tb::strerror(e as tb::err));
27 defer tb::shutdown()!;
28
29 let w = tb::width()!;
30 let h = tb::height()!;
31 tb::print(0, (h - 1): int, tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
32 "Press any key to exit")!;
33
34 switch (tb::OPT_ATTR_W) {
35 case 64 => show_colors(0, 0, w, h-1);
36 case => tb::print(0, ((h+1)/2): int, tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
37 "This demo is only available with truecolor support, here "
38 "tb::OPT_ATTR_W is {}", tb::OPT_ATTR_W)!;
39 };
40
41 for (true) {
42 let e = tb::present();
43 if (e is tb::err)
44 fmt::fatalf(tb::strerror(e as tb::err));
45 match (tb::poll_event()) {
46 case let e: tb::err => {
47 if (e == tb::ERR.NO_EVENT)
48 continue
49 else
50 tb::print(0, h:int -1,
51 tb::COLOR.DEFAULT, tb::COLOR.DEFAULT,
52 "Unexpected error {}!", tb::strerror(e))!;
53 };
54 case tb::key_event => break;
55 case (tb::mouse_event | tb::resize_event) => continue;
56 };
57 };
58 return 0;
59};
diff --git a/demo/hjkl/hjkl.ha b/demo/hjkl/hjkl.ha
new file mode 100644
index 0000000..487ebd3
--- /dev/null
+++ b/demo/hjkl/hjkl.ha
@@ -0,0 +1,190 @@
1use fmt;
2use tb = termbox2;
3
4def bg = tb::COLOR.DEFAULT;
5def fg = tb::COLOR.DEFAULT | tb::ATTRIBUTE.BOLD;
6def exit_help: str = "Use :q to exit (colon, q, enter). Sad to see you go :(";
7
8let wpos: (int, int) = (-1, -1);
9let msg: str = "Use HJKL to move the widget around";
10let colon_mode: bool = false;
11let exit_attempts: size = 0;
12
13type cmd = enum {
14 UP,
15 DOWN,
16 LEFT,
17 RIGHT,
18 COLON,
19 ARROW,
20 Q,
21 ENTER,
22 EXIT_ATTEMPT,
23 NONE,
24};
25
26fn draw_small_widget_thing(w: size, h: size) void = {
27 if (wpos.0 < 4) wpos.0 += 1
28 else if (wpos.0 > w: int - 5) wpos.0 -= 1
29 else if (wpos.1 < 2) wpos.1 += 1
30 else if (wpos.1 > h: int - 3) wpos.1 -= 1;
31
32 tb::print(wpos.0, wpos.1 - 1, fg, bg, "K")!;
33 tb::print(wpos.0, wpos.1 + 1, fg, bg, "J")!;
34 tb::print(wpos.0 - 2, wpos.1, fg, bg, "H + L")!;
35};
36
37fn paint(x: int, y: int, c: tb::uattr) void =
38 tb::set_cell(x, y, ' ', tb::COLOR.DEFAULT, c)!;
39
40fn paint_col3(x: int, y: int, c: tb::uattr) void = {
41 paint(x, y-1, c);
42 paint(x, y, c);
43 paint(x, y+1, c);
44};
45
46fn paint_row5(x: int, y: int, c: tb::uattr) void = {
47 paint(x-2, y, c);
48 paint(x-1, y, c);
49 paint(x, y, c);
50 paint(x+1, y, c);
51 paint(x+2, y, c);
52};
53
54fn paint_cell(x: int, y: int, c: tb::uattr, s: str) void = {
55 paint_col3(x-2, y, c);
56 paint_row5(x, y-1, c);
57 tb::print(x, y, fg, bg, s)!;
58 paint_row5(x, y+1, c);
59 paint_col3(x+2, y, c);
60};
61
62fn draw_large_widget_thing(w: size, h: size) void = {
63 if (wpos.0 < 10) wpos.0 += 1
64 else if (wpos.0 > w: int - 11) wpos.0 -= 1
65 else if (wpos.1 < 7) wpos.1 += 1
66 else if (wpos.1 > h: int - 8) wpos.1 -= 1;
67
68 let c = tb::COLOR.BLUE;
69 paint_cell(wpos.0-6, wpos.1, c, "H");
70 paint_cell(wpos.0+6, wpos.1, c, "L");
71 paint_cell(wpos.0, wpos.1-4, c, "K");
72 paint_cell(wpos.0, wpos.1+4, c, "J");
73 paint_col3(wpos.0, wpos.1, c);
74 paint_row5(wpos.0, wpos.1, c);
75};
76
77fn draw_widget_thing(w: size, h: size) void = {
78 if (w < 30 || h < 15)
79 draw_small_widget_thing(w, h)
80 else
81 draw_large_widget_thing(w, h);
82};
83
84fn draw_bottom_bar(w: size, h: size) void = {
85 tb::print(0, h: int - 1, fg, bg, msg)!;
86};
87
88fn handle_events_and_exit() bool = {
89 let e = tb::poll_event();
90 if (e is tb::err)
91 return false;
92
93 return match (e as tb::event) {
94 case tb::resize_event => yield false;
95 case tb::mouse_event => yield {
96 msg = "A mouse? Are you serious?";
97 yield false;
98 };
99 case let ke: tb::key_event => yield handle_key_event_and_exit(ke);
100 };
101};
102
103fn is_arrow(k: tb::key) bool =
104 k == tb::KEY.ARROW_UP || k == tb::KEY.ARROW_DOWN ||
105 k == tb::KEY.ARROW_LEFT || k == tb::KEY.ARROW_RIGHT;
106
107fn is_exit_attempt(k: tb::key) bool =
108 k == tb::KEY.CTRL_Q || k == tb::KEY.CTRL_C || k == tb::KEY.CTRL_X ||
109 k == tb::KEY.CTRL_Z || k == tb::KEY.CTRL_D ||
110 k == tb::KEY.DELETE || k == tb::KEY.BACKSPACE || k == tb::KEY.ESC;
111
112fn get_cmd(ke: tb::key_event) cmd = match (ke.key_or_ch) {
113 case let r: rune => yield
114 if (r == 'h') cmd::LEFT
115 else if (r == 'j') cmd::DOWN
116 else if (r == 'k') cmd::UP
117 else if (r == 'l') cmd::RIGHT
118 else if (r == ':') cmd::COLON
119 else if (r == 'q') cmd::Q
120 else if (r == 'Q') cmd::EXIT_ATTEMPT
121 else cmd::NONE;
122 case let k: tb::key => yield
123 if (k == tb::KEY.ENTER) cmd::ENTER
124 else if (is_arrow(k)) cmd::ARROW
125 else if (is_exit_attempt(k)) cmd::EXIT_ATTEMPT
126 else cmd::NONE;
127 };
128
129fn exit_attempt() void = {
130 exit_attempts += 1;
131 msg = if (exit_attempts < 3) "Trying to get out? :3"
132 else if (exit_attempts < 6) "It's just like Vim!"
133 else if (exit_attempts < 8) "Uhm no, that won't work"
134 else if (exit_attempts < 10) "Ok, I'll tell you..."
135 else exit_help;
136};
137
138fn handle_key_event_and_exit(ke: tb::key_event) bool = {
139 let c = get_cmd(ke);
140
141 if (c == cmd::COLON)
142 colon_mode = true;
143
144 if (colon_mode) {
145 if (msg == ":q" && c == cmd::ENTER)
146 return true;
147
148 msg = if (msg == ":") {
149 yield if (c == cmd::Q) ":q" else exit_help;
150 } else if (c == cmd::COLON) ":" else exit_help;
151
152 return false;
153 };
154
155 switch (c) {
156 case cmd::UP => wpos.1 -= 1;
157 case cmd::DOWN => wpos.1 += 1;
158 case cmd::LEFT => wpos.0 -= 1;
159 case cmd::RIGHT => wpos.0 += 1;
160 case cmd::ARROW => msg = "No arrows allowed!";
161 case cmd::COLON => colon_mode = true;
162 case cmd::EXIT_ATTEMPT => exit_attempt();
163 case cmd::Q => exit_attempt();
164 case => yield;
165 };
166
167 return false;
168};
169
170export fn main() void = {
171 let e = tb::init();
172 if (e is tb::err)
173 fmt::fatalf(tb::strerror(e as tb::err));
174 defer tb::shutdown()!;
175
176 wpos = (tb::width()!: int / 2, tb::height()!: int / 2);
177 for (true) {
178 tb::clear()!;
179
180 let w = tb::width()!;
181 let h = tb::height()!;
182
183 draw_widget_thing(w, h);
184 draw_bottom_bar(w, h);
185 tb::present()!;
186
187 if (handle_events_and_exit()) break;
188 };
189 return;
190};
diff --git a/demo/size/size.ha b/demo/size/size.ha
new file mode 100644
index 0000000..55b6a3c
--- /dev/null
+++ b/demo/size/size.ha
@@ -0,0 +1,35 @@
1use fmt;
2use tb = termbox2;
3
4export fn main() void = {
5 let e = tb::init();
6 if (e is tb::err)
7 fmt::fatalf(tb::strerror(e as tb::err));
8 defer tb::shutdown()!;
9
10 let w = tb::width()!;
11 let h = tb::height()!;
12 tb::print(0, 0, tb::COLOR.GREEN, tb::COLOR.BLACK,
13 "Terminal width: {}", w)!;
14 tb::print(0, 1, tb::COLOR.GREEN, tb::COLOR.BLACK,
15 "Terminal height: {}", h)!;
16 tb::print(0, 2, tb::COLOR.WHITE, tb::COLOR.BLACK,
17 "Press any key to exit")!;
18 for (true) {
19 let e = tb::present();
20 if (e is tb::err)
21 fmt::fatalf(tb::strerror(e as tb::err));
22 match (tb::poll_event()) {
23 case let e: tb::err => {
24 if (e == tb::ERR.NO_EVENT)
25 continue
26 else
27 tb::print(0, 4, tb::COLOR.WHITE, tb::COLOR.BLACK,
28 "Unexpected error {}!", tb::strerror(e))!;
29 };
30 case tb::key_event => break;
31 case (tb::mouse_event | tb::resize_event) => continue;
32 };
33 };
34 return;
35};

Generated with cgit - Back to sebastiano.tronto.net