====== 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]]