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