;;; win-alg.el --- Window size computation ;; ;; Author: Lennart Borgman (lennart O borgman A gmail O com) ;; Created: 2009-08-12 Wed ;; Version: 0.1 ;; Last-Updated: 2009-08-12 Wed ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;; Code: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Window creation etc ;;(defun wa-make-window (width wmin wmax height hmin hmax) (defun wa-make-window (name width wmin wmax) (list (list 'name name) ;; Easier communication ... (list 'child nil) ;; Child (list 'size width wmin wmax) ;; Actual values (list 'compsize nil nil) ;; Slot for computation, wmin wmax )) ;; Fix-me: Make defmacro to make those getters setters... - including ;; checks... (defun wa-name (window) (nth 1 (nth 0 window))) (defun wa-child (window) (nth 1 (nth 1 window))) (defun wa-width (window) (nth 1 (nth 2 window))) (defun wa-wmin (window) (nth 2 (nth 2 window))) (defun wa-wmax (window) (nth 3 (nth 2 window))) (defun wa-wcmin (window) (nth 1 (nth 3 window))) (defun wa-wcmax (window) (nth 2 (nth 3 window))) (defun wa-set-name (window name) (setcar (nthcdr 1 (nth 0 window)) name)) (defun wa-set-child (window child) (setcar (nthcdr 1 (nth 1 window)) child)) (defun wa-set-width (window width) (setcar (nthcdr 1 (nth 2 window)) width)) (defun wa-set-wmin (window wmin) (setcar (nthcdr 2 (nth 2 window)) wmin)) (defun wa-set-wmax (window wmax) (setcar (nthcdr 3 (nth 2 window)) wmax)) (defun wa-set-wcmin (window wmin) (setcar (nthcdr 1 (nth 3 window)) wmin)) (defun wa-set-wcmax (window wmax) (setcar (nthcdr 2 (nth 3 window)) wmax)) (defun wa-check-fit (win) (let ((wmin (wa-wmin win)) (wmax (wa-wmax win)) (wcmin (wa-wcmin win)) (wcmax (wa-wcmax win))) (when (and wmax wcmin) (unless (<= wcmin wmax) (error "Window %s is too small, min=%d, but can be max=%d" (wa-name win) wcmin wmax))) (when (and wcmax wmin) (unless (<= wcmax wmin) (error "Window %s's childs are too small, max=%d, but can be min=%d" (wa-name win) wcmax wmin))))) (defvar wa-root-window nil) (defun wa-set-child-windows (parent vertical &rest sizes) (dolist (s sizes) (assert (= 3 (length s)) t)) (let* ((tot-given (apply '+ (mapcar (lambda (s) (car s)) (cdr sizes)))) (par-size (if vertical (wa-width parent) (wa-height parent))) ;;(par-other-size (if vertical (wa-height parent) (wa-width parent))) (real-sizes (copy-sequence sizes)) children (num 0)) (setcar (nth 1 real-sizes) (- par-size tot-given)) (setq children (mapcar (lambda (size) (setq num (1+ num)) (if vertical (wa-make-window (format "%s-%d" (wa-name parent) num) (nth 0 size) (nth 1 size) (nth 2 size)) ;;(wa-make-window size par-other-size) )) real-sizes)) (wa-set-child parent children))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Computation of sizes (defun wa-clear-computed (win) (wa-set-wcmin win nil) (wa-set-wcmax win nil) (dolist (c (wa-child win)) (wa-clear-computed c))) (defun wa-compute-required (win) (let ((wmin (wa-wmin win)) (wmax (wa-wmax win)) (cmin 0) (cmax -1) ) (dolist (c (wa-child win)) (let* ((res (wa-compute-required c)) (res-min (nth 0 res)) (res-max (nth 1 res))) ;; Just sum the MIN (when res-min (setq cmin (+ cmin res-min))) (if res-max ;; ... ok, let us sum MAX to see how big we can be ... (if (numberp cmax) (setq cmax (+ cmax res-max)) (setq cmax res-max)) ;; Hurray, at least one child can grow! (setq cmax nil)) )) (when (and cmax (< cmax 0)) (setq cmax nil)) ;; There was no max, ie no childs (when wmin (setq cmin (max wmin cmin))) (wa-set-wcmin win cmin) (wa-set-wcmax win cmax) (wa-check-fit win) (list (wa-wcmin win) (wa-wcmax win)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Testing part (defun wa-add-test-childs () (wa-set-child-windows wa-root-window t '(nil nil nil) '(5 4 nil) '(8 nil nil) '(4 3 nil) )) (setq wa-root-window (wa-make-window "Root" 80 nil nil)) (setq wa-root-window (wa-make-window "Root" 80 nil 8)) (setq wa-root-window (wa-make-window "Root" 80 nil 6)) (setq wa-root-window (wa-make-window "Root" 80 5 nil)) (setq wa-root-window (wa-make-window "Root" 80 15 nil)) ;; (wa-child wa-root-window) ;; (wa-width wa-root-window) ;; (wa-wmin wa-root-window) ;; (wa-wmax wa-root-window) ;; (wa-clear-computed wa-root-window) (wa-add-test-childs) (wa-compute-required wa-root-window) (describe-variable 'wa-root-window) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; win-alg.el ends here