|
13 | 13 | <img src="https://img.shields.io/badge/license-MIT-green" alt="License"> |
14 | 14 | </p> |
15 | 15 |
|
16 | | -**SharpConsoleUI** is a multi-window TUI framework for .NET 9 that combines Spectre.Console's rich markup with true overlapping window capabilities. Cross-platform (Windows, Linux, macOS). |
| 16 | +**SharpConsoleUI** is a terminal GUI framework for .NET — not just a TUI library, but a full **retained-mode GUI framework** that targets the terminal as its display surface. Cross-platform (Windows, Linux, macOS). |
17 | 17 |
|
| 18 | +The rendering engine follows the same architecture as desktop GUI frameworks like WPF and Avalonia: a **Measure → Arrange → Paint** layout pipeline, **double-buffered compositing** with occlusion culling, and a **unified cell pipeline** where ANSI never crosses layer boundaries. The terminal is just the rasterization target. |
| 19 | + |
| 20 | +- **GUI-grade rendering engine** — DOM-based layout, three-level dirty tracking, occlusion culling, adaptive Cell/Line/Smart rendering modes |
18 | 21 | - **Multi-window with per-window threads** — each window updates independently without blocking others |
19 | 22 | - **Spectre.Console markup everywhere** — just `[bold red]text[/]` and it works, no complex styling APIs |
20 | 23 | - **Any Spectre.Console widget works as a control** — Tables, BarCharts, Trees, Panels — wrap any `IRenderable` |
21 | | -- **Double-buffered, flicker-free rendering** with dirty region tracking |
22 | 24 | - **30+ built-in controls** — buttons, lists, trees, tables, text editors, dropdowns, menus, tabs, and more |
23 | 25 | - **Compositor effects** — PreBufferPaint/PostBufferPaint hooks for custom rendering, transitions, or even games |
24 | 26 | - **Fluent builders** for windows, controls, and layouts |
@@ -80,12 +82,15 @@ dotnet add package SharpConsoleUI |
80 | 82 | - **Mouse Support**: Click, drag, and mouse event handling |
81 | 83 | - **Input Queue**: Efficient input processing system |
82 | 84 |
|
83 | | -### Rendering System |
84 | | -- **Spectre.Console Foundation**: Leverages Spectre's perfect rendering engine for rich TUI widgets |
85 | | -- **Double Buffering**: Smooth rendering without flicker |
86 | | -- **Dirty Regions**: Efficient partial updates |
87 | | -- **Render Modes**: Direct and buffered rendering |
88 | | -- **Compositor Effects**: Post-processing buffer manipulation for transitions, blur, and filters |
| 85 | +### Rendering Engine |
| 86 | +- **Retained-Mode GUI Pipeline**: Measure → Arrange → Paint layout passes, DOM-based control tree with persistent state — same architecture as WPF/Avalonia |
| 87 | +- **Unified Cell Pipeline**: All rendering flows through typed `Cell` structs (char + fg + bg). ANSI is only generated once at the terminal output boundary — no format conversions in the hot path |
| 88 | +- **Two-Level Double Buffering**: CharacterBuffer (window-level) + ConsoleBuffer (screen-level) with front/back buffer diff detection |
| 89 | +- **Three-Level Dirty Tracking**: Window-level (did anything change?), cell-level (which cells?), screen-level (front vs back buffer comparison) |
| 90 | +- **Adaptive Rendering**: Smart mode analyzes each line and chooses Cell or Line rendering based on coverage and fragmentation heuristics |
| 91 | +- **Occlusion Culling**: Rectangle subtraction algorithm computes visible regions per window — occluded content is never rendered |
| 92 | +- **Multi-Pass Compositing**: Normal → Active → AlwaysOnTop rendering passes with proper Z-order stacking |
| 93 | +- **Compositor Effects**: PreBufferPaint/PostBufferPaint hooks for custom backgrounds, transitions, filters, and overlays |
89 | 94 | - **BufferSnapshot API**: Immutable buffer capture for screenshots and recording |
90 | 95 | - **Themes**: Multiple built-in themes (Classic, ModernGray) with runtime switching |
91 | 96 | - **Plugins**: Extensible architecture with DeveloperTools plugin |
@@ -286,44 +291,55 @@ This enables **pure declarative UIs** where all control interactions happen thro |
286 | 291 |
|
287 | 292 | ## Architecture Overview |
288 | 293 |
|
289 | | -### Core Components |
| 294 | +### Core Architecture |
290 | 295 |
|
291 | 296 | ``` |
292 | 297 | ┌─────────────────────────────────────────────────────────────┐ |
293 | | -│ SharpConsoleUI Architecture │ |
294 | | -├─────────────────────────────────────────────────────────────┤ |
295 | 298 | │ Application Layer (Your Code) │ |
296 | | -│ └── Window Builders & Event Handlers │ |
| 299 | +│ └── Window Builders, Event Handlers, Controls │ |
297 | 300 | ├─────────────────────────────────────────────────────────────┤ |
298 | 301 | │ Framework Layer │ |
299 | 302 | │ ├── Window Builders (Fluent API) │ |
300 | 303 | │ ├── State Services (Focus, Modal, Notification, etc.) │ |
301 | 304 | │ ├── Logging Service (ILogService) │ |
302 | 305 | │ └── Resource Management (DisposableManager) │ |
303 | 306 | ├─────────────────────────────────────────────────────────────┤ |
304 | | -│ Core UI Layer │ |
305 | | -│ ├── ConsoleWindowSystem (Window Management) │ |
306 | | -│ ├── Window (Container & Rendering) │ |
307 | | -│ ├── Controls (UI Components) │ |
308 | | -│ └── Themes (Appearance) │ |
| 307 | +│ Layout Layer │ |
| 308 | +│ ├── DOM Tree (LayoutNode hierarchy) │ |
| 309 | +│ ├── Measure → Arrange → Paint passes │ |
| 310 | +│ └── Layout containers (Stack, Column, Absolute, Fill) │ |
| 311 | +├─────────────────────────────────────────────────────────────┤ |
| 312 | +│ Rendering Layer │ |
| 313 | +│ ├── Multi-pass renderer (Normal → Active → AlwaysOnTop) │ |
| 314 | +│ ├── Occlusion culling (visible region calculation) │ |
| 315 | +│ ├── Border caching (CharacterBuffer-based) │ |
| 316 | +│ └── Portal system (floating overlays, dropdowns) │ |
| 317 | +├─────────────────────────────────────────────────────────────┤ |
| 318 | +│ Buffering Layer │ |
| 319 | +│ ├── CharacterBuffer (window-level cell buffer) │ |
| 320 | +│ ├── ConsoleBuffer (screen-level double buffer) │ |
| 321 | +│ └── Adaptive dirty tracking (Cell/Line/Smart modes) │ |
309 | 322 | ├─────────────────────────────────────────────────────────────┤ |
310 | 323 | │ Driver Layer │ |
311 | | -│ ├── IConsoleDriver (Abstraction) │ |
312 | | -│ ├── NetConsoleDriver (Implementation) │ |
313 | | -│ └── Input/Output Handling │ |
| 324 | +│ ├── IConsoleDriver abstraction │ |
| 325 | +│ ├── NetConsoleDriver (production) │ |
| 326 | +│ ├── HeadlessConsoleDriver (testing) │ |
| 327 | +│ └── Raw libc I/O (Unix) / Console API (Windows) │ |
314 | 328 | └─────────────────────────────────────────────────────────────┘ |
315 | 329 | ``` |
316 | 330 |
|
| 331 | +The terminal is the rasterization target. CharacterBuffer is the framebuffer. ConsoleBuffer is the display controller that diff-scans and outputs only changed cells — like a GPU compositor, but with characters instead of pixels. |
| 332 | + |
317 | 333 | ### Spectre.Console Integration |
318 | 334 |
|
319 | | -SharpConsoleUI uses **Spectre.Console as its rendering foundation**, combining Spectre's beautiful rendering with a complete windowing system: |
| 335 | +SharpConsoleUI uses **Spectre.Console for rich text markup**, but the rendering engine is independent: |
320 | 336 |
|
321 | | -1. **Capture Spectre Output**: `AnsiConsoleHelper` captures Spectre's ANSI rendering into our CharacterBuffer |
322 | | -2. **Wrap Any Spectre Widget**: `SpectreRenderableControl` makes any `IRenderable` (Tables, Trees, Panels, Charts) work as a window control |
323 | | -3. **Combine with Windows**: Multiple Spectre-rendered controls + interactive controls + independent window threads |
324 | | -4. **Result**: Best of both worlds - Spectre's rich rendering + full windowing system + multi-threading |
| 337 | +1. **Markup as Input**: Controls use Spectre markup (`[bold red]text[/]`) as a convenient authoring format |
| 338 | +2. **ANSI as Intermediate**: Spectre renders markup to ANSI strings, which `AnsiParser` converts to typed `Cell` structs (char + foreground + background) |
| 339 | +3. **Cells as Pipeline**: From that point, everything flows as cells through CharacterBuffer → ConsoleBuffer → terminal output |
| 340 | +4. **Any Spectre Widget**: `SpectreRenderableControl` wraps any `IRenderable` (Tables, Trees, Charts) as a window control |
325 | 341 |
|
326 | | -This architecture allows using Spectre's perfect rendering engine while adding features Spectre.Console doesn't provide: overlapping windows, Z-order management, independent window threads, and a complete event-driven UI system. |
| 342 | +ANSI exists only within the control paint phase — it never reaches the screen buffer. The unified cell pipeline ensures type-safe rendering from control to terminal, with no format conversions in the hot path. |
327 | 343 |
|
328 | 344 | ### Modern C# Features Used |
329 | 345 | - **Records**: Immutable data structures (WindowBounds, InputEvent, etc.) |
|
0 commit comments