v0.2.0: Box and Text renderables + dirty tracking #3

Merged
amr merged 4 commits from feature/v0.2.0-box-and-text into main 2026-05-11 22:02:21 -04:00
5 changed files with 56 additions and 6 deletions
Showing only changes of commit a1b1352d10 - Show all commits

View File

@@ -18,6 +18,7 @@
(:module "src/components"
:components
((:file "package")
(:file "dirty")
(:file "box" :depends-on ("package"))
(:file "text" :depends-on ("package" "box")))))
:in-order-to ((test-op (test-op :cl-tui-tests))))
@@ -34,6 +35,7 @@
((:file "tests")))
(:module "src/components"
:components
((:file "box-tests"))))
((:file "box-tests")
(:file "dirty-tests"))))
:perform (test-op (o c)
(uiop:symbol-call :cl-tui-backend-test '#:run!)))

View File

@@ -157,11 +157,14 @@ The first two renderable types that every application uses. A Box draws borders
and backgrounds. A Text renders strings with color and style. Together they
cover 80% of terminal UI.
*** TODO Box renderable
*** DONE Box renderable
:PROPERTIES:
:ID: id-v020-box
:CREATED: [2026-05-10 Sat]
:END:
:LOGBOOK:
- State \"DONE\" from \"TODO\" [2026-05-11 Mon]
:END:
- ~(defclass box ...)~ — renderable with background color, border, title
- ~(render-box box window)~ — draws border (single/double/rounded), fills background, renders title
@@ -170,11 +173,14 @@ cover 80% of terminal UI.
- ~:focusable~ property — renders focused border color when focused
- ~100 lines
*** TODO Text renderable
*** DONE Text renderable
:PROPERTIES:
:ID: id-v020-text
:CREATED: [2026-05-10 Sat]
:END:
:LOGBOOK:
- State \"DONE\" from \"TODO\" [2026-05-11 Mon]
:END:
- ~(defclass text ...)~ — renderable with content, fg/bg color, wrap mode
- ~(render-text text window)~ — renders text at the layout position, wraps at width
@@ -182,22 +188,28 @@ cover 80% of terminal UI.
- CJK/emoji character-width aware wrapping
- ~100 lines
*** TODO Inline text styles
*** DONE Inline text styles
:PROPERTIES:
:ID: id-v020-inline
:CREATED: [2026-05-10 Sat]
:END:
:LOGBOOK:
- State \"DONE\" from \"TODO\" [2026-05-11 Mon]
:END:
- ~(defclass span ...)~ — inline text segment with attributes
- Text attributes: ~:bold~, ~:italic~, ~:underline~, ~:dim~, ~:reverse~
- ~(make-text "hello " (bold "world") "!")~ — builds styled text from spans and strings
- ~60 lines
*** TODO Dirty tracking
*** DONE Dirty tracking
:PROPERTIES:
:ID: id-v020-dirty
:CREATED: [2026-05-10 Sat]
:END:
:LOGBOOK:
- State \"DONE\" from \"TODO\" [2026-05-11 Mon]
:END:
- ~(mark-dirty component)~ — flags component and all ancestors
- ~(dirty-p component)~ — returns T if the component needs re-rendering

View File

@@ -0,0 +1,20 @@
;; Dirty tracking tests are in box-tests.lisp (same test suite)
(in-package :cl-tui-box-test)
(test dirty-mixin-default-is-dirty
"A dirty-mixin starts as dirty"
(let ((c (make-instance 'dirty-mixin)))
(is-true (dirty-p c) "new component should be dirty")))
(test mark-clean-clears-dirty
"mark-clean sets dirty to nil"
(let ((c (make-instance 'dirty-mixin)))
(mark-clean c)
(is-false (dirty-p c) "after mark-clean, should not be dirty")))
(test mark-dirty-sets-dirty
"mark-dirty sets dirty to t"
(let ((c (make-instance 'dirty-mixin)))
(mark-clean c)
(mark-dirty c)
(is-true (dirty-p c) "after mark-dirty, should be dirty again")))

14
src/components/dirty.lisp Normal file
View File

@@ -0,0 +1,14 @@
(in-package :cl-tui.box)
;; ── Dirty Tracking ─────────────────────────────────────────────
(defclass dirty-mixin ()
((dirty :initform t :accessor dirty-p)))
(defgeneric mark-clean (component)
(:method ((c dirty-mixin))
(setf (dirty-p c) nil)))
(defgeneric mark-dirty (component)
(:method ((c dirty-mixin))
(setf (dirty-p c) t)))

View File

@@ -17,5 +17,7 @@
#:text-fg #:text-bg #:text-wrap-mode
#:render-text
;; Utilities (for tests)
#:word-wrap #:split-string))
#:word-wrap #:split-string
;; Dirty tracking
#:dirty-mixin #:dirty-p #:mark-clean #:mark-dirty))
(in-package :cl-tui.box)