Skip to content

Repository files navigation

AppCUI-rs

⯈ 𝗔𝗽𝗽𝗖𝗨𝗜-𝗿𝘀 🖳

Windows Build Status Linux Build Status macOS Build Status Code Coverage License Crates.io Docs.rs Gallery

AppCUI-rs is a fast, cross-platform Rust library for building modern, text-based user interfaces (TUIs) with rich widgets, themes, and full Unicode support—an alternative to ncurses and other terminal UI frameworks.

✨ Features

  • multiple out-of-the-box controls (buttons, labels, text boxes, check boxes, radio buttons, list views, tree views, buffer view, hexview, progress bar, graph view, combo boxes, date/time pickers, color pickers, tabs, accordions, etc.).
  • powerful layout system that allows you to position controls using absolute coordinates, relative coordinates, docking, alignment, anchors, or pivot positioning (see more here)
  • menus and toolbars
  • multi-platform support (Windows via API and virtual terminal, Linux via ncurses, macOS via termios)
  • multi-threading support to allow background tasks
  • timers
  • mouse support
  • clipboard support
  • color themes
  • support for Unicode characters
  • predefined dialogs (message box, input box, color picker, save & open dialogs, folder navigator, etc.)
  • true-color support (24 bits per pixel) for terminals that support it.

📦 Out-of-the-box controls and widgets

AppCUI-rs ships with a rich set of controls and widgets for building terminal user interfaces. The full list of stock controls is documented here.

Basic controls

  • Button — clickable action trigger
  • ToggleButton — button with pressed/unpressed state
  • Label — static, non-interactive text
  • CheckBox — toggle on/off
  • RadioBox — mutually exclusive choice within a group
  • ThreeStateBox — tri-state checkbox (checked/unchecked/unknown)
  • Toolbar - for window controls (with buttons, checkboxes, radioboxes)

Containers - Group and organize other controls.

  • Panel — simple rectangular grouping container
  • Tab — switch between multiple pages of content
  • Accordion — collapsible/expandable panels
  • Window — top-level movable/resizable frame
  • Desktop — root container hosting windows
  • Modal dialog — blocking dialog window

Separators

  • HSplitter / VSplitter — resizable dividers between regions (horizontal & vertical)
  • HLine / VLine — static visual separator lines (horizontal & vertical)

Selectors - Choose from a set of values you provide.

  • Selector — generic single-value enum selector
  • DropDownList — dropdown list of typed items
  • ComboBox — editable dropdown selection
  • ListBox — scrollable list selection
  • NumericSelector — pick a number within a range
  • KeySelector — capture a keyboard key/shortcut
  • HSlider — value slider

Pickers - Choose from a built-in domain.

  • DatePicker — select a date
  • TimePicker — select a time
  • ColorPicker — select a color
  • CharPicker — pick a character/glyph
  • PathFinder — browse and select a filesystem path

Data viewers - Display and navigate structured or large data sets.

  • ListView — tabular, multi-column data
  • TreeView — hierarchical data
  • BufferView — raw binary/byte (hex) inspection (also a HexViewer or BinaryDataViewer)
  • Markdown — rendered Markdown content
  • GraphView — nodes-and-edges graph rendering
  • ImageViewer — display images

Text

  • TextField — single-line text input
  • RichTextField — text with formatting/styling
  • Password — masked text input
  • TextArea — multi-line text input

Navigation

  • Menu — classic dropdown menus (including buttons, checkboxes, radioboxes, separators, sub-menus)
  • CommandBar — key-bound command strip
  • PopupMenu — contextual popup menu

Drawing

  • Canvas — free-form drawing surface

Other

  • HyperLink — clickable link
  • ToolTip — hover hint text
  • ProgressBar — task progress indicator

📸 Screenshots

👉 Check out the Gallery for full demos of all controls!

🖥️ Backends

AppCUI supports various backends depending on the operating system:

  • Windows Console - based on the Win32 low-level API, designed for the classical Windows console
  • Windows VT - based on ANSI sequences, designed for modern Windows virtual terminals
  • NCurses - based on the NCurses API for Linux environments
  • Termios - based on ANSI sequences and low-level APIs for macOS
  • Web Terminal - designed for web implementations (based on WebGL)
  • CrossTerm - based on the crossterm crate, enabled via a feature flag

More on the supported backends can be found here

🚀 Quick Start

Add the following to your Cargo.toml:

[dependencies]
appcui = "0.5"

Then create a new Rust project and add the following code:

use appcui::prelude::*;

fn main() -> Result<(), appcui::system::Error> {
    App::new()
        .window(|| {
            let mut win = Window::new(
                "Test",
                LayoutBuilder::new().alignment(Alignment::Center).width(30).height(9).build(),
                window::Flags::Sizeable,
            );
            win.add(Label::new(
                "Hello World !",
                LayoutBuilder::new().alignment(Alignment::Center).width(13).height(1).build(),
            ));
            win
        })
        .run()
}

Or a more compact version using proc-macros:

use appcui::prelude::*;

fn main() -> Result<(), appcui::system::Error> {
    App::new()
        .window(|| {
            let mut win = window!("Test,a:c,w:30,h:9");
            win.add(label!("'Hello World !',a:c,w:13,h:1"));
            win
        })
        .run()
}

Alternatively, you can use the frame-based or input-based mode to create applications that can access the screen directly (without needing the entire UI architecture):

use appcui::prelude::*;

struct HelloWorld;
impl InputApp for HelloWorld {
    fn on_paint(&self, surface: &mut Surface) {
        surface.write_string(0, 0, "Hello World !", charattr!("white"), false);
    }
}
fn main() -> Result<(), appcui::system::Error> {
    App::input_app(HelloWorld {}).run()
}

Then run the project with cargo run. You should see a window with the title Test and the text Hello World ! in the center.

🧪 Examples

AppCUI-rs comes with a set of examples to help you get started. You can find them in the examples folder, including:

🛠️ A more complex example

An example that creates a window with a button that, when pressed, increases a counter.

use appcui::prelude::*;

// Create a window that handles button events and has a counter
#[Window(events = ButtonEvents)]
struct CounterWindow {
    counter: i32
}

impl CounterWindow {
    fn new() -> Self {
        let mut w = Self {
            // set up the window title and position
            base: window!("'Counter window',a:c,w:30,h:5"),
            // initial counter is 1
            counter: 1            
        };
        // add a single button with the caption "1" (like the counter)
        w.add(button!("'1',d:b,w:20"));
        w
    }
}
impl ButtonEvents for CounterWindow {
    // When the button is pressed, this function will be called
    // with the handle of the button that was pressed
    // Since we only have one button, we don't need to store its handle 
    // in the struct, as we will receive the handle via the on_pressed method
    fn on_pressed(&mut self, handle: Handle<Button>) -> EventProcessStatus {
        // increase the counter
        self.counter += 1;
        // create a text that contains the new counter
        let text = format!("{}",self.counter);
        // acquire a mutable reference to the button using its handle
        if let Some(button) = self.control_mut(handle) {
            // set the caption of the button to the new text
            button.set_caption(&text);
        }
        // Tell the AppCUI framework that we have processed this event
        // This allows AppCUI to repaint the button
        EventProcessStatus::Processed
    }
}

fn main() -> Result<(), appcui::system::Error> {
    // create a new application, add a CounterWindow, and start the event loop
    App::new().window(|| CounterWindow::new()).run()
}

🛣️ Roadmap

  • Basic set of widgets and support for Windows, Linux, and macOS
  • WebGL / WebAssembly support
  • Frame-based mode support (ideal for game development)
  • Input-based mode support (for applications that require user input)
  • OpenGL / SDL / Vulkan support
  • Editor support (syntax highlighting, code folding, etc.)
  • Rich Text support (rich text editing, formatting, etc.)
  • Sixel support for terminal graphics
  • Property Grid control

🤝 Contributing

Contributions, issues, and feature requests are welcome!
Check out CONTRIBUTING.md to get started.

Join the discussion in GitHub Discussions.

About

AppCUI is a fast, cross-platform console and text-based user interface (CUI/TUI) framework for Rust. It combines a low-level console engine for input (mouse, keyboard, clipboard, etc.), colors, and rendering with a high-level, rich toolkit of widgets such as windows, menus, buttons, checkboxes, and many more, available for Windows, Linux and Mac.

Topics

Resources

Code of conduct

Contributing

Stars

401 stars

Watchers

11 watching

Forks

Releases

Packages

Contributors

Languages