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

Zuletzt geändert: 29.01.2026. u 22:40