;+ ;NAME: ; spd_ui_draw_event ; ;PURPOSE: ; This routine handles all events that occur in the draw window ; ;CALLING SEQUENCE: ; info=spd_ui_draw_event(event, info) ; ;INPUT: ; event - the structure from the draw window event ; info - the main information structure from splash_gui ; ;OUTPUT: ; info - the updated main information structure ; ;HISTORY: ; ;$LastChangedBy: jimm $ ;$LastChangedDate: 2014-02-11 10:54:32 -0800 (Tue, 11 Feb 2014) $ ;$LastChangedRevision: 14326 $ ;$URL: svn+ssh://thmsvn@ambrosia.ssl.berkeley.edu/repos/spdsoft/tags/spedas_4_0/spedas_gui/display/spd_ui_draw_event.pro $ ;- FUNCTION spd_ui_draw_event, event, info ; Catch errors here Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel ok = Error_Message(Traceback=1) RETURN, info ENDIF ;to desensitize to erroneous events that occur during panels if info.drawDisabled then return,info ;to desensitize to erroneous events that occur after panels if systime(/seconds) - info.drawDisableTimer lt .5 then return,info if info.draw_select eq 1 then begin widget_control,info.drawId,/input_focus endif ; fixing issue with the click flag getting stuck if the user ; clicks inside the draw object and drags the cursor outside if (info.click eq 1 && info.ctrl eq 0) then info.click = 0 ; Convert cursor location from device to normalized values info.drawWin->GetProperty, Dimensions=windowDimensions info.cursorPosition = [event.x/windowDimensions[0], event.y/windowDimensions[1]] if event.type eq 0 && event.clicks gt 0 && event.press eq 1 then begin info.click = 1 info.historyWin->update,'Click On' endif if event.type eq 1 && event.release eq 1 then begin info.click = 0 info.historyWin->update,'Click Off' info.contextMenuOn = 0 endif if info.contextMenuOn then return,info IF Size(event.release, /Type) ne 0 && event.release EQ 4 THEN BEGIN ; Print, 'Right Click - display context menu' ;Reset tracking and return if the user is rubberbanding or creating a marker if info.marking ne 0 or info.rubberbanding ne 0 then begin spd_ui_reset_tracking, info RETURN, info endif Widget_DisplayContextMenu, info.drawID, event.x, event.y, info.drawContextBase info.contextMenuOn = 1 info.prevEvent='RIGHTCLICK' info.marking=0 RETURN, info ENDIF ;help,event,/str ;turn marking on IF event.ch NE 0 OR event.key NE 0 THEN BEGIN if event.key eq 2 && event.press then begin info.ctrl = 1 info.historyWin->update,'Ctrl On' endif if event.key eq 2 && event.release then begin info.ctrl = 0 info.historyWin->update,'Ctrl Off' endif endif if info.marking eq 0 && info.ctrl && info.click then begin info.marking = 1 info.markers[0] = info.cursorposition[0] info.historyWin->update,'Turning Marking On' IF info.rubberbanding EQ 1 THEN BEGIN info.rubberbanding=0 info.rubberBandTimer=0D info.drawObject->rubberBandOff legend = Widget_Info(info.showPositionMenu, /Button_Set) if info.tracking && legend then begin if info.trackAll then info.drawObject->legendOn,/all else info.drawObject->legendOn endif ENDIF if info.trackall eq 1 then begin info.drawObject->markerOn,/all,fail=fail endif else begin info.drawObject->markerOn,fail=fail endelse IF fail EQ 1 && info.markerfail eq 0 THEN BEGIN info.statusBar->Update, 'Failed to create marker. Cursor was outside panel area' info.marking=0 info.markers=[0.0,0.0] info.markerfail=1 ;this flag prevents many copies of the message being printed and crudding things up. Also, prevents marker title query from popping up when a marker error has already occurred. spd_ui_reset_tracking,info ENDIF ELSE BEGIN FOR i=0,N_Elements(info.markerButtons)-1 DO Widget_Control, info.markerButtons[i], sensitive=1 ENDELSE endif ;turn marking off if info.marking eq 1 && (~info.ctrl || ~info.click) then begin info.historyWin->update,'Turning Marking Off' info.drawObject->markerOff info.markers[1]=info.cursorPosition[0] ;only allow selection for markers that have width greater than or equal to 1 pixel ;this prevents markers that are too small for the user to select. We may be able to remove this ;check in the future if we implement a menu that allows selection of markers without an on-screen ;selection on-screen ;info.markerTitle->GetProperty, UseDefault=useDefault ; if info.markerTitleOn then spd_ui_marker_title, info.master, info.markerTitle, info.historywin, info.statusbar $ ; else info.markerTitle=obj_new('SPD_UI_MARKER_TITLE') ;info.markerTitle->GetProperty, Cancelled=cancelled spd_ui_create_marker, info ; updates history and status bar internally ; since marking is done, reset everything info.markers=[0.0,0.0] info.marking= 2 info.drawObject->Update, info.windowStorage, info.loadedData info.drawObject->Draw info.click = 0 info.ctrl = 0 ; lphilpott 5-mar-2012 ; On windows we have a problem where holding down the ctrl key after the mouse ; button is released in marker creation causes a flood of ctrl on events after the ; Query for marker title dialog is closed. This means that the next thing the user tries ; to do acts as if ctrl is pressed. ; Clearing all these backed up ctrl events is a possible solution. widget_control, event.top, /clear_events endif ; Done with special cases, check button event type to determine what happened ; Button Press - marking in progress, draw rubberband box, or display options panel ; Button Release - end marking, drawing box, or displaying panel ; Motion Event - draw tracking line, marking or drawing box CASE event.type OF ; Button Press ; set the coordinates and event information, wait for a button release 0:BEGIN ; NOTE: if marking was not on then this is either a press to display options ; panel or the start of a click-drag event. Do nothing for now since we will ; not know which of the two options it is until the button is released if event.press eq 1 then begin info.lastclick[0] = event.x info.lastclick[1] = event.y info.prevEventX = event.x info.prevEvent='PRESS' info.drawObject->setCursor, info.cursorPosition endif ; tmp = info.drawObject->getClick() ; print,'Got Click.' ; if ~is_struct(tmp) then begin ;print,'Clicked Page' ; endif else begin ; print,'Clicked Panel: ' + strtrim(string(tmp.panelidx),2) ; if tmp.component eq 0 then print,'Component: Panel' ; if tmp.component eq 1 then print,'Component: Xaxis' ; if tmp.component eq 2 then print,'Component: Yaxis' ; if tmp.component eq 3 then print,'Component: Zaxis' ; if tmp.component eq 4 then print,'Component: Variables' ; print,"marker:",tmp.marker ;endelse RETURN, info END ; Button Release, either ; 1)marking done, ; 2)rubberband box done, or ; 3)display options panel 1: BEGIN ; Print, 'Button release' ; display options IF info.marking EQ 0 && info.prevEvent EQ 'PRESS' && event.release eq 1 THEN BEGIN info.historyWin->update,'Options Click' ; print, 'display options' spd_ui_display_options, info info.marking=0 info.prevEventX = event.x info.prevEvent='RELEASE' info.drawingBox=0 info.rubberBanding=0 info.drawObject->rubberBandOff info.drawObject->markerOff RETURN, info ENDIF ; rubber band box IF info.rubberBanding EQ 1 && info.prevEvent EQ 'MOTION' THEN BEGIN ; print, 'rubber band off' info.historyWin->update,'Turning Rubber Band Off' info.drawObject->setCursor, info.cursorPosition info.drawObject->rubberBandOff vBar = widget_info(info.trackVMenu,/button_set) if vBar eq 1 then begin IF info.trackAll EQ 1 THEN info.drawObject->vBarOn, /all ELSE info.drawObject->vBarOn endif hBar = widget_info(info.trackhMenu,/button_set) if hBar eq 1 then begin ; IF info.trackAll EQ 1 THEN info.drawObject->hBarOn, /all ELSE info.drawObject->hBarOn info.drawObject->hBarOn endif legend = Widget_Info(info.showPositionMenu, /Button_Set) IF legend EQ 1 && info.tracking THEN BEGIN IF info.trackAll EQ 1 THEN info.drawObject->legendOn, /all ELSE info.drawObject->legendOn ENDIF ; If rubber band time or distance is too short then treat as normal click. ; This prevents clicks from getting lost if user drags the mouse bit while clicking. tm = sysTime(/seconds) IF tm - info.rubberBandTimer GT 0.18 || $ sqrt( abs(info.lastclick[0] - event.x)^2 + abs(info.lastclick[1] - event.y)^2 ) gt 15 then begin spd_ui_rubber_band_box, info spd_ui_update_title, info endif else begin spd_ui_display_options, info endelse info.drawObject->draw info.drawingBox=0 info.marking=0 info.rubberBanding=0 info.rubberBandTimer=0D info.prevEventX = event.x info.prevEvent='RELEASE' RETURN, info ENDIF END ; Motion Event ; 1)If marking is on -> draw line ; 2)If marking is just finishing -> reset marking params and draw line ; 3)draw rubberbsand box 2: BEGIN ;print, 'motion event' info.prevEventX = event.x info.prevEventType = event.type ; marking is on, draw line IF info.marking EQ 1 && (info.prevEvent EQ 'CTRL' OR info.prevEvent EQ 'MOTION') THEN BEGIN ; print, 'marking on' info.drawObject->setCursor, info.cursorPosition info.prevEvent='MOTION' RETURN, info ENDIF ; marking was on and just turned off - needed to wait for cursor ; motion to reset marking variables IF info.marking EQ 2 THEN BEGIN ; print, 'marking officially off' info.marking=0 info.markerfail=0 info.drawObject->setCursor, info.cursorPosition info.prevEvent='MOTION' RETURN, info ENDIF ; marking was not on, but button was pressed then start drawing box IF info.marking EQ 0 && info.prevEvent EQ 'PRESS' THEN BEGIN ; print, 'starting rubber band box' info.drawingBox=1 info.drawObject->setCursor, info.cursorPosition info.drawObject->rubberBandOn info.rubberBandTimer=sysTime(/seconds) info.drawObject->vBarOff info.drawObject->hBarOff info.drawObject->legendOff info.marking=0 info.markerfail=0 info.rubberBanding=1 info.prevEvent='MOTION' RETURN, info ENDIF ; drawing box IF info.drawingBox EQ 1 && info.prevEvent EQ 'MOTION' THEN BEGIN ; print, 'drawing box' info.drawObject->setCursor, info.cursorPosition info.marking=0 info.markerfail=0 info.prevEvent='MOTION' RETURN, info ENDIF ; just tracking IF info.marking EQ 0 && info.drawingBox EQ 0 THEN BEGIN ; print, 'just tracking' info.drawObject->setCursor, info.cursorPosition info.marking=0 info.markerfail=0 info.prevEvent='MOTION' RETURN, info ENDIF info.prevEvent='MOTION' RETURN, info END 5: BEGIN ; print,event.ch ;this code block manually implements accelerator keys on platforms without accelerator support if info.ctrl && event.press && info.marking eq 0 && info.rubberBanding eq 0 then begin info.ctrl=0 if event.ch eq 3 then begin ; Ctrl+C spd_ui_copy, info endif else if event.ch eq 26 then begin spd_ui_close_window,info endif else if event.ch eq 14 then begin spd_ui_window,info endif else if event.ch eq 15 then begin spd_ui_open,info endif else if event.ch eq 19 then begin spd_ui_save,info endif else if event.ch eq 16 then begin spd_ui_print,info endif else if event.ch eq 17 then begin spd_ui_exit,event,info=info return,0 endif else if event.ch eq 18 then begin spd_ui_refresh,info endif endif if event.press then begin if event.ch eq 9 then begin spd_ui_expand,info endif else if event.ch eq 8 then begin spd_ui_reduce,info endif else begin ; print,event.ch endelse endif END 6: BEGIN if event.press && event.key eq 5 then begin spd_ui_scrollb,info ;move the displayed data in back in time/left along x-axis endif else if event.press && event.key eq 6 then begin spd_ui_scrollf,info ;move the displayed data in forward in time/right along x-axis endif else if event.press && event.key eq 7 then begin spd_ui_scroll_view,info.drawID,1 ;moves the displayed region of the view up(shortcut for clicking the vertical scroll bar) endif else if event.press && event.key eq 8 then begin spd_ui_scroll_view,info.drawID,0 ;moves the displayed region of the view down(shortcur for clicking the vertical scroll bar) endif END ELSE: BEGIN END ENDCASE RETURN, info END