Re: ERASING a line [message #7163 is a reply to message #7159] |
Wed, 09 October 1996 00:00   |
Peter Mason
Messages: 145 Registered: June 1996
|
Senior Member |
|
|
On Tue, 8 Oct 1996, Mario Noyon wrote:
> I would like to draw a vertical line on a drawing widget and erase it
> afterwards. Just like idl does it with the BOX_CURSOR.
> I watched this routine to see how they did, but my pocedure refuses to
> redraw the line erased.
Here are two ways to do it:
The first is the easiest; it just involves using "XOR" mode. In XOR mode
you can erase a graphic simply by redrawing it. BOX_CURSOR uses this method.
Here's how:
1] Draw your "main" graphics as usual (e.g., a plot or an image).
2] Wait for some initialisation signal (e.g., a button-down event from your
draw widget).
3] Use DEVICE,GET_GRAPHICS=old,SET_GRAPHICS=6 to enter "xor" drawing mode.
4] Draw your initial line (or box or whatever). It's best if you draw it
using "device" coordinates, as it's possible that "data" coords might not
be established, and "normal" coords can be imperfectly repeatable (well,
I've noticed this once or twice with some older versions of IDL).
5] Wait for the user to update the line's position, or to issue a termination
signal. e.g., Wait for a motion- or button-up event from your draw
widget.
6] Redraw your line in the same position as before - this rubs it out.
7] If you got a position-update (e.g., a motion event) in 5], draw the line
in the new position and go back to 5].
8] Use DEVICE,SET_GRAPHICS=old to restore the graphics mode. (Normally "old"
is 3, meaning "copy".)
Commonly the line (or box...) would be drawn with the highest available
colour (!d.table_size in 8-bit mode). In XOR mode it will only come out in
this colour in areas which are otherwise black (if you're lucky) - in other
areas it'll come out in some arbitrary colour. But it'll usually stand out
against the background. If you want total control over the line's colour,
you have to resort to method 2...
Method 2 is more complicated - it's the hard and thorough way.
Before drawing the line, you save the bits of your graphics window which are
about to be overwritten (by the line) to PIXMAP (invisible) window(s). You
erase the line by restoring the bits from the pixmap window(s).
A pixmap window can be created by:
WINDOW,/FREE,/PIXMAP,XSIZE=xpix,YSIZE=ypix &pixid=!D.WINDOW
The easy way out is to make the pixmap window the same size as your draw
widget. But since graphics memory can be a scarce resource and since you'll
just be "overplotting" a vertical line, xpix=1 and ypix=[your widget's height]
will suffice.
To save a "line's worth" to the pixmap window, use:
WSET,pixid &DEVICE,COPY=[xpos,ypos,1,ypix,0,0,drawid] &WSET,drawid
where: xpos&ypos are your line-to-be's position in your draw widget (device
coords); ypix is the height (in pixels) of your draw widget; drawid
is the "value" of your draw widget; pixid is the window ID of your
pixmap window.
To restore from the pixmap window, use:
DEVICE,COPY=[0,0,1,ypix,xpos,ypos,pixid]
So..
Steps 3] and 8] disappear.
Before you draw the line (steps 4] and 7]), save to the pixmap window.
To erase the line (step 6]), just restore from the pixmap window.
This method has an additional complication: you have to destroy and recreate
the pixmap window if the size of your draw widget is changed.
Hope this helps
Peter Mason
|
|
|