diff --git a/cl-tui.asd b/cl-tui.asd index e07c66a..d93fd8a 100644 --- a/cl-tui.asd +++ b/cl-tui.asd @@ -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!))) diff --git a/docs/ROADMAP.org b/docs/ROADMAP.org index c9d2bf0..ee91999 100644 --- a/docs/ROADMAP.org +++ b/docs/ROADMAP.org @@ -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 diff --git a/src/components/dirty-tests.lisp b/src/components/dirty-tests.lisp new file mode 100644 index 0000000..c6a4d56 --- /dev/null +++ b/src/components/dirty-tests.lisp @@ -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"))) diff --git a/src/components/dirty.lisp b/src/components/dirty.lisp new file mode 100644 index 0000000..0de9a9f --- /dev/null +++ b/src/components/dirty.lisp @@ -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))) diff --git a/src/components/package.lisp b/src/components/package.lisp index 8a3a6a7..e9b7ff9 100644 --- a/src/components/package.lisp +++ b/src/components/package.lisp @@ -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)