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

presentations



    Date: Fri, 3 Mar 89 11:32 CST
    From: vaughan@MCC.COM (Paul Vaughan)

    Ok, all you presentations wizards out there.  Since people seem to love
    questions about simple concrete examples, I've composed some.

    Consider

    (defun 1test-1 0()
      (graphics:with-room-for-graphics (*standard-output* 100)
	(let ((outer (graphics:with-output-as-graphics-presentation
		       (*standard-output* :object 'foo :type 'sys:expression)
		       (graphics:draw-rectangle 0 0 100 100 :filled nil)
		       (let ((inner (graphics:with-output-as-graphics-presentation
				      (*standard-output* :object 'bar :type 'sys:expression)
				      (graphics:draw-rectangle 0 45 10 55))))
			 (sleep 1)
			 (graphics:erase-graphics-presentation inner)
			 (setq inner (graphics:with-output-as-graphics-presentation
				       (*standard-output* :object 'bar :type 'sys:expression)
				       (graphics:draw-rectangle 90 45 100
    55))))))))))

    When executed in a Lisp Listener dynamic window, this seems to work
    correctly.  The little inner box moves from the left side of the outer
    box to the right side.  Everything gets erased and incrementally redrawn
    very neatly, and both the inner and outer boxes are mouse sensitive. 

OK.  What is wrong with this approach?

    Now, consider this 

    (defun 1test-2 0()
      (graphics:with-room-for-graphics (*standard-output* 100)
	(let ((outer (graphics:with-output-as-graphics-presentation
		       (*standard-output* :object 'foo :type 'sys:expression)
		       (graphics:draw-rectangle 0 0 100 100 :filled nil)
		       (let ((inner (graphics:with-output-as-graphics-presentation
				      (*standard-output* :object 'bar :type 'sys:expression)
				      (graphics:draw-rectangle 0 45 10 55))))
			 (sleep 1)
			 (graphics:replacing-graphics-presentation (*standard-output* inner)
			   (graphics:draw-rectangle 90 45 100 55)))))))))

    According to the document examiner, I would expect this to work even
    better.  That is, less consing and "minimized flicker."  However, for
    me, it leaves a munged image of the outer box.  Also, the inner box is
    no longer individually selectable--moving the mouse over it causes both
    boxes to be highlighted.

There do seem to be bugs in replacing-graphics-presentation.  It invokes
:erase-displayed-presentation with :redisplay-overlapping-presentations
nil, which accounts for the "missing chunk".  It apparently also screws
up the presentation being moved; after the replacement, the FOO
presentation has an inferior of type T, with object NIL.

    Now consider this.  This uses some undocumented code
    (dw::displayed-presentation-add-inferior and (setf
    (dw:presentation-superior inner) outer)).

    (defun 1test-3 0()
      (graphics:with-room-for-graphics (*standard-output* 100)
	(let* ((outer (graphics:with-output-as-graphics-presentation
			(*standard-output* :object 'foo :type 'sys:expression)
			(graphics:draw-rectangle 0 0 100 100 :filled nil)))
	       (inner (graphics:with-output-as-graphics-presentation
			(*standard-output* :object 'bar :type 'sys:expression)
			(graphics:draw-rectangle 0 45 10 55))))
	  (dw::displayed-presentation-add-inferior outer inner)
	  (setf (dw:presentation-superior inner) outer)
	  (sleep 1)
	  (graphics:erase-graphics-presentation inner)
	  (setq inner (graphics:with-output-as-graphics-presentation
			(*standard-output* :object 'bar :type 'sys:expression)
			(graphics:draw-rectangle 90 45 100 55)))
	  (dw::displayed-presentation-add-inferior outer inner)
	  (setf (dw:presentation-superior inner) outer))))

    This one seems to work just fine, but if I move the mouse to where the
    inner box used to be on the left, I get a ghost--the invisible
    presentation highlights.  Does anybody know a technique that works like
    this to add inferiors after the fact?  I'd like to use such a technique
    to incrementally add, remove, and update inferiors.

Why are you messing with the presentation hierarchy if you don't want
nested sensitivity?  Or, if you want nested sensitivity, why aren't you
nestine your with-output-as-graphics-presentation forms as before?
Consider:

(defun 1test-04 ()
  (send *standard-output* :expose)
  (send *standard-output* :clear-history)
  (graphics:with-room-for-graphics (*standard-output* 100)
    (let ((outer (graphics:with-output-as-graphics-presentation
		   (*standard-output* :object 'foo :type 'sys:expression)
		   (graphics:draw-rectangle 0 0 10 10)
		   (let ((inner (graphics:with-output-as-graphics-presentation
				  (*standard-output* :object 'bar :type 'sys:expression)
				  (graphics:draw-rectangle 20 20 30 30))))
		     )))))))

This displays nested sensitivity behaviour.  If you point at the
upper-right block it is sensitive as 'bar.  If you point at the lower
left block, both blocks light up, sensitive as 'foo.  Maybe using
:single-box t would make this clearer.

The erase-graphics-presentation call in your test-3 doesn't work right
because you have played with the presentation hierarchy.  What did you
want to happen?  Did you want to arrange it so that when you erased the
"outer" presentation the "inner" one would be deleted as well?

Again, I guess my basic question is "what is wrong with the behavior of
test-1?