Ciao, Luca. With all this Olympic coverage on television, I feel Italy is now our nearest neighbor. Nice job in 1500 m Men's Speed Skating tonight. Felicitazione!
... but that is "beside the point." IDL interfaces with two types of graphics libraries. One is called Direct Graphics. That is the library, to which IDL's WINDOW procedure interfaces. It is also the library, to which CURSOR interfaces. The behavior you are describing above is CURSOR starting a WINDOW, when there is none on the current display.
The other graphics library, to which IDL interfaces, is OpenGL, an "Object Graphics" library. Object Graphics are more powerful than Direct Graphics - more functionality, easier to code very complex "scenes" in, but basic Object Graphics programming is much more complex than basic Direct Graphics programming. Object Graphics is the interface that IDL's iTools depends on and ITS particular API is still more complex. I do not mean to discourage you from attempting these interfaces; they are simply not the easy introduction to IDL programming that Direct Graphics offers.
In some ways, I am not sure that your issue is Direct Graphics vs. Object Graphics. If your program is actually designed to use just a small bit of the iTools interface, your best approach for starting out might be simply to learn IDL's widget programming interface, an easier alternative to iTools coding, if you are only needing to implement a few buttons or menu items.
; EVENT HANDLER FOR ALL UI EVENTS
PRO draw_box_on_plot_event, event
; Get latest widget state information
widget_control, event.top, GET_UVALUE=info
case event.id of
info.wButton: begin ; Case of button event
wset, info.winID ; get drawing focus on draw window
plot, sqrt(findgen(10)), PSYM=2, XSTYLE=1, YSTYLE=1
info.bGraphLoaded = 1
widget_control, info.wButton, SENSITIVE=0 ; desensitize button
end
info.wDraw: begin
; Do nothing, if there is no plot loaded on display
if info.bGraphLoaded eq 0 then return
; Do nothing until button is released
if event.release ne 1B then return
; Case of user has clicked on first corner point
if total(info.pt1 ge 0) ne 2 then begin
info.pt1 = [event.x,event.y] ; Start a new box
endif else begin
wset, info.winID
; Case of user has clicked on second corner point
if total(info.pt2 ge 0) ne 2 then begin
info.pt2 = [event.x,event.y] ; Finish a box
left = min([info.pt1[0], info.pt2[0]], MAX=right)
bottom = min([info.pt1[1], info.pt2[1]], MAX=top)
boxCoords = [[left, bottom], [left,top], [right,top], $
right,bottom], [left, bottom]]
plots, boxCoords, /DEVICE
; Case of user has clicked after box has been drawn. Start over.
endif else begin
plot, sqrt(findgen(10)), PSYM=2, XSTYLE=1, YSTYLE=1 ; clean up
info.pt2 = [-1,-1] ; "Un-set point 2"
info.pt1 = [event.x,event.y] ; Start a new point 1
endelse
endelse
; Demonstrate Direct Graphics coordinate conversion in IDL output log
iPoint = convert_coord(event.x, event.y, 0, /DEVICE, /TO_DATA)
print, 'XYZ Data coords of point just clicked: ', iPoint
end
endcase
widget_control, event.top, SET_UVALUE=info ; update state struct
END
; WIDGET CREATION CODE
PRO draw_box_on_plot
tlb = widget_base(/COLUMN)
wLabel = widget_label(tlb, VALUE='Click on two points inside plot axes')
wDraw = widget_draw(tlb, XSIZE=400, YSIZE=300, /BUTTON_EVENTS)
wButton = widget_button(tlb, VALUE='Click to load graph')
widget_control, tlb, /REALIZE
widget_control, wDraw, GET_VALUE=winID ; get WIDGET_DRAW's WINDOW ID
; Set widget state information to share with event handler
info = {wDraw:wDraw, wButton:wButton, bGraphLoaded:0, $
pt1:[-1,-1], pt2:[-1,-1], winID:winID}
widget_control, tlb, SET_UVALUE=info
xmanager, 'draw_box_on_plot', tlb
END
To code the same kind of user interface handling in iPlot programming will take more time to learn. To replace the direct graphics PLOT and PLOTS calls above with Object Graphics calls would also be more complicated. The main information sources you need anyhow are in Online Help's:
For Programming like example shown above: Contents -> Programmer's Guides -> Building IDL Applications -> Part IV: Creating Graphical User Interfaces in IDL
For iTools event programming: Contents -> Programmer's Guides -> iTool Developer's Guide -> Part II: Using the iTools Component Framework -> Creating a Manipulator
|