use ftui_core::event::{Event, KeyCode, KeyEvent, KeyEventKind, Modifiers};
use ftui_core::geometry::Rect;
use ftui_layout::{Constraint, Flex};
use ftui_render::frame::Frame;
use ftui_runtime::{App, Cmd, Model, ScreenMode};
use ftui_widgets::Widget;
use ftui_widgets::paragraph::Paragraph;
struct Counter {
count: i64,
}
enum Msg {
Increment,
Decrement,
Quit,
Noop,
}
impl From<Event> for Msg {
fn from(e: Event) -> Self {
match e {
Event::Key(KeyEvent {
code: KeyCode::Up,
kind: KeyEventKind::Press,
..
}) => Msg::Increment,
Event::Key(KeyEvent {
code: KeyCode::Down,
kind: KeyEventKind::Press,
..
}) => Msg::Decrement,
Event::Key(KeyEvent {
code: KeyCode::Char('c'),
modifiers,
kind: KeyEventKind::Press,
..
}) if modifiers.contains(Modifiers::CTRL) => Msg::Quit,
_ => Msg::Noop,
}
}
}
impl Model for Counter {
type Message = Msg;
fn update(&mut self, msg: Msg) -> Cmd<Self::Message> {
match msg {
Msg::Increment => self.count += 1,
Msg::Decrement => self.count -= 1,
Msg::Quit => return Cmd::Quit,
Msg::Noop => {}
}
Cmd::None
}
fn view(&self, frame: &mut Frame) {
let area = Rect::from_size(frame.buffer.width(), frame.buffer.height());
let rows = Flex::vertical()
.constraints([
Constraint::Fixed(1),
Constraint::Fixed(1),
Constraint::Fixed(1),
])
.split(area);
let title = Paragraph::new("Counter Example");
title.render(rows[0], frame);
let value = Paragraph::new(format!(" Count: {}", self.count));
value.render(rows[1], frame);
let help = Paragraph::new(" Up/Down: ±1 | Ctrl+C: Quit");
help.render(rows[2], frame);
}
}
fn main() -> std::io::Result<()> {
App::new(Counter { count: 0 })
.screen_mode(ScreenMode::Inline { ui_height: 3 })
.run()
}