The following example demonstrates how user values can be used to simplify event processing and to pass values between routines. It creates a base widget with three buttons and a text field that reports which button was pressed.

Note: If you are new to IDL widget programming, some parts of this example may not be immediately clear to you. As you read further through this section, the principles of the event-driven programming model and IDL’s specific implementation of that model will become clearer.

This example is included in the file doc_widget2.pro in the examples/doc/widgets subdirectory of the IDL distribution. Run this example procedure by entering doc_widget2 at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT doc_widget2.pro. See Running the Example Code if IDL does not run the program as expected.

PRO doc_widget2_event, ev
  WIDGET_CONTROL, ev.TOP, GET_UVALUE=textwid
  WIDGET_CONTROL, ev.ID, GET_UVALUE=uval
  CASE uval OF
    'ONE' : WIDGET_CONTROL, textwid, SET_VALUE='Button 1 Pressed'
    'TWO' : WIDGET_CONTROL, textwid, SET_VALUE='Button 2 Pressed'
    'DONE': WIDGET_CONTROL, ev.TOP, /DESTROY
  ENDCASE
END
 
PRO doc_widget2
  base = WIDGET_BASE(/COLUMN)
  button1 = WIDGET_BUTTON(base, VALUE='One', UVALUE='ONE')
  button2 = WIDGET_BUTTON(base, VALUE='Two', UVALUE='TWO')
  text = WIDGET_TEXT(base, XSIZE=20)
  button3 = WIDGET_BUTTON(base, value='Done', UVALUE='DONE')
  WIDGET_CONTROL, base, SET_UVALUE=text
  WIDGET_CONTROL, base, /REALIZE
  XMANAGER, 'doc_widget2', base
END

Let’s examine the creation routine, doc_widget2, first. We first create a top-level base, this time specifying the COLUMN keyword to ensure that the widgets contained in the base are stacked vertically. We create two buttons with values “One” and “Two,” and user values “ONE” and “TWO.” Remember that the value of a button widget is also the button’s label. We create a text widget, and specify its width to be 20 characters using the XSIZE keyword. The last button is the “Done” button, with a the user value “DONE.”

Next follow two calls to the WIDGET_CONTROL procedure. The first call sets the user value of the top-level base widget equal to the widget ID of our text widget, allowing easy access to the text widget from the event handling routine. The second call realizes the top-level base and all its child widgets. Finally, we invoke the XMANAGER to manage the widget application.

The doc_widget2_event routine is slightly more complicated than the event handler in Example: A Simple Widget Application, but it is still relatively simple. We begin by using WIDGET_CONTROL to retrieve the widget ID of our text widget from the user value of the top-level base. We can do this because the widget ID of our top-level base is contained in the TOP field of the widget event structure. We use the GET_UVALUE keyword to store the widget ID of the text widget in the variable textwid.

Next, we use WIDGET_CONTROL with the GET_UVALUE keyword to retrieve the user value of the widget that generated the event. Again, we can do this because we know that the widget ID of the widget that generated the event is stored in the ID field of the event structure. We then use a CASE statement to compare the user value of the widget, now stored in the variable uval, with the list of possible user values to determine which button was pressed and act accordingly.

In the CASE statement, we check to see if uval is the user value associated with either button one or button two. If it is, we use WIDGET_CONTROL and the SET_VALUE keyword to alter the value of the text widget, whose ID we stored in the variable textwid. If uval is 'DONE', we recognize that the user has clicked on the “Done” button and use WIDGET_CONTROL to destroy the widget hierarchy.