Skip to main content

Crate ratatui_input_manager

Crate ratatui_input_manager 

Source
Expand description

§Ratatui Input Manager

Crate Badge Repo Badge Docs Badge
License Badge CI Badge Deps Badge

A small utility crate providing a declarative approach to handling inputs in ratatui.

§Usage

[dependencies]
ratatui-input-manager = { version = "0.1.0", features = ["crossterm", "widgets"] }

§Keymap Macro

use std::io;

use crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use ratatui_core::{
    backend::TestBackend,
    layout::{Constraint, Layout},
    terminal::{Frame, Terminal},
    text::Line,
    widgets::Widget,
};
use ratatui_input_manager::{keymap, KeyMap};
use ratatui_input_manager::widgets::HelpBar;

#[derive(Default)]
struct App {
    counter: i32,
    quit: bool,
}

#[keymap(backend = "crossterm")]
impl App {
    /// Increment the counter
    #[keybind(pressed(key=KeyCode::Char('+')))]
    fn increment(&mut self) {
        self.counter += 1;
    }

    /// Decrement the counter
    #[keybind(pressed(key=KeyCode::Char('-')))]
    fn decrement(&mut self) {
        self.counter -= 1;
    }

    /// Exit the application
    #[keybind(pressed(key=KeyCode::Esc))]
    #[keybind(pressed(key=KeyCode::Char('q')))]
    #[keybind(pressed(key=KeyCode::Char('c'), modifiers=KeyModifiers::CONTROL))]
    fn quit(&mut self) {
        self.quit = true
    }
}

const TEST_EVENTS: &[Event] = &[
    Event::Key(KeyEvent::new(KeyCode::Char('+'), KeyModifiers::NONE)),
    Event::Key(KeyEvent::new(KeyCode::Char('-'), KeyModifiers::NONE)),
    Event::Key(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE)),
];

fn main() -> io::Result<()> {
    let mut terminal = Terminal::new(TestBackend::new(80, 32)).unwrap();

    let mut app = App::default();
    let mut events = TEST_EVENTS.iter();

    loop {
        terminal.draw(|frame: &mut Frame| {
            let [counter_area, help_bar_area] = Layout::vertical([
                Constraint::Fill(1),
                Constraint::Length(1),
            ]).areas(frame.area());
            frame.render_widget(
                Line::from(format!("Counter: {}", app.counter)).centered(),
                counter_area
            );

            frame.render_widget(
                HelpBar::new(App::KEYBINDS),
                help_bar_area,
            );
            // Renders as: "Increment the counter: <+> | Decrement the counter: <-> | Exit: <Esc>, <q>, <Ctrl+c>"
        }).unwrap();

        /// use [`crossterm::event::poll`] in place of iterating through test
        /// events
        if let Some(event) = events.next() {
            app.handle(event);
        }

        if app.quit {
            break Ok(());
        }
    }
}

§Widgets

This crate provides two widgets for displaying keybindings:

use crossterm::event::KeyCode;
use ratatui_core::terminal::Frame;
use ratatui_input_manager::{keymap, KeyMap};
use ratatui_input_manager::widgets::{Help, HelpBar};

struct App;

#[keymap(backend = "crossterm")]
impl App {
    /// Increment the counter
    #[keybind(pressed(key=KeyCode::Char('+')))]
    fn increment(&mut self) {}

    /// Decrement the counter
    #[keybind(pressed(key=KeyCode::Char('-')))]
    fn decrement(&mut self) {}
}

fn render_help(frame: &mut Frame) {
    let help = Help::new(App::KEYBINDS);
    frame.render_widget(help, frame.area());
}

fn render_help_bar(frame: &mut Frame) {
    let help_bar = HelpBar::new(App::KEYBINDS);
    frame.render_widget(help_bar, frame.area());
}

The Help widget displays keybindings in a table format:

┌────────────────────────────────────────────┐
│  +  Increment the counter                  │
│  -  Decrement the counter                  │
└────────────────────────────────────────────┘

The HelpBar widget displays keybindings in a single line:

Increment the counter: <+> | Decrement the counter: <->

§License

This project is licensed under the MIT license and the Apache License (Version 2.0). See LICENSE-MIT and LICENSE-APACHE for details.

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Modules§

widgets
Ratatui widgets displaying keybinds

Structs§

CrosstermBackend
Backend for crossterm
KeyBind
Key binding metadata, including the handled key presses and a description of behaviour
KeyPress
A key press event, combining a key code with modifiers

Traits§

Backend
A backend that provides types for key events
DynKeyMap
A dyn compatible equivalent to KeyMap
KeyMap
A mapping between keybinds and methods on the type which mutate the state

Attribute Macros§

keymap
Generate an implementation of [ratatui_input_manager::KeyMap], dispatching input events to the appropriate methods according to the attributes provided