///|
/// Interactive counter demo demonstrating the Pippa TUI framework.
///
/// This example showcases a counter with keybinds for incrementing, decrementing,
/// and resetting the count. It also demonstrates how to use the `Program::run`
/// entry point and input subscriptions.
///
/// Run with: `moon run src/examples/hello`
///|
/// The application model — a counter app.
struct Model {
count : Int
quitting : Bool
} derive(Debug)
///|
/// Application messages.
enum Msg {
Increment
Decrement
Reset
Quit
} derive(Debug)
///|
/// Initialise the model.
fn hello_init() -> @pippa.UpdateResult[Model, Msg] {
@pippa.UpdateResult::new(
model={ count: 0, quitting: false },
cmd=@pippa.Cmd::none(),
)
}
///|
/// Update the model in response to a message.
fn hello_update(model : Model, msg : Msg) -> @pippa.UpdateResult[Model, Msg] {
if model.quitting {
return @pippa.UpdateResult::new(model~, cmd=@pippa.Cmd::none())
}
let mut next_count = model.count
let mut quitting = false
match msg {
Increment => next_count = model.count + 1
Decrement => next_count = model.count - 1
Reset => next_count = 0
Quit => quitting = true
}
@pippa.UpdateResult::new(
model={ count: next_count, quitting },
cmd=@pippa.Cmd::none(),
)
}
///|
/// Map input events to messages.
fn hello_sub(event : @pippa.InputEvent) -> Msg? {
match event {
@pippa.Key(@pippa.Char('+')) | @pippa.Key(@pippa.Special("up")) =>
Some(Increment)
@pippa.Key(@pippa.Char('-')) | @pippa.Key(@pippa.Special("down")) =>
Some(Decrement)
@pippa.Key(@pippa.Char('r')) => Some(Reset)
@pippa.Key(@pippa.Char('q')) | @pippa.Key(@pippa.Modified("ctrl", "c")) =>
Some(Quit)
_ => None
}
}
///|
/// Render the model to a string of ANSI-formatted output.
fn hello_view(model : Model) -> String {
if model.quitting {
return "\n Goodbye!\n\n"
}
let bold = @pippa.bold()
let dim = @pippa.dim()
let reset = @pippa.reset()
"\n Pippa Counter Demo\n\n Count: \{bold}\{model.count}\{reset}\n\n \{dim}+ increment - decrement r reset q quit\{reset}\n"
}
///|
/// Entry point — create the program and run it.
fn main {
let program = @pippa.Program::new(
init=hello_init,
update=hello_update,
view=hello_view,
sub=hello_sub,
should_quit=fn(model) { model.quitting },
)
ignore(@pippa.Program::run(program))
}