(in-package :cl-tui.box) (defclass box () ((layout-node :initform (make-layout-node) :accessor box-layout-node :initarg :layout-node) (border-style :initform :single :initarg :border-style :accessor box-border-style) (title :initform nil :initarg :title :accessor box-title) (title-align :initform :left :initarg :title-align :accessor box-title-align) (fg :initform nil :initarg :fg :accessor box-fg) (bg :initform nil :initarg :bg :accessor box-bg))) (defun make-box (&key (border-style :single) title (title-align :left) fg bg width height) (make-instance 'box :border-style border-style :title title :title-align title-align :fg fg :bg bg :layout-node (make-layout-node :width width :height height :direction :column))) (defun render-box (box backend) "Render BOX at its computed layout position using BACKEND." (let ((ln (box-layout-node box)) (bs (box-border-style box)) (title (box-title box)) (fg (box-fg box)) (bg (box-bg box))) (let ((x (layout-node-x ln)) (y (layout-node-y ln)) (w (layout-node-width ln)) (h (layout-node-height ln))) (when (or (zerop w) (zerop h) (< w 2) (< h 2)) (return-from render-box (values))) (when bg (draw-rect backend x y w h :bg bg)) (when bs (draw-border backend x y w h :style bs :fg fg :bg bg)) (when title (let* ((content-w (- w 4)) (tx (+ x 2)) (ty (+ y (if bs 1 0))) (ta (box-title-align box)) (display (subseq title 0 (min (length title) content-w)))) (case ta (:center (draw-text backend (+ x (ceiling (- w (length display)) 2)) ty display fg bg)) (:right (draw-text backend (+ x (- w (length display) 2)) ty display fg bg)) (t (draw-text backend tx ty display fg bg))))))))