nandi/jolt-nativepublic Fork 0
65272e3e9431369b8ac5bf985825fb43c8a7048a
Commits
Clone
git clone https://git.rickub.com/nandi/jolt-native.git
git clone ssh://git@rickub.com/nandi/jolt-native.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

showcase.rs · 109 lines · 3.4 KBRust Blame HistoryRaw
Paint the same tree into a terminal, for the machines with no window a7f6202 nandi 17d ago1//! Every tag this backend has, driven through the C ABI itself.
2//!
3//! cargo run -p jolt-tui --example showcase
4//!
5//! It calls `tui_*` exactly as jolt does — nodes by handle, props by name,
6//! events polled off a queue — so it doubles as a check that the ABI is usable
7//! from the outside and not only from the inside.
8//!
9//! Tab and Shift-Tab move, Enter and Space activate, j/k and the arrows move
10//! the list, the wheel scrolls, Ctrl-C or Ctrl-Q quits.
11
12use std::ffi::{CStr, CString};
13
14use jolttui::*;
15
16fn node(tag: &str) -> i32 {
17 let tag = CString::new(tag).unwrap();
18 unsafe { tui_node_new(tag.as_ptr()) }
19}
20
21fn set(id: i32, key: &str, value: &str) {
22 let (key, value) = (CString::new(key).unwrap(), CString::new(value).unwrap());
23 unsafe { tui_node_set_str(id, key.as_ptr(), value.as_ptr()) }
24}
25
26fn set_num(id: i32, key: &str, value: f64) {
27 let key = CString::new(key).unwrap();
28 unsafe { tui_node_set_num(id, key.as_ptr(), value) }
29}
30
31fn get(id: i32, key: &str) -> String {
32 let key = CString::new(key).unwrap();
33 unsafe { CStr::from_ptr(tui_node_get_str(id, key.as_ptr())) }
34 .to_string_lossy()
35 .into_owned()
36}
37
38fn child(parent: i32, tag: &str, props: &[(&str, &str)]) -> i32 {
39 let id = node(tag);
40 for (key, value) in props {
41 set(id, key, value);
42 }
43 tui_node_append(parent, id);
44 id
45}
46
47fn main() {
48 if tui_open(1) == 0 {
49 eprintln!("showcase: this example needs a terminal");
50 return;
51 }
52 let root = tui_tree_root();
53 let page = child(root, "vbox", &[]);
54 set_num(page, "margin", 1.0);
55 set_num(page, "spacing", 1.0);
56
57 child(page, "title", &[("label", "jolt-tui")]);
58 let status = child(
59 page,
60 "dim-label",
61 &[("label", "tab moves · enter activates · ctrl-c quits")],
62 );
63
64 let row = child(page, "hbox", &[("orientation", "horizontal")]);
65 set_num(row, "spacing", 2.0);
66 child(row, "button", &[("label", "count")]);
67 child(
68 row,
69 "button",
70 &[("label", "reset"), ("kind", "destructive")],
71 );
72 child(row, "checkbutton", &[("label", "live")]);
73
74 child(page, "entry", &[("placeholder", "type something")]);
75 let bar = child(page, "progress", &[("label", "")]);
76 let frame = child(page, "frame", &[("label", "Rows")]);
77 let list = child(frame, "listbox", &[]);
78 for name in ["alpha", "beta", "gamma", "delta"] {
79 child(list, "label", &[("label", name)]);
80 }
81
82 let mut count = 0.0f64;
83 while tui_should_close() == 0 {
84 tui_tick(50);
85 while tui_tree_poll_event() == 1 {
86 let node = tui_tree_event_node();
87 let name = unsafe { CStr::from_ptr(tui_tree_event_name()) }
88 .to_string_lossy()
89 .into_owned();
90 let text = unsafe { CStr::from_ptr(tui_tree_event_text()) }
91 .to_string_lossy()
92 .into_owned();
93 match name.as_str() {
94 "click" => {
95 let label = get(node, "label");
96 count = if label == "reset" { 0.0 } else { count + 1.0 };
97 set_num(bar, "value", (count / 10.0).min(1.0));
98 set(status, "label", &format!("{label}: {count}"));
99 }
100 "select" | "activate" | "toggled" | "change" => {
101 set(status, "label", &format!("{name} {text}"));
102 }
103 _ => {}
104 }
105 }
106 tui_frame();
107 }
108 tui_close();
109}