literate: convert org/layout-engine.org from doc-only to tangle source
Now tangles to layout.lisp + layout/tests.lisp. Deleted hand-written originals and regenerated — GREEN.
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
;;; layout — Pure CL Flexbox layout engine
|
||||
|
||||
(defpackage :cl-tty.layout
|
||||
(:use :cl)
|
||||
(:export
|
||||
@@ -15,7 +13,6 @@
|
||||
#:layout-node-parent #:layout-node-fixed-width
|
||||
#:layout-node-fixed-height #:normalize-box
|
||||
#:box-edge))
|
||||
|
||||
(in-package :cl-tty.layout)
|
||||
|
||||
(defun normalize-box (spec)
|
||||
@@ -70,14 +67,7 @@
|
||||
(delete child (layout-node-children parent)))
|
||||
child)
|
||||
|
||||
;; ── Solver ─────────────────────────────────────────────────────
|
||||
|
||||
(defun distribute-sizes (children avail gap horizontal)
|
||||
"Compute child sizes given available space and gap.
|
||||
HORIZONTAL is non-nil when distributing width (row layout).
|
||||
Each child starts from its fixed size (if any). Remaining space
|
||||
is distributed by grow ratio; overflow is reduced by shrink ratio.
|
||||
Rounding errors are amortized across the first N children."
|
||||
(let* ((n (length children))
|
||||
(gap-total (* gap (max 0 (1- n))))
|
||||
(base (mapcar (lambda (c)
|
||||
@@ -98,10 +88,6 @@ Rounding errors are amortized across the first N children."
|
||||
(decf sz (round (* (abs remaining) (/ (layout-node-shrink c) shrink-total)))))
|
||||
(max 1 sz)))
|
||||
children base)))
|
||||
;; Distribute rounding remainder to first N children so that
|
||||
;; the total of sizes exactly fills avail minus gap-total.
|
||||
;; Only correct when grow or shrink was actually applied —
|
||||
;; otherwise children keep their fixed sizes and may not fill space.
|
||||
(when (or (and (plusp remaining) (plusp grow-total))
|
||||
(and (minusp remaining) (plusp shrink-total)))
|
||||
(let ((delta (- avail gap-total (reduce #'+ sizes))))
|
||||
@@ -111,8 +97,6 @@ Rounding errors are amortized across the first N children."
|
||||
sizes)))
|
||||
|
||||
(defun compute-layout (root available-width available-height)
|
||||
"Layout all children of ROOT within the given dimensions.
|
||||
Recursively computes position and size for every node."
|
||||
(labels ((place-children (node x y max-w max-h)
|
||||
(let* ((children (layout-node-children node))
|
||||
(is-row (eql (layout-node-direction node) :row))
|
||||
@@ -124,10 +108,8 @@ Recursively computes position and size for every node."
|
||||
(ch (max 0 (- max-h pt pb)))
|
||||
(gap (layout-node-gap node))
|
||||
(sizes (distribute-sizes children (if is-row cw ch) gap is-row)))
|
||||
;; Position the node (content area starts at padding inset)
|
||||
(setf (layout-node-x node) (+ x pl)
|
||||
(layout-node-y node) (+ y pt))
|
||||
;; Place each child sequentially
|
||||
(loop :with pos = 0
|
||||
:for child :in children
|
||||
:for size :in sizes
|
||||
@@ -146,7 +128,6 @@ Recursively computes position and size for every node."
|
||||
(if is-row size cw)
|
||||
(if is-row ch size))
|
||||
(incf pos (+ size gap)))
|
||||
;; Compute own size from children
|
||||
(let ((last-child (car (last children))))
|
||||
(if is-row
|
||||
(setf (layout-node-width node)
|
||||
@@ -170,8 +151,6 @@ Recursively computes position and size for every node."
|
||||
(place-children root 0 0 available-width available-height)
|
||||
root))
|
||||
|
||||
;; ── Macros ─────────────────────────────────────────────────────
|
||||
|
||||
(defmacro vbox ((&key grow shrink padding margin gap width height) &body children)
|
||||
(let ((n (gensym)))
|
||||
`(let ((,n (make-layout-node :direction :column
|
||||
|
||||
Reference in New Issue
Block a user