CLIM mail archive


Recycle presentations

   Date: Thu, 19 Nov 92 07:33:20 PST
   From: Curt Eggemeyer <>

   Now that I got my recycling to work with output-records, is there a way
   to recycle presentations on the screen too?

Presentations are just a special sub-class of output record.  From the


(defclass presentation () ())

(defun-inline presentationp (object) (typep object 'presentation))

(defclass standard-presentation
	  (linear-output-record presentation)
     ((object :accessor presentation-object :initarg :object)
      (type :accessor presentation-type :initarg :type)
      (single-box :accessor presentation-single-box :initarg :single-box))
  (:default-initargs :size 5))


So, just make sure that you deal with the (de)initialization of the
presentation-specific slots.

The with-output-as-presentation macro just uses
with-new-output-record, so you can make a new version that uses your
with-new-output-record replacement.


(defmacro with-output-as-presentation ((&key object type stream modifier
					     single-box (allow-sensitive-inferiors t)
					     (record-type `'standard-presentation)
				       &body body)
  #+Genera (declare (zwei:indentation 0 3 1 1))
  (default-output-stream stream)
  ;; Maybe with-new-output-record should turn record-p on?
  (let ((nobject '#:object)			;(once-only (object type) ...)
	(ntype '#:type))
    `(with-output-recording-options (,stream :record-p t)
       (let ((,nobject ,object)
	     (,ntype ,type))
	 (with-new-output-record (,stream ,record-type nil
				  :object ,nobject
				  :type (if ,ntype
					    (expand-presentation-type-abbreviation ,ntype)
					    (presentation-type-of ,nobject))
				  :single-box ,single-box
				  :allow-sensitive-inferiors ,allow-sensitive-inferiors
				  ,@(when modifier `(:modifier ,modifier))
				  ,@(when parent `(:parent ,parent)))


And the PRESENT function just invokes the PRESENT method for the
presentation type inside a WITH-OUTPUT-AS-PRESENTATION (with some
added hair for type expansion).


(defun present (object &optional (presentation-type (presentation-type-of object))
		&key (stream *standard-output*) (view (stream-default-view stream))
		     (modifier nil) (acceptably nil)
		     (for-context-type presentation-type)
		     (single-box nil) (allow-sensitive-inferiors t)
		     (sensitive t) (record-type 'standard-presentation))

  ;; The arguments are allowed to be presentation type abbreviations
  (multiple-value-bind (expansion expanded)
      (expand-presentation-type-abbreviation presentation-type)
    (when expanded
      (when (eq for-context-type presentation-type)
	(setq for-context-type expansion))
      (setq presentation-type expansion)))
  (unless (eq for-context-type presentation-type)
    (multiple-value-bind (expansion expanded)
	(expand-presentation-type-abbreviation for-context-type)
      (when expanded
	(setq for-context-type expansion))))

  (unless (presentation-typep object presentation-type)
    (cerror "Use the type ~*~*~S instead"
	    "The object ~S is not of type ~S"
	    object presentation-type (class-name (class-of object))))

  ;; Make a presentation if desired, and call the type's present method to fill it in
  (if (and sensitive
	   ;; the right way to fix this is probably
	   ;; to make all the with-xxx macros turn into noops on non-window-streams, but
	   ;; this is easier and less expensive.
	   (extended-output-stream-p stream))
      (with-output-as-presentation (:stream stream
				    :object object
				    :type presentation-type
				    :modifier modifier
				    :single-box single-box
				    :allow-sensitive-inferiors allow-sensitive-inferiors
				    :record-type record-type)
	(call-presentation-generic-function present
	  object presentation-type stream view
	  :acceptably acceptably :for-context-type for-context-type))
      (call-presentation-generic-function present
	object presentation-type stream view
	:acceptably acceptably :for-context-type for-context-type)))



Main Index | Thread Index