CLIM mail archive

[Prev][Next][Index][Thread]

Redisplay of a changing (and growing) list



    Date: Mon, 6 Jan 1992 21:31+0200
    From: "William (Bill" <waarbau@tycho.ncsc.mil>, "Arbaugh)"@BBN.COM


    I'm using:
    (Genera 8.1.1, Clim 27.5)

    Does anyone know how to use incremental redisplay with a list
    that not only will be changing (items exchanging places) but
    is also growing inside an application frame?  For example, this
    works in a CLIM window (modified example from documentation):

	    (defun test (stream)
	      (let* ((list (list 1 2 3 4 5))
		     (record
		      (updating-output (stream)
			(do* ((elements list (cdr elements))
			      (count 0 (1+ count))
			      (element (first elements)(first elements)))
			     ((null elements))
			    (updating-output (stream :unique-id count
						     :cache-value element)
			      (format stream "Element ~D" element)
			      (terpri stream))))))
		    (sleep 3)
		    (setq list (append list (list 6)))
		    (redisplay record stream)
		    (setq list (append list (list 7)))
		    (sleep 3)
		    (redisplay record stream)))


    However when I modify it to "work" with an application frame, each
    new item appears but the old ones disappear!  Here's the jest of the code:

	    (define-application-frame test ()
		    ((pane-list :initform (list 1 2 3 4 5)
				:accessor pane-list)
		     (pane-rec  :accessor pane-rec))
		    ...
		    (:panes ((display-pane  :application
					    :display-after-commands T
					    :display-function 'draw-display
					    :scroll-bars :vertical
					    :end-of-page-action :scroll)
			    ...))
		    ...
	    )

	    ;; initialize the output record for our pane
	    (defmethod run-frame-top-level :before ((frame test))
	      (with-slots (pane-list) frame
		(let ((stream (get-frame-pane frame 'display-pane)))
		    (setf (pane-rec frame)
			  (updating-output (stream)
			    (do* ((elements (pane-list frame)(cdr elements))
				  (count 0 (1+ count))
				  (element (first elements)(first elements)))
				 ((null elements))
		    e test) stream)
	      (redisplay (pane-rec frame) stream))

	    ;; define a command to add items to the list
	    (define-test-command (com-test :menu "test")
		    ()
	       (with-slots (pane-list) *application-frame*
		    (setf pane-list (append pane-list (list (accept 'integer))))))


    I've tried several different variations of this all pretty much with the
    same effect.  I did get one version to work (unacceptably), but that 
    redisplayed each integer every time (Kind of defeats the purpose of redisplay).
    In that version, I created the output record in the draw-display method
    which correctly redisplays each element.

			    Thanks for any help, Bill

    waarbau@tycho.ncsc.mil


You have some understanding problems about Incremental Redisplay, like Lawrence does,
possibly due to the not very good documentation about this topic.

However, your code is not executable due to another problem, too: it is just incomplete
yanked: I think quite a few lines of code are just omitted in the run-frame-top-level :before method!

I took the time to reconstruct and correct it anyway:

Here`s the result:



(define-application-frame test ()
    ((pane-list :initform (list 1 2 3 4 5)
		:accessor pane-list)
     (pane-rec  :accessor pane-rec))
  (:panes
    ((display-pane  :application
		    :display-after-commands T
		    :DISPLAY-FUNCTION 'DRAW-DISPLAY
		    :INCREMENTAL-REDISPLAY T
		    :scroll-bars :vertical
		    :end-of-page-action :scroll)
     (interactor :interactor)))
  (:layout ((one
	      (:column 1
	       (display-pane :compute)
	       (interactor :compute))))))

(define-genera-application test :select-key #\!)


(defmethod draw-display ((frame test) stream)
  (do* ((elements (pane-list frame) (cdr elements))
	(count 0 (1+ count))
	(element (first elements)(first elements)))
       ((null elements))
    (UPDATING-OUTPUT (STREAM :CACHE-VALUE ELEMENT :CACHE-TEST #'EQUAL
			     :UNIQUE-ID COUNT :ID-TEST #'=)
      (FORMAT STREAM "~A" ELEMENT))))

;; define a command to add items to the list
(define-test-command (com-test :name T :menu "test")
		     ()
  (with-slots (pane-list) *application-frame*
    (setf pane-list (append pane-list (list (accept 'integer))))))

Several comments about that:

1) if you specify :INCREMENTAL-REDISPLAY T for a pane, CLIM automatically captures
all output done to this stream within a top-level updating-output. You don't have
to do this anymore. So to cope with run-frame-top-level is unnecessary for this purpose.

2) if you provide :display-after-commands T and :INCREMENTAL-REDISPLAY T a redisplay is done
to that stream after every command. I guess that's the thing you want to do.

3) (style issue only) I find LOOP a very convenient tool to use instead of do, do*, dolist etc.

4) with define-genera-application you have also a quite convenient tool to automatically
generate and run frames

Markus Fischer
Consulting Services
Symbolics Systemhaus GmbH
Mergenthaler Allee 77-81
6236 Eschborn
West Germany
Tel (from the US): 011-6196-47220


References:

Main Index | Thread Index