comp.lang.idl-pvwave archive
Messages from Usenet group comp.lang.idl-pvwave, compiled by Paulo Penteado

Home » Public Forums » archive » Re: drawing lines in IDL
Show: Today's Messages :: Show Polls :: Message Navigator
E-mail to friend 
Switch to threaded view of this topic Create a new topic Submit Reply
Re: drawing lines in IDL [message #11512] Tue, 31 March 1998 00:00
David Foster is currently offline  David Foster
Messages: 341
Registered: January 1996
Senior Member
>
> Steve Hartmann (morph@vuse.vanderbilt.edu) writes:
>
>> Does anyone know how to use the mouse to draw free hand lines over a
>> displayed image?
>

You might take a look at the DEFROI function, or the DEFROI2 function
that I've included below, which is a modified and enhanced version
of DEFROI. I've also included DEFROIS, which simply allows you to
call DEFROI2 iteratively when you want multiple ROI's.


************************************************************ ********
D E F R O I 2
************************************************************ ********

; DEFROI2.PRO 10-25-95
;
;+
; IMPORTANT NOTE:
;
; THIS ROUTINE IS OUR OWN "INTERNAL" VERSION OF THE DEFROI() IDL USER'S
; LIBRARY ROUTINE. WE HAVE MADE ADDITIONS TO THE ROUTINE, AND,
; UNFORTUNATELY, HAVE HAD TO MAKE CORRECTIONS AS WELL!
;
; Most notably, the indices of the roi returned, and any optional
; vertices returned, correspond to the ORIGINAL image, without
; the zoom factor being applied. This behavior is different
; from IDL's DEFROI() which returns indices and vertices
; that correspond to the zoomed image.
;
;
; NAME: DEFROI2
; PURPOSE: Define an irregular region of interest of an image
; using the image display system and the cursor/mouse.
; CATEGORY: Image processing.
; CALLING SEQUENCE:
; R = Defroi(Sx, Sy, X0, Y0)
; INPUTS:
; Sx, Sy = Size of image, in pixels.
; Optional Inputs:
; X0, Y0 = Coordinate of Lower left corner of image on display.
; If omitted, (0,0) is assumed. Screen device coordinates.
; ZOOM = zoom factor, if omitted, 1 is assumed.
; OUTPUTS:
; Function result = vector of subscripts of pixels inside the region.
; Side effect: The lowest bit in which the write mask is enabled
; is changed.
; OPTIONAL OUTPUTS:
; Xverts, Yverts = Optional output parameters which will contain
; the vertices enclosing the region. These always correspond
; to the original image, without the zoom factor being applied.
; KEYWORD Parameters:
; ALT_WINDOWS = set to window ID(s) of alternate windows in which the
; polygon(s) will be drawn in XOR mode; these are erased at the
; end of the routine. It is currently assumed all windows are the
; same size.
; COLOR = if set, polygon is displayed using specified color. Note
; that this implies that the middle cursor button may NOT be used
; to erase the last designation!
; MIDDLE_QUIT = if set, the middle mouse button will close the polygon
; and quit the polygon selection. If argument RTNVAL is supplied
; the value of !ERR which corresponds to the button used to close
; the polygon is returned.
; NOFILL = if set, inhibits filling of irregular region on completion.
; NOREGION = Setting NOREGION inhibits the return of the
; pixel subscripts.
; QUIET = if set, suppresses display of instructions on STDIO.
; RESTORE = if set, original image on display is restored to its
; original state on completion.
; PREPEND, APPEND = set these to coordinates to insert before and
after
; those chosen by user (use: designation of midline for example).
; TEXT_ID = set to widget id of text widget to have current cursor
; coordinates displayed while taking points.
;
; COMMON BLOCKS:
; None.
; SIDE EFFECTS:
; Display is changed if RESTORE is not set. If COLOR is set, display
; is changed regardless.
; RESTRICTIONS:
; Only works for interactive, pixel oriented devices with a
; cursor and an exclusive or writing mode.
; A region may have at most 1000 vertices. If this is not enough
; edit the line setting MAXPNTS.
; PROCEDURE:
; The exclusive or drawing mode is used to allow drawing and
; erasing objects over the original object.
; If COLOR is set then the copy mode is used.
;
; The operator marks the vertices of the region, either by
; dragging the mouse with the left button depressed or by
; marking vertices of an irregular polygon by clicking the
; left mouse button, or with a combination of both.
; The center button removes the most recently drawn points, unless
; COLOR is specified, in which case the middle button is disabled.
; Press the right mouse button when finished.
; When the operator is finished, the region is filled using
; the polyfill function, and the polyfillv function is used
; to compute the subscripts within the region.
;
; MODIFICATION HISTORY: DMS, March, 1987.
; Revised for SunView, DMS, Nov, 1987.
; Added additional argument checking, SNG April, 1991
; Modified for devices without write masks: DMS, March, 1992.
; Uses exclusive or mode rather than write masks.
; Return correct subscripts when using ZOOM keyword, DSFoster,
; Dec, 1993.
; Corrected so that correct subscripts and vertices are
; computed when !order=1 and ZOOM not equal to 1,
; DSFoster, Dec, 1993.
; Keyword QUIET added to disable instructions being sent to
; console, DSF, Feb, 1994.
; Keyword COLOR added to allow specification of drawing color.
; If set, the copy graphics mode is used, and the display
; is changed.
; Keyword MIDDLE_QUIT added to add flexibility in calling module.
; Implies that middle button has same function as right.
; Done to support multiple region designations in calling
; module. Added RTNVAL as 5th argument, to return the
; button-press used to close the polygon. This argument
; is optional; it will not be set if undefined. DSF, Mar, 1994.
; Keywords PREPEND and APPEND added to introduce coordinates
; before and after the ones chosen interactively; this is
; used when, say, you want the user to designate a midline
; only and have it converted into a polygon.
;
; Improved precision of arithmetic operations to improve
; correspondence between device coors and image coors. Added
arrays
; to hold device coordinates for improved plotting accuracy.
; DSF, 9-26-94.
; Keyword TEXT_ID added to have cursor coordinates displayed in
; text widget specified by TEXT_ID.
;
;-
;
;----------------------------------------------------------- ---------------
; procedure DEFROI2_PLOT_ALT
;
; Procedure to plot lines in alternate window(s) specified by keyword
; ALT_WINDOWS in call to DEFROI2().
;----------------------------------------------------------- ---------------

PRO defroi2_plot_alt, windows, xcoors, ycoors, color, g_mode

old_window = !d.window

if (g_mode ne 6) then device, get_graphics=tempg, set_graphics=6 ; Set
XOR

for i = 0, n_elements(windows) - 1 do begin
if (windows(i) ne -1L) then begin
wset, windows(i)
plots, xcoors, ycoors, /dev, color=color, /noclip
endif
endfor

if (g_mode ne 6) then device, set_graphics=tempg
if (old_window ne -1) then wset, old_window

return
END

;----------------------------------------------------------- ---------------
; function DEFROI2
;
; Main function.
;----------------------------------------------------------- ---------------

Function Defroi2, Sx, Sy, Xverts, Yverts, rtnval, X0=x0, Y0=y0,
ZOOM=ZOOM, $
NOREGION=Noregion, NOFILL=Nofill, RESTORE=restore, QUIET=quiet, $
COLOR=color, MIDDLE_QUIT=middle_quit, PREPEND=prepend,
APPEND=append, $
TEXT_ID=text_id, ALT_WINDOWS=alt_windows

on_error,2 ; Return to caller if error

if (keyword_set(TEXT_ID)) then begin ; Check for valid widget ID
(DSF)
if (widget_info(text_id, /valid_id) eq 0) then $
text_id = 0
endif

if (keyword_set(ALT_WINDOWS)) then begin ; Check whether windows IDs
valid
device, window_state=windows ; DSF
n_windows = n_elements(alt_windows)
for i = 0, n_windows - 1 do begin
if (windows(alt_windows(i)) ne 1) then $
alt_windows(i) = -1L
endfor
endif

if (keyword_set(COLOR)) then begin ; DSF
if (color gt !d.table_size-1) then $
message, 'Only ' + strtrim(string(!d.table_size-1),2) + $
' colors available ' + '(specified: ' + $
strtrim(string(color),2) + ')'
nc1 = color
if (keyword_set(RESTORE)) then $
message, 'Cannot use keywords COLOR and RESTORE together'
endif else begin
nc1 = !d.table_size-1 ;# of colors available
endelse

if sx lt 1 or sy lt 1 then $ ; Check some obvious things
message, 'Dimensions of the region must be greater than zero.'

if sx gt !d.x_size then $
message, 'The width of the region must be less than ' + $
strtrim(string(!d.x_size),2)

sy = sy < !d.y_size

if (keyword_set(COLOR)) then begin ; Save current graphics
mode
device, get_graphics=oldg, set_graphics=3 ; Copy mode (overwrite)
DSF
g_mode = 3
endif else begin
device, get_graphics=oldg, set_graphics=6 ; Set XOR mode
g_mode = 6
endelse

repeat cursor,x,y,/dev,/nowait until !err eq 0 ; Flush cursor buffer
DSF


AGAIN:

if (not keyword_set(quiet)) then begin ; DSF
print,'Left button to mark point'
if (keyword_set(MIDDLE_QUIT)) then begin
print,'Middle or right button to close region'
endif else if (not keyword_set(COLOR)) then begin
print,'Middle button to erase previous point'
print,'Right button to close region'
endif else begin
print,'Right button to close region'
endelse
endif

n = 0 ; Number of points taken
maxpnts = 2000 ; Max # of points.
xverts = intarr(maxpnts) ; Arrays of coordinates
yverts = intarr(maxpnts)
dev_xverts = intarr(maxpnts) ; Arrays for device coordinates
dev_yverts = intarr(maxpnts)
xprev = -1
yprev = -1
if n_elements(x0) le 0 then x0 = 0
if n_elements(y0) le 0 then y0 = 0
if n_elements(zoom) le 0 then zoom = 1
fzoom = float(zoom)

if (keyword_set(PREPEND)) then begin ; Insert points at
beginning
info = size(prepend)
if (info(0) ne 2 or info(1) ne 2) then $
message, 'Must set PREPEND to INTARR(2,?)'
pts = info(2)
xverts(0:pts-1) = fix(round(prepend(0,*) / fzoom))
yverts(0:pts-1) = fix(round(prepend(1,*) / fzoom))
dev_xverts(0:pts-1) = prepend(0,*)
dev_yverts(0:pts-1) = prepend(1,*)
n = pts
plots, dev_xverts(0:n-1), dev_yverts(0:n-1), /dev, color=nc1,
/noclip

if (keyword_set(ALT_WINDOWS)) then begin ; Plot in alternate
window(s)
defroi2_plot_alt, alt_windows, dev_xverts(0:n-1), $
dev_yverts(0:n-1), nc1, g_mode
endif
endif


; Get first point. Display coordinates in text widget if specified

if (keyword_set(TEXT_ID)) then begin
!err = 0
while (!err eq 0) do begin
cursor, xxx, yyy, /CHANGE, /DEV
msg = '[' + strtrim(xxx,2) + ', ' + strtrim(yyy,2) + ']'
WIDGET_CONTROL, text_id, set_value=msg, /no_copy
endwhile
endif else begin
cursor, xxx, yyy, /WAIT, /DEV
endelse

plots, [xxx,xxx], [yyy,yyy], /dev, color=nc1, /noclip ; Mark first
point

if (keyword_set(ALT_WINDOWS)) then begin ; Plot in alternate
window(s)
defroi2_plot_alt, alt_windows, [xxx,xxx], [yyy,yyy+1], nc1, g_mode
endif

repeat begin
if (n_elements(cursor_x)) then begin ; Update cursor
coors
cursor_x = xxx - x0
cursor_y = yyy - x0
endif
xx = fix(round((xxx - x0) / fzoom)) ; To image
coords
yy = fix(round((yyy - y0) / fzoom))
if (xx lt sx) and (yy lt sy) and (!err eq 1) and $
((xx ne xprev) or (yy ne yprev)) then begin ; New point?
xprev = xx
yprev = yy
if (n ge (maxpnts-1)) then begin
print,'^GDEFROI2(): Too many points'
n = n-1
endif
xverts(n) = xx ; Image
coordinates
yverts(n) = yy
dev_xverts(n) = xxx ; Device
coordinates
dev_yverts(n) = yyy

if (n ne 0) then begin
plots, dev_xverts(n-1:n), dev_yverts(n-1:n), /dev, $
color=nc1, /noclip
if (keyword_set(ALT_WINDOWS)) then begin ; Alternate
window(s)
defroi2_plot_alt, alt_windows, dev_xverts(n-1:n), $
dev_yverts(n-1:n), nc1, g_mode
endif
endif

n = n + 1
endif

; We use 2 or 5 for the middle button because some Microsoft
; compatible mice use 5.

if ((!err eq 2) or (!err eq 5)) and (n gt 0) and $
not keyword_set(MIDDLE_QUIT) then begin
if (not keyword_set(COLOR)) then begin ; DSF
n = n-1
if (n gt 0) then begin ; Remove a vertex
plots, dev_xverts(n-1:n), dev_yverts(n-1:n), $
color=nc1, /dev, /noclip
if (keyword_set(ALT_WINDOWS)) then begin ; Alternate
window
defroi2_plot_alt, alt_windows, dev_xverts(n-1:n), $
dev_yverts(n-1:n), nc1, g_mode
endif
endif
endif
endif
if (keyword_set(TEXT_ID)) then begin
!err = 0
while (!err eq 0) do begin
cursor, xxx, yyy, /CHANGE, /DEV
msg = '[' + strtrim(xxx,2) + ', ' + strtrim(yyy,2) + ']'
WIDGET_CONTROL, text_id, set_value=msg, /no_copy
endwhile
endif else begin
cursor, xxx, yyy, /WAIT, /DEV
endelse
endrep until ( !err eq 4 or $
((!ERR eq 2 or !ERR eq 5) and keyword_set(MIDDLE_QUIT)) )


if (keyword_set(APPEND)) then begin ; Points inserted at end
info = size(append)
if (info(0) ne 2 or info(1) ne 2) then $
message, 'Must set APPEND to INTARR(2,?)'
pts = info(2)
xverts(n:n+pts-1) = fix(round(append(0,*) / fzoom))
yverts(n:n+pts-1) = fix(round(append(1,*) / fzoom))
dev_xverts(n:n+pts-1) = append(0,*)
dev_yverts(n:n+pts-1) = append(1,*)
plots, dev_xverts(n-1:n+pts-1), dev_yverts(n-1:n+pts-1), $
/dev, color=nc1, /noclip

if (keyword_set(ALT_WINDOWS)) then begin ; Alternate window(s)
defroi2_plot_alt, alt_windows, dev_xverts(n-1:n+pts-1), $
dev_yverts(n-1:n+pts-1), nc1, g_mode
endif
n = n + pts
endif

if (n_params() gt 4) then rtnval = !ERR ; Return button-press

if (n lt 3) then begin
print,'ROI - Must have 3 points for region. Try again.'
goto, AGAIN
endif
xverts = xverts(0:n-1) ; Truncate
yverts = yverts(0:n-1)
dev_xverts = dev_xverts(0:n-1)
dev_yverts = dev_yverts(0:n-1)

; Erase polygons in alternate window if necessary.

if (keyword_set(ALT_WINDOWS)) then begin
defroi2_plot_alt, alt_windows, dev_xverts, dev_yverts, nc1, g_mode
endif

if keyword_set(RESTORE) then begin
plots, dev_xverts, dev_yverts, /dev, color=nc1, /noclip
endif else if keyword_set(NOFILL) then begin
plots, [dev_xverts(0),dev_xverts(n-1)],
[dev_yverts(0),dev_yverts(n-1)], $
/dev, color = nc1,/noclip ; Complete polygon
endif else begin
polyfill, dev_xverts, dev_yverts, /dev, color=nc1, /noclip
endelse

; DSFoster modification: divide SY by ZOOM below. Before if
; !order=1 and ZOOM<>1 then YVERTS inverted incorrectly;
; you have to scale the size of the image (SY) by ZOOM.
; Use FIX() to avoid conversion to LONG.

if (!order ne 0) then $
yverts = fix(sy/ZOOM) - 1 - yverts ; Invert Y?

device,set_graphics=oldg ; Re-enable original
graphics mode

; DSFoster modification: divide SX and SY by ZOOM below so that the
; correct subscripts are returned when using ZOOM.

if keyword_set(NOREGION) then begin
a = 0
endif else begin
a = polyfillv(xverts,yverts,sx/ZOOM,sy/ZOOM) ; Get subscripts
inside area
endelse

if (keyword_set(TEXT_ID)) then $
WIDGET_CONTROL, text_id, set_value=''

return, a
end


************************************************************ ********
D E F R O I S
************************************************************ ********

; DEFROIS.PRO 11-18-97 DSFoster
;
; Routine to allow user to choose multiple regions of interest from
; the current graphics device. Calls DEFROI2.PRO, our own modified
; version of the IDL DEFROI procedure. Returns the indices of the
; ROI's matrix locations, just like DEFROI.
; An array of long integers will be returned as argument PIXELS, and
; this array will contain the number of pixels chosen in each
; region designated; its dimension will be the number of regions chosen.

; 9-26-94 DSF Add keywords PREPEND and APPEND so they may be passed
; on to DEFROI2() (see DEFROI2 for details).
; 12-01-94 DSF Add TEXT_ID keyword to pass to DEFROI2() to print
; current cursor locations in specified text widget.
; 5-18-95 DSF Add keyword ALT_WINDOWS to enable the plotting of
; polygons on alternate windows in DEFROI2().
; 11-18-97 DSF Add keyword NOFILL to prevent polygon from being filled.


FUNCTION defrois, xdim,ydim,xcoors,ycoors,pixels,ZOOM=zoom,COLOR=color,
$
PREPEND=prepend, APPEND=append, TEXT_ID=text_id, $
ALT_WINDOWS=alt_windows, NOFILL=nofill

if (not keyword_set(TEXT_ID)) then text_id = 0
if (not keyword_set(ALT_WINDOWS)) then alt_windows = 0

max_poly = 100
pixels = LONARR(max_poly)
DEVICE, CURSOR_STANDARD=68
chosen = 0

AGAIN:

roi = defroi2(xdim,ydim,xc,yc,ret,zoom=zoom,color=color,/middle_qu it, $
PREPEND=prepend, APPEND=append, TEXT_ID=text_id, $
ALT_WINDOWS=alt_windows, NOFILL=nofill)

pixels(chosen) = n_elements(roi)
if (n_elements(all_rois) eq 0) then begin
all_rois = roi
xcoors = xc
ycoors = yc
endif else begin
all_rois = [all_rois, roi]
xcoors = [xcoors, xc]
ycoors = [ycoors, yc]
endelse

chosen = chosen + 1
if (chosen eq max_poly) then begin
message, 'Maximum of ' + strtrim(max_poly,2) + ' polygons allowed',
$
/continue
endif else if (ret eq 2 or ret eq 5) then begin
goto, AGAIN
endif

DEVICE, /CURSOR_ORIGINAL
pixels = pixels(0:chosen-1)

return, all_rois

END


--

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
David S. Foster Univ. of California, San Diego
Programmer/Analyst Brain Image Analysis Laboratory
foster@bial1.ucsd.edu Department of Psychiatry
(619) 622-5892 8950 Via La Jolla Drive, Suite 2240
La Jolla, CA 92037
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~
Re: drawing lines in IDL [message #11514 is a reply to message #11512] Tue, 31 March 1998 00:00 Go to previous message
davidf is currently offline  davidf
Messages: 2866
Registered: September 1996
Senior Member
Steve Hartmann (morph@vuse.vanderbilt.edu) writes:

> Does anyone know how to use the mouse to draw free hand lines over a
> displayed image?

Here is an example that involved some simple modifications of
the example program to draw rubberband boxes that appears on my
web page.

Click and draw with the LEFT mouse button to draw free-hand
lines on the image. Click and drag with the RIGHT mouse
button to draw straight lines on the image. Among other
things this example illustrates is how you might go about
collecting points for creating a free-hand region of interest
using pointers.

Cheers,

David

***********************************************************
PRO Example_Button_Events, event

; All program button events handled here.

Widget_Control, event.top, Get_UValue=info, /No_Copy

; Which button caused this event?

Widget_Control, event.id, Get_Value=thisButtonValue
CASE thisButtonValue OF

'Quit': BEGIN
Widget_Control, event.top, /Destroy
RETURN
ENDCASE

'Erase Lines': BEGIN
WSet, info.wid
TV, BytScl(info.image, Top=info.drawColor-1)
ENDCASE

ENDCASE
Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;----------------------------------------------------------- -------



PRO Example_Draw_Events, event

; All program draw widget events handled here.

; Deal only with DOWN, UP, and MOTION events.

IF event.type GT 2 THEN RETURN

; Get the info structure.

Widget_Control, event.top, Get_UValue=info, /No_Copy

; What kind of event is this?

eventTypes = ['DOWN', 'UP', 'MOTION']
thisEvent = eventTypes[event.type]

whichButton = ['NONE', 'LEFT', 'MIDDLE', 'NONE', 'RIGHT']

CASE thisEvent OF

'DOWN': BEGIN

; Which button was used? LEFT or RIGHT?

info.buttonUsed = whichButton(event.press)

; Turn motion events on for the draw widget.

Widget_Control, info.drawID, Draw_Motion_Events=1

; Create a pixmap. Store its ID. Copy window contents into it.

Window, /Free, /Pixmap, XSize=info.xsize, YSize=info.ysize
info.pixID = !D.Window
Device, Copy=[0, 0, info.xsize, info.ysize, 0, 0, info.wid]

; Initialize the starting coordinates of the line.

IF info.buttonUsed EQ 'RIGHT' THEN BEGIN
info.xstart = event.x
info.ystart = event.y
ENDIF ELSE BEGIN
info.xvalues = Ptr_New([event.x])
info.yvalues = Ptr_New([event.y])
ENDELSE

ENDCASE

'UP': BEGIN

; Erase the last line drawn. Destroy the pixmap.

WSet, info.wid
Device, Copy=[0, 0, info.xsize, info.ysize, 0, 0, info.pixID]
WDelete, info.pixID

; Turn draw motion events off. Clear events queued for widget.

Widget_Control, info.drawID, Draw_Motion_Events=0, Clear_Events=1

; Draw the final line.

IF info.buttonUsed EQ 'RIGHT' THEN BEGIN

PlotS, [info.xstart, event.x], [info.ystart, event.y], $
/Device, Color=info.drawColor

; Reinitialize the line starting coordinates.

info.xstart = -1
info.ystart = -1

ENDIF ELSE BEGIN

PlotS, *info.xvalues, *info.yvalues, /Device, $
Color=info.drawColor

; Reinitialize the pointers.

Ptr_Free, info.xvalues
Ptr_Free, info.yvalues
info.xvalues = Ptr_New()
info.yvalues = Ptr_New()

ENDELSE
ENDCASE

'MOTION': BEGIN

; Here is where the actual line is drawn and erased.
; First, erase the last line.

WSet, info.wid
Device, Copy=[0, 0, info.xsize, info.ysize, 0, 0, info.pixID]

IF info.buttonUsed EQ 'RIGHT' THEN BEGIN

; Draw a straight line.

PlotS, [info.xstart, event.x], [info.ystart, event.y], /Device, $
Color=info.drawColor

ENDIF ELSE BEGIN

; Get the points of the new free-hand line and draw it.

*info.xvalues = [*info.xvalues, event.x]
*info.yvalues = [*info.yvalues, event.y]
PlotS, *info.xvalues, *info.yvalues, /Device, Color=info.drawColor

ENDELSE

ENDCASE

ENDCASE

; Store the info structure.

Widget_Control, event.top, Set_UValue=info, /No_Copy
END
;----------------------------------------------------------- -------



PRO Example

; Open an image data set.

file = Filepath(SubDirectory=['examples','data'], 'ctscan.dat')
OpenR, lun, file, /Get_Lun
image = BytArr(256, 256)
ReadU, lun, image
Free_Lun, lun

xsize = (Size(image))[1]
ysize = (Size(image))[2]

; Create the TLB.

tlb = Widget_Base(Title='Free-Hand Lines in a Widget Program', $
MBar=menubase)

; Create some menu bar buttons.

fileID = Widget_Button(menubase, Value='File', $
Event_Pro='Example_Button_Events')
eraseID = Widget_Button(fileID, Value='Erase Lines')
quitID = Widget_Button(fileID, Value='Quit')

; Create the draw widget graphics window. Turn button events ON.

drawID = Widget_Draw(tlb, XSize=xsize, YSize=ysize, Button_Events=1, $
Event_Pro='Example_Draw_Events')

; Realize widgets and make draw widget the current window.

Widget_Control, tlb, /Realize
Widget_Control, drawID, Get_Value=wid
WSet, wid

; Load drawing color and display the image.

drawColor = !D.N_Colors-1
TVLCT, 255, 255, 0, drawColor
TV, BytScl(Image, Top=drawColor-1)

; Create an "info" structure with information to run the program.

info = { image:image, $ ; The image data.
wid:wid, $ ; The window index number.
drawID:drawID, $ ; The draw widget identifier.
pixID:-1, $ ; The pixmap identifier.
xsize:xsize, $ ; The X size of the graphics window.
ysize:ysize, $ ; The Y size of the graphics window.
xstart:-1, $ ; The starting X coordinate of the line.
ystart:-1, $ ; The starting Y coordinate of the line.
xvalues:Ptr_New(), $ ; The X coordinates of the free-hand line.
yvalues:Ptr_New(), $ ; The Y coordinates of the free-hand line.
buttonUsed:'NONE', $ ; A flag to indicate which button is used.
drawColor:drawColor } ; The rubberband box color.

; Store the info structure.

Widget_Control, tlb, Set_UValue=info, /No_Copy

; Start the program going.

XManager, 'example', tlb, /No_Block
END

-----------------------------------------------------------
David Fanning, Ph.D.
Fanning Software Consulting
E-Mail: davidf@dfanning.com
Phone: 970-221-0438
Coyote's Guide to IDL Programming: http://www.dfanning.com/
  Switch to threaded view of this topic Create a new topic Submit Reply
Previous Topic: Deleting files from IDL
Next Topic: IDL batch mode: Command line args?

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ] [ PDF ]

Current Time: Wed Oct 08 15:13:43 PDT 2025

Total time taken to generate the page: 0.00723 seconds