IDL provides several routines that allow you to manipulate and manage widgets programmatically:
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_CONTROL for complete details. We discuss here only a few of the more common uses of this procedure.
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
base is the widget ID of the top-level base widget for your widget hierarchy.
The standard way to destroy a widget hierarchy is with the statement:
WIDGET_CONTROL, base, /DESTROY
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.
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 WSET, 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
WIDGET_CONTROL, event.id, GET_UVALUE=uval
For more on widget user values, see Widget User Values.
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.
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 simply 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
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_EVENT for 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)
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_INFO for 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 XMANAGER for 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 XREGISTERED for complete details.