use lv_tui::prelude::*;
use lv_tui::Component;
use lv_tui::widgets::Column;
#[derive(Component)]
struct Blinker {
#[reactive(paint, copy)]
visible: bool,
}
impl Blinker {
fn new() -> Self { Self { visible: true } }
fn render(&self, cx: &mut RenderCx) {
if self.get_visible() {
cx.line("*** BLINK ***");
} else {
cx.line(" ");
}
}
fn event(&mut self, event: &Event, cx: &mut EventCx) {
if event.is_key(Key::Char('q')) { cx.quit(); }
if matches!(event, Event::Tick) && cx.phase() == EventPhase::Target {
self.set_visible(!self.get_visible(), cx);
}
}
}
struct Root { body: Column }
impl Root {
fn new(body: Column) -> Self { Self { body } }
}
impl Component for Root {
fn render(&self, cx: &mut RenderCx) { self.body.render(cx); }
fn layout(&mut self, r: Rect, cx: &mut LayoutCx) { self.body.layout(r, cx); }
fn focusable(&self) -> bool { false }
fn event(&mut self, e: &Event, cx: &mut EventCx) {
if e.is_key(Key::Char('q')) { cx.quit(); }
self.body.event(e, cx);
}
fn for_each_child(&self, f: &mut dyn FnMut(&Node)) { self.body.for_each_child(f); }
fn for_each_child_mut(&mut self, f: &mut dyn FnMut(&mut Node)) { self.body.for_each_child_mut(f); }
}
fn main() -> lv_tui::Result<()> {
let body = Column::new()
.padding(1).gap(1)
.child(lv_tui::widgets::Label::new("=== Timer Demo ==="))
.child(Blinker::new())
.child(lv_tui::widgets::Label::new("press q to quit"));
lv_tui::app::App::new(Root::new(body)).run()
}