====== TUI Engine ======
Arhitektura in zahteve kakovosti TUI izrisovalnega motorja.
Te zahteve so **neizpogajljive** - določajo minimalni standard za kakovost TUI podobno GUI.
===== Zahteve kakovosti =====
==== 1. Izrisovanje brez utripanja ====
OBVEZNO:
- Dvojno medpomnenje z diferenčnim izpiranjem
- Optimizacija umazanih pravokotnikov ali stiskanja zaporedij
- Brez popolnih ponovnih izrisov zaslona v zanki
**Zakaj:** Utripanje uničuje uporabniško izkušnjo in naredi TUI neuporaben za profesionalne aplikacije.
==== 2. Deterministična razporeditev + obrezovanje ====
OBVEZNO:
- Implementiran življenjski cikel Measure/Arrange/Paint
- Risanje obrezano na dodeljene pravokotnike
- Brez pisanja izven meja
==== 3. Pravilnost Unicode ====
OBVEZNO:
- Pravilno ravnanje s širokimi znaki (East Asian Width)
- Pravilno ravnanje s kombinirnimi oznakami
- Pravilno izračunavanje širine emojijev
- Pozicioniranje kurzorja mora upoštevati grafeme
**Problem:** "Plavajoči kazalec" - kurzor drsi pri širokih znakih.
**Rešitev:** Uporaba grafemskih grozdov za izračun kurzorja.
==== 4. Tema + plastenje stanj ====
OBVEZNO:
- Podpora žetonom slogov
- Implementirana plast stanj:
Base → Hover (če miška) → Focus → Pressed → Disabled → Error/Validation
- Indikatorji fokusa konsistentni čez vse kontrole
==== 5. Vnos + fokus kot prvovrstna ====
OBVEZNO:
- Navigacija s fokusom (Tab/Shift+Tab)
- Deterministično urejanje fokusa
- Normaliziran model vnosnih dogodkov:
Tipke, vnos besedila, sprememba velikosti, opcijska miška
==== 6. Zmogljivost in skaliranje ====
OBVEZNO:
- Virtualizacija za velike površine (tabele/dnevniki/drevesa)
- Izogibanje O(N) ponovnemu izrisovanju vrstic/stolpcev izven zaslona
- Učinkovita poraba pomnilnika
==== 7. Podpora slik (SCADA/MES) ====
OBVEZNO:
- Implementirano zaznavanje zmogljivosti
- Nadomestna veriga:
1. Kitty Graphics (prednostno)
2. Sixel
3. Nadomestek (okvir + napis + "slika ni na voljo")
===== Gradniki motorja =====
==== A) Plast zmogljivosti terminala ====
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) Model izrisovanja: CellBuffer + DiffEngine ====
TCell = record
Grapheme: string; (* Unicode grafemski grozd *)
Fg: TColor; (* Barva ospredja *)
Bg: TColor; (* Barva ozadja *)
Attrs: TAttributes; (* Krepko, ležeče, podčrtano, itd. *)
Link: string; (* Opcijsko: hiperpovezava *)
ImageRef: Integer; (* Opcijsko: referenca slike *)
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 okvir *)
FFrontBuffer: TCellBuffer; (* Zadnji izpran okvir *)
public
procedure ComputeDiff(out ADirtyRects: TRectArray);
procedure Flush(ATerminal: TTerminalIO);
end;
**Zahteve za DiffEngine:**
* Minimalni premiki kurzorja
* Minimalne menjave slogov
* Stabilnost pri hitri spremembi velikosti
==== C) Izrisovalna površina (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;
**Pomembno:** Surface piše samo v BackBuffer, ne neposredno v TerminalIO.
==== D) Motor razporeditve ====
Kontrole se razporedijo v pravokotnike.
Minimalni vsebniki:
- Stack (navpično/vodoravno)
- Dock (Left, Top, Right, Bottom, Fill)
- Grid (kasneje)
- Overlay (za pojavna okna/modalna okna)
==== E) Pogodba za izrisovanje gradnikov/kontrol ====
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;
===== Testiranje =====
==== Testi posnetkov ====
OBVEZNO:
- Izpis BackBuffer v stabilno tekstovno predstavitev
- Primerjava s pričakovanim izhodom
==== Unicode testni primeri ====
OBVEZNO:
- Testi s širokimi znaki (中文, 日本語)
- Testi s kombinirnimi oznakami (é = e + ´)
- Testi z emojiji (👍, 🎉)
==== Testi nadomestkov za slike ====
OBVEZNO:
- Testiranje nadomestne verige Kitty → Sixel → Placeholder
- Preverjanje zaznavanja zmogljivosti
===== Kontrolni seznam preverjanja =====
Preverjanje TUI Engine:
Izrisovanje:
- [ ] Brez utripanja pri ponavljajočem se ponovnem izrisovanju
- [ ] Sprememba velikosti proizvede stabilen razpored
- [ ] Brez obtičanega kurzorja
- [ ] Brez prekinjenega obrezovanja
Unicode:
- [ ] Široki znaki pravilno pozicionirani
- [ ] Kombinirne oznake pravilno prikazane
- [ ] Širina emojijev pravilna
Zmogljivost:
- [ ] Table/List izrisuje 10k vrstic z drsenjem
- [ ] Brez O(N) ponovnega izrisovanja za izven zaslona
Slike:
- [ ] Kitty Graphics deluje (če podprto)
- [ ] Sixel nadomestek deluje
- [ ] Nadomestek pri manjkajoči podpori
===== Glejte tudi =====
* [[.:tui-entwicklung|Pregled TUI razvoja]]
* [[.:tui-controls|TUI Controls]]
* [[.:tui-layout|TUI Layout]]