Borland Turbo Vision windowing patterns for Ratatui.
Overlapping windows, modal dialogs, dropdown menus, and more — all rendering through Ratatui's Frame/Buffer system.
- Command System —
u16command IDs with bitfield enable/disable - View Trait — Base trait with
ViewId, focus management, state flags - Container — Z-order management, three-phase event dispatch
- Overlapping Windows — Drag by title bar, resize from corner, zoom toggle
- Modal Dialogs — Self-contained event loop, OK/Cancel/Yes/No
- Menu Bar — Dropdown submenus via OverlayManager,
~X~hotkey markers, Alt+Letter - Status Bar — Context-sensitive shortcuts, click-to-execute
- Scrollbars — Vertical/horizontal with draggable thumb, active/inactive styling
- JSON Themes — 6 built-in themes with full JSON serialization
🟢 v0.2.3 — Released — 357 tests, 21 source files, ~15,000 lines. Clippy pedantic clean, zero unsafe.
[dependencies]
turbo-tui = { git = "https://github.com/four-bytes/turbo-tui" }use turbo_tui::prelude::*;
let mut desktop = Desktop::new(Rect::new(0, 0, 80, 24));
// Basic window
let mut win = Window::new(Rect::new(5, 5, 40, 15), "Editor");
// Builder Lite pattern
let mut win = Window::new(Rect::new(5, 5, 40, 15), "Editor")
.with_min_size(20, 8)
.with_scrollbars(true, false)
.with_closeable(true)
.with_resizable(true);
// Preset constructors
let mut palette = Window::palette(Rect::new(50, 2, 20, 10), "Colors");
let mut tool = Window::tool(Rect::new(1, 20, 15, 5), "Tools");
win.insert(Box::new(Button::new("OK", CM_OK, Rect::new(5, 10, 10, 1))));
desktop.add_window(Box::new(win));use turbo_tui::prelude::*;
let menu = Menu::new("~F~ile", vec![
MenuItem::action("~O~pen", CM_OPEN),
MenuItem::action("~S~ave", CM_SAVE),
MenuItem::separator(),
MenuItem::action("E~x~it", CM_QUIT),
]);
let mut menu_bar = MenuBar::new(Rect::new(0, 0, 80, 1));
menu_bar.add_entries(menu_bar_from_menus(vec![menu]));use turbo_tui::prelude::*;
let mut dlg = Dialog::new(Rect::new(20, 8, 40, 10), "Confirm");
dlg.insert(Box::new(StaticText::new("Save changes?", Rect::new(5, 3, 30, 1))));
dlg.insert(Box::new(Button::new("~Y~es", CM_YES, Rect::new(5, 6, 10, 1))));
dlg.insert(Box::new(Button::new("~N~o", CM_NO, Rect::new(20, 6, 10, 1))));
// Run modal — returns the command that closed it
let result = dlg.run(&mut terminal, &mut theme)?;use turbo_tui::prelude::*;
let mut app = Application::new()?;
app.set_menu_bar(menu_bar);
app.set_status_bar(status_bar);
app.set_desktop(desktop);
app.run()?; // Blocks until CM_QUITEvery interactive element implements View:
draw(&self, buf: &mut Buffer, theme: &Theme, clip: ClipRegion)— Render the viewhandle_event(&mut self, event: &mut Event) -> bool— Handle input events (true= consumed)state_flags(&self) -> StateFlags/set_state_flags(&mut self, flags: StateFlags)— Query/set statebounds(&self) -> Rect/set_bounds(&mut self, bounds: Rect)— Geometryview_id(&self) -> ViewId— Stable identity (atomic counter, survives moves)cursor_position(&self) -> Option<Position>— Optional cursor position for Ratatui
Orchestrates the entire event loop:
run(&mut self) -> Result<()>— Main event loop (blocks untilCM_QUIT)post_event(&mut self, event: Event)— Queue deferred eventstheme(&self) -> &Theme/set_theme(&mut self, theme: Theme)— Global themeset_menu_bar(&mut self, menu_bar: MenuBar)— Attach optional menu barset_status_bar(&mut self, status_bar: StatusLine)— Attach optional status barset_desktop(&mut self, desktop: Desktop)— Attach desktop with windows
Overlapping window with drag, resize, and zoom:
Window::new(bounds: Rect, title: &str)— Base constructorWindow::with_config(bounds: Rect, title: &str, config: FrameConfig)— From configwith_min_size(self, w: u16, h: u16) -> Self— Builder: minimum sizewith_drag_limits(self, limits: Rect) -> Self— Builder: drag boundswith_scrollbars(self, v: bool, h: bool) -> Self— Builder: scrollbarswith_closeable(self, v: bool) -> Self— Builder: close buttonwith_resizable(self, v: bool) -> Self— Builder: resize handleminimize(&mut self)— Collapse to task shelf (managed by Desktop)minimized_width(&self) -> u16— Width when minimized
turbo-tui does not replace Ratatui — it extends it. All rendering goes through Ratatui's Frame and Buffer. The patterns are adapted from turbo-vision-4-rust (MIT licensed), reimplemented for the Ratatui ecosystem.
Application
└── Ratatui Terminal
└── turbo-tui views
├── Desktop (background + window manager)
│ ├── Window 1 (back)
│ ├── Window 2
│ └── Window N (front/focused)
├── MenuBar (optional)
└── StatusBar (optional)
cargo test # Run all 357 tests
cargo clippy -- -D warnings # Lint (pedantic enabled)
cargo fmt # Format code
cargo run --example demo # Run the interactive demo- Branch naming:
feature/<name>,fix/<name>, orrefactor/<name> - Include tests for new functionality
- Ensure
cargo clippy -- -D warningspasses - Update
HISTORY.mdwith a changelog entry - Keep doc comments on all public items
- ROADMAP.md — Version roadmap and future phases
- HISTORY.md — Detailed change log
- docs/ — Architecture plans and design documents
- PLAN-v0.2.md — v0.2 rebuild architecture plan
- PLAN-v0.2.1.md — v0.2.1 progression plan
- PLAN-v0.2.2.md — MenuBar→Overlay refactor plan
- ARCHITECTURE.md — System diagram and module dependencies
- STANDARDS.md — Coding standards and conventions
- TESTING.md — Test architecture and patterns
Having grown up with Turbo Pascal 5, TASM, and later Borland Pascal for Protected Mode — the Turbo Vision UI framework left a lasting impression. This crate brings those Borland Turbo Vision patterns (1991) to modern Rust terminal applications. The original TV powered Turbo Pascal and Turbo C++ IDEs. Norton Commander's dual-panel paradigm will also influence future development.
MIT — see LICENSE