Creating the Interface Routine

The IDL procedure that creates your custom iTool widget interface will look much like a widget creation routine from a traditional widget application. This section points out some things you should be aware of.

Note
Code fragments used in this section, and those that follow, are taken from the example custom interface developed in Example: a Custom iTool Interface.

Routine Signature

Your widget creation routine should be an IDL procedure with a signature that looks something like:

PRO example2_wdtool, oTool, TITLE = titleIn, $ 
   LOCATION = location, $ 
   VIRTUAL_DIMENSIONS = virtualDimensions, $ 
   USER_INTERFACE = oUI, $  ; output keyword 
   _REF_EXTRA = _extra 

where:

Your routine may handle other keyword values as well.

Error Checking

Since the successful creation of an iTool interface relies on the presence of a valid iTool object reference, it is a good idea to check the oTool argument before proceeding. A statement like the following serves as a reasonable check:

IF (~OBJ_VALID(oTool)) THEN $ 
   MESSAGE, 'Tool is not a valid object.' 
 

Top Level Base

The first widget you will need to create when building a custom iTool widget interface is a top-level widget base to hold the interface. Your call to the WIDGET_BASE function should look something like:

wBase = WIDGET_BASE(/COLUMN, MBAR = wMenubar, $ 
   TITLE = title, $ 
   /TLB_KILL_REQUEST_EVENTS, $ 
   /TLB_SIZE_EVENTS, $ 
   /KBRD_FOCUS_EVENTS, $ 
   _EXTRA = _extra) 

All of the keywords shown here are documented along with the WIDGET_BASE function, but you should note the following things:

User Interface Object

Your widget interface must be associated with an iTool user interface object. Since we will need the object reference to the user interface object when creating the iTool compound widgets, we include the following statement after creating our top level base widget:

oUI = OBJ_NEW('IDLitUI', oTool, GROUP_LEADER = wBase) 

Note that we need the iTool object that was the argument to our interface creation routine to create the user interface object. Note also that we specify our top level base as the GROUP_LEADER of the interface object; this will ensure that any floating or modal dialogs displayed by the interface appear in the correct place.

Widget Creation and Layout

Your custom iTool interface can include both iTool compound widgets and traditional IDL widgets. These are created in the same way as in a traditional widget application. The finer points of creating iTool compound widgets are discussed in later sections of this chapter.

User Interface Registration

Near the end of the widget creation routine, after the widget hierarchy has been realized, we must register the top-level base with the user interface object:

myID = oUI->RegisterWidget(wBase, 'Example 2 Tool', $ 
   'example2_wdtool_callback') 

Here we specify the name of the callback routine that will handle messages from the iTool components. The return value from the RegisterWidget method is the iTool full identifier of the widget interface. We next use the identifier to specify that the interface is an observer (that is, that it can receive messages generated by iTool components) for the associated iTool:

oUI->AddOnNotifyObserver, myID, oTool->GetFullIdentifier() 

This ensures that messages generated by the iTool are handled by the specified callback routine.

Handling Widget Destruction

Many complex interfaces rely on a state structure containing information about the widgets in the interface. If you pass a reference to this state structure between routines in your user interface code using one or more pointers, free the pointers when the widget interface is destroyed. In our example interface, a pointer to the state structure is stored in the user value of the first child widget of the top level base widget. The following statement specifies a routine to be called when the widgets are destroyed:

WIDGET_CONTROL, wChild, KILL_NOTIFY = "example2_wdtool_cleanup" 

Issues related to the destruction of the interface are discussed in more detail in Handling Shutdown Events.