IDL provides several routines that allow you to manipulate and manage widgets programmatically:
- WIDGET_CONTROL allows you to realize widget hierarchies, manipulate them, and destroy them.
- WIDGET_EVENT allows you to process events generated by a specific widget hierarchy.
- WIDGET_INFO allows you to obtain information about the state of a specific widget or widget hierarchy.
- XMANAGER provides an event loop and manages events generated by all existing widget hierarchies.
- XREGISTERED allows you to test whether a specific widget is currently registered with XMANAGER.
These widget manipulation routines are discussed in more detail in the following sections.
The WIDGET_CONTROL procedure allows you to realize, manage, and destroy widget hierarchies. It is often used to change the default behavior or appearance of previously-realized widgets.
Keywords to WIDGET_CONTROL may affect only certain types of widgets, any type of widget, or the widget system in general. See WIDGET_CONTROLfor complete details. We discuss here only a few of the more common uses of this procedure.
Realizing Widget Hierarchies
IDL widgets are actually widget records that represent platform-specific user interface toolkit elements. In order to instantiate the platform-specific toolkit elements, widgets must be realized with the following statement:
WIDGET_CONTROL, base, /REALIZE
where base is the widget ID of the top-level base widget for your widget hierarchy.
Destroying Widget Hierarchies
The standard way to destroy a widget hierarchy is with the statement:
WIDGET_CONTROL, base, /DESTROY
where base is the widget ID of the top-level base widget of the hierarchy to be killed. Usually, IDL programs that use widgets issue this statement in their event-handling routine in response to the user’s clicking on a “Done” button in the application.
In addition, some window managers place a pulldown menu on the frame of the top-level base widget that allows the user to kill the entire hierarchy. Using the window manager to kill a widget hierarchy is equivalent to using the DESTROY keyword to the WIDGET_CONTROL procedure.
When designing widget applications, you should always include a “Done” button (or some other widget that allows the user to exit) in the application itself, since some window managers do not provide the user with a kill option from the outer frame.
Retrieving or Changing Widget Values
You can use WIDGET_CONTROL to retrieve or change widget values using the GET_VALUE and SET_VALUE keywords. Similarly, you can retrieve or change widget user values with the GET_UVALUE and SET_UVALUE keywords.
For example, you could use the following commands to retrieve the value of a draw widget whose widget ID is stored in the variable drawwid, and to make that draw widget the current graphics window:
WIDGET_CONTROL, drawwid, GET_VALUE=draw
Similarly, you could use the following command in an event handling procedure to save the user value of the widget that generates an event into an IDL variable named uval:
WIDGET_CONTROL, event.id, GET_UVALUE=uval
For more on widget user values, see Widget User Values.
Controlling Widget Visibility
You can display or remove realized widgets from the screen by mapping or unmapping them. Unmapped widgets still exist in the widget hierarchy, but they are not displayed and do not generate events.
Set the MAP keyword to WIDGET_CONTROL equal to zero to hide a widget, or to a nonzero value to display it again. For example, to hide the base1 widget and all its child widgets from view, use the following command:
WIDGET_CONTROL, base1, MAP=0
By default, widgets are mapped automatically when they are realized. You can prevent a widget from appearing on screen when you realize it by setting MAP=0 before realizing the widget hierarchy.
Note: While it is possible to call WIDGET_CONTROL, MAP=0 with the widget ID of any widget, only base widgets can actually be unmapped. If you specify a widget ID that is not from a base widget, IDL searches upward in the widget hierarchy until it finds the closest base widget. The map operation is applied to that base.
Use sensitivity to control when a user is allowed to manipulate a widget. When a widget is sensitive, it has a normal appearance and can receive user input. When a widget is insensitive, it ignores any input directed at it. Note that while most widgets change their appearance when they become insensitive, some stop generating events.
Set the SENSITIVE keyword equal to zero to desensitize a widget, or to a nonzero value to make it sensitive. For example, you might wish to make a group of buttons contained in a base whose widget ID is stored in the variable bgroup insensitive after some user input. You would use the following command:
WIDGET_CONTROL, bgroup, SENSITIVE=0
Indicating Time-Consuming Operations
In an event driven environment, it is important that the interface be highly responsive to the user’s manipulations. Widget event handlers should be written to execute quickly and return. However, sometimes the event handler has no option but to perform an operation that is slow. In such a case, it is a good idea to give the user feedback that the system is busy. This is easily done using the HOURGLASS keyword just before the expensive operation is started:
This command causes IDL to turn on an hourglass-shaped cursor for all IDL widgets and graphics windows. The hourglass remains active until the next event is processed, at which point the previous cursor is automatically restored.
The WIDGET_EVENT function returns events for the widget hierarchy rooted at Widget_ID. Events are generated when a button is pressed, a slider position is changed, and so forth. In most cases, you will not use WIDGET_EVENT directly, but instead will use the XMANAGER routine to manage widget events. Event processing is discussed in detail in Widget Event Processing. See also WIDGET_EVENTfor additional details.
The WIDGET_INFO function is used to obtain information about the widget subsystem and individual widgets. You supply the widget ID of a widget for which you want to retrieve some information, along with a keyword that specifies the type of information. For example, to determine the index of the selected item in a list widget whose widget ID is contained in the variable list, you would use a command like the following:
listindex = WIDGET_INFO(list, /LIST_SELECT)
Finding Widget IDs using WIDGET_INFO
One noteworthy use of WIDGET_INFO is to locate the widget ID of a widget with a specified user name. (A user name is a part of the widget’s widget record that contains a text identifier, specified by the programmer.) See Working With Widget IDs for more information on this technique.
See WIDGET_INFOfor more information.
The XMANAGER procedure provides the main event loop registration and widget management. Calling XMANAGER “registers” a widget program with the XMANAGER event handler. XMANAGER takes control of event processing until all widgets have been destroyed.
Using XMANAGER allows you to run multiple widget applications and work at the IDL command line at the same time. While it is possible to use WIDGET_EVENT directly to manage events in your application, it is almost always easier to use XMANAGER.
See XMANAGERfor complete details.
The XREGISTERED function returns True if the widget specified by its argument is currently registered with the XMANAGER.
One use of the XREGISTERED function is to control the number of instances of a given widget application that run at a given time. For example, suppose that you have a widget program that registers itself with the XMANAGER with the command:
XMANAGER, 'mywidget', base
You could limit this widget to one instantiation by adding the following line as the first line (after the procedure definition statement) of the widget creation routine:
IF (XREGISTERED('mywidget') NE 0) THEN RETURN
See XREGISTEREDfor complete details.