CLIM mail archive


Re: lack of :extend-width arg to clim:formatting-table

    Date: Thu, 2 Apr 1992 14:03 PST
    From: Scott McKay <>

	Date: Thu, 2 Apr 1992 16:47 EST
	From: "Meir Laker" <>

	3. Is the method I specify above (using a helper stream and bounding
	rectangle) a reasonable approach if I don't want to hack the
	clim:formatting-table code at the moment?

    I would find it easier to extend CLIM:TABLE-FORMATTING, but of course I
    am familiar with the code.  You might find it easier, too, but your
    approach is not unreasonable if you are willing to pay the performance

You don't really have to modify or extend the table-formatting
code to do this (although it would be more efficient if the
capability was "built-in" to table formatting).  In fact, you can
(almost) do it without resorting to any magic CLIM internals at

The following code shows how you can post-process a formatted
table to extend the columns across the full width of the window.
It only using one CLIM internal funciton, MAP-OVER-TABLE-COLUMNS.
See if it does what you want.

;;; -*- Mode: LISP; Syntax: Common-Lisp; Base: 10; Package: CLIM-USER -*-

;;; Make the columns of a table span the width of the window.
;;; Only works for column-oriented tables.
(defun column-extension (stream)
  (window-clear stream)
  ;; First, collect the table output record, containing the tree
  ;; of output records as formatted by the standard table-formtting
  ;; mechanism.  :DRAW-P NIL means that the table will not be
  ;; made visible yet.
  (let ((table (with-output-recording-options (stream :draw-p nil)
		 ;; A simple four-column, five-row table showing
		 ;; integer powers.
		 (formatting-table (stream)
		   (dotimes (exponent 4)
		     ;; Column-oriented.
		     (formatting-column (stream)
		       (dotimes (n 5)
			 (formatting-cell (stream :align-x :right)
			   (format stream "~D" (expt n (1+ exponent)))))))))))

    ;; Now call the column-shuffler
    (expand-table table stream)
    ;; Finally, show the re-aligned table.
    (replay table stream)

;;; Move the columns of a table so that they fill the full
;;; width of the window.
(defun expand-table (table stream)
  (let ((column-count 0))
    ;; Count the number of columns.
      #'(lambda (column)
	  (declare (ignore column))
	  (incf column-count)))
    ;; Now we know how much space to leave between columns.
    (let ((column-width (floor (window-inside-width stream) column-count))
	  (column-index 0))
      ;; Go over the columns again, relocating them.
	#'(lambda (column)
	    ;; New X position, same Y
	    (multiple-value-bind (x y) (output-record-position* column)
	      (declare (ignore x))
	      (output-record-set-position* column (* column-index column-width) y))
	    (incf column-index))))))

;;; A macro to wrap around table-formatting code that expands
;;; the columns to fit.
(defmacro with-columns-extended ((stream) &body body)
  (let ((table-var (gensym)))
    `(let ((,table-var (with-output-recording-options (,stream :draw-p nil)
           (expand-table ,table-var ,stream)
	   (replay ,table-var ,stream))))

;;; An example, using the same table from the first example
(defun column-extension-easy (stream)
  (with-columns-extended (stream)
    ;; A simple four-column, five-row table showing
    ;; integer powers.
    (formatting-table (stream)
      (dotimes (exponent 4)
	;; Column-oriented.
	(formatting-column (stream)
	  (dotimes (n 5)
	    (formatting-cell (stream :align-x :right)
	      (format stream "~D" (expt n (1+ exponent))))))))))


Main Index | Thread Index