Creating a New iTool Class

An iTool object class definition file must contain, at the least, the class Init method and the class structure definition routine. The Init method contains the statements that register any operations, visualizations, manipulators, and file readers or writers available in the iTool. The class structure definition routine defines an IDL structure that will be used when creating new instances of the iTool object.

The process of creating an iTool definition is outlined in the following sections:

Creating the Class Structure Definition

When any IDL object is created, IDL looks for an IDL class structure definition that specifies the instance data fields needed by an instance of the object, along with the data types of those fields. The object class structure must have been defined before any objects of the type are created. In practice, when the IDL OBJ_NEW function attempts to create an instance of a specified object class, it executes a procedure named ObjectClass__define (where ObjectClass is the name of the object), which is expected to define an IDL structure variable with the correct name and structure fields. For additional information on how IDL creates object instances, see The Object Lifecycle (Object Programming).

Note
The class structure definition is generally the last routine in the .pro file that defines an object class.

Subclassing from the IDLitToolbase Class

The IDLitToolbase class defines the base operations and user interface functionality used in iTools created by ITT Visual Information Solutions. If your aim is to create an iTool that has base functionality similar to that included in the standard iTools, you will want to subclass from the IDLitToolbase class, or from another tool that subclasses from the IDLitToolbase class.

The IDLitToolbase class registers a large number of operations, manipulators, file readers, and file writers. This base feature set may change from release to release; inspect the file idlittoolbase__define.pro in the lib/itools subdirectory of your IDL distribution for the exact set of features included in your distribution.

Note
To create an iTool that does not include the standard iTool functionality, subclass from the IDLitTool class.

In general, the IDLitToolbase class registers the following types of features:

Standard menu items

Operations that appear in the File, Edit, Insert, Window, and Help menus are defined in the IDLitToolbase class. If you are building a subclass of the IDLitToolbase class, you have the option of adding items to or removing items from these menus in your own class definition file.

Operations menu items

Standard data-centric operations provided as part of the iTools distribution and which appear in all of the standard iTools are placed on the Operations menu by the IDLitToolbase class.

Context menu items

Standard operations such as Cut, Copy, Paste, Group, Ungroup, etc. are included on the context menu by the IDLitToolbase class.

Toolbar items

Operations that enable standard File and Edit menu functionality are placed on the toolbar by the IDLitToolbase class. In addition, standard manipulators (zoom, arrow, and rotate), and annotations (text, line, rectangle, oval, polygon, and freeform) are placed on the toolbar.

File readers

All file readers included in the iTools distribution are registered by the IDLitToolbase class. File readers do not appear in the iTool interface, but are used automatically when importing a data file.

File writers

All file writers included in the iTools distribution are registered by the IDLitToolbase class. File writers do not appear in the iTool interface, but are used automatically when exporting data to a file.

Hiding Compilation Messages

When IDL compiles an object class, it prints a compilation message similar to the following to the IDL Console:

% Compiled module: FIRSTEXAMPLETOOL__DEFINE. 

To prevent the compilation message from appearing when the class is compiled, add the following line to the class structure definition:

COMPILE_OPT hidden 

Example Class Structure Definition

The following is a very simple iTool class structure definition for an iTool named FirstExampleTool. This procedure should be the last procedure in a file named firstexampletool__define.pro.

PRO FirstExampleTool__Define 
 
   COMPILE_OPT hidden 
 
   struct = { FirstExampleTool,             $ 
            INHERITS IDLitToolbase    $ ; Provides iTool interface 
           } 
END 

Discussion

The purpose of the structure definition routine is to define a named IDL structure with structure fields that will contain the iTool object instance data. The structure name should be the same as the iTool's class name — in this case, FirstExampleTool.

Like many iTools, FirstExampleTool is created as a subclass of the IDLitToolbase class. iTools that subclass from IDLitToolbase inherit all of the standard iTool functionality, as described in Subclassing from the IDLitToolbase Class.

Note
This example is intended to demonstrate how simple it can be to create a new iTool class definition. While the class definition for an iTool with significant extra functionality will likely define additional structure fields, and may inherit from other iTool classes, the basic principles are the same.

Creating an Init Method

The iTool class Init method handles any initialization required by the iTool object, and should do the following:

Definition of the Init Function

Begin by defining the argument and keyword list for your Init method. The argument and keyword list defines positional parameters (arguments) accepted by your method, defines any keywords that will be handled directly by your method, and specifies that keywords not explicitly handled by your method will be passed through to other routines called by your method via IDL's keyword inheritance mechanism. The Init method for a tool generally looks something like this:

FUNCTION MyTool::Init, MYKEYWORD1 = mykeyword1, $ 
   MYKEYWORD2 = mykeyword2, ..., _REF_EXTRA = _extra 

where MyTool is the name of your tool class and the MYKEYWORD parameters are keywords handled explicitly by your Init function.

Note
Always use keyword inheritance (the _REF_EXTRA keyword) to pass keyword parameters through to any called routines. See Keyword Inheritance (Application Programming) for details on IDL's keyword inheritance mechanism.

Superclass Initialization

The iTool class Init method should call the Init method of any required superclasses. For example, if your iTool is based on an existing iTool, you would call that tool's Init method:

success = self->SomeToolClass::Init(_EXTRA = _extra) 

where SomeToolClass is the class definition file for the iTool on which your new iTool is based. The variable success contains a 1 if the initialization was successful.

Note
Your iTool class may have multiple superclasses. In general, each superclass' Init method should be invoked by your class' Init method.

Error Checking

Rather than simply calling the superclass Init method, it is a good idea to check whether the call to the superclass Init method succeeded. The following statement checks the value returned by the superclass Init method; if the returned value is 0 (indicating failure), the current Init method also immediately returns with a value of 0:

IF (self->SomeToolClass::Init(_EXTRA = _extra) EQ 0) THEN RETURN, 
0 

This convention is used in all iTool classes included with IDL. W strongly suggest that you include similar checks in your own class definition files.

Keywords to the Init Method

Properties of the iTool class can be set in the Init method by specifying the property names and values as IDL keyword-value pairs. In addition to any keywords implemented directly in the Init method of the superclass on which you base your class, the properties of the IDLitTool class are available to any iTool class. See "IDLitTool Properties" (IDL Reference Guide).

Note
Always use keyword inheritance (the _EXTRA keyword) to pass keyword parameters through to the superclass. See Keyword Inheritance (Application Programming) for details on IDL's keyword inheritance mechanism.

Standard Base Class

While you can create your new iTool from any existing iTool class, in many cases, iTool classes you create will be subclassed directly from the base class IDLitToolbase:

IF (self->IDLitToolbase::Init(_EXTRA = _extra) EQ 0) THEN $ 
   RETURN, 0 
 

The IDLitToolbase class provides the base iTool functionality used in the tools created by ITT Visual Information Solutions. See Subclassing from the IDLitToolbase Class for details.

Note
To create an iTool that does not include the standard iTool functionality, subclass from the IDLitTool class.

Return Value

If all of the routines and methods used in the Init method execute successfully, the method should indicate successful initialization by returning 1. Other iTools that subclass from your iTool class may check this return value, as your routine should check the value returned by any superclass Init methods called.

Registering Visualizations

Registering a visualization type with an iTool class allows instances of the iTool to create and display visualizations of that type. Any number of visualization types can be registered for use by a given iTool.

Note
You must register at least one visualization type with your iTool class. Unlike operations, manipulators, and file readers and writers, no visualization types are registered by the IDLitToolbase class.

Visualization types are registered by calling the IDLitTool::RegisterVisualization method:

self->RegisterVisualization, Visualization_Type, $ 
   VisType_Class_Name 

where Visualization_Type is the string you will use when referring to the visualization type, and VisType_Class_Name is a string that specifies the name of the class file that contains the visualization type's definition.

Note
The file VisType_Class_Name__define.pro must exist somewhere in IDL's path for the visualization type to be successfully registered.

For example, the following method call registers a visualization type named myVis for which the class definition is stored in the file myVisualization__define.pro:

self->RegisterVisualization, 'myVis', 'myVisualization' 

See Registering a Visualization Type for additional details. See Predefined iTool Visualization Classes for a list of visualization types included in the iTool system as installed with IDL.

Registering Operations

Registering an operation with an iTool class allows instances of the iTool to apply the registered operation to data selected in the iTool. Any number of operations can be registered with a given iTool.

Operations are registered by calling the IDLitTool::RegisterOperation method:

self->RegisterOperation, Operation_Type, OpType_Class_Name, $ 
   IDENTIFIER = identifier 

where Operation_Type is the string you will use when referring to the operation, OpType_Class_Name is a string that specifies the name of the class file that contains the operation's definition, and identifier is a string containing the operation's iTool identifier. (The identifier is used to specify where on the iTool's menu bar the operation will appear. See iTool Object Identifiers for a discussion of iTool system identifiers.)

Note
The file OpType_Class_Name__define.pro must exist somewhere in IDL's path for the visualization type to be successfully registered.

For example, the following method call registers an operation named myOp for which the class definition is stored in the file myOperation__define.pro, and places the menu selection Change My Data in the Filters folder of the iTool Operations menu.

self->RegisterVisualization, 'myOp', 'myOperation', $ 
   IDENTIFIER = 'Operations/Filters/Change My Data' 

See Registering an Operation for additional details. See Predefined iTool Operations for a list of operations included in the iTool system as installed with IDL.

Registering Manipulators

Registering a manipulator with an iTool class allows instances of the iTool to enable the registered manipulator for use in the iTool. Any number of manipulators can be registered with a given iTool.

Manipulators are registered by calling the IDLitTool::RegisterManipulator method:

self -> RegisterManipulator, ManipulatorName, $ 
   Manipulator_Class_Name, ICON = icon 

where ManipulatorName is the string you will use when referring to the manipulator, Manipulator_Class_Name is a string that specifies the name of the class file that contains the manipulator's definition, and icon is a string containing the name of a bitmap file to be used in the toolbar button. (See Icon Bitmaps for details on where bitmap icon files are located.).

Note
The file Manipulator_Class_Name__define.pro must exist somewhere in IDL's path for the visualization type to be successfully registered.

For example, the following method call registers a manipulator named myManip for which the class definition is stored in the file myManipulator__define.pro, and specifies the file arrow.bmp located in the bitmaps subdirectory of the resource subdirectory of the IDL distribution as the icon to use on the toolbar.

self -> RegisterManipulator, 'myManip', 'myManipulator', $ 
   ICON = 'arrow' 

See Registering a Manipulator for additional details. See Predefined iTool Manipulators for a list of manipulators included in the iTool system as installed with IDL.

Registering File Readers and Writers

Registering a file reader or file writer with an iTool class allows instances of the iTool to read or write files of the type handled by the reader or writer. Any number of file readers and writers can be registered with a given iTool.

File readers are registered by calling the IDLitTool::RegisterFileReader method:

self->RegisterFileReader, Reader_Type, ReaderType_Class_Name, $ 
   ICON = icon 

where Reader_Type is the string you will use when referring to the file reader, ReaderType_Class_Name is a string that specifies the name of the class file that contains the file writer's definition, and icon is a string containing the name of a bitmap file used to represent the file reader.

Similarly, file writers are registered by calling the IDLitTool::RegisterFileWriter method:

self->RegisterFileWriter, Writer_Type, WriterType_Class_Name, $ 
   ICON = icon 

where Reader_Type is the string you will use when referring to the file reader, ReaderType_Class_Name is a string that specifies the name of the class file that contains the file writer's definition, and icon is a string containing the name of a bitmap file used to represent the file writer. See Icon Bitmaps for details on where bitmap icon files are located.

Note
The class definition files ReaderType_Class_Name__define.pro or WriterType_Class_Name__define.pro must exist somewhere in IDL's path for the file reader or writer to be successfully registered.

For example, the following method call registers a file reader named myReader for which the class definition is stored in the file myFileReader__define.pro, and specifies the file reader.bmp located in the home/mydir directory as the icon to use on the toolbar.

self->RegisterFileReader, 'myReader', 'myFileReader', $ 
   ICON = '/home/mydir/reader.bmp' 

See Registering a File Reader for additional details. See Predefined iTool File Readers for a list of file readers included in the iTool system as installed with IDL.

Similarly, the following method call registers a file writer named myWriter for which the class definition is stored in the file myFileWriter__define.pro, and specifies the file writer.bmp located in the home/mydir directory as the icon to use on the toolbar.

self->RegisterFileReader, 'myWriter', 'myFileWriter', $ 
   ICON = '/home/mydir/writer.bmp' 

See Registering a File Writer for additional details. See Predefined iTool File Writers for a list of file writers included in the iTool system as installed with IDL.

Example Init Method

The following example code shows a very simple Init method for an iTool named FirstExampleTool. This function should be included in a file named FirstExampleTool__define.pro.

FUNCTION FirstExampleTool::Init, _REF_EXTRA = _extra 
 
; Call the Init method of the super class. 
IF (self->IDLitToolbase::Init(NAME='FirstExampleTool', $ 
   DESCRIPTION = 'Example Tool Class', _EXTRA = _extra) EQ 0) THEN 
$ 
   RETURN, 0 
 
; Register a visualization 
self->RegisterVisualization, 'Image', 'IDLitVisImage', $ 
   ICON = 'image' 
 
; Register an operation 
self->RegisterOperation, 'Byte Scale', 'IDLitOpBytScl', $ 
   IDENTIFIER = 'Operations/Byte Scale' 
 
RETURN, 1 
 
END 

Discussion

The FirstExampleTool is based on the IDLitToolbase class (discussed in Subclassing from the IDLitToolbase Class). As a result, all of the standard iTool operations, manipulators, file readers and writers are already present. The FirstExampleTool Init method needs to do only three things:

  1. Call the Init method of the superclass, IDLitToolbase, using the _EXTRA keyword inheritance mechanism to pass through any keywords provided when the FirstExampleTool Init method is called.
  2. Register a visualization type for the tool. We choose the standard image visualization defined by the idlitvisimage__define.pro class definition file,
  3. Register an operation. We choose an operation that implements the IDL BYTSCL function, defined by the idlitopbytscl__define.pro class definition file and place a menu item in the iTool Operations menu.
  4. Note
    This example is intended to demonstrate how simple it can be to create a new iTool class definition. While the class definition for an iTool with significant extra functionality will register more features, the process is the same.

Unregistering Components

In some cases, you may want to subclass from an iTool class that contains features you do not want to include in your class. Rather than building a class that duplicates most, but not all, of the functionality of the existing class, you can create a subclass that explicitly unregisters the components that you don't want included.

For each Register method of the IDLitTool class there is a corresponding UnRegister method. Call the UnRegister method with the Name you used when registering the component. For example, if your superclass registers an operation with the identifier 'MultiplyBy100' and you do not want this operation included in your class, you would include the following method call in your iTool class Init method:

self->UnRegisterOperation, 'MultiplyBy100'