Introducing EzTerm - A template-based cross-platform Terminal UI framework
I needed to create a UI for a command line app recently, and spoiled as I am creating UI's from config files with Kivy in Python, I decided to create a template-based terminal UI framework for Rust, which became EzTerm. It was just added to cargo, and has a full tutorial available.
The idea is that anything that doesn't have to be code (like callbacks) can be written in YAML-like config files. In these config files you declare layouts and widgets, and the framework will make it happen. This means you don't have to think about the specifics of positioning, sizing and scaling (although manual options are available). Instead you can use smart layout modes to automatically create tables, tabs, screens, scrollviews, etc. As a compromise between fully manual and fully automatic you can also declare size hints (I want this widget to be 50% the width of its parent) and/or position hints (I want this widget to be 'top left'), which will hold true even when the terminal resizes.
Supported widgets are Labels, Text inputs, Buttons, Checkboxes, Radio Buttons, Sliders, Dropdowns, Progress bars and canvases. Supported layout modes are Box, Stack, Table, Float (free widget placement), Tab and Screen.
Here is a fully functional example with two labels (first we'll see the config file, then the Rust code):
- Layout:
mode: box
orientation: horizontal
- Label:
text: Hello,
border: true
- Label:
text: World!
border: true
use ez_term::*;
fn main() {
let (root_widget, state_tree, mut scheduler) = load_ui();
run(root_widget, state_tree, scheduler);
}
The config files support template inheritance so you can define widget styles and reuse them. They are automatically merged into your binary at compile time, so you don't ship them with your binary.
Other features of the framework are full callback support for all widgets, scheduling (recurring) tasks, programmatically creating/destroying widgets, and much more.
Combining all layout modes, widgets, and API functions, you can create complex UIs will relative ease, such as this (way too convoluted) example:
https://i.redd.it/2vtc1ufrqpl91.gif
I've learned a lot so far writing this framework and have found it to be useful in my own projects. I'm now sharing it for anyone that, like me, likes to focus on coding their apps instead of their UI. If there's any questions or issues feel free to ask here or in a GitHub issue.