CLIM mail archive
[Prev][Next][Index][Thread]
dragging
Reply-To: jmorrill@BBN.COM
Date: Thu, 17 Dec 92 10:25:13 -0500
From: Jeff Morrill <jmorrill@BBN.COM>
Date: Thu, 17 Dec 1992 11:57:17 +0100
From: Dietmar Pree <dp@cast.uni-linz.ac.at>
To: clim@BBN.COM
I am searching for a (very) efficient way to code a function like
clim:dragging-output-record stream output-record & key (:repaint t)
which enters an interaction mode in which the user moves the
pointer, and output-record is RESIZED (and not dragged !!!) on stream
when the pointer is moved.
In general, all dragging or "rubberbanding" should be done this way:
Use tracking-pointer to get reports on mouse motion. Each time
the mouse moves, you:
1. erase (that is, draw with the flip ink) at the old position
2. display (that is, draw with the flip ink) at the new position
Obviously you need a display function that takes INK as one
of its arguments.
In your case, the display function should also take some sort of
size arguments that are a function of the mouse position. Then you:
1. erase (that is, draw with the flip ink) at the old size
2. display (that is, draw with the flip ink) at the new size
Display should be done with output recording disabled because there is
no point recording what you are going to erase the next time the mouse
moves. With output recording disabled, the display function probably
won't take longer than a fraction of a second, and the animation
effect will seem real enough. Dragging with output recording
enabled is almost always wrong. When you are done dragging, you can
draw it once with output recording enabled to make it persist.
More concretely, here is a simple example of a "rubber band" box.
(in-package :clim-user)
(defun rubber-band-box (win)
(let ((start-x nil) (start-y nil)
(prev-x nil) (prev-y nil))
;; Draw a box from the start point to (x, y), erasing
;; the previous box (if any)
(flet ((draw-box (x y)
(when start-x
;; erase old box
(when prev-x
(draw-rectangle* win start-x start-y prev-x prev-y
:filled nil
:ink +flipping-ink+))
;; draw new
(draw-rectangle* win start-x start-y x y
:filled nil
:ink +flipping-ink+)
;; remember newly old box
(setq prev-x x prev-y y))))
;; Doesn't do anything until a button is pressed, then
;; rubber bands until the button is released.
(with-output-recording-options (win :record-p nil)
(tracking-pointer (win)
(:pointer-motion (x y)
(draw-box x y))
(:presentation (x y)
(draw-box x y))
(:pointer-button-press (x y)
(setq start-x x start-y y))
(:pointer-button-release ()
(setq start-x nil)
(return-from rubber-band-box)))))))
0,,
Follow-Ups:
References:
Main Index |
Thread Index