Architecture and quality requirements for the TUI rendering engine.
REQUIRED: - Double-buffering with diff-based flush - Dirty-rect or run-length optimization - No full-screen redraw loops
Why: Flicker destroys user experience and makes TUI unusable for professional applications.
REQUIRED: - Implement Measure/Arrange/Paint lifecycle - Clip drawing to assigned rectangles - No out-of-bounds write operations
REQUIRED: - Handle wide characters (East Asian Width) correctly - Handle combining marks correctly - Calculate emoji width correctly - Cursor positioning must be grapheme-aware
Problem: „Drifting caret“ - cursor wanders with wide chars.
Solution: Use grapheme clusters for cursor calculation.
REQUIRED: - Support style tokens - Implement layered states: Base → Hover (if mouse) → Focus → Pressed → Disabled → Error/Validation - Consistent focus indicators across all controls
REQUIRED: - Focus navigation (Tab/Shift+Tab) - Deterministic focus ordering - Normalized input event model: Keys, text input, resize, optional mouse
REQUIRED: - Virtualization for large surfaces (tables/logs/trees) - Avoid O(N) repaint of offscreen rows/columns - Efficient memory usage
REQUIRED: - Implement capability detection - Fallback chain: 1. Kitty Graphics (preferred) 2. Sixel 3. Placeholder (frame + caption + "image unavailable")
TTerminalCaps = record SupportsAnsi: Boolean; SupportsAltScreen: Boolean; SupportsTrueColor: Boolean; Supports256Color: Boolean; SupportsMouse: Boolean; SupportsKittyGraphics: Boolean; SupportsSixel: Boolean; SupportsUnicodeWidth: Boolean; end; TTerminalIO = class procedure EnterAltScreen; procedure ExitAltScreen; procedure ShowCursor; procedure HideCursor; procedure WriteEscapeSequence(const ASeq: string); procedure WriteTextRun(const AText: string); procedure MoveCursor(AX, AY: Integer); procedure SetStyle(AStyle: TStyle); procedure BatchFlush; end;
TCell = record Grapheme: string; (* Unicode Grapheme Cluster *) Fg: TColor; (* Foreground Color *) Bg: TColor; (* Background Color *) Attrs: TAttributes; (* Bold, Italic, Underline, etc. *) Link: string; (* Optional: Hyperlink *) ImageRef: Integer; (* Optional: Image Reference *) end; TCellBuffer = class private FCells: array of array of TCell; FWidth, FHeight: Integer; public procedure SetCell(AX, AY: Integer; const ACell: TCell); function GetCell(AX, AY: Integer): TCell; procedure Clear; procedure Resize(AWidth, AHeight: Integer); end;
DiffEngine:
TDiffEngine = class private FBackBuffer: TCellBuffer; (* Target frame *) FFrontBuffer: TCellBuffer; (* Last flushed frame *) public procedure ComputeDiff(out ADirtyRects: TRectArray); procedure Flush(ATerminal: TTerminalIO); end;
DiffEngine Requirements:
TRenderSurface = class private FBuffer: TCellBuffer; FClipStack: TRectStack; public procedure FillRect(ARect: TRect; AChar: Char; AStyle: TStyle); procedure DrawText(AX, AY: Integer; const AText: string; AStyle: TStyle); procedure DrawBorder(ARect: TRect; ABorderStyle: TBorderStyle); procedure DrawImage(ARect: TRect; AImageRef: Integer); procedure ClipPush(ARect: TRect); procedure ClipPop; end;
Important: Surface writes only to BackBuffer, not directly to TerminalIO.
Controls are arranged into rects. Minimum Containers: - Stack (vertical/horizontal) - Dock (Left, Top, Right, Bottom, Fill) - Grid (later) - Overlay (for popups/modals)
IWvdSTUIRenderer = interface function Measure(AControl: TWvdSControl; AAvailable: TSize): TSize; procedure Arrange(AControl: TWvdSControl; ARect: TRect); procedure Paint(AControl: TWvdSControl; ASurface: TRenderSurface); function HandleInput(AControl: TWvdSControl; AEvent: TInputEvent): Boolean; end;
REQUIRED: - Dump BackBuffer to stable text representation - Compare with expected output
REQUIRED: - Tests with wide characters (Chinese, Japanese) - Tests with combining marks (e + accent) - Tests with emoji
REQUIRED: - Test Kitty → Sixel → Placeholder fallback - Verify capability detection
TUI Engine Verification: Rendering: - [ ] No flicker during repeated repaint - [ ] Resize produces stable layout - [ ] No stuck cursor - [ ] No broken clipping Unicode: - [ ] Wide characters positioned correctly - [ ] Combining marks displayed correctly - [ ] Emoji width correct Performance: - [ ] Table/List renders 10k rows with scroll - [ ] No O(N) repaint for offscreen Images: - [ ] Kitty Graphics works (if supported) - [ ] Sixel fallback works - [ ] Placeholder when no support