⯈ 𝗔𝗽𝗽𝗖𝗨𝗜-𝗿𝘀 🖳
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.
👉 Check out the Gallery for full demos of all controls!
- 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, bar charts, pie charts, line charts, usage charts, 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.
- retained mode and immediate mode support (through Frame-based and Input-based modes)
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.
- 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)
- 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
- HSplitter / VSplitter — resizable dividers between regions (horizontal & vertical)
- HLine / VLine — static visual separator lines (horizontal & vertical)
- 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
- DatePicker — select a date
- TimePicker — select a time
- ColorPicker — select a color
- CharPicker — pick a character/glyph
- PathFinder — browse and select a filesystem path
- 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
- VBarChart — vertical bar chart for a numeric series (scale, axes, and per-bar appearance)
- HBarChart — horizontal bar chart for a numeric series (scale, axes, and per-bar appearance)
- PieChart — pie chart for a numeric series (scale, axes, and per-slice appearance)
- LineChart — line chart for a numeric series (scale, axes, and per-point appearance)
- UsageChart — horizontal bar split into segments that share one total (per-segment fill and a hover tooltip)
- TextField — single-line text input
- RichTextField — text with formatting/styling
- Password — masked text input
- TextArea — multi-line text input
- MarkdownComposer — edit Markdown with formatting applied as you type
- Menu — classic dropdown menus (including buttons, checkboxes, radioboxes, separators, sub-menus)
- CommandBar — key-bound command strip
- PopupMenu — contextual popup menu
- Canvas — free-form drawing surface
- HyperLink — clickable link
- ToolTip — hover hint text
- ProgressBar — task progress indicator
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
crosstermcrate, enabled via a feature flag
More on the supported backends can be found here
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::Sizeabl
8000
e,
);
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.
AppCUI-rs comes with a set of examples to help you get started. You can find them in the examples folder, including:
- Games such as Tic Tac Toe, Snake, Flappy Bird, Minesweeper, Ram it, PacMan, Chess, Connect Four, 2048, Memory, or Tetris
- Utilities such as Calculator, CSV Viewer, Temperature Converter, HexViewer, or a Timer
- Animations such as Matrix, Game of Life, Fractals, Plasma or Spiral
- Controls/Widgets such as Button, CheckBox, ComboBox, DatePicker, ListView, TreeView, Vertical Bar Chart, Markdown Composer and many more.
- Dialogs such as Notification or Input
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()
}- 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
Contributions, issues, and feature requests are welcome!
Check out CONTRIBUTING.md to get started.
Join the discussion in GitHub Discussions.