====== TUI Engine ====== Arhitektura i zahtjevi kvalitete TUI Rendering Enginea. Ovi zahtjevi su **nepregovarajući** - definiraju minimalni standard za GUI-sličnu TUI-kvalitetu. ===== Zahtjevi kvalitete ===== ==== 1. Flicker-free Rendering ==== OBAVEZNO: - Double-Buffering s Diff-based Flushom - Dirty-Rect ili Run-Length Optimizacija - Nikakve Full-Screen Redraw Petlje **Zašto:** Flicker uništava korisničko iskustvo i čini TUI neupotrebljivim za profesionalne aplikacije. ==== 2. Deterministički Layout + Clipping ==== OBAVEZNO: - Implementirati Measure/Arrange/Paint Lifecycle - Clipati crtanje na dodijeljene Rectangles - Nikakve Out-of-Bounds pisanja ==== 3. Unicode-Korektnost ==== OBAVEZNO: - Pravilno rukovanje Wide Characters (East Asian Width) - Pravilno rukovanje Combining Marks - Pravilno izračunavanje Emoji-širine - Pozicioniranje Cursora mora biti Grapheme-aware **Problem:** "Drifting Caret" - Cursor se pomiče kod Wide Chars. **Rješenje:** Koristiti Grapheme-Cluster za izračun Cursora. ==== 4. Theme + State Layering ==== OBAVEZNO: - Podržati Style Tokens - Implementirati Layered States: Base → Hover (ako Mouse) → Focus → Pressed → Disabled → Error/Validation - Focus-Indikatori konzistentni preko svih Controls ==== 5. Input + Focus kao First-Class ==== OBAVEZNO: - Focus Navigation (Tab/Shift+Tab) - Deterministički Focus Ordering - Normalizirani Input Event Model: Keys, Text Input, Resize, opcionalni Mouse ==== 6. Performanse i Skaliranje ==== OBAVEZNO: - Virtualizacija za velike Surfaces (Tables/Logs/Trees) - Izbjegavati O(N) Repaint Offscreen Rows/Columns - Efikasno korištenje memorije ==== 7. Image-Support (SCADA/MES) ==== OBAVEZNO: - Implementirati Capability Detection - Fallback-lanac: 1. Kitty Graphics (preferirano) 2. Sixel 3. Placeholder (Frame + Caption + "image unavailable") ===== Engine-Komponente ===== ==== A) Terminal Capability Layer ==== 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; ==== B) Render Model: CellBuffer + DiffEngine ==== TCell = record Grapheme: string; (* Unicode Grapheme Cluster *) Fg: TColor; (* Foreground Color *) Bg: TColor; (* Background Color *) Attrs: TAttributes; (* Bold, Italic, Underline, itd. *) Link: string; (* Opcionalno: Hyperlink *) ImageRef: Integer; (* Opcionalno: 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; (* Ciljni Frame *) FFrontBuffer: TCellBuffer; (* Zadnji flushani Frame *) public procedure ComputeDiff(out ADirtyRects: TRectArray); procedure Flush(ATerminal: TTerminalIO); end; **Zahtjevi za DiffEngine:** * Minimalna pomicanja Cursora * Minimalne promjene Stylea * Stabilan kod brzog Resizea ==== C) Render Surface (Drawing API) ==== 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; **Važno:** Surface piše samo u BackBuffer, ne direktno u TerminalIO. ==== D) Layout Engine ==== Controls se aranžiraju u Rectove. Minimalni Containeri: - Stack (vertikalno/horizontalno) - Dock (Left, Top, Right, Bottom, Fill) - Grid (kasnije) - Overlay (za Popupe/Modale) ==== E) Widget/Control Rendering Contract ==== 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; ===== Testing ===== ==== Snapshot Testovi ==== OBAVEZNO: - Dumpati BackBuffer u stabilnu tekstualnu reprezentaciju - Usporediti s očekivanim izlazom ==== Unicode-Fixtures ==== OBAVEZNO: - Testovi s Wide Characters (中文, 日本語) - Testovi s Combining Marks (é = e + ´) - Testovi s Emoji (👍, 🎉) ==== Image-Fallback Testovi ==== OBAVEZNO: - Testirati Kitty → Sixel → Placeholder Fallback - Verificirati Capability Detection ===== Verifikacijska checklista ===== TUI Engine Verifikacija: Rendering: - [ ] Nema flickera pri ponovljenom Repaintu - [ ] Resize proizvodi stabilan Layout - [ ] Nema zaglavljenog Cursora - [ ] Nema polomljenog Clippinga Unicode: - [ ] Wide Characters ispravno pozicionirani - [ ] Combining Marks ispravno prikazani - [ ] Emoji-širina ispravna Performanse: - [ ] Table/List renderira 10k redaka sa Scrollom - [ ] Nema O(N) Repainta za Offscreen Images: - [ ] Kitty Graphics funkcionira (ako je podržano) - [ ] Sixel Fallback funkcionira - [ ] Placeholder kod nedostatka podrške ===== Vidi također ===== * [[.:tui-entwicklung|TUI-Razvoj Pregled]] * [[.:tui-controls|TUI Controls]] * [[.:tui-layout|TUI Layout]]