turbo_vision/lib.rs
1// (C) 2025 - Enzo Lombardi
2
3//! Turbo Vision - A modern Text User Interface (TUI) framework for Rust.
4//!
5//! Turbo Vision is a Rust port of the classic Borland Turbo Vision framework,
6//! providing a powerful and flexible system for building terminal-based
7//! applications with a rich set of widgets and an event-driven architecture.
8//!
9//! # Features
10//!
11//! - **Event-driven architecture** - Handle keyboard, mouse, and custom events
12//! - **Flexible view hierarchy** - Compose UIs from reusable widget components
13//! - **Built-in widgets** - Windows, dialogs, buttons, input fields, lists, menus
14//! - **Syntax highlighting** - Extensible syntax highlighting system for editors
15//! - **Command system** - Global command routing and enable/disable states
16//! - **Clipboard support** - Copy/paste operations
17//! - **History management** - Input history for text fields
18//! - **Double-buffered rendering** - Flicker-free terminal updates
19//! - **Mouse support** - Full mouse capture and tracking
20//! - **Borland TV compatibility** - Familiar API for Turbo Vision users
21//!
22//! # Quick Start
23//!
24//! ```rust,no_run
25//! use turbo_vision::prelude::*;
26//!
27//! fn main() -> turbo_vision::core::error::Result<()> {
28//! // Create application with terminal
29//! let mut app = Application::new()?;
30//!
31//! // Create a simple window
32//! let mut window = turbo_vision::views::window::Window::new(
33//! Rect::new(10, 5, 50, 15),
34//! "My First Window"
35//! );
36//!
37//! // Add a button
38//! let button = turbo_vision::views::button::Button::new(
39//! Rect::new(15, 5, 25, 7),
40//! "Click Me",
41//! turbo_vision::core::command::CM_OK,
42//! false
43//! );
44//! window.add(Box::new(button));
45//!
46//! // Add window to desktop
47//! app.desktop.add(Box::new(window));
48//!
49//! // Run event loop
50//! app.running = true;
51//! while app.running {
52//! app.desktop.draw(&mut app.terminal);
53//! app.terminal.flush()?;
54//!
55//! if let Ok(Some(mut event)) = app.terminal.poll_event(
56//! std::time::Duration::from_millis(50)
57//! ) {
58//! app.desktop.handle_event(&mut event);
59//!
60//! if event.what == EventType::Command {
61//! match event.command {
62//! CM_QUIT => app.running = false,
63//! CM_OK => {
64//! // Handle button click
65//! app.running = false;
66//! }
67//! _ => {}
68//! }
69//! }
70//! }
71//! }
72//!
73//! app.terminal.shutdown()?;
74//! Ok(())
75//! }
76//! ```
77//!
78//! # Architecture
79//!
80//! The framework is organized into several key modules:
81//!
82//! ## Core Modules
83//!
84//! - **[`core`]** - Fundamental types and utilities
85//! - [`geometry`](core::geometry) - Point, Rect for positioning
86//! - [`event`](core::event) - Event handling and keyboard/mouse input
87//! - [`command`](core::command) - Command IDs and routing
88//! - [`error`](core::error) - Error types and Result alias
89//! - [`palette`](core::palette) - Color management
90//!
91//! - **[`views`]** - Built-in widgets and view components
92//! - [`View`](views::View) - Base trait for all UI components
93//! - [`Window`](views::window::Window), [`Dialog`](views::dialog::Dialog) - Containers
94//! - [`Button`](views::button::Button), [`InputLine`](views::input_line::InputLine) - Controls
95//! - [`Editor`](views::editor::Editor) - Multi-line text editor
96//! - [`MenuBar`](views::menu_bar::MenuBar), [`StatusLine`](views::status_line::StatusLine) - Navigation
97//!
98//! - **[`app`]** - Application infrastructure
99//! - [`Application`](app::Application) - Main application coordinator
100//!
101//! - **[`terminal`]** - Terminal abstraction layer
102//! - [`Terminal`](terminal::Terminal) - Crossterm-based rendering backend
103//!
104//! ## Application Structure
105//!
106//! ```text
107//! Application
108//! ├── Terminal (crossterm backend)
109//! ├── Desktop (window manager)
110//! │ ├── Background
111//! │ └── Windows/Dialogs
112//! │ └── Child widgets (buttons, inputs, etc.)
113//! ├── MenuBar (optional)
114//! └── StatusLine (optional)
115//! ```
116//!
117//! # Examples
118//!
119//! ## Creating a Dialog
120//!
121//! ```rust,no_run
122//! use turbo_vision::prelude::*;
123//! use turbo_vision::views::{dialog::Dialog, button::Button, static_text::StaticText};
124//!
125//! # fn create_dialog() -> Box<Dialog> {
126//! let dialog_bounds = Rect::new(20, 8, 60, 16);
127//! let mut dialog = Dialog::new_modal(dialog_bounds, "Confirmation");
128//!
129//! // Add message text
130//! let text = StaticText::new(
131//! Rect::new(2, 2, 38, 3),
132//! "Are you sure you want to continue?"
133//! );
134//! dialog.add(Box::new(text));
135//!
136//! // Add OK button
137//! let ok_button = Button::new(
138//! Rect::new(10, 4, 18, 6),
139//! "OK",
140//! turbo_vision::core::command::CM_OK,
141//! true // default button
142//! );
143//! dialog.add(Box::new(ok_button));
144//!
145//! // Add Cancel button
146//! let cancel_button = Button::new(
147//! Rect::new(22, 4, 32, 6),
148//! "Cancel",
149//! turbo_vision::core::command::CM_CANCEL,
150//! false
151//! );
152//! dialog.add(Box::new(cancel_button));
153//!
154//! dialog
155//! # }
156//! ```
157//!
158//! ## Handling Events
159//!
160//! ```rust,no_run
161//! use turbo_vision::prelude::*;
162//! # use turbo_vision::app::Application;
163//! # use turbo_vision::core::error::Result;
164//! # fn example(mut app: Application) -> Result<()> {
165//!
166//! app.running = true;
167//! while app.running {
168//! // Draw UI
169//! app.desktop.draw(&mut app.terminal);
170//! app.terminal.flush()?;
171//!
172//! // Poll for events
173//! if let Ok(Some(mut event)) = app.terminal.poll_event(
174//! std::time::Duration::from_millis(50)
175//! ) {
176//! // Let desktop handle event
177//! app.desktop.handle_event(&mut event);
178//!
179//! // Check for commands
180//! if event.what == EventType::Command {
181//! match event.command {
182//! CM_QUIT => {
183//! app.running = false;
184//! }
185//! _ => {}
186//! }
187//! }
188//! }
189//! }
190//! # Ok(())
191//! # }
192//! ```
193//!
194//! # Borland Turbo Vision Compatibility
195//!
196//! This implementation maintains conceptual compatibility with Borland Turbo Vision
197//! while modernizing the design for Rust's ownership model:
198//!
199//! - **TView** → [`View`](views::View) trait
200//! - **TWindow** → [`Window`](views::window::Window)
201//! - **TDialog** → [`Dialog`](views::dialog::Dialog)
202//! - **TButton** → [`Button`](views::button::Button)
203//! - **TInputLine** → [`InputLine`](views::input_line::InputLine)
204//! - **TProgram** → [`Application`](app::Application)
205//!
206//! Event handling uses Rust's ownership system instead of raw pointers, with
207//! events bubbling up through the call stack rather than using owner pointers.
208//!
209//! # See Also
210//!
211//! - [Examples](https://github.com/anthropics/turbo-vision/tree/main/examples) - Complete working examples
212//! - [Borland TV Documentation](https://github.com/magiblot/tvision) - Original reference
213
214// Core modules
215pub mod core;
216pub mod terminal;
217pub mod views;
218pub mod app;
219pub mod helpers;
220
221// SSH server support (only available with ssh feature)
222#[cfg(feature = "ssh")]
223pub mod ssh;
224
225// Test utilities (only available with test-util feature)
226#[cfg(feature = "test-util")]
227pub mod test_util;
228
229// Re-export commonly used types
230pub mod prelude {
231 pub use crate::core::geometry::{Point, Rect};
232 pub use crate::core::event::{Event, EventType, KeyCode};
233
234 // Explicit command re-exports (no glob imports)
235 pub use crate::core::command::{
236 CommandId,
237 // Basic dialog commands
238 CM_QUIT,
239 CM_CLOSE,
240 CM_OK,
241 CM_CANCEL,
242 CM_YES,
243 CM_NO,
244 CM_DEFAULT,
245 // Internal view system commands
246 CM_COMMAND_SET_CHANGED,
247 CM_RECEIVED_FOCUS,
248 CM_RELEASED_FOCUS,
249 CM_GRAB_DEFAULT,
250 CM_RELEASE_DEFAULT,
251 CM_FILE_FOCUSED,
252 CM_FILE_DOUBLE_CLICKED,
253 // Application commands
254 CM_ABOUT,
255 CM_BIRTHDATE,
256 CM_TEXT_VIEWER,
257 CM_CONTROLS_DEMO,
258 // File operations
259 CM_NEW,
260 CM_OPEN,
261 CM_SAVE,
262 CM_SAVE_AS,
263 CM_SAVE_ALL,
264 CM_CLOSE_FILE,
265 // Edit operations
266 CM_UNDO,
267 CM_REDO,
268 CM_CUT,
269 CM_COPY,
270 CM_PASTE,
271 CM_SELECT_ALL,
272 CM_FIND,
273 CM_REPLACE,
274 CM_SEARCH_AGAIN,
275 CM_FIND_IN_FILES,
276 CM_GOTO_LINE,
277 // View commands
278 CM_ZOOM_IN,
279 CM_ZOOM_OUT,
280 CM_TOGGLE_SIDEBAR,
281 CM_TOGGLE_STATUSBAR,
282 // Help commands
283 CM_HELP_INDEX,
284 CM_KEYBOARD_REF,
285 // Demo commands
286 CM_LISTBOX_DEMO,
287 CM_LISTBOX_SELECT,
288 CM_MEMO_DEMO,
289 };
290
291 pub use crate::views::View;
292 pub use crate::app::Application;
293}