; $Id: Ex_ContextMenus.pro,v 1.1 2001/07/17 16:47:49 scottm Exp $ ; ; Copyright (c) 1998-2001, Research Systems, Inc. All rights reserved. ; Unauthorized reproduction prohibited. ;+ ; NAME: ; Ex_ContextMenus ; ; PURPOSE: ; This is an application example of using context (shortcut) menus.. ; ; CATEGORY: ; Toolkit ; ; CALLING SEQUENCE: ; Ex_ContextMenus ; ; INPUTS: ; None. ; ; OPTIONAL KEYWORDS: ; None. ; ; OUTPUTS: ; None ; ; EXAMPLE: ; ; Ex_ContextMenus ; ; Using Ex_ContextMenu ; Right-click on the draw widget (which contains the world ; elevation image) to obtain a context menu for selecting ; XLOADCT, XPALETTE, or quitting out of the application. ; Left-click in the list widget to select either the "rotate" ; or "shift" item. Right-click on "rotate" item to obtain ; a context menu for selecting a 90 degree rotation, a 180 ; degree rotation, or a 270 degree rotaion. Right-click on ; "shift" item to obtain a context menu for selecting an ; one-quarter column shift, an one-half column shift, or ; a three-quarters column shift. ; Right-click on the text widget to obtain a context menu for ; selecting column text or row text to be entered into the ; text widget. Values entered into the text widget change ; the current location of the cursor in the draw widget. ; The label widgets display the current cursor location in the ; draw widget and the value of the pixel at that location. ; ; MODIFICATION HISTORY: ; Written by: LHD, RSI, July 2001 ; ;- ; ; Event handler routine for the "XLOADCT" button in ; the context menu of the draw widget. PRO LoadCTEvent, event ; Display the XLOADCT utility to allow the user to ; change the current color table. XLOADCT, /BLOCK, GROUP = event.id ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Obtain the image to redisplay it with the updated ; color table from XLOADCT utility. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Redisplay the image with the updated color table. WSET, windowDraw TV, image END ; Event handler routine for the "XPALETTE" button in ; the context menu of the draw widget. PRO PaletteEvent, event ; Display the XPALETTE utility to allow the user to ; modify some or all of the current color table. XPALETTE, /BLOCK, GROUP = event.id ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Obtain the image to redisplay it with the updated ; color table from XPALETTE utility. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Redisplay the image with the updated color table. WSET, windowDraw TV, image END ; Event handler routine for the "Done" button in ; the context menu of the draw widget. PRO DoneEvent, event WIDGET_CONTROL, event.top, /DESTROY END ; Event handler routine for the "Rotate 90 Degrees" button in ; the context menu of the list widget. PRO Rotate90Event, event ; Obtain the image to rotate it 90 degrees. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Rotate the image 90 degrees. image = ROTATE(image, 1) ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Display the updated image. WSET, windowDraw TV, image ; Store updated image in the UVALUE of the ; top level base. WIDGET_CONTROL, event.top, SET_UVALUE = image END ; Event handler routine for the "Rotate 180 Degrees" button in ; the context menu of the list widget. PRO Rotate180Event, event ; Obtain the image to rotate it 180 degrees. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Rotate the image 180 degrees. image = ROTATE(image, 180) ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Display the updated image. WSET, windowDraw TV, image ; Store updated image in the UVALUE of the ; top level base. WIDGET_CONTROL, event.top, SET_UVALUE = image END ; Event handler routine for the "Rotate 270 Degrees" button in ; the context menu of the list widget. PRO Rotate270Event, event ; Obtain the image to rotate it 270 degrees. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Rotate the image 270 degrees. image = ROTATE(image, 3) ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Display the updated image. WSET, windowDraw TV, image ; Store updated image in the UVALUE of the ; top level base. WIDGET_CONTROL, event.top, SET_UVALUE = image END ; Event handler routine for the "Shift One Quarter" button in ; the context menu of the list widget. PRO Shift025Event, event ; Obtain the image to horizontally shift it one quarter of the ; horizontal image size. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Initialize the image size parameter. imageSize = SIZE(image, /DIMENSIONS) ; Horizontally shift it one quarter of the horizontal image size. image = SHIFT(image, imageSize[0]/4, 0) ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Display the updated image. WSET, windowDraw TV, image ; Store updated image in the UVALUE of the ; top level base. WIDGET_CONTROL, event.top, SET_UVALUE = image END ; Event handler routine for the "Shift One Half" button in ; the context menu of the list widget. PRO Shift050Event, event ; Obtain the image to horizontally shift it one half of the ; horizontal image size. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Initialize the image size parameter. imageSize = SIZE(image, /DIMENSIONS) ; Horizontally shift it one half of the horizontal image size. image = SHIFT(image, imageSize[0]/2, 0) ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Display the updated image. WSET, windowDraw TV, image ; Store updated image in the UVALUE of the ; top level base. WIDGET_CONTROL, event.top, SET_UVALUE = image END ; Event handler routine for the "Shift Three Quarters" button in ; the context menu of the list widget. PRO Shift075Event, event ; Obtain the image to horizontally shift it three quarters of the ; horizontal image size. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Initialize the image size parameter. imageSize = SIZE(image, /DIMENSIONS) ; Horizontally shift it three quarters of the horizontal image size. image = SHIFT(image, (3*imageSize[0])/4, 0) ; Obtain the window ID of the draw widget. imageDraw = WIDGET_INFO(event.top, FIND_BY_UNAME = 'imageDisplay') WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Display the updated image. WSET, windowDraw TV, image ; Store updated image in the UVALUE of the ; top level base. WIDGET_CONTROL, event.top, SET_UVALUE = image END ; Event handler routine for the "Column" button in ; the context menu of the text widget. PRO ColumnEvent, event ; Obtain the location variable from the UVALUE of the ; text widget. locationText = WIDGET_INFO(event.top, FIND_BY_UNAME = 'xyText') WIDGET_CONTROL, locationText, GET_UVALUE = location ; If location index is set to "Row" change it to "Column". IF (location[2] EQ 1) THEN BEGIN titleLabel = WIDGET_INFO(event.top, FIND_BY_UNAME = 'xyLabel') WIDGET_CONTROL, titleLabel, SET_VALUE = 'Column: ' WIDGET_CONTROL, locationText, SET_VALUE = STRTRIM(location[0], 2) location[2] = 0 ENDIF ELSE RETURN ; Store updated location variable in the UVALUE of the ; text widget. WIDGET_CONTROL, locationText, SET_UVALUE = location END ; Event handler routine for the "Row" button in ; the context menu of the text widget. PRO RowEvent, event ; Obtain the location variable from the UVALUE of the ; text widget. locationText = WIDGET_INFO(event.top, FIND_BY_UNAME = 'xyText') WIDGET_CONTROL, locationText, GET_UVALUE = location ; If location index is set to "Column" change it to "Row". IF (location[2] EQ 0) THEN BEGIN titleLabel = WIDGET_INFO(event.top, FIND_BY_UNAME = 'xyLabel') WIDGET_CONTROL, titleLabel, SET_VALUE = 'Row: ' WIDGET_CONTROL, locationText, SET_VALUE = STRTRIM(location[1], 2) location[2] = 1 ENDIF ELSE RETURN ; Store updated location variable in the UVALUE of the ; text widget. WIDGET_CONTROL, locationText, SET_UVALUE = location END ; Event handler routine for the events of the draw ; widget. This event handler routine is called ; when the user left- or right-clicks on the draw widget. PRO DrawEvents, event ; If either a left- or right-click occurs, obtain the image to ; determine the value of the pixel at the location under the ; cursor. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Update the column location label. columnString = 'Column: ' + STRTRIM(event.x, 2) columnLabel = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'xLabel') WIDGET_CONTROL, columnLabel, SET_VALUE = columnString ; Update the row location label. rowString = 'Row: ' + STRTRIM(event.y, 2) rowLabel = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'yLabel') WIDGET_CONTROL, rowLabel, SET_VALUE = rowString ; Update the image pixel value label. value = image[event.x, event.y] valueString = 'Value: ' + STRTRIM(FIX(value), 2) valueLabel = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'dataLabel') WIDGET_CONTROL, valueLabel, SET_VALUE = valueString ; Update the text within the text widget. locationText = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'xyText') WIDGET_CONTROL, locationText, GET_UVALUE = location IF (location[2] EQ 0) THEN WIDGET_CONTROL, locationText, $ SET_VALUE = STRTRIM(event.x, 2) ELSE WIDGET_CONTROL, $ locationText, SET_VALUE = STRTRIM(event.y, 2) ; If a right-click occurs, display the context menu and send ; its events to the other event handler routines. IF (event.release EQ 4) THEN BEGIN ; Obtain the widget ID of the context menu base. contextBase = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'drawContext') ; Display the context menu and send its events to the ; other event handler routines. WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, $ contextBase ENDIF END ; Event handler routine for the events of the list ; widget. This event handler routine is called ; when the user left- or right-clicks on the list widget. PRO ListEvents, event ; If either a left- or right-click occurs, obtain the selection ; index to determine the type of geometry change to occur. selection = WIDGET_INFO(event.id, /LIST_SELECT) ; If a right-click occurs display the appropriate context menu. IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_CONTEXT') THEN $ BEGIN ; If "Rotate" is selected, then use the rotate context menu. IF (selection EQ 0) THEN BEGIN ; Obtain the widget ID of the rotate context menu base. contextBase = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'contextRotate') ; Display the context menu and send its events to the ; other event handler routines. WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, $ event.y, contextBase ENDIF ; If "Shift" is selected, then use the shift context menu. IF (selection EQ 1) THEN BEGIN ; Obtain the widget ID of the shift context menu base. contextBase = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'contextShift') ; Display the context menu and send its events to the ; other event handler routines. WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, $ event.y, contextBase ENDIF ENDIF END PRO TextEvents, event ; If a right-click occurs display the context menu. IF (TAG_NAMES(event, /STRUCTURE_NAME) EQ 'WIDGET_CONTEXT') THEN $ BEGIN ; Obtain the widget ID of the context menu base. contextBase = WIDGET_INFO(event.top, FIND_BY_UNAME = 'contextMenu') ; Display the context menu and send its events to the other event ; handler routines. WIDGET_DISPLAYCONTEXTMENU, event.id, event.x, event.y, contextBase ENDIF ; If text is edited, obtain new text inputed into widget. WIDGET_CONTROL, event.id, GET_VALUE = textString IF ((FIX(textString) GE 0) AND (FIX(textString) LE 360)) $ THEN textValue = FIX(textString) ELSE RETURN textValue = textValue[0] ; Obtain the location variable from the UVALUE of the ; text widget. WIDGET_CONTROL, event.id, GET_UVALUE = location ; Determine if inputed value should be column or row. IF(location[2] EQ 0) THEN location[0] = textValue $ ELSE location[1] = textValue ; Store updated location variable in the UVALUE of the ; text widget. WIDGET_CONTROL, event.id, SET_UVALUE = location ; Obtain the image to determine the value of the pixel ; under the cursor. WIDGET_CONTROL, event.top, GET_UVALUE = image ; Set location parameters derived from the text widget. column = location[0] row = location[1] value = image[column, row] ; Update the column location label. columnString = 'Column: ' + STRTRIM(column, 2) columnLabel = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'xLabel') WIDGET_CONTROL, columnLabel, SET_VALUE = columnString ; Update the row location label. rowString = 'Row: ' + STRTRIM(row, 2) rowLabel = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'yLabel') WIDGET_CONTROL, rowLabel, SET_VALUE = rowString ; Update the image pixel value label. valueString = 'Value: ' + STRTRIM(FIX(value), 2) valueLabel = WIDGET_INFO(event.top, $ FIND_BY_UNAME = 'dataLabel') WIDGET_CONTROL, valueLabel, SET_VALUE = valueString ; Relocate the cursor with the updated location information. TVCRS, column, row END ; Main Routine: GUI creation routine. PRO Ex_ContextMenus ; Determine the path to the file containing the image. file = FILEPATH('worldelv.dat', $ SUBDIRECTORY = ['examples', 'data']) ; Initialize the image size parameter. imageSize = [360, 360] ; Import in the image from the file. image = READ_BINARY(file, DATA_DIMS = imageSize) ; Initialize the top level (background) base. topLevelBase = WIDGET_BASE(/COLUMN) ; Initialize the draw widget to contain the display ; of the image. This draw widget contains buttons events. In ; other words, the user can left- or right-click on the image ; display to obtain the location of the pixel under the ; cursor or to obtain a context menu, respectively. imageDraw = WIDGET_DRAW(topLevelBase, /BUTTON_EVENTS, $ XSIZE = imageSize[0], YSIZE = imageSize[1], $ EVENT_PRO = 'DrawEvents', UNAME = 'imageDisplay') ; Initialize the base for the context menu. contextBase = WIDGET_BASE(topLevelBase, /CONTEXT_MENU, $ UNAME = 'drawContext') ; Initialize the buttons of the context menu. loadCTButton = WIDGET_BUTTON(contextBase, $ VALUE = 'XLOADCT', EVENT_PRO = 'LoadCTEvent') paletteButton = WIDGET_BUTTON(contextBase, $ VALUE = 'XPALETTE', EVENT_PRO = 'PaletteEvent') doneButton = WIDGET_BUTTON(contextBase, VALUE = 'Done', $ /SEPARATOR, EVENT_PRO = 'DoneEvent') ; Initialize the pixel information. column = imageSize[0]/2 row = imageSize[1]/2 value = image[column, row] ; Initialize a row base to contain the geometry transform list, ; the location text, and the pixel information labels. listTextLabelBase = WIDGET_BASE(topLevelBase, /ROW, $ /ALIGN_CENTER, /FRAME) ; Initialize the geometry transform list.This list widget contains ; context events. In other words, the user can left- or right-click ; on the list to obtain a general selection or to make a specific ; selection, respectively. listBase = WIDGET_BASE(listTextLabelBase, /COLUMN, /FRAME, $ /ALIGN_CENTER) list = ['Rotate', 'Shift'] geometryList = WIDGET_LIST(listBase, VALUE = list, $ /CONTEXT_EVENTS, SCR_YSIZE = 28, EVENT_PRO = 'ListEvents') ; Initialize the base for the rotate context menu. contextRotateBase = WIDGET_BASE(topLevelBase, /CONTEXT_MENU, $ UNAME = 'contextRotate') ; Initialize the buttons of the rotate context menu. rotate90Button = WIDGET_BUTTON(contextRotateBase, $ VALUE = 'Rotate 90 Degrees', EVENT_PRO = 'Rotate90Event') rotate180Button = WIDGET_BUTTON(contextRotateBase, $ VALUE = 'Rotate 180 Degrees', EVENT_PRO = 'Rotate180Event') rotate270Button = WIDGET_BUTTON(contextRotateBase, $ VALUE = 'Rotate 270 Degrees', EVENT_PRO = 'Rotate270Event') ; Initialize the base for the shift context menu. contextShiftBase = WIDGET_BASE(topLevelBase, /CONTEXT_MENU, $ UNAME = 'contextShift') ; Initialize the buttons of the shift context menu. shift025Button = WIDGET_BUTTON(contextShiftBase, $ VALUE = 'Shift One Quarter', EVENT_PRO = 'Shift025Event') shift050Button = WIDGET_BUTTON(contextShiftBase, $ VALUE = 'Shift One Half', EVENT_PRO = 'Shift050Event') shift075Button = WIDGET_BUTTON(contextShiftBase, $ VALUE = 'Shift Three Quarter', EVENT_PRO = 'Shift075Event') ; Initialize location variable. This variable contains ; the column value, the row value, and a location index. ; The location index determines if the text value represents ; a column value, or it represents a row value. locationIndex = 0 location = [column, row, locationIndex] ; Set initial title of the label for the text widget. title = 'Column: ' ; Initialize a base to contain the text widget and its label. textBase = WIDGET_BASE(listTextLabelBase, /ROW, /FRAME) ; Initialize the label of the text widget. titleLabel = WIDGET_LABEL(textBase, VALUE = title, $ /DYNAMIC_RESIZE, UNAME = 'xyLabel') ; Initialize the text widget. locationText = WIDGET_TEXT(textBase, VALUE = STRTRIM(column, 2), $ /EDITABLE, UNAME = 'xyText', /CONTEXT_EVENTS, $ UVALUE = location, EVENT_PRO = 'TextEvents') ; Initialize the base for the context menu. contextBase = WIDGET_BASE(topLevelBase, /CONTEXT_MENU, $ UNAME = 'contextMenu') ; Initialize the buttons of the context menu. columnButton = WIDGET_BUTTON(contextBase, $ VALUE = 'Column', EVENT_PRO = 'ColumnEvent') rowButton = WIDGET_BUTTON(contextBase, $ VALUE = 'Row', EVENT_PRO = 'RowEvent') ; Initialize the pixel information labels. labelBase = WIDGET_BASE(listTextLabelBase, /COLUMN, /FRAME) columnString = 'Column: ' + STRTRIM(column, 2) columnLabel = WIDGET_LABEL(labelBase, VALUE = columnString, $ UNAME = 'xLabel') rowString = 'Row: ' + STRTRIM(row, 2) rowLabel = WIDGET_LABEL(labelBase, VALUE = rowString, $ /DYNAMIC_RESIZE, UNAME = 'yLabel') valueString = 'Value: ' + STRTRIM(FIX(value), 2) valueLabel = WIDGET_LABEL(labelBase, VALUE = valueString, $ /DYNAMIC_RESIZE, UNAME = 'dataLabel') ; Display the GUI. WIDGET_CONTROL, topLevelBase, /REALIZE ; Set the UVALUE of the top level base to the image so ; it contain be accessed within the event handler routines. WIDGET_CONTROL, topLevelBase, SET_UVALUE = image ; Obtain the window ID of the draw widget. WIDGET_CONTROL, imageDraw, GET_VALUE = windowDraw ; Set the display to the window within the draw ; widget. WSET, windowDraw ; Initialize the display. DEVICE, DECOMPOSED = 0 LOADCT, 5 ; Display the image in the window of the draw ; widget. TV, image ; Determine the center location of the image display. column = imageSize[0]/2 row = imageSize[1]/2 ; Initially show the cursor in the center of the image ; display. TVCRS, column, row ; Handle the events from the GUI. XMANAGER, 'LocationAndValueApplication', topLevelBase, $ /NO_BLOCK END