fix: distribute-sizes rounding remainder, render-screen uses backend-size
This commit is contained in:
@@ -76,7 +76,8 @@
|
|||||||
"Compute child sizes given available space and gap.
|
"Compute child sizes given available space and gap.
|
||||||
HORIZONTAL is non-nil when distributing width (row layout).
|
HORIZONTAL is non-nil when distributing width (row layout).
|
||||||
Each child starts from its fixed size (if any). Remaining space
|
Each child starts from its fixed size (if any). Remaining space
|
||||||
is distributed by grow ratio; overflow is reduced by shrink ratio."
|
is distributed by grow ratio; overflow is reduced by shrink ratio.
|
||||||
|
Rounding errors are amortized across the first N children."
|
||||||
(let* ((n (length children))
|
(let* ((n (length children))
|
||||||
(gap-total (* gap (max 0 (1- n))))
|
(gap-total (* gap (max 0 (1- n))))
|
||||||
(base (mapcar (lambda (c)
|
(base (mapcar (lambda (c)
|
||||||
@@ -89,7 +90,7 @@ is distributed by grow ratio; overflow is reduced by shrink ratio."
|
|||||||
(remaining (- avail base-total gap-total))
|
(remaining (- avail base-total gap-total))
|
||||||
(grow-total (reduce #'+ (mapcar #'layout-node-grow children)))
|
(grow-total (reduce #'+ (mapcar #'layout-node-grow children)))
|
||||||
(shrink-total (reduce #'+ (mapcar #'layout-node-shrink children))))
|
(shrink-total (reduce #'+ (mapcar #'layout-node-shrink children))))
|
||||||
(mapcar (lambda (c b)
|
(let ((sizes (mapcar (lambda (c b)
|
||||||
(let ((sz b))
|
(let ((sz b))
|
||||||
(when (and (plusp remaining) (plusp grow-total))
|
(when (and (plusp remaining) (plusp grow-total))
|
||||||
(incf sz (round (* remaining (/ (layout-node-grow c) grow-total)))))
|
(incf sz (round (* remaining (/ (layout-node-grow c) grow-total)))))
|
||||||
@@ -97,6 +98,17 @@ is distributed by grow ratio; overflow is reduced by shrink ratio."
|
|||||||
(decf sz (round (* (abs remaining) (/ (layout-node-shrink c) shrink-total)))))
|
(decf sz (round (* (abs remaining) (/ (layout-node-shrink c) shrink-total)))))
|
||||||
(max 1 sz)))
|
(max 1 sz)))
|
||||||
children base)))
|
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))))
|
||||||
|
(when (/= delta 0)
|
||||||
|
(loop :for i :from 0 :below (min (abs delta) n)
|
||||||
|
:do (incf (nth i sizes) (signum delta))))))
|
||||||
|
sizes)))
|
||||||
|
|
||||||
(defun compute-layout (root available-width available-height)
|
(defun compute-layout (root available-width available-height)
|
||||||
"Layout all children of ROOT within the given dimensions.
|
"Layout all children of ROOT within the given dimensions.
|
||||||
|
|||||||
@@ -32,9 +32,9 @@
|
|||||||
(defun render-screen (root backend)
|
(defun render-screen (root backend)
|
||||||
"Render the component tree ROOT using BACKEND.
|
"Render the component tree ROOT using BACKEND.
|
||||||
Computes layout for dirty branches, calls render on each component,
|
Computes layout for dirty branches, calls render on each component,
|
||||||
and wraps output in synchronized updates."
|
and wraps output in synchronized updates. Uses the actual terminal
|
||||||
(let ((w (available-width root))
|
dimensions from BACKEND rather than hardcoded defaults."
|
||||||
(h (available-height root)))
|
(multiple-value-bind (w h) (backend-size backend)
|
||||||
(begin-sync backend)
|
(begin-sync backend)
|
||||||
(render-node root backend w h)
|
(render-node root backend w h)
|
||||||
(end-sync backend)))
|
(end-sync backend)))
|
||||||
|
|||||||
Reference in New Issue
Block a user