;;; demo.lisp — cl-tty demo application ;;; Run: sbcl --script demo.lisp (load "~/quicklisp/setup.lisp") (ql:register-local-projects) (ql:quickload :cl-tty :silent t) (in-package :cl-tty) ;; ─── Helper: write a string at (x, y) with optional styling ──────────────── (defun write-at (backend x y string &key fg bg bold) (let ((styled (if bold (format nil "~c[1m~a~c[0m" #\Esc string #\Esc) string))) (backend-write backend x y styled fg bg))) ;; ─── Demo ─────────────────────────────────────────────────────────────────── (defun run-demo () (let* ((backend (make-instance 'cl-tty.backend:modern-backend)) (w 80) (h 24)) ;; Initialize (initialize-backend backend) (clear-screen backend) (backend-write backend 0 0 (format nil "~c[?25l" #\Esc)) ; hide cursor ;; Title box (draw-border backend 1 1 78 3 :double :title " cl-tty Demo ") (write-at backend 3 2 "A pure-CL terminal UI framework. No ncurses, no FFI." :bold t) ;; Feature grid (draw-border backend 1 5 78 12 :single :title " Components ") (let ((items '((" Box Bordered containers with title and background" " Text Styled text with word-wrap and spans") (" ScrollBox Scrollable viewport with scrollbars" " TabBar Horizontal tab navigation") (" Select Dropdown with fuzzy filter" " TextInput / TextArea Single/multi-line input with undo") (" Markdown Renders markdown with syntax highlighting" " Dialog / Toast Modal overlays and notifications") (" Mouse Event handlers and text selection" " Slot System Named slots for extensible UI")))) (loop for i from 0 below 5 for (col1 col2) = (nth i items) do (write-at backend 3 (+ 7 i) col1) (write-at backend 42 (+ 7 i) col2))) ;; Backend features table (draw-border backend 1 18 78 5 :single :title " Backend Support ") (write-at backend 3 20 "Feature" :bold t) (write-at backend 25 20 "modern" :bold t) (write-at backend 40 20 "simple" :bold t) (write-at backend 3 21 "Truecolor (24-bit)") (write-at backend 25 21 "yes") (write-at backend 40 21 "no") (write-at backend 3 22 "OSC 8 hyperlinks") (write-at backend 25 22 "yes") (write-at backend 40 22 "no") ;; Footer (write-at backend 1 24 " Press q to quit " :bold t :fg :white :bg :blue) (backend-write backend 0 0 (format nil "~c[?25h" #\Esc)) ; show cursor ;; Wait for q (loop (let ((ch (read-raw-byte :timeout 1))) (when ch (when (or (char= (code-char ch) #\q) (= ch 3)) ; Ctrl+C (return))))) ;; Cleanup (clear-screen backend) (shutdown-backend backend))) ;; ─── Run ──────────────────────────────────────────────────────────────────── (when (probe-file "/dev/tty") (run-demo))