2 releases

0.1.1 Jan 1, 2019
0.1.0 Jan 1, 2019

#556 in Command-line interface

Download history 43/week @ 2023-11-27 76/week @ 2023-12-04 97/week @ 2023-12-11 92/week @ 2023-12-18 30/week @ 2023-12-25 2/week @ 2024-01-01 25/week @ 2024-01-08 26/week @ 2024-01-15 76/week @ 2024-01-22 34/week @ 2024-01-29 49/week @ 2024-02-05 21/week @ 2024-02-12 69/week @ 2024-02-19 68/week @ 2024-02-26 64/week @ 2024-03-04 50/week @ 2024-03-11

252 downloads per month

Apache-2.0/MIT

17KB
366 lines

A library for building interactive apps with the terminal.

The usual way to interact with a terminal is to use ansi escape sequences. These are commands like "use green foreground" or "move cursor up 1 place". This library presents a blank buffer for the user to draw on, and converts this buffer into the minimum (aspirational) number of bytes to send to the terminal. This is sometimes referred to as immediate mode drawing, where you draw everything each frame.

The library also provides an interator over all input events received since the last request for the iterator.

Example

use termbuffer::{App, Event, Key, char, Color};
use std::time::{Duration, Instant};
use std::thread;

const FRAME_TIME: Duration = Duration::from_millis(1000 / 60); // 60 fps

fn main() {
    let mut shutdown = false;

    // Currently there are no options, but I'm planning to add for things like
    // what color to clear the screen to, etc.
    let mut app = App::builder().build().unwrap();
    // As this counter is incremented, we will move along the rows.
    let mut counter = 0;
    loop {
        if shutdown {
            break;
        }
        let time_start = Instant::now();
        {
            // Call draw when you are ready to start rendering the next frame.
            let mut draw = app.draw();
            // The draw object contains the new number of rows and columns
            // (this will change if the user resizes the terminal).
            let cols = draw.columns();
            let rows = draw.rows();
            // Math to convert counter to position.
            let row = counter / cols;
            let col = counter % cols;
            // We set all the characters we want.
            draw.set(row, col, char!('.', Color::Default, Color::Red));
            counter = (counter + 1) % (cols * rows);
        }
        // Call app.events to pump the event loop.
        for evt in app.events() {
            match evt.unwrap() {
                Event::Key(Key::Char('q')) => {
                    shutdown = true;
                }
                _ => ()
            }
        }
        let time_end = Instant::now();
        // Sleep for the remainder of the frame.
        if time_end < time_start + FRAME_TIME {
            thread::sleep(FRAME_TIME - (time_end - time_start));
        }
    }
}

Dependencies

~165KB