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
//! The smallest quadraui app, on the canonical `ShellApp` path.
//!
//! [`AppShellLayout::status_bar_bounds`] below is computed for us, so there
//! is no viewport arithmetic anywhere in this file, and painting goes
//! through [`ScreenLayout`]/[`Surface`] — the same declarative frame-list
//! path a multi-primitive screen uses — rather than a raw `Backend::draw_*`
//! call (`Backend::draw_*` is the *low-level* entry point; see
//! `docs/decisions/DECISIONS.md` D-006).
//!
//! Deliberately has no shared `examples/common/` module: that module pulls
//! in every other example, so this "hello world" would secretly compile
//! thousands of lines nothing here needs.
//!
//! `cargo run --example hello --features tui`
//!
//! Press any key to bump the counter; `q` or Esc to quit.
use quadraui::prelude::*;
use quadraui::{AppShellLayout, ScreenLayout, Surface};
pub struct Hello {
pub keys_pressed: u32,
}
impl Hello {
/// No sidebar panels and no activity bar — this app has nothing to put
/// in either — just the one status-bar band it actually uses.
pub fn config() -> ShellConfig {
ShellConfig::new("Hello", Vec::new())
.with_status_bar()
.with_activity_bar_width(0.0)
}
}
impl ShellApp for Hello {
fn render_content(&self, backend: &mut dyn Backend, layout: &AppShellLayout) {
let Some(rect) = layout.status_bar_bounds else {
return;
};
let bar = StatusBar {
id: WidgetId::new("status:bar"),
left_segments: vec![StatusBarSegment {
text: format!(" Hello, quadraui! (keys: {}) ", self.keys_pressed),
fg: Color::rgb(255, 255, 255),
bg: Color::rgb(40, 80, 120),
bold: true,
action_id: None,
}],
right_segments: vec![StatusBarSegment {
text: " q to quit ".into(),
fg: Color::rgb(220, 220, 220),
bg: Color::rgb(40, 80, 120),
bold: false,
action_id: None,
}],
};
let mut frame = ScreenLayout::new();
frame.push(Surface::StatusBar {
rect,
bar,
hovered: None,
pressed: None,
});
frame.draw(backend);
}
fn handle(
&mut self,
event: UiEvent,
_backend: &mut dyn Backend,
_ctx: &ShellContext,
) -> Reaction {
match event {
UiEvent::KeyPressed { key, .. } => {
if matches!(key, Key::Char('q') | Key::Named(NamedKey::Escape)) {
return Reaction::Exit;
}
self.keys_pressed += 1;
Reaction::Redraw
}
UiEvent::WindowResized { .. } => Reaction::Redraw,
_ => Reaction::Continue,
}
}
}
fn main() {
quadraui::tui::shell_runner::run_with_shell(Hello { keys_pressed: 0 }, Hello::config());
}