Fixes from subagent review: - render-tests.lisp: added (in-suite box-suite) — tests were registered to default suite, never executed by runner - dirty-tests.lisp: same fix - cl-tui.asd: version 0.2.0 → 0.3.0 - render.lisp: component-children default method (c t) nil for protocol completeness (component-parent already had this)
67 lines
2.4 KiB
Common Lisp
67 lines
2.4 KiB
Common Lisp
(in-package :cl-tui.box)
|
|
|
|
;; ── Component Protocol ────────────────────────────────────────
|
|
|
|
(defgeneric component-layout-node (component)
|
|
(:documentation "Return the layout-node for COMPONENT.")
|
|
(:method ((bx box)) (box-layout-node bx))
|
|
(:method ((tx text)) (text-layout-node tx)))
|
|
|
|
(defgeneric component-children (component)
|
|
(:documentation "Return the children of COMPONENT, or nil.")
|
|
(:method ((c t)) nil))
|
|
|
|
(defgeneric component-parent (component)
|
|
(:documentation "Return the parent of COMPONENT, or nil.")
|
|
(:method ((c t)) nil))
|
|
|
|
;; ── Rendering Pipeline ────────────────────────────────────────
|
|
|
|
(defgeneric render (component backend)
|
|
(:documentation "Render COMPONENT at its computed position using BACKEND.")
|
|
(:method ((c t) backend)
|
|
(declare (ignore backend))
|
|
(values)))
|
|
|
|
(defmethod render ((bx box) backend)
|
|
(render-box bx backend))
|
|
|
|
(defmethod render ((tx text) backend)
|
|
(render-text tx backend))
|
|
|
|
(defun render-screen (root backend)
|
|
"Render the component tree ROOT using BACKEND.
|
|
Computes layout for dirty branches, calls render on each component,
|
|
and wraps output in synchronized updates."
|
|
(let ((w (available-width root))
|
|
(h (available-height root)))
|
|
(begin-sync backend)
|
|
(render-node root backend w h)
|
|
(end-sync backend)))
|
|
|
|
(defun render-node (node backend w h)
|
|
"Render a component NODE and its children."
|
|
(compute-layout (component-layout-node node) w h)
|
|
(render node backend)
|
|
(dolist (child (component-children node))
|
|
(render-node child backend w h)))
|
|
|
|
(defun available-width (component)
|
|
"Return the available width for COMPONENT (or 80 as default)."
|
|
(let ((ln (component-layout-node component)))
|
|
(if ln (layout-node-width ln) 80)))
|
|
|
|
(defun available-height (component)
|
|
"Return the available height for COMPONENT (or 24 as default)."
|
|
(let ((ln (component-layout-node component)))
|
|
(if ln (layout-node-height ln) 24)))
|
|
|
|
;; ── Dirty Propagation ─────────────────────────────────────────
|
|
|
|
(defun propagate-dirty (component)
|
|
"Mark COMPONENT and all ancestors dirty."
|
|
(mark-dirty component)
|
|
(let ((parent (component-parent component)))
|
|
(when parent
|
|
(propagate-dirty parent))))
|