iTool Programming IDL Version 7.
Restricted Rights Notice The IDL®, IDL Analyst™, ENVI®, and ENVI Zoom™ software programs and the accompanying procedures, functions, and documentation described herein are sold under license agreement. Their use, duplication, and disclosure are subject to the restrictions stated in the license agreement. ITT Visual Information Solutions reserves the right to make changes to this document at any time and without notice.
Contents Chapter 1 Overview of iTools ................................................................................... 9 What are iTools? ............................................................................................................. What is the iTools Component Framework? ................................................................... About this Manual ...........................................................................................................
Registering Components .................................................................................................. 38 iTool Messaging System .................................................................................................. 41 System Resources ............................................................................................................ 44 Chapter 3 Data Management .................................................................................
Chapter 6 Creating a Visualization ...................................................................... 113 Overview of iTool Visualization Types ........................................................................ Predefined iTool Visualization Classes ......................................................................... Creating a New Visualization Type .............................................................................. Registering a Visualization Type .............................
Creating a New File Reader ........................................................................................... 234 Registering a File Reader ............................................................................................... 245 Unregistering a File Reader ........................................................................................... 246 Example: TIFF File Reader ...........................................................................................
Chapter 14 Creating a User Interface Panel ......................................................... 311 Overview of the iTool UI Panel .................................................................................... Creating a UI Panel Interface ........................................................................................ Creating Callback Routines ........................................................................................... Registering a UI Panel ...........................
Appendix B iTool Compound Widgets .................................................................. 397 Overview of iTools Compound Widgets ....................................................................... 398 CW_ITMENU ................................................................................................................ 399 CW_ITPANEL .............................................................................................................. 404 CW_ITSTATUSBAR ........................
Chapter 1 Overview of iTools This chapter provides an overview of the IDL iTool Component Framework. What are iTools? . . . . . . . . . . . . . . . . . . . . . 10 What is the iTools Component Framework? 11 About this Manual . . . . . . . . . . . . . . . . . . . . 12 iTool Developer’s Guide About the iTools Code Base . . . . . . . . . . . . 13 Skills Required to Use the iTools Component Framework . . . . . . . . . . . . . . . . . . . . . . . . .
Chapter 1: Overview of iTools What are iTools? IDL Intelligent Tools, or iTools, are applications written in IDL to perform a variety of data analysis and visualization tasks. iTools share a common underlying application framework, presenting a full-featured, customizable, application-like user interface with menus, toolbars, and other graphical features.
Chapter 1: Overview of iTools 11 What is the iTools Component Framework? The iTools component framework is a set of object class definitions written in the IDL language.
Chapter 1: Overview of iTools About this Manual The iTool Developer’s Guide describes the IDL iTools component framework and provides examples of its use. After reading this manual, you will understand how to use the component framework to create your own intelligent tools.
Chapter 1: Overview of iTools 13 About the iTools Code Base The iTools component framework is written almost entirely in the IDL language. The IDL code that implements both the component framework and all of the standard iTools included with IDL is available for you to inspect, copy, and learn from. To inspect the iTools code, look in the lib/itools subdirectory of your IDL installation directory.
Chapter 1: Overview of iTools • The core iTool component framework classes used to build individual iTools, visualization types, operations, etc. are formally documented in the IDL Reference Guide and discussed in detail in this manual. If an object class, method, or property is necessary for the construction of a new iTool or component of an iTool, it is formally documented in the IDL Reference Guide or in this manual.
Chapter 1: Overview of iTools 15 Skills Required to Use the iTools Component Framework The iTools component framework consists of a set of IDL object classes, supplemented by utility routines. If you are already familiar with the concepts of object-oriented programming, or have written programs that use IDL object graphics, you will find the iTools framework easy to understand and use.
Skills Required to Use the iTools Component Framework Chapter 1: Overview of iTools iTool Developer’s Guide
Part I: Understanding the iTools Component Framework
Chapter 2 iTool System Architecture This chapter describes the iTool component framework architecture. Overview of the iTool System Architecture iTools Object Model Diagram . . . . . . . . . . . iTool Object Identifiers . . . . . . . . . . . . . . . . iTool Object Hierarchy . . . . . . . . . . . . . . . . iTool Developer’s Guide 20 21 28 31 Registering Components . . . . . . . . . . . . . . 38 iTool Messaging System . . . . . . . . . . . . . . 41 System Resources . . . . . . . . . . . . . . . . . . . .
Chapter 2: iTool System Architecture Overview of the iTool System Architecture The iTool system architecture is designed to maintain a separation between the functionality provided by an iTool and the graphical presentation layer that reveals that functionality to an iTool user (the iTool user interface).
iTool Developer’s Guide Figure 2-1: iTools Object Model Hierarchy The following figure shows inheritance among the iTools component object classes that define the base functionality of all iTools. The diagram is intended to provide a visual overview of the structure of the iTools, and to provide a quick indication of the methods and properties available to objects of a given class. See the IDL Reference Guide for details regarding the available properties and methods of these components.
Chapter 2: iTool System Architecture Every iTool is constructed using the hierarchy of predefined and documented object classes shown in the previous figure. Each of these predefined (as opposed to userdefined) object classes are available to use or customize in your iTool application. However, there is no need to create and instantiate the entire hierarchy when creating a custom iTool object.
Chapter 2: iTool System Architecture 23 for additional information about iTools code and the differences between documented and undocumented classes. IDLitVisualization Classes The IDLitVisualization class provides methods for adding, deleting, and grouping objects within a visualization. The following predefined classes contain graphic objects and other visualizations.
Chapter 2: iTool System Architecture on included functionality. See the iTool User’s Guide for information on using individual iTools. • IDLitToolContour (iContour tool) • IDLitToolSurface (iSurface tool) • IDLitToolImage (iImage tool) • IDLitToolVolume (iVolume tool) • IDLitToolMap (iMap tool) • IDLitToolVector (iVector tool) • IDLitToolPlot (iPlot tool) IDLitData Classes The IDLitData class stores core IDL data types, gets and sets data, and receives updates regarding data changes.
Chapter 2: iTool System Architecture 25 IDLitWriter Classes The IDLitWriter class contains predefined file writers that export graphics or data to a file of a specified type. See Chapter 10, “Creating a File Writer” for details on creating and using file writers.
Chapter 2: iTool System Architecture IDLitManipulator Classes The IDLitManipulator class allows the user to select and interact with a visualization through mouse movements and keyboard events. See Chapter 8, “Creating a Manipulator” for information on the following predefined manipulators and creating a new manipulator.
Chapter 2: iTool System Architecture 27 • IDLgrPlot • IDLgrText • IDLgrPolygon • IDLgrVolume iTool Developer’s Guide iTools Object Model Diagram
Chapter 2: iTool System Architecture iTool Object Identifiers iTool object identifiers are simple strings that uniquely identify individual objects within the hierarchy of iTool objects in much the same way that a computer file system identifies files within a hierarchy of files.
Chapter 2: iTool System Architecture 29 Similarly, the identifier string OPERATIONS/FILTERS/MY FILTER refers to an object named MY FILTER, located in a sub-container of the iTool-level OPERATIONS container named FILTERS. Because the identifier is relative, the MY FILTER object is visible only to the current iTool. Note Object identifiers are stored as upper-case strings. Spaces are allowed.
Chapter 2: iTool System Architecture Proxy Identifiers Because the location of an object in the iTool object hierarchy corresponds to the place that object is made visible to iTool users, you may at times want an object to be located in multiple places in the iTool object hierarchy. For example, the Undo operation appears in two places in the standard iTool user interface: under the Edit menu and on the toolbar.
Chapter 2: iTool System Architecture 31 iTool Object Hierarchy The iTool system is a collection of object class instances organized in a hierarchy of container objects. The hierarchy serves both to organize the numerous object instances and to display information about the objects in the iTool user interface. In most cases, an object’s location in the iTool hierarchy controls where and how the object is made visible in the user interface.
Chapter 2: iTool System Architecture /TOOLS This container holds references to all active iTools. /CLIPBOARD This container holds items that are on the local system clipboard. /REGISTRY This container holds object descriptors for the iTool object classes that are registered with the system object. Individual iTools, Visualization types, and User Interface types can all be registered with the system object; other iTool object types are registered only with the individual iTool to which they belong.
Chapter 2: iTool System Architecture 33 iTool Objects Individual iTool tool objects contain all objects that are directly associated with a particular instance of a particular iTool. Any number of tool objects can exist; their unique identifiers are found in the /TOOLS container of the iTools system object. As an iTool developer, you will use both the tool’s object reference and its object identifier inside your code.
Chapter 2: iTool System Architecture iTool. Default properties of file readers can be set interactively via the System Preferences dialog. See Chapter 9, “Creating a File Reader” for more on file readers. For example, the relative identifier for the ASCII file reader is: FILE READERS/ASCII TEXT FILE WRITERS A file writer is an iTool component object that contains the information necessary to create a file from data stored in the iTools data manager.
Chapter 2: iTool System Architecture 35 container, the second specifies that it appears in the Operations menu. For example, the relative identifier for the Statistics operation is: OPERATIONS/OPERATIONS/STATISTICS TOOLBAR A toolbar is an iTool component object that contains information about buttons that should be displayed in the iTool’s main interface. The TOOLBAR container holds the object descriptors of operations, manipulators, and annotations that are exposed via the iTool’s toolbar.
Chapter 2: iTool System Architecture DATA SPACE A data space is an iTool component that manages the data range, transformation matrix, and other data-centric properties of visualizations in a visualization layer. Each data space contains one or more visualizations.
Chapter 2: iTool System Architecture 37 Note Annotation numbering is zero-based — that is, the first annotation of a specific type created within a data space is number zero. The object identifier for the first annotation, however, does not include the number. Identifiers for additional annotations of the same type within the same data space do include the number.
Chapter 2: iTool System Architecture Registering Components Registering an object class links the file containing the IDL code that defines the object (an iTool, a visualization type, an operation, etc.) with the object identifier. Objects can be registered either with the iTool system object (in which case their identifiers are fully qualified) or with an individual iTool class (in which case their identifiers are relative to the iTool or to a specific container within the tool).
Chapter 2: iTool System Architecture 39 iTool except for visualization types, which may have been registered with the iTool system object. Note Many operations, manipulators, file readers, and file writers are registered by the IDLitToolbase class. If you create a new iTool based on this class, these features will be registered automatically. See “Subclassing from the IDLitToolbase Class” on page 91 for details.
Chapter 2: iTool System Architecture hierarchy in the specified place, but actually calls the original object when a user requests the proxied object. To register a proxy object, specify an object identifier string as the value of the PROXY keyword to the Register method.
Chapter 2: iTool System Architecture 41 iTool Messaging System Notifications are messages sent from one iTool component to one or more observer components. The iTool messaging system provides a unified way for components to notify each other of important changes; it is quite general, and can be used to send messages related to any type of change. Some examples: • Visualizations send notifications when components of the visualization are selected or unselected.
Chapter 2: iTool System Architecture The IdOriginator argument is generally the object identifier of an iTool component object, but it can be any string value. Notification Messages The value of the IdMessage argument to the DoOnNotify method is a string value that must uniquely identify the message being sent.
Chapter 2: iTool System Architecture Message String SENSITIVE UNSENSITIVE 43 Meaning The SENSITIVE property of a component has changed. Value contains an empty string. VIEW_PAN The currently selected view has been panned. Value is a two-element integer vector [x, y] specifying the location of the lower left corner of the visible portion of the view relative to the lower left corner of the entire view. VIEW_ZOOM The currently selected view has been zoomed.
Chapter 2: iTool System Architecture System Resources This section contains information on resources used by the iTool system. Icon Bitmaps Some iTool components have associated icons. Icons for iTool components are displayed in the tree view of a browser window. Bitmaps used as icons in the iTool system must be either .bmp or .png files. The images contained in icon bitmap files can be either True Color (24-bit color) images or paletted (8-bit color) images.
Chapter 2: iTool System Architecture 45 iconPath = path + iconName This code uses the ROUTINE_INFO function to retrieve the path to the file specified by the string routineName. It then extracts the directory that contains the file using the FILE_DIRNAME function, and concatenates the directory name with the name of the bitmap file contained in the string iconName. Note The routine specified by routineName must have been compiled for the ROUTINE_INFO function to return the correct value.
Chapter 2: iTool System Architecture Note You must also copy the file /help/itools.xsd into your help directory. See “Example: Help Topic for MyVisType” on page 48 for an example outlining the process of creating a help topic for a user-created iTool component. Format of Help Entries The format for a help entry in the *help.
Chapter 2: iTool System Architecture 47 The book attribute of the element defines the location of your iTool’s help system. The type of file specified as the value for the book attribute depends on the value of the type attribute: Link type Value of book attribute IDLHELP The book attribute should contain the name of your help system’s .adp file. MSHTMLHELP The book attribute should contain the name of your help system’s .chm file.
Chapter 2: iTool System Architecture The value of the element specifies the specific content to be displayed from the help system specified by the book attribute. The value depends on the value of the type attribute: Link type Value of the Link Element IDLHELP The base name of an HTML file (do not include the file extension) to be displayed in the main window of the IDL Assistant help viewer. The file must be located in the same directory as the help system’s .adp file.
Chapter 2: iTool System Architecture 49 MyVisType.html to describe it. In order to display your HTML file when the user selects a MyVisType visualization and selects Help → Help on Selected Item, you would do something like the following: 1. Install the MyVisType.html file somewhere. Installing the file in the same directory as the MyVisType__define.pro and other associated iTool files would be a reasonable choice, and for the purposes of this example we assume this is the location of the file.
System Resources Chapter 2: iTool System Architecture iTool Developer’s Guide
Chapter 3 Data Management This chapter describes the iTool data management system. Overview of iTool Data Management . . . . . iTool Data Manager . . . . . . . . . . . . . . . . . . . iTool Data Types . . . . . . . . . . . . . . . . . . . . . iTool Data Objects . . . . . . . . . . . . . . . . . . . . iTool Developer’s Guide 52 53 54 56 Predefined iTool Data Classes . . . . . . . . . . Parameters . . . . . . . . . . . . . . . . . . . . . . . . . Data Type Matching . . . . . . . . . . . . . . . . . .
Chapter 3: Data Management Overview of iTool Data Management The iTools system is designed to turn raw data — numbers stored in computer memory — into visualizations that convey information to the viewer. Using data to create a visual display requires some way to route each piece of data to the appropriate part of the algorithm that displays it. In the terminology used by the iTool system, each data item must be associated with a parameter of a visualization.
Chapter 3: Data Management 53 iTool Data Manager Data imported into the iTool system is stored in a separate data object hierarchy that is available to all iTools. When a data item is placed in the data manager hierarchy, whether interactively by a user or automatically by some operation of an iTool, the data item is immediately visible to all iTools. The hierarchy of the data manager reflects the hierarchy of the data containers (IDLitDataContainer and IDLitParameterSet objects) it holds.
Chapter 3: Data Management iTool Data Types Every iTool data item (IDLitData object or IDLitDataContainer object) has an associated iTool data type. The iTool data type of a data item is specified via the TYPE property of the data object, which can contain any scalar string. Note Do not confuse iTool data types with IDL’s inherent data types — integers and floating-point integers of various sizes and precisions, strings, structures, pointers, and object references.
Chapter 3: Data Management 55 Table 3-1 lists the iTool data types defined by the standard iTools included with IDL. You should avoid using these iTool data type names when defining data objects that do not match the contents listed here; if data objects with different contents are given these iTool data type names, portions of the standard iTool functionality may no longer function correctly.
Chapter 3: Data Management iTool Data Objects Each item of data used by an iTool must be encapsulated in an IDLitData object. Data objects can be grouped into collections using the IDLitDataContainer class or its subclass, IDLitParameterSet. Data Objects IDLitData objects can hold data items of any IDL data type.
Chapter 3: Data Management 57 In this example we do not specify an iTool data type for the data container object itself. Tip Often, you will organize data using a subclass of the IDLitDataContainer class: the IDLitParameterSet. See “IDLitDataContainer” (IDL Reference Guide) for a complete description of the data container object, its methods, and its properties.
Chapter 3: Data Management Predefined iTool Data Classes The iTool system distributed with IDL includes a number of predefined data classes. The predefined classes are subclasses of the IDLitData class; each performs initialization steps that are commonly used when creating data objects that contain data of specific composite data types. Some of the predefined data classes create data sub-containers to hold associated data objects, and some register properties associated with the data.
Chapter 3: Data Management 59 IDLitDataIDLImage Creates an IDLitData object of whose TYPE property is set to IDLIMAGE. Used to store two-dimensional image data. Images can be constructed from multiple image planes. Registered Properties • INTERLEAVE Data Sub-containers • An IDLitDataIDLPalette object named “Palette” that contains palette information provided as an argument to the Init method.
Chapter 3: Data Management Registered Properties • None Data Sub-containers • An IDLitData object named “Vertices” (IDLVERTEX) that contains the vertex list. • An IDLitData object named “Connectivity” (IDLCONNECTIVITY) that contains the connectivity list. IDLitDataIDLVector Creates an IDLitData object of whose TYPE property is set to IDLVECTOR. Used to store a one-dimensional array of any IDL data type.
Chapter 3: Data Management 61 Parameters Parameters represent data items used in a well-defined way by an algorithm that is computing a result. In the scheme of the iTools, parameters are the raw material fed to visualization objects — the IDL routines that create visual displays. For example, a visualization object that creates a simple line plot might require two parameters: vectors of dependent and independent data values.
Chapter 3: Data Management method of the IDLitParameter class (of which iTool visualization classes are a subclass): self->RegisterParameter, ParmameterName, $ TYPES = ['DataType1', ..., 'DataTypeN'] where ParameterName is a string that defines the name of the parameter and the TYPES keyword is set equal to a string or array of strings specifying the iTool system data types the parameter can represent. (See “iTool Data Types” on page 54 for information on iTools data types.
Chapter 3: Data Management 63 Data Type Matching To understand how the iTool data type matching system works, consider the following: • When a visualization is created, it registers one or more parameters, assigning a parameter name and one or more iTool data types to each. • When a data object is imported or created by an iTool, it is assigned one or more iTool data types.
Chapter 3: Data Management The Figure 3-1 illustrates this process as a flow diagram. Figure 3-1: Data type matching algorithm used by iTools.
Chapter 3: Data Management 65 Data Update Mechanism When the data contained in a data item changes (usually as the result of the application of a data-centric operation), all visualizations that depend on that data item are automatically notified of the change via a call to the visualization object’s OnDataChangeUpdate method. (See “Creating an OnDataChangeUpdate Method” on page 133 for details.
Data Update Mechanism Chapter 3: Data Management iTool Developer’s Guide
Chapter 4 Property Management This chapter describes the iTool property interface. About the Properties Interface . . . . . . . . . . . Property Data Types . . . . . . . . . . . . . . . . . . Registering Properties . . . . . . . . . . . . . . . . . Property Identifiers . . . . . . . . . . . . . . . . . . . iTool Developer’s Guide 68 71 74 77 Property Attributes . . . . . . . . . . . . . . . . . . . Property Aggregation . . . . . . . . . . . . . . . . . Property Update Mechanism . . . . . . . . . . .
Chapter 4: Property Management About the Properties Interface Object properties are used to store settings and values that relate to visualizations, data, and other components of an iTool. The iTools system presents a graphical property sheet interface to tool users; see “Property Sheets” (Chapter 6, iTool User’s Guide) for a description of the property sheet interface.
Chapter 4: Property Management 69 of visual objects (default line style, colors, etc.), and default properties for file readers, and file writers. How are Properties Displayed? Any iTool object can have properties. Properties are always displayed via the iTool property sheet interface, which uses the IDL WIDGET_PROPERTYSHEET function to present property names and values in a columnar display.
Chapter 4: Property Management Property Registration In order for an object property to be displayed by the graphical property sheet interface, it must be registered with the iTool system. Properties are generally registered when an object is created; see “Registering Properties” on page 74 for additional details. Property Identifiers Properties are referenced within the iTools system using property identifiers, which are simple scalar strings defined when the property is registered.
Chapter 4: Property Management 71 Property Data Types Registered properties must be of one of the data types listed in the following table. Note Properties of objects that are not registered (that is, properties that cannot appear in a property sheet) can be of any IDL data type. Type Code Type Description 0 USERDEF User Defined properties can contain values of any IDL type, but must also include a string value that will be displayed in the property sheet.
Chapter 4: Property Management Type Code 6 Type LINESTYLE Description Linestyle properties contain an integer value between 0 and 6, corresponding to the following IDL line styles: • 0 = Solid • 1 = Dotted • 2 = Dashed • 3 = Dash Dot • 4 = Dash Dot Dot • 5 = Long Dashes • 6 = No Line See Appendix B, “Property Controls” (iTool User’s Guide) for a visual example of the available line styles.
Chapter 4: Property Management Type Code 73 Type Description 8 THICKNESS Thickness properties contain an integer value between 1 and 10, corresponding to the thickness (in points) of the line. 9 ENUMLIST Enumerated List properties contain an array of string values defined when the property is registered. The GetProperty method returns the zero-based index of the selected item.
Chapter 4: Property Management Registering Properties In order for a property associated with an iTool component to be included in the property sheet for that component, the property must be registered with the iTool. The property registration mechanism accomplishes several things: • It allows you to expose as many or as few of the properties of an underlying object as you choose.
Chapter 4: Property Management 75 self->RegisterProperty, 'FONT_STYLE', $ ENUMLIST = ['Normal', 'Bold'], $ NAME = 'Font style' Here, the string argument FONT_STYLE is the property identifier of the property being registered; this string must be the same as the name of the keyword used with the GetProperty or SetProperty method when changing the value of the property.
Chapter 4: Property Management 2. Use the REGISTER_PROPERTIES keyword when instantiating the graphics object, then set the HIDE property attribute on the properties you want to remove from the property sheet. See “Property Attributes” on page 78 for more on this option.
Chapter 4: Property Management 77 Property Identifiers Property identifiers are scalar string values that identify a registered property. The property identifier string must be accepted as a keyword by the GetProperty and SetProperty methods for the object. Like all IDL keywords, property identifier strings must be valid IDL variable names, and cannot contain spaces or non-alphanumeric characters other than “_”, “!”, and “$”.
Chapter 4: Property Management Property Attributes Property attributes are values associated with a property that affect the way the property is displayed in the iTool property sheet interface. Attributes could be considered properties-of-properties; as with actual properties, special methods are used to get and set attribute values. Note A property must be registered in order to set or retrieve attribute values.
Chapter 4: Property Management 79 DESCRIPTION (Get, Set) A string value containing a text description of the property. This string is displayed in the property sheet interface. ENUMLIST (Get, Set) An array of string values to be displayed in the property sheet interface as an enumerated list. This property type allows the user to select a string value from a dropdown list in the user interface, but returns the integer index of the selected item as the value of the property.
Chapter 4: Property Management of multiple objects are displayed in the property sheet (either because multiple objects are selected, or because the objects have been grouped). Note The iTool developer is responsible for setting this property attribute back to zero. Use the SET_DEFINED field of the WIDGET_PROPERTYSHEET event structure to determine when to set the UNDEFINED attribute back to zero. USERDEF (Get, Set) A string that represents the value of a user-defined property.
Chapter 4: Property Management 81 Property Aggregation The iTools property aggregation mechanism allows the properties of several different objects held by the same container object to be displayed in the same property sheet automatically. Without property aggregation, you would have to manually register all of the properties of the objects contained in your visualization type object.
Chapter 4: Property Management must manually register only the unambiguous property names with each object before calling the Aggregate method or using the AGGREGATE keyword. Working with Aggregated Properties When the properties of multiple objects are aggregated in a visualization object, there are two possible ways to display the combined property set: a union or an intersection.
Chapter 4: Property Management 83 the property will not be displayed). Selecting an individual aggregated object in the browser hierarchy will display that object’s own properties. • If the value of a property that is common to all of the aggregated objects is different for different objects, the value will show in the parent container’s property sheet as undefined.
Chapter 4: Property Management Property Update Mechanism When a user changes the value of a property via the property sheet interface, the object that implements the property is automatically updated. If the object has a visual representation, the display of the iTool window is also updated automatically. The update mechanism is handled by the SetProperty method; as long as any SetProperty methods you create call the SetProperty methods of their superclasses, there is nothing more you need to do.
Chapter 4: Property Management 85 Properties of the iTools System iTools system preferences are default settings for the values of properties of file readers, file writers, and the iTool system itself. System preferences are revealed to the user via the system preferences browser, which is displayed when a user selects File → Preferences in an iTool.
Properties of the iTools System Chapter 4: Property Management iTool Developer’s Guide
Part II: Using the iTools Component Framework
Chapter 5 Creating an iTool This chapter describes the process of creating an new iTool definition and command-line launch routine. Overview of iTool Creation . . . . . . . . . . . . . 90 Creating a New iTool Class . . . . . . . . . . . . . 91 Registering a New Tool Class . . . . . . . . . . 101 iTool Developer’s Guide Creating an iTool Launch Routine . . . . . . 103 Example: Simple iTool . . . . . . . . . . . . . . .
Chapter 5: Creating an iTool Overview of iTool Creation Creating a new iTool using the iTools component framework is vastly simpler than creating a similar tool from scratch in IDL. The standard iTool user interface and functionality can be included in any new iTool with a few simple lines of code. Using the iTools framework leaves you free to concentrate on developing functionality unique to your application.
Chapter 5: Creating an iTool 91 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.
Chapter 5: Creating an iTool 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.
Chapter 5: Creating an iTool 93 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” on page 91. Note This example is intended to demonstrate how simple it can be to create a new iTool class definition.
Chapter 5: Creating an iTool Note Always use keyword inheritance (the _REF_EXTRA keyword) to pass keyword parameters through to any called routines. See “Keyword Inheritance” (Chapter 5, 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.
Chapter 5: Creating an iTool 95 Note Always use keyword inheritance (the _EXTRA keyword) to pass keyword parameters through to the superclass. See “Keyword Inheritance” (Chapter 5, Application Programming) for details on IDL’s keyword inheritance mechanism.
Chapter 5: Creating an iTool 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.
Chapter 5: Creating an iTool 97 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” on page 182 for additional details. See “Predefined iTool Operations” on page 148 for a list of operations included in the iTool system as installed with IDL.
Chapter 5: Creating an iTool 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.
Chapter 5: Creating an iTool 99 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” on page 269 for additional details. See “Predefined iTool File Writers” on page 255 for a list of file writers included in the iTool system as installed with IDL.
Chapter 5: Creating an iTool 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. Note This example is intended to demonstrate how simple it can be to create a new iTool class definition.
Chapter 5: Creating an iTool 101 Registering a New Tool Class Before an instance of a new iTool can be created, the tool’s class definition must be registered with the iTool system. Registering an iTool class with the system links the class definition file containing the actual IDL code that initializes an iTool object with a simple string that names the iTool.
Chapter 5: Creating an iTool Example Suppose you have an iTool class definition file named myTool__define.pro, located in a directory included in IDL’s !PATH system variable. Register this class with the iTool system with the following command: ITREGISTER, 'My First Tool', 'myTool' Tools defined by the myTool class definition file can now be created by the iTool system by specifying the tool name My First Tool.
Chapter 5: Creating an iTool 103 Creating an iTool Launch Routine An iTool launch routine is an IDL procedure that creates an instance of an iTool by calling the IDLITSYS_CREATETOOL function. The launch routine may do other things as well, including creating data objects to pass to the create function from command-line arguments.
Chapter 5: Creating an iTool user to retrieve the newly-created iTool’s identifier in an IDL variable by including the IDENTIFIER keyword in the call to the launch routine. The iTool identifier can then be used to specify the iTool as the target for another operation, such as overplotting. The _EXTRA Keyword Optionally, you can use IDL’s keyword inheritance mechanism to pass keyword parameters that are not explicitly handled by your routine through to other routines.
Chapter 5: Creating an iTool 105 turn, hold the actual data used by the iTool.
Chapter 5: Creating an iTool CATCH, /CANCEL IF OBJ_VALID(oDataObject) THEN OBJ_DESTROY, oDataObject MESSAGE, /REISSUE_LAST RETURN ENDIF This block of error-handling code does the following: 1. Uses the ON_ERROR procedure to instruct IDL to return to the caller of the program that establishes an error condition. 2. Uses the CATCH procedure to establish an error-handler for the iTool launch routine, returning the error code in the variable iErr. 3.
Chapter 5: Creating an iTool 107 We also use IDL’s keyword inheritance mechanism (the _EXTRA keyword) to pass any additional keyword parameters specified when the launch routine is called through to the lower-level iTool routines. See “IDLITSYS_CREATETOOL” (IDL Reference Guide) for details. iTool Class Registration Before an instance of an iTool can be created, the iTool class must be registered with the iTool system.
Chapter 5: Creating an iTool Example: Simple iTool This example creates a very simple iTool named example1tool that incorporates standard functionality from the iTools distribution, along with other example iTool features created in other chapters of this manual. Example Code The class definition code for this example iTool is included in the file example1tool__define.pro in the examples/doc/itools subdirectory of the IDL distribution.
Chapter 5: Creating an iTool 109 ;*** Visualizations ; Here we register a custom visualization type described in ; the "Creating Visualizations" chapter of this manual. self->RegisterVisualization, 'Image-Contour', $ 'example1_visImageContour', ICON = 'image', /DEFAULT ;*** Operations menu ; Here we register a custom operation described in the "Creating ; Operations" chapter of this manual.
Chapter 5: Creating an iTool functionality automatically. Any “extra” keywords specified in the call to our Init method are passed to the IDLitToolbase::Init method via the keyword inheritance mechanism. Because our iTool class will inherit from the IDLitToolbase class, our tool will automatically provide all of the standard features of the iTools. In addition, we register the following custom items: • A custom visualization type: Image-Contour.
Chapter 5: Creating an iTool 111 IF (N_ELEMENTS(data) GT 0) THEN BEGIN oData = OBJ_NEW('IDLitDataIDLImagePixels') result = oData->SetData(data, _EXTRA = _extra) oParmSet->Add, oData, PARAMETER_NAME = 'ImagePixels' ; Create a default grayscale ramp.
Chapter 5: Creating an iTool We next create a default grayscale ramp in an IDLitDataIDLPalette object, and assign this the parameter name 'Palette'. We use the ITREGISTER procedure to register our iTool class with the name "Example 1 Tool". Finally, we call the IDLITSYS_CREATETOOL function with the registered name of our iTool class, specifying the visualization type as 'Image-Contour', which is the name of our custom visualization.
Chapter 6 Creating a Visualization This chapter describes the process of creating an iTool visualization type. Overview of iTool Visualization Types . . . 114 Predefined iTool Visualization Classes . . . 115 Creating a New Visualization Type . . . . . . 121 iTool Developer’s Guide Registering a Visualization Type . . . . . . . 136 Unregistering a Visualization Type . . . . . 138 Example: Image-Contour Visualization . .
Chapter 6: Creating a Visualization Overview of iTool Visualization Types A visualization type is an iTool component object class that contains core IDL graphic objects (IDLgrPlot objects, for example), other iTool visualization components, or both. Visualization type components can also contain data. A number of visualization types are predefined and included in the IDL iTools package.
Chapter 6: Creating a Visualization 115 Predefined iTool Visualization Classes The iTool system distributed with IDL includes a number of predefined visualization classes. The visualization type (the TYPE keyword value of the visualization with which it is initialized) and the accepted data type(s) are shown for the predefined visualization classes.
Chapter 6: Creating a Visualization Data Types Accepted • Histogram data: IDLVECTOR, IDLARRAY2D, IDLARRAY3D IDLitVisImage Displays an image. Visualization type: IDLIMAGE Data Types Accepted • Image data: IDLIMAGE, IDLARRAY2D • Palette data: IDLPALETTE, IDLARRAY2D IDLitVisImagePlane Displays an image extracted from a plane passing through volumetric data.
Chapter 6: Creating a Visualization 117 • Palette data: IDLPALETTE • Volume dimensions, location, connectivity lists: IDLVECTOR IDLitVisLegend Displays a legend that can contain multiple IDLitVisLegendContourItem, IDLitVisLegendPlotItem, and IDLitVisLegendSurfaceItem objects. Visualization type: IDLLEGEND Data Types Accepted • None IDLitVisLegendItem Displays an item contained within a legend.
Chapter 6: Creating a Visualization Data Types Accepted • None. IDLitVisPlot Displays a two-dimensional line plot. Visualization type: IDLPLOT Data Types Accepted • X and Y data: IDLVECTOR • Vertex data: IDLARRAY2D • X and Y error data: IDLVECTOR, IDLARRAY2D IDLitVisPlotProfile Displays a two-dimensional plot profile. Visualization type: IDLPLOT PROFILE Data Types Accepted • Image data or line endpoints: IDLARRAY2D IDLitVisPlot3D Displays a three-dimensional line plot.
Chapter 6: Creating a Visualization 119 IDLitVisPolyline Displays a single polyline. Visualization type: IDLPOLYLINE Data Types Accepted • Vertex data: IDLVERTEX, IDLCONNECTIVITY IDLitVisRoi Defines and displays a polygonal region of interest. Visualization type: IDLROI Data Types Accepted • Vertex data: IDLARRAY2D IDLitVisShapePoint Displays point vertices from a Shapefile.
Chapter 6: Creating a Visualization IDLitVisSurface Displays a three-dimensional surface plot. Visualization type: IDLSURFACE Data Types Accepted • Z (surface) data: IDLARRAY2D • X and Y data: IDLVECTOR, IDLARRAY2D • Vertex color data: IDLVECTOR, IDLARRAY2D • Texture maps: IDLARRAY3D, IDLARRAY2D • Palette colors: IDLARRAY2D IDLitVisText Displays text string.
Chapter 6: Creating a Visualization 121 Creating a New Visualization Type An iTool visualization class definition file must (at the least) provide methods to initialize the visualization class, get and set property values, handle changes to the underlying data, clean up when the visualization is destroyed, and define the visualization class structure. Complex visualization types will likely provide additional methods.
Chapter 6: Creating a Visualization IDLitVisualization class. See “IDLitVisualization” (IDL Reference Guide) for details on the methods and properties available to classes that subclass from IDLitVisualization. Example Class Structure Definition The following is the class structure definition for the ExampleVis visualization class. This procedure should be the last procedure in a file named examplevis__define.pro.
Chapter 6: Creating a Visualization 123 with significant extra functionality will likely define additional structure fields, and may inherit from other iTool classes, the basic principles are the same.
Chapter 6: Creating a Visualization where MyVisualization is the name of your visualization class and the MYKEYWORD parameters are keywords handled explicitly by your Init function. Always use keyword inheritance (the _REF_EXTRA keyword) to pass keyword parameters through to any called routines. See “Keyword Inheritance” (Chapter 5, Application Programming) for details on IDL’s keyword inheritance mechanism.
Chapter 6: Creating a Visualization 125 Note Always use keyword inheritance (the _EXTRA keyword) to pass keyword parameters through to the superclass. See “Keyword Inheritance” (Chapter 5, Application Programming) for details on IDL’s keyword inheritance mechanism.
Chapter 6: Creating a Visualization Register a property by calling the RegisterProperty method of the IDLitComponent class: self->RegisterProperty, PropertyIdentifier [, TypeCode] $ [, ATTRIBUTE = value] where PropertyIdentifier is a string that uniquely identifies the property, TypeCode is an integer between 0 and 9 specifying the property data type, and ATTRIBUTE is a property attribute. See “Registering Properties” on page 74 for details.
Chapter 6: Creating a Visualization 127 Setting Property Attributes If a property has already been registered, perhaps by a superclass of your visualization class, you can change the registered attribute values using the SetPropertyAttribute method of the IDLitComponent class: self->SetPropertyAttribute, Identifier where Identifier is the name of the keyword to the GetProperty and SetProperty methods used to retrieve or change the value of this property.
Chapter 6: Creating a Visualization /PRIVATE) self->Add, self._oPlot, /AGGREGATE Here, we create a new IDLitVisPlot object instance and place the object reference in the _oPlot field of the visualization’s class structure. The REGISTER_PROPERTIES keyword ensures that all of the registrable IDLitVisPlot properties are registered with the visualization automatically.
Chapter 6: Creating a Visualization 129 /INPUT, TYPES='IDLVECTOR', /OPTARGET ; Add a plotting symbol object and aggregate its properties ; into the visualization. self._oSymbol = OBJ_NEW('IDLitSymbol', PARENT = self) self->Aggregate, self._oSymbol ; Create an IDLitVisPlot object, setting its SYMBOL property to ; the symbol object we just created. Add the plot object to the ; visualization, and aggregate its properties. self._oPlot = OBJ_NEW('IDLitVisPlot', /REGISTER_PROPERTIES, $ SYMBOL = self.
Chapter 6: Creating a Visualization 3. Creates a plotting symbol created from the IDLitSymbol class and aggregate its properties with the other ExampleVis properties. 4. Creates an IDLitGrPlot object that uses the IDLitSymbol object for its plotting symbols. 5. Registers an example property that holds a string value. 6. Passes any “extra” keyword properties through to the SetProperty method. 7. Returns the integer 1, indicating successful initialization.
Chapter 6: Creating a Visualization 131 Creating a GetProperty Method The visualization class GetProperty method retrieves property values from the visualization object instance or from instance data of other associated objects. The method can retrieve the requested property value from the visualization object’s instance data or by calling another class’ GetProperty method.
Chapter 6: Creating a Visualization Finally, the method calls the superclass’ GetProperty method, passing in all of the keywords stored in the _extra structure. Creating a SetProperty Method The visualization class SetProperty method stores property values in the visualization object’s instance data or in properties of associated objects.
Chapter 6: Creating a Visualization 133 object. We set the value of the ExampleProperty directly in the ExampleVis object’s instance data. Finally, we call the superclass’ SetProperty method, passing in all of the keywords stored in the _extra structure. Creating an OnDataChangeUpdate Method The visualization class OnDataChangeUpdate method takes care of updating the visualization when one or more of the data parameters used to create the visualization change their values.
Chapter 6: Creating a Visualization MIN_VALUE = minn, MAX_VALUE = maxx ENDIF END ELSE: self->ErrorMessage, 'Unknown parameter' ENDCASE END Discussion The OnDataChangeUpdate method must accept two arguments: an object reference to the data object whose data has changed (oSubject in the previous example), and a string containing the name of the parameter associated with the data object (parmName in the example).
Chapter 6: Creating a Visualization 135 visualizations. The general idea is that when a data item is disassociated from a visualization parameter, one or more properties of the visualization may need to be reset to reasonable default values. For example, in the case of a plot visualization, if the plotted data is disconnected, we want to reset the data ranges to their default values and hide the plot visualization. See “IDLitParameter::OnDataDisconnect” (IDL Reference Guide) for additional details.
Chapter 6: Creating a Visualization Registering a Visualization Type Before a visualization of a given type can be created by an iTool, the visualization type’s class definition must be registered as being available to the iTool. Registering a visualization type with the iTool links the class definition file containing the actual IDL code that defines the visualization type with a simple string that names the type.
Chapter 6: Creating a Visualization 137 tree view. See “Icon Bitmaps” on page 44 for details on where bitmap icon files are located. TYPE A string or an array of strings indicating the types of data that can be displayed by the visualization. iTools data types are described in Chapter 3, “Data Management”. Set this property to a null string ('') to specify that all types of data can be displayed.
Chapter 6: Creating a Visualization Unregistering a Visualization Type If you are creating a new iTool from an existing iTool class, you may want to remove a visualization type registered with the existing class from your new tool. This can be useful if you have an iTool class that implements all of the functionality you need, but which registers a visualization type you don’t want included in your iTool.
Chapter 6: Creating a Visualization 139 vislist = oTool->FindIdentifiers('*/visualizations/*') FOR i = 0, N_ELEMENTS(vislist)-1 DO PRINT, $ STRMID(vislist[i], STRPOS(vislist[i], '/', /REVERSE_SEARCH)+1) See “IDLitTool::FindIdentifiers” (IDL Reference Guide) for details.
Chapter 6: Creating a Visualization Example: Image-Contour Visualization This example creates a visualization type named example1_visImageContour that displays an image and overlays it with a contour based on the image data. Example Code The code for this example visualization type is included in the file example1_visimagecontour__define.pro in the examples/doc/itools subdirectory of the IDL distribution.
Chapter 6: Creating a Visualization 141 Init Method The Init method is called when the example1_visImageContour visualization is created.
Chapter 6: Creating a Visualization We register two parameters used by our visualization: IMAGEPIXELS and PALETTE. Both parameters are input parameters (meaning they are used to create the visualization), and both can be the target of an operation. The IMAGEPIXELS parameter can contain data of two iTool data types: IDLIMAGEPIXELS or IDLARRAY2D. When data are assigned to the visualization’s parameter set, only data that matches one of these two types can be assigned to the IMAGEPIXELS parameter.
Chapter 6: Creating a Visualization 143 END ; The method was called with an image array as the argument. 'IMAGEPIXELS': BEGIN void = self._oImage->SetData(oSubject, $ PARAMETER_NAME = 'IMAGEPIXELS') void = self._oContour->SetData(oSubject, $ PARAMETER_NAME = 'Z') ; Make our contour appear at the top of the surface. IF (oSubject->GetData(zdata)) THEN $ self._oContour->SetProperty, ZVALUE = MAX(zdata) END ; The method was called with a palette as the argument. 'PALETTE': BEGIN void = self.
Chapter 6: Creating a Visualization Finally, we handle the PALETTE parameter by calling the SetData method again, this time to set the PALETTE parameters of both the IDLitVisImage and IDLitVisContour objects. OnDataDisconnect Method The OnDataDisconnect method is called automatically when a data value has been disconnected from a parameter. PRO example1_visImageContour::OnDataDisconnect, ParmName CASE STRUPCASE(parmname) OF 'IMAGEPIXELS': BEGIN self->SetProperty, DATA = 0 self.
Chapter 7 Creating an Operation This chapter describes the process of creating an iTool operation. Overview of Creating an iTool Operation . Predefined iTool Operations . . . . . . . . . . . Operations and the Undo/Redo System . . . Creating a New Data-Centric Operation . . Creating a New Generalized Operation . . . iTool Developer’s Guide 146 148 150 152 165 Operations and Macros . . . . . . . . . . . . . . . Registering an Operation . . . . . . . . . . . . . Unregistering an Operation . . . . . . . .
Chapter 7: Creating an Operation Overview of Creating an iTool Operation An operation is an iTool component object class that can be used to modify selected data, change the way a visualization is displayed in the iTool window, or otherwise affect the state of the iTool. Some examples of iTool operations are: • performing the IDL SMOOTH operation on selected data, • rotating a selected visualization by a specified angle, • displaying data statistics.
Chapter 7: Creating an Operation 147 that you provide methods to store values before and after the operation is executed. • Override methods used to get or set properties, react to changes in the underlying data, and clean up, as necessary. This chapter describes the process of creating new operations based on the IDLitDataOperation and IDLitOperation classes.
Chapter 7: Creating an Operation Predefined iTool Operations The iTool system distributed with IDL includes a number of predefined operations. You can include these operations in an iTool directly by registering the class with your iTool (as described in “Registering an Operation” on page 182). You can also create a new operation class based on one of the predefined classes.
Chapter 7: Creating an Operation 149 Note There are many additional operations (named with the prefix “idlitop”) in the lib\itools\components subdirectory of your IDL installation.
Chapter 7: Creating an Operation Operations and the Undo/Redo System The iTools system provides users with the ability to interactively undo and redo actions performed on visualizations or data items. As an iTool developer, you will need to provide some code to support the undo/redo feature; the amount of code required depends largely on the type of operation your operation class performs.
Chapter 7: Creating an Operation 151 Generalized Operations To provide undo/redo functionality, generalized operations (those based on the IDLitOperation class) must provide methods that record the initial and final values of the item being modified, along with methods that use the recorded values to undo or redo the operation. The following things happen when the user requests an operation: • The DoAction method creates an IDLitCommandSet object to hold the initial and final values.
Chapter 7: Creating an Operation Creating a New Data-Centric Operation iTool operations that act primarily on data are based on the IDLitDataOperation class. The class definition file for an IDLitDataOperation object must (at the least) provide methods to initialize the operation class, get and set property values, execute the operation, and define the operation class structure. Complex operations will likely provide additional methods.
Chapter 7: Creating an Operation 153 Creating an IDLitDataOperation The process of creating an IDLitDataOperation is outlined in the following sections: • “Creating the Class Structure Definition” on page 153 • “Creating an Init Method” on page 154 • “Creating a Cleanup Method” on page 158 • “Creating an Execute Method” on page 159 • “Creating a DoExecuteUI Method” on page 160 • “Creating a GetProperty Method” on page 161 • “Creating a SetProperty Method” on page 162 • “Creating an UndoExec
Chapter 7: Creating an Operation the methods and properties available to classes that subclass from IDLitDataOperation. Example Class Structure Definition The following is the class structure definition for the ExampleDataOp operation class. This procedure should be the last procedure in a file named exampledataop__define.pro.
Chapter 7: Creating an Operation 155 • call the Init methods of any superclasses, using the keyword inheritance mechanism to pass “extra” keywords • register any properties of the operation, and set property attributes as necessary • perform other initialization steps as necessary • return the value 1 if the initialization steps are successful, or 0 otherwise Definition of the Init Function Begin by defining the argument and keyword list for your Init method.
Chapter 7: Creating an Operation Note Your operation 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.
Chapter 7: Creating an Operation 157 Return Value If all of the routines and methods used in the Init method execute successfully, it should indicate successful initialization by returning 1. Other operation classes that subclass from your operation class may check this return value, as your routine should check the value returned by any superclass Init methods called. Registering Properties Operations can register properties with the iTool.
Chapter 7: Creating an Operation NAME='Example Data Operation', ICON='sum', $ _EXTRA = _extra) NE 1) THEN $ RETURN, 0 ; Register a property that holds a byte value. self->RegisterProperty, 'ByteTop', $ DESCRIPTION='An example property', $ NAME='Byte Threshold', SENSITIVE = 1 ; Unhide the SHOW_EXECUTION_UI property.
Chapter 7: Creating an Operation 159 Note If your operation class is based on the IDLitDataOperation class, and does not create any pointers or objects of its own, the Cleanup method is not strictly required. It is always safest, however, to create a Cleanup method that calls the superclass’ Cleanup method. See “IDLitDataOperation::Cleanup” (IDL Reference Guide) for additional details.
Chapter 7: Creating an Operation our ExampleDataOp operation works on image data, this means the operation has the effect of producing the negative image. FUNCTION ExampleDataOp::Execute, data ; If byte data then offsets are 0 and 255, otherwise ; use data minimum and maximum.
Chapter 7: Creating an Operation • 161 For operations that return a two-dimensional array, the Operation Preview UI service displays the operation’s property sheet and a small window that previews the result of the operation. See “Predefined iTool UI Services” on page 295 for additional details. Example DoExecuteUI Method The following example code shows a simple DoExecuteUI method for the ExampleDataOp operation.
Chapter 7: Creating an Operation Note Any property registered with a call to the RegisterProperty method must be listed as a keyword to the GetProperty method either of the operation class or one of its superclasses. See “IDLitDataOperation::GetProperty” (IDL Reference Guide) for additional details.
Chapter 7: Creating an Operation 163 property value, either by storing the value directly in the operation object’s instance data or by calling another class’ SetProperty method. Note Any property registered with a call to the RegisterProperty method must be listed as a keyword to the SetProperty method either of the operation class or one of its superclasses. See “IDLitDataOperation::SetProperty” (IDL Reference Guide) for additional details.
Chapter 7: Creating an Operation Creating an UndoExecute Method The operation class’ UndoExecute method is called when the user undoes an invocation of the operation and the REVERSIBLE_OPERATION property is set on the operation object. (See “Operations and the Undo/Redo System” on page 150 for details on how undo and redo are handled in different situations.) The UndoExecute method must reverse the effect of the Execute method.
Chapter 7: Creating an Operation 165 Creating a New Generalized Operation Generalized operations are iTool operations that are not limited to acting on data that underlies a visualization. Generalized operations are based on the IDLitOperation class. The class definition file for an IDLitOperation object must (at the least) provide methods to initialize the operation class, get and set property values, execute the operation, undo and redo the operation, and define the operation class structure.
Chapter 7: Creating an Operation • “Creating a SetProperty Method” on page 177 • “Creating an UndoOperation Method” on page 178 • “Creating a RedoOperation Method” on page 179 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.
Chapter 7: Creating an Operation 167 struct = { ExampleOp, INHERITS IDLitOperation} END Discussion The purpose of the structure definition routine is to define a named IDL structure with structure fields that will contain the operation object instance data. The structure name should be the same as the operation’s class name — in this case, ExampleOp. Like many iTool operations that act on data, ExampleOp is created as a subclass of the IDLitOperation class.
Chapter 7: Creating an Operation Note Because iTool operations are invoked by the user’s interactive choice of an item from a menu, they generally do not accept any keywords of their own. The function signature of an Init method for an operation generally looks something like this: FUNCTION MyOperation::Init, _REF_EXTRA = _extra where MyOperation is the name of your operation class. Note Always use keyword inheritance (the _REF_EXTRA keyword) to pass keyword parameters through to any called routines.
Chapter 7: Creating an Operation 169 This convention is used in all operation classes included with IDL. ITT Visual Information Solutions strongly suggests that you include similar checks in your own class definition files. Keywords to the Init Method Properties of the operation class can be set in the Init method by specifying the property names and values as IDL keyword-value pairs.
Chapter 7: Creating an Operation self->RegisterProperty, PropertyIdentifier [, TypeCode] $ [, ATTRIBUTE = value] where PropertyIdentifier is a string that uniquely identifies the property, TypeCode is an integer between 0 and 9 specifying the property data type, and ATTRIBUTE is a property attribute. See “Registering Properties” on page 74 for details.
Chapter 7: Creating an Operation 171 keyword values to be handled explicitly in the Init method, but we do use the keyword inheritance mechanism to pass keyword values through to methods called within the Init method. The ExampleOp Init method does the following things: 1. Calls the Init method of the superclass, IDLitOperation. We use the TYPES keyword to specify that our operation works on data that has the iTool data type 'IDLARRAY2D', provide a Name for the object instance, and provide an icon.
Chapter 7: Creating an Operation Discussion Since our operation does not have any instance data of its own, the Cleanup method simply calls the superclass Cleanup method. Creating a DoAction Method The operation class DoAction method is called by the iTool system when an operation is requested by the user. (Note that data-centric operations do not need to implement the DoAction method because it is implemented by the IDLitDataOperation class itself.
Chapter 7: Creating an Operation 173 ; Make sure we have a valid iTool object. IF ~ OBJ_VALID(oTool) THEN RETURN, OBJ_NEW() ; Get the selected objects oTargets = oTool->GetSelectedItems() ; Select only IDLitVisSurface objects. If there are ; no surface objects selected, return a null object.
Chapter 7: Creating an Operation END Discussion The ExampleOp operation DoAction method does the following things: 1. Checks the validity of the iTool object passed to the DoAction method. 2. Retrieves the list of selected objects from the iTool object. 3. Filters out any selected objects that are not IDLitVisSurface objects. 4. Calls the superclass DoAction method to create an IDLitCommandSet object. 5.
Chapter 7: Creating an Operation 175 oTargets[i]->GetProperty, STYLE = styleIndex ; Add the value to the command object void = oCmd->AddItem('OLD_STYLE', styleIndex) ; Add the command object to the command set oCmdSet->Add, oCmd ENDFOR RETURN, 1 END Discussion The ExampleOp operation RecordInitialValues method simply loops through the supplied list of target objects, creating a new IDLitCommand object for each. We set the TARGET_IDENTIFIER property for each command object.
Chapter 7: Creating an Operation RETURN, 1 END Discussion The ExampleOp operation RecordFinalValues method simply loops through the supplied list of target objects, recording the new value for the STYLE property in the IDLitCommand object associated with each target. Creating a GetProperty Method The operation class GetProperty method retrieves property values from the operation object instance or from instance data of other associated objects.
Chapter 7: Creating an Operation 177 In this example, there are no properties specific to the ExampleOp object, so we simply call the superclass’ GetProperty method, passing in all of the keywords stored in the _extra structure. Creating a SetProperty Method The operation class SetProperty method stores property values in the operation object’s instance data or in properties of associated objects.
Chapter 7: Creating an Operation Creating an UndoOperation Method The operation class UndoOperation method is called when the user undoes the operation by selecting “Undo” from a menu or toolbar. Example UndoOperation Method The following example code shows a very simple UndoOperation method for the ExampleOp operation: FUNCTION ExampleOp::UndoOperation, oCommandSet ; Retrieve the IDLitCommand objects stored in the ; command set object.
Chapter 7: Creating an Operation 179 Note The UndoOperation method could also have been implemented without the use of the values stored in the command set object simply by decrementing the value of the STYLE property for each target. Creating a RedoOperation Method The operation class RedoOperation method is called when the user redoes the operation by selecting “Redo” from a menu or toolbar.
Chapter 7: Creating an Operation 3. For each command object, retrieve the identifier string for the target object. Use the identifier string to retrieve a reference to the target object itself. 4. Retrieve the NEW_STYLE Item from the command object and use its value to set the STYLE property on the target object.
Chapter 7: Creating an Operation 181 Operations and Macros The concept of a macro was introduced to the iTool system in IDL 6.1. Macros allow iTool users to record a series of actions for later playback. A related feature, the history of an iTool, lists all actions performed in a given iTool, whether or not actions are currently being recorded. For additional information on macros and history, see Chapter 8, “Working with Macros” (iTool User’s Guide).
Chapter 7: Creating an Operation Registering an Operation Before an operation can be performed by an iTool, the operation’s class definition must be registered as being available to the iTool. Registering an operation with the iTool links the class definition file that contains the actual IDL code that defines the operation with a simple string that names the type. Code that performs an operation in an iTool uses the name string to specify which operation should be performed.
Chapter 7: Creating an Operation 183 ICON A string value giving the name of an icon to be associated with this object. Typically, this property is the name of a bitmap file to be used when displaying the object in a tree view. See “Icon Bitmaps” on page 44 for details on where bitmap icon files are located. IDENTIFIER A string that will be used as the identifier of the object.
Chapter 7: Creating an Operation Unregistering an Operation If you are creating a new iTool from an existing iTool class, you may want to remove an operation registered for the existing class from your new tool. This can be useful if you have an iTool class that implements all of the functionality you need, but which registers an operation you don’t want included in your iTool.
Chapter 7: Creating an Operation 185 Alternatively, to generate a list of relative identifiers for all operations registered with the current tool, use the following statements: void = ITGETCURRENT(TOOL=oTool) opslist = oTool->FindIdentifiers(/OPERATIONS) FOR i = 0, N_ELEMENTS(opslist)-1 DO PRINT, $ STRMID(opslist[i], STRPOS(opslist[i], '/OPERATIONS', $ /REVERSE_SEARCH)+1) Note that the string in the call to STRPOS must be in upper case.
Chapter 7: Creating an Operation Example: Data Resample Operation This example creates a data operation to resample data in a dataset using the IDL CONGRID function. Example Code The code for this example operation is included in the file example1_opresample__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Run the example procedure by entering example1_opresample__define at the IDL command prompt or view the file in an IDL Editor window by entering .
Chapter 7: Creating an Operation 187 Init Method FUNCTION example1_opresample::Init, _REF_EXTRA = _extra IF (~ self->IDLitDataOperation::Init(NAME='Resample', $ TYPES=['IDLVECTOR','IDLARRAY2D','IDLARRAY3D'], $ DESCRIPTION="Resampling", _EXTRA = _extra)) THEN $ RETURN, 0 ; Default self._x = self._y = self._z = values for resampling factors. 2 2 2 ; Register properties self->RegisterProperty, 'X', /FLOAT, $ DESCRIPTION='X resampling factor.
Chapter 7: Creating an Operation Next, we call the Init method of the superclass. In this case, we are creating a subclass of the IDLitDataOperation class; this provides us with all of the standard iTool data operation functionality automatically. We specify three iTool data types on which our operation will work: “IDLVECTOR”, “IDLARRAY2D”, and “IDLARRAY3D”.
Chapter 7: Creating an Operation 189 INTERP = interp, CUBIC = cubic) ; CONGRID always uses linear interp with 3D 3: data = CONGRID(data, newdims[0], newdims[1], newdims[2]) ENDCASE RETURN, 1 END Discussion The Execute method does the work of our operation. Since example1_opresample is based on the IDLitDataOperation class, when the operation is requested by a user the Execute method is automatically called with each of the currently selected data objects as the data argument.
Chapter 7: Creating an Operation IF ARG_PRESENT(y) THEN $ y = self._y IF ARG_PRESENT(z) THEN $ z = self._z IF ARG_PRESENT(method) THEN $ method = self._method ; Superclass properties. IF (N_ELEMENTS(_extra) gt 0) THEN $ self->IDLitDataOperation::GetProperty, _EXTRA = _extra END Discussion The GetProperty method for our operation supports four properties named X, Y, Z, and METHOD, stored in instance data fields of the same name (with an underscore prepended).
Chapter 7: Creating an Operation 191 self->IDLitDataOperation::SetProperty, _EXTRA = _extra END Discussion The SetProperty method for our operation supports four properties named X, Y, Z, and METHOD, stored in instance data fields of the same name (with an underscore prepended). If any of these properties is specified in the call to the SetProperty method, its value is stored in the appropriate instance data field.
Example: Data Resample Operation Chapter 7: Creating an Operation iTool Developer’s Guide
Chapter 8 Creating a Manipulator This chapter describes creating a custom manipulator. See the following topics for details. Overview of iTool Manipulators . . . . . . . . The Manipulator Creation Process . . . . . . Predefined iTool Manipulators . . . . . . . . . Manipulators and the Undo/Redo System . Using Manipulator Public Instance Data . . iTool Developer’s Guide 194 197 198 202 204 Creating a New Manipulator . . . . . . . . . . Registering a Manipulator . . . . . . . . . . . .
Chapter 8: Creating a Manipulator Overview of iTool Manipulators A manipulator is an iTool component object class that defines a way the user can interact with visualizations in the iTool window using the mouse or keyboard.
Chapter 8: Creating a Manipulator 195 Note A manipulator need not always be interactively selected. The IDLitTool::ActivateManipulator method can be used to programmatically start a manipulator. This can be especially useful when you need to reactivate a tool’s default manipulator because none of the conditions required by a custom manipulator have been met. An IDLitManipulatorManager object is a specialized manipulator container that acts as the root of a manipulator hierarchy.
Chapter 8: Creating a Manipulator Selection Visuals Figure 8-1: Rotate Manipulator Selection Visuals When you initialize a manipulator, you can define the type of selection visual that appears by setting the VISUAL_TYPE keyword to the Init method. If you create a custom IDLitManipulatorVisual object, then the VISUAL_TYPE property values of the IDLitManipulator and IDLitManipulatorVisual objects are the same.
Chapter 8: Creating a Manipulator 197 The Manipulator Creation Process To create a new iTool manipulator, you will do the following: • Choose an iTool manipulator class on which your new manipulator will be based. In almost all cases, you will base your new manipulator on the IDLitManipulator class, which provides methods for detecting selections made by the user, mouse button-press events, mouse motion, and other low-level manipulator functions. • Define the properties of the manipulator.
Chapter 8: Creating a Manipulator Predefined iTool Manipulators The iTool system distributed with IDL includes a number of predefined manipulators. You can include these manipulators in an iTool directly by registering the class with your iTool (as described in “Registering a Manipulator” on page 223). You can also create a new manipulator class based on one of the predefined classes.
Chapter 8: Creating a Manipulator 199 • IDLitAnnotateOval — adds an oval to the iTool window • IDLitAnnotatePolygon — adds a polygon to the iTool window • IDLitAnnotateFreehand — adds a freehand shape to the iTool window IDLitManipLineProfile The profile line manipulator creates a profile plot for a line drawn on a surface or image. IDLitManipRotate The rotation manipulator rotates a visualization in the iTool window.
Chapter 8: Creating a Manipulator IDLitManipROIFree The freehand ROI manipulator draws a freehand ROI on the image. IDLitManipROIOval The oval ROI manipulator draws an oval ROI on the image. IDLitManipROIPoly The polygon ROI manipulator draws a polygonal ROI on the image. IDLitManipROIRect The rectangle ROI manipulator draws a rectangular ROI on the image.
Chapter 8: Creating a Manipulator 201 Note This manipulator is not to be confused with the Operations → Contour selection, which draws a specified number of contour levels, projected onto the XY plane at Z=0. Volume Manipulators The following manipulator is available in the iVolume iTool and any tools that subclass from IDLitToolVolume.
Chapter 8: Creating a Manipulator Manipulators and the Undo/Redo System A manipulator can be configured to support undo/redo functionality when it invokes an associated operation that records the actions performed by the manipulator in the undo/redo buffer. This operation can be a custom operation or an existing operation. (See Chapter 7, “Creating an Operation” for details on operation creation.
Chapter 8: Creating a Manipulator 203 Capturing Information for the Undo/Redo System The initial and final values of the manipulated item must be recorded so that the operation can be undone and redone. Two manipulator object methods allow you to specify when values are initially recorded and committed. The RecordUndoValues and CommitUndoValues methods work in conjunction with the operation defined during manipulator initialization by the OPERATION_IDENTIFIER keyword.
Chapter 8: Creating a Manipulator Using Manipulator Public Instance Data The IDLitManipulator class automatically manages selection state between mousedown and mouse-up interactions. Three public instance fields are exposed, providing information about the mouse button state (ButtonPress), the number of selected items (nSelectionList), and an array of the currently selected visualizations (pSelectionList).
Chapter 8: Creating a Manipulator 205 Using the nSelectionList Field The nSelectionList field contains the number of currently selected items in the window associated with the current manipulator. This corresponds to the number of visualizations contained within the pSelectionList pointer, described in the following section. If no visualizations have been selected, the nSelectionList value equals 0 and the pSelectionList will contain an undefined IDL variable.
Chapter 8: Creating a Manipulator Creating a New Manipulator The manipulator class definition file will have the following components: • A Class Structure Definition — this creates an instance of the manipulator class and instantiates required instance data. See “Creating the Manipulator Class Structure Definition” on page 207. • An Init method — this method initializes a manipulator object. See “Creating a Manipulator Init Method” on page 208.
Chapter 8: Creating a Manipulator 207 Creating the Manipulator 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 be defined before any objects of the type are created.
Chapter 8: Creating a Manipulator INHERITS IDLitManipulator, $ Superclass oImage: OBJ_NEW(), $ Target image } END Discussion The purpose of the structure definition routine is to define a named IDL structure with structure fields that will contain the manipulator object instance data. The structure name should be the same as the manipulator’s class name — in this case, ExampleManip. Like many iTool manipulators, ExampleManip is created as a subclass of the IDLitManipulator class.
Chapter 8: Creating a Manipulator 209 whether keywords not explicitly handled by your method will be passed through to other routines called by your method via IDL’s keyword inheritance mechanism. Note Because iTool manipulators are invoked by the user’s interactive choice of a toolbar item, they generally do not accept any keywords of their own.
Chapter 8: Creating a Manipulator RETURN, 0 This convention is used in all manipulator classes included with IDL. We strongly suggest that you include similar checks in your own class definition files. Keywords to the Init Method Properties of the manipulator class can be set in the Init method by specifying the property names and values as IDL keyword-value pairs.
Chapter 8: Creating a Manipulator 211 FUNCTION ExampleManip::Init, _REF_EXTRA = _extra ; Initialize the superclass. IF (self->IDLitManipulator::Init(TYPES=['IDLIMAGE'], $ NAME='Sample Manipulator', TRANSIENT_DEFAULT=1, $ OPERATION_IDENTIFIER='SET_PROPERTY', $ PARAMETER_IDENTIFIER='ALPHA_CHANNEL', $ _EXTRA = _extra) NE 1) THEN $ RETURN, 0 ; Call a custom method that registers a cursor for this ; manipulator. self->DoRegisterCursor ; Indicate success.
Chapter 8: Creating a Manipulator • The TRANSIENT_DEFAULT keyword indicates that this manipulator is transient, and that the default manipulator should be automatically started when this manipulator finishes (on mouse up). • If the manipulator is to support undo/redo functionality, you must specify an operation associated with the manipulator as the OPERATION_IDENTIFIER keyword value.
Chapter 8: Creating a Manipulator 213 required. It is always safest, however, to create a Cleanup method that calls the superclass’ Cleanup method. See “IDLitManipulator::Cleanup” (IDL Reference Guide) for additional details. Example Cleanup Method The following example code shows a very simple Cleanup method for the ExampleManip manipulator: PRO ExampleManip::Cleanup ; Clean up superclass.
Chapter 8: Creating a Manipulator up initial values required for manipulator actions. If your manipulator calls a custom operation or the SET_PROPERTY operation, and you want to enable undo/redo support, call the RecordUndoValues method in the OnMouseDown method to record the initial values. See “Manipulators and the Undo/Redo System” on page 202 for more information. Example OnMouseDown Method The following example code shows a simple OnMouseDown method for the ExampleManip manipulator.
Chapter 8: Creating a Manipulator 215 to determine whether a button is pressed during mouse motion, or which button is pressed if this level of granularity is needed. See “Using Manipulator Public Instance Data” on page 204 for details. Example OnMouseMotion Method The following example shows elements common in an interactive manipulator’s OnMouseMotion method. For a complete working example, see “Example: Color Table Manipulator” on page 226. ; Configure mouse motion method.
Chapter 8: Creating a Manipulator “IDLitManipulator::OnMouseMotion” (IDL Reference Guide) for details. Before exiting, call our superclass. Implementing an OnMouseUp Method The manipulator class OnMouseUp method is called when a mouse up event occurs over the target window. The method typically includes a call to the CommitUndoValues method to commit the user’s changes during the mouse transaction. (This is only required to support undo/redo functionality.
Chapter 8: Creating a Manipulator 217 If the manipulator supports undo/redo functionality, call RecordUndoValues prior to modifying the visualization in response to scroll wheel actions, and call CommitUndoValues prior to exiting the method. See “Manipulators and the Undo/Redo System” on page 202 for details.
Chapter 8: Creating a Manipulator scroll wheel event is processed — the magnitude of the Delta parameter (indicating how far the wheel was scrolled) is ignored. Creating an OnKeyboard Method Once a manipulator has been started, and a mouse event has been registered in the iTool window, the OnKeyboard method can support additional user interaction through keyboard actions. The OnKeyboard event often includes execution logic from each of the mouse methods.
Chapter 8: Creating a Manipulator 219 ; the retrieved IDLitVisImage object. self.oImage = (*self.pSelectionList)[0] ENDIF ELSE BEGIN RETURN ENDELSE ; Record the current values for the selected images. iStatus = self->RecordUndoValues() ; *** Interact with the visualization based upon key press. ; ... ; Commit this transaction. iStatus = self->CommitUndoValues() ; Write information to the status bar ; using inherited IDLitIMessaging ProbeStatusMessage method.
Chapter 8: Creating a Manipulator includes the IDLitManpulator::RegisterCursor method. Call this method to register a custom cursor when the manipulator is initialized. The RegisterCursor method accepts a 16-element string array of 16 characters each that defines the body, mask area, and hot spot of the cursor. See “IDLitManipulator::RegisterCursor” (IDL Reference Guide) for details. This lets you quickly configure a cursor without having to create and reference a separate bitmap file.
Chapter 8: Creating a Manipulator 221 Discussion This DoRegisterCursor method defines a 16-element string array of 16 characters each that represents the cursor. The strArray contains the following elements: • the “#” symbols translate into the black areas of the cursor body • the “.
Chapter 8: Creating a Manipulator PRO ExampleManip::SetProperty, _REF_EXTRA = _extra IF (N_ELEMENTS(_extra) GT 0) THEN $ self->IDLitManipulator::SetProperty, _EXTRA = _extra END Discussion The GetProperty and SetProperty methods first define the keywords they will accept. There must be a keyword for each property of the manipulator type. The keyword inheritance mechanism allows properties to be retrieved from or set on the ExampleManip class’ superclasses without knowing the names of the properties.
Chapter 8: Creating a Manipulator 223 Registering a Manipulator Before a manipulator can be activated by an iTool, the manipulator’s class definition must be registered as being available to the iTool. Registering a manipulator with the iTool links the class definition file that contains the actual IDL code that defines the manipulator with a simple string that names the manipulator. Code that defines a manipulator in an iTool uses the name string to specify which manipulation should be performed.
Chapter 8: Creating a Manipulator ICON A string value giving the name of an icon to be associated with this object. Typically, this property is the name of a bitmap file that is used to represent the manipulator on the toolbar. The location of the icon image file determines how it is specified. If it exists in the resource/bitmaps subdirectory of the IDL installation, simply use the name of the file minus the extension. For example, 'crop' references the Crop tool’s associated icon, crop.bmp.
Chapter 8: Creating a Manipulator 225 Unregistering a Manipulator If you are creating a new iTool from an existing iTool class, you may want to remove a manipulator registered for the existing class from your new tool. This can be useful if you have an iTool class that implements all of the functionality you need, but which registers a manipulator you don’t want included in your iTool.
Chapter 8: Creating a Manipulator Example: Color Table Manipulator The following example creates a custom manipulator that allows you to interactively change the palette applied to a single-plane image. After activating the manipulator by selecting the Color Table tool icon on the toolbar, position the cursor over the image and with the mouse button held down, move the mouse to the right or left to change the palette.
Chapter 8: Creating a Manipulator 227 This example creates three files: • Manipulator Class Definition (example3_manippalette__define.pro) – defines the characteristics and actions of the manipulator in response to mouse and keyboard events. See “Color Table Manipulator Class Definition” below. • iTool Class Definition (example3tool__define.pro) – defines this tool’s inheritance of the IDLitToolImage tool and registers the custom manipulator.
Chapter 8: Creating a Manipulator Example Code The class definition code for this example tool is included in the file example3tool__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Run the example procedure by entering example3tool__define at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT example3tool__define.pro. Tool Launch Routine for Custom Color Table Manipulator Create a launch routine (example3tool.
Chapter 9 Creating a File Reader This chapter describes the process of creating an iTool file reader. Overview of iTool File Readers . . . . . . . . . 230 Predefined iTool File Readers . . . . . . . . . . 231 Creating a New File Reader . . . . . . . . . . . . 234 iTool Developer’s Guide Registering a File Reader . . . . . . . . . . . . . 245 Unregistering a File Reader . . . . . . . . . . . 246 Example: TIFF File Reader . . . . . . . . . . .
Chapter 9: Creating a File Reader Overview of iTool File Readers A file reader is an iTool component object class that defines how data stored in a file should be imported into the iTool environment. File readers have mechanisms for determining the type of data stored in a file, which allows them to create IDLitData objects from the stored data.
Chapter 9: Creating a File Reader 231 Predefined iTool File Readers The iTool system distributed with IDL includes a number of predefined file readers. You can include these file readers in an iTool directly by registering the class with your iTool (as described in “Registering a File Reader” on page 245). You can also create a new file reader class based on one of the predefined classes.
Chapter 9: Creating a File Reader Registered Properties None IDLitReadISV The iTools Saved Variables file reader restores a saved iTool state (*.isv) file. All data objects in the file are placed into the current iTool data manager session, and all visualization objects are restored and displayed. Registered Properties None IDLitReadJPEG The iTools JPEG file reader uses the IDL READ_JPEG procedure to read a *.jpg or *.jpeg file and place the image data in an iTool image data object.
Chapter 9: Creating a File Reader 233 Registered Properties None IDLitReadPNG The iTools PNG file reader uses the IDL READ_PNG function to read a *.png file and place the image (and, optionally, palette) data in an iTool image data object. Registered Properties None IDLitReadShapefile The iTools Shapefile reader uses the IDLffShape object to read an ESRI shapefile and place the polygons or polylines in an iTool image data object.
Chapter 9: Creating a File Reader Creating a New File Reader An iTool file reader class definition file must (at the least) provide methods to initialize the file reader class, get and set property values, handle changes to the underlying data, clean up when the file reader is destroyed, and define the file reader class structure. Complex file reader types will likely provide additional methods.
Chapter 9: Creating a File Reader 235 See “IDLitReader” (IDL Reference Guide) for details on the methods and properties available to classes that subclass from IDLitReader. Example Class Structure Definition The following is the class structure definition for the ExampleReader file reader class. This procedure should be the last procedure in a file named examplereader__define.pro.
Chapter 9: Creating a File Reader • return the value 1 if the initialization steps are successful, or 0 otherwise Definition of the Init Function Begin by defining the argument and keyword list for your Init method.
Chapter 9: Creating a File Reader 237 (indicating failure), the current Init method also immediately returns with a value of 0: IF (self->SomeFileReaderClass::Init(_EXTRA = _extra) EQ 0) THEN $ RETURN, 0 This convention is used in all file reader classes included with IDL. We strongly suggest that you include similar checks in your own class definition files.
Chapter 9: Creating a File Reader Return Value If all of the routines and methods used in the Init method execute successfully, it should indicate successful initialization by returning 1. Other file reader classes that subclass from your file reader class may check this return value, as your routine should check the value returned by any superclass Init methods called. Registering Properties File reader objects can register properties with the iTool.
Chapter 9: Creating a File Reader 239 Passing Through Caller-Supplied Property Settings If you have included the _REF_EXTRA keyword in your function definition, you can use IDL’s keyword inheritance mechanism to pass any “extra” keyword values included in the call to the Init method through to other routines.
Chapter 9: Creating a File Reader 2. Returns the integer 1, indicating successful initialization. Creating a Cleanup Method The file reader class Cleanup method handles any cleanup required by the file reader object, and should do the following: • destroy any pointers or objects created by the file reader • call the superclass’ Cleanup method Calling the superclass’ cleanup method will destroy any objects created when the superclass was initialized.
Chapter 9: Creating a File Reader 241 Note Any property registered with a call to the RegisterProperty method must be listed as a keyword to the GetProperty method either of the visualization class or one of its superclasses. Note A file reader need not register any properties at all, if the read operation is simple. Many of the standard iTool image file readers work without registering any properties. See “IDLitReader::GetProperty” (IDL Reference Guide) for additional details.
Chapter 9: Creating a File Reader Note Any property registered with a call to the RegisterProperty method must be listed as a keyword to the SetProperty method either of the visualization class or one of its superclasses. Note A file reader need not register any properties at all, if the read operation is simple. Many of the standard iTool image file readers work without registering any properties. See “IDLitReader::SetProperty” (IDL Reference Guide) for additional details.
Chapter 9: Creating a File Reader 243 Example IsA Method FUNCTION ExampleReader::IsA, strFilename iDot = STRPOS(strFilename, '.', /REVERSE_SEARCH) IF (iDot GT 0) THEN BEGIN fileSuffix = STRUPCASE(STRMID(strFilename, iDot + 1)) IF (STRUPCASE(fileSuffix) EQ 'PPM') THEN RETURN, 1 ENDIF self->IDLitIMessaging::ErrorMessage, $ ["The specified file is not a PPM file.
Chapter 9: Creating a File Reader ; Get the name of the file currently associated with the reader. filename = self->GetFilename() ; Read the file. READ_PPM, filename, image ; Store image data in Image Data object.
Chapter 9: Creating a File Reader 245 Registering a File Reader Before a file reader can be used by an iTool to read in a file, the file reader’s class definition must be registered as being available to the iTool. Registering a file reader with the iTool links the class definition file that contains the actual IDL code that defines the file reader with a simple string that names the reader. Code that calls a file reader in an iTool uses the name string to specify which reader should be created.
Chapter 9: Creating a File Reader Unregistering a File Reader If you are creating a new iTool from an existing iTool class, you may want to remove a file reader registered for the existing class from your new tool. This can be useful if you have an iTool class that implements all of the functionality you need, but which registers a file reader you don’t want included in your iTool.
Chapter 9: Creating a File Reader 247 STRMID(frlist[i], STRPOS(frlist[i], '/', /REVERSE_SEARCH)+1) See “IDLitTool::FindIdentifiers” (IDL Reference Guide) for details.
Chapter 9: Creating a File Reader Example: TIFF File Reader This example creates a file reader to read TIFF format files. Example Code The code for this example file reader is included in the file example1_readtiff__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Run the example procedure by entering example1_readtiff__define at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT example1_readtiff__define.pro.
Chapter 9: Creating a File Reader 249 Init Method FUNCTION example1_readtiff::Init, _REF_EXTRA = _extra ; Call the superclass Init method IF (self->IDLitReader::Init(["tiff", "tif"],$ NAME="Tiff Files", $ DESCRIPTION="TIFF File format", $ _EXTRA = _extra) NE 1) THEN $ RETURN, 0 ; Initialize the instance data field self._index = 0 ; Register the index property self->RegisterProperty, 'IMAGE_INDEX', /INTEGER, $ Description='Index of the image to read from the TIFF file.
Chapter 9: Creating a File Reader Finally, we return the value 1 to indicate successful initialization. IsA Method FUNCTION example1_readtiff::Isa, strFilename RETURN, QUERY_TIFF(strFilename) END Discussion The IsA method for our TIFF file reader is simple: we use the IDL QUERY_TIFF function to determine whether the specified file is a TIFF file, returning the function’s return value.
Chapter 9: Creating a File Reader 251 RETURN, result END Discussion The GetData method for our TIFF file reader begins by retrieving the name of the file associated with the reader object. We then use the IDL QUERY_TIFF function to check whether the image specified by the value of the IMAGE_INDEX property (stored in the _index instance data field) exists, returning 0 for failure if the specified image does not exist.
Chapter 9: Creating a File Reader END Discussion The GetProperty method for our TIFF file reader supports a single property named IMAGE_INDEX. If this property is specified in the call to the GetProperty method, its value is retrieved from the _index instance data field. Any other properties included in the method call are passed to the superclass’ GetProperty method.
Chapter 10 Creating a File Writer This chapter describes the process of creating an iTool file writer. Overview of iTool File Writers . . . . . . . . . 254 Predefined iTool File Writers . . . . . . . . . . 255 Creating a New File Writer . . . . . . . . . . . . 258 iTool Developer’s Guide Registering a File Writer . . . . . . . . . . . . . 269 Unregistering a File Writer . . . . . . . . . . . 270 Example: TIFF File Writer . . . . . . . . . . . .
Chapter 10: Creating a File Writer Overview of iTool File Writers A file writer is an iTool component object class that defines how data stored in the iTool data manager can be exported to a file. File writers have mechanisms for manipulating data stored in iTool data objects into the proper format for a given file type. Some examples of iTool file writers are: • the ASCII file writer, which uses the IDL PRINTF procedure to write data to a text file.
Chapter 10: Creating a File Writer 255 Predefined iTool File Writers The iTool system distributed with IDL includes a number of predefined file writers. You can include these file writers in an iTool directly by registering the class with your iTool (as described in “Registering a File Writer” on page 269). You can also create a new file writer class based on one of the predefined classes. IDLitWriteASCII The iTools ASCII file writer uses the IDL PRINTF procedure to print strings to a file.
Chapter 10: Creating a File Writer IDLitWriteEMF The iTools EMF file writer uses the iTools system clipboard to write an image and its color table vectors to a Microsoft Windows Enhanced Metafile (.emf). Registered Properties GRAPHICS_FORMAT — A integer that specifies whether graphics should be rendered using bitmap (0) or vector (1) output. IDLitWriteEPS The iTools EPS file writer uses the iTools system clipboard to write an image and its color table vectors to a Encapsulated PostScript (.
Chapter 10: Creating a File Writer 257 good quality. Lower values of QUALITY produce higher compression ratios and smaller files. IDLitWriteJPEG2000 The iTools JPEG2000 file writer uses the IDL WRITE_JPEG2000 procedure to write compressed images to files. JPEG 2000 is a wavelet-based compression method for full-color and gray-scale images. Registered Properties N_LAYERS — An integer specifying the number of quality layers to include.
Chapter 10: Creating a File Writer Creating a New File Writer The process of creating an visualization type is outlined in the following sections: • “Creating the Class Structure Definition” on page 258 • “Creating an Init Method” on page 259 • “Creating a Cleanup Method” on page 264 • “Creating a GetProperty Method” on page 264 • “Creating a SetProperty Method” on page 265 • “Creating a SetData Method” on page 266 Creating the Class Structure Definition When any IDL object is created, IDL
Chapter 10: Creating a File Writer 259 Example Class Structure Definition The following is the class structure definition for the ExampleWriter file writer class. This procedure should be the last procedure in a file named examplewriter__define.pro. PRO ExampleWriter__Define struct = { ExampleWriter, INHERITS IDLitWriter $ } $ END Discussion The purpose of the structure definition routine is to define a named IDL structure with structure fields that will contain the visualization object instance data.
Chapter 10: Creating a File Writer 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 whether keywords not explicitly handled by your method will be passed through to other routines called by your method via IDL’s keyword inheritance mechanism.
Chapter 10: Creating a File Writer 261 This convention is used in all file writer classes included with IDL. We strongly suggest that you include similar checks in your own class definition files. Keywords to the Init Method Properties of the file writer class can be set in the Init method by specifying the property names and values as IDL keyword-value pairs.
Chapter 10: Creating a File Writer Return Value If all of the routines and methods used in the Init method execute successfully, it should indicate successful initialization by returning 1. Other file writer classes that subclass from your file writer class may check this return value, as your routine should check the value returned by any superclass Init methods called. Registering Properties File writer objects can register properties with the iTool.
Chapter 10: Creating a File Writer 263 Passing Through Caller-Supplied Property Settings If you have included the _REF_EXTRA keyword in your function definition, you can use IDL’s keyword inheritance mechanism to pass any “extra” keyword values included in the call to the Init method through to other routines.
Chapter 10: Creating a File Writer inheritance mechanism to pass through any keywords provided when the ExampleWriter Init method is called. 2. Returns the integer 1, indicating successful initialization.
Chapter 10: Creating a File Writer 265 Note Any property registered with a call to the RegisterProperty method must be listed as a keyword to the GetProperty method either of the visualization class or one of its superclasses. Note A file writer need not register any properties at all, if the write operation is simple. Many of the standard iTool image file writers work without registering any properties. See “IDLitWriter::GetProperty” (IDL Reference Guide) for additional details.
Chapter 10: Creating a File Writer Note Any property registered with a call to the RegisterProperty method must be listed as a keyword to the SetProperty method either of the visualization class or one of its superclasses. Note A file writer need not register any properties at all, if the write operation is simple. Many of the standard iTool image file writer work without registering any properties. See “IDLitWriter::SetProperty” (IDL Reference Guide) for additional details.
Chapter 10: Creating a File Writer 267 Example SetData Method FUNCTION ExampleWriter::SetData, oImageData ; Prompt user for a file in which to save the data strFilename = self->GetFilename() IF (strFilename EQ '') THEN $ RETURN, 0 ; failure ; Check validity of the input data object IF (~ OBJ_VALID(oImageData)) THEN BEGIN self->ErrorMessage, ['Invalid image data object'], $ TITLE = 'Error', SEVERITY = 2 RETURN, 0 ; failure ENDIF ; Check the iTool data type of the selected data object.
Chapter 10: Creating a File Writer TITLE = 'Error', SEVERITY = 2 RETURN, 0 ; failure ENDIF ; Get number of dimensions of image array. ndim = SIZE(image, /N_DIMENSIONS) ; Write to a PPM file. Use REVERSE to make image appear ; with correct orientation. WRITE_PPM, strFilename, REVERSE(image, ndim) ; Return 1 for success. RETURN, 1 END Discussion The SetData method accepts an IDLitData object (oImageData) as its input parameter.
Chapter 10: Creating a File Writer 269 Registering a File Writer Before a file writer can be used by an iTool to write a file, the file writer’s class definition must be registered as being available to the iTool. Registering a file writer with the iTool links the class definition file that contains the actual IDL code that defines the file writer with a simple string that names the writer. Code that calls a file writer in an iTool uses the name string to specify which writer should be created.
Chapter 10: Creating a File Writer Unregistering a File Writer If you are creating a new iTool from an existing iTool class, you may want to remove a file writer registered for the existing class from your new tool. This can be useful if you have an iTool class that implements all of the functionality you need, but which registers a file writer you don’t want included in your iTool.
Chapter 10: Creating a File Writer 271 STRMID(fwlist[i], STRPOS(fwlist[i], '/', /REVERSE_SEARCH)+1) See “IDLitTool::FindIdentifiers” (IDL Reference Guide) for details.
Chapter 10: Creating a File Writer Example: TIFF File Writer This example creates a file writer to write TIFF format files. Example Code The code for this example file writer is included in the file example1_writetiff__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Run the example procedure by entering example1_writetiff__define at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT example1_writetiff__define.pro.
Chapter 10: Creating a File Writer 273 IF (self->IDLitWriter::Init('tiff', $ TYPES=['IDLIMAGE', 'IDLIMAGEPIXELS', 'IDLARRAY2D'], $ NAME="Tag Image File Format", $ DESCRIPTION="Tag Image File Format (TIFF)", $ _EXTRA = _extra) EQ 0) THEN $ RETURN, 0 RETURN, 1 END Discussion The first item in our class definition file is the Init method. The Init method’s function signature is defined first, using the class name example1_writetiff.
Chapter 10: Creating a File Writer RETURN, 0 ; failure ; Make sure that the object passed to this method is valid. IF (~ OBJ_VALID(oImageData)) THEN BEGIN MESSAGE, 'Invalid image data object.', /CONTINUE RETURN, 0 ; failure ENDIF ; First, we look for some image data. oData = (oImageData->GetByType('IDLIMAGEPIXELS'))[0] ; If we did not get any image data, try retrieving a ; 2D array.
Chapter 10: Creating a File Writer RETURN, 1 275 ; success END Discussion The SetData method accepts an IDLitData object (oImageData) as its input parameter. Before processing the input data, the method prompts the user for a file in which to save the image, using the GetFilename method of the IDLitWriter object. After securing a filename, the method proceeds to check the input data object. First it checks to make sure that the input object is valid.
Example: TIFF File Writer Chapter 10: Creating a File Writer iTool Developer’s Guide
Part III: Modifying the iTool User Interface
Chapter 11 iTool User Interface Architecture This chapter provides an overview of the iTool user interface architecture. Overview of iTool Interface Architecture . 280 iTool Developer’s Guide User Interface Objects . . . . . . . . . . . . . . .
Chapter 11: iTool User Interface Architecture Overview of iTool Interface Architecture The iTool user interface architecture is designed to preserve the separation between the functionality provided by an iTool application and the manner in which that functionality is presented to the user.
Chapter 11: iTool User Interface Architecture 281 iImage tools provide examples of a panel interface. Panel interfaces are described in Chapter 14, “Creating a User Interface Panel”.
Chapter 11: iTool User Interface Architecture User Interface Objects The iTool user interface object is an instance of the class IDLitUI. The UI object provides a way for the iTool to communicate with interface elements created using the IDL widget toolkit. As the center of communication between the user interface and the underlying iTool functionality, the UI object provides the following functionality: • Access to and communication with the underlying iTool object.
Chapter 11: iTool User Interface Architecture 283 Widget Registration Methods The IDLitUI::RegisterWidget and IDLitUI::UnRegisterWidget methods allow user interface code to register (and unregister) widget callback routines as the target of OnNotify messages. Registration allows the user interface to receive messages generated by iTool components and to react accordingly. Widget registration is discussed in detail in Chapter 14, “Creating a User Interface Panel”.
User Interface Objects Chapter 11: iTool User Interface Architecture iTool Developer’s Guide
Chapter 12 Using iTool User Interface Elements This chapter describes user interface elements that can be incorporated into an iTool without the need to write any user interface code. The iTools Feedback Mechanism . . . . . . . 286 Status Messages . . . . . . . . . . . . . . . . . . . . . 287 iTool Developer’s Guide Prompts . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 Informational Messages . . . . . . . . . . . . . .
Chapter 12: Using iTool User Interface Elements The iTools Feedback Mechanism The IDLitIMessaging class provides methods that allow you to accept and return feedback via the iTool interface without writing any interface code yourself.
Chapter 12: Using iTool User Interface Elements 287 Status Messages Status messages are simple text messages displayed in a way that does not impede the user’s operation of the iTool. In the standard iTool user interface created using the IDL widget toolkit, status messages are text strings displayed at the bottom of the iTool window. Figure 12-1: The status areas of a standard iTool. The IDLitIMessaging class provides two methods that display status messages.
Chapter 12: Using iTool User Interface Elements In the standard set of iTools provided with IDL, the probe status area is used to display the position of the cursor within the iTool window. The following code places the text “X: 300, Y:146” in the status area: self->ProbeStatusMessage, 'X: 300, Y:146' In most cases, the values displayed in the probe status area have some relationship to the position of the cursor or to the action performed by the current manipulator.
Chapter 12: Using iTool User Interface Elements 289 Prompts Prompts solicit information from the user. Prompts are generally presented as modal dialogs, meaning that the user must respond to the prompt before operation of the iTool can continue. Figure 12-2: Yes/No and Text Prompt dialogs. The IDLitIMessaging class provides two methods that prompt for user input: PromptUserYesNo and PromptUserText. See “IDLitIMessaging” (IDL Reference Guide) for additional details on these methods.
Chapter 12: Using iTool User Interface Elements PromptUserText The IDLitIMessaging::PromptUserText method displays a prompt string and a textentry field along with OK and Cancel buttons. In the standard iTool interface created using the IDL widget toolkit, text prompts appear as modal dialogs as shown in Figure 12-2. Note The PromptUserText function returns 1 if the user clicks the OK button, or 0 if the user clicks the Cancel button.
Chapter 12: Using iTool User Interface Elements 291 Informational Messages Informational Messages inform the user that some condition has occurred in the iTool application. The condition may be an error, but it can also be any other occurrence of which the user should be informed. Informational messages are presented as modal dialogs, generally with a single OK button that dismisses the dialog. Figure 12-3: An informational message dialog.
Informational Messages Chapter 12: Using iTool User Interface Elements iTool Developer’s Guide
Chapter 13 Creating a User Interface Service This chapter describes the process of creating a user interface service. Overview of the iTool UI Service . . . . . . . 294 Predefined iTool UI Services . . . . . . . . . . . 295 Creating a New UI Service . . . . . . . . . . . . 297 iTool Developer’s Guide Registering a UI Service . . . . . . . . . . . . . 302 Executing a User Interface Service . . . . . 304 Example: Changing a Property Value . . .
Chapter 13: Creating a User Interface Service Overview of the iTool UI Service A UI service is an iTool component object class that defines how and when a user interface element is presented to an iTool user. UI services provide a way to separate platform-independent iTool functionality from platform-dependent user interface code.
Chapter 13: Creating a User Interface Service 295 Predefined iTool UI Services The iTool system distributed with IDL includes a number of predefined UI services. These UI services are registered with the iTool system, which means that you can call them from any operation, visualization, or other iTool component using the DoUIService method of the IDLitTool class. The majority of the predefined UI services provide interface elements that are specific to the standard iTool implementation.
Chapter 13: Creating a User Interface Service Example RETURN, oTool->DoUIService('PropertySheet', self) Operation Preview Service This service is designed to be called from within the DoExecuteUI method of an iTool operation that acts on a two-dimensional array. It displays the property sheet for the operation, allowing the user to set any operation properties before the operation is executed, along with a preview window showing the result. The self argument is the IDLitOperation object.
Chapter 13: Creating a User Interface Service 297 Creating a New UI Service A user interface service is responsible for creating a user interface element that is displayed when an iTool user takes some action. A simple UI service may do no more than display the “hourglass” cursor while an operation is being performed; more complicated UI services may be small applications unto themselves. For simple operations the UI service routine can contain everything necessary to implement the UI service.
Chapter 13: Creating a User Interface Service Return Value The user interface service routine should return 1 if the action succeeds, or 0 otherwise. Retrieving Property Information The oRequester argument to the user interface service function contains an object reference to the iTool component on which the UI service was invoked. Use this reference to retrieve any properties of the object that are relevant to the operation being performed by the user interface.
Chapter 13: Creating a User Interface Service 299 Displaying the User Interface If the user interface being displayed by the UI service is simple, it may be convenient to include the code for creating it directly in the definition of the user interface service itself.
Chapter 13: Creating a User Interface Service Example The following example routine is the full definition of the ScaleFactor user interface service described in the previous sections. It is presented here again for completeness, so you can see the entire function at once. FUNCTION IDLituiScaleFactor, oUI, oRequester ; Retrieve widget ID of top-level base. oUI->GetProperty, GROUP_LEADER = groupLeader ; Retrieve geometry information and calculate offsets.
Chapter 13: Creating a User Interface Service 301 Place data collected by the user interface in the function’s return value Create your user interface routine (the routine that creates the IDL widgets that make up the user interface displayed by your UI service) as a function, returning the data values collected by the interface in the function’s return value. If you are collecting several values of different data types, return a structure variable containing the data.
Chapter 13: Creating a User Interface Service Registering a UI Service Before a user interface service can be called from an iTool, the routine that implements the service must be registered with the iTool system. Registering a UI service with the system links the file containing the actual IDL code that creates the user interface elements with a simple string that names the UI service.
Chapter 13: Creating a User Interface Service 303 Example Suppose you have a UI service definition file named myUIService.pro, located in a directory included in IDL’s !PATH system variable. Register this service with the iTool system with the following command: ITREGISTER, 'My UI Service', 'myUIService', /UI_SERVICE The user interface service can now be invoked via the DoUIService method: success = oTool->DoUIService('My UI Service', self) where oTool is an object reference to the current iTool object.
Chapter 13: Creating a User Interface Service Executing a User Interface Service Once you have defined and registered a user interface service and created any supporting user interface code, you can call the service from any iTool operation simply by calling the DoUIService method of the IDLitTool class. In most cases, the DoUIService method is called from the DoExecuteUI method of an IDLitOperation or an IDLitDataOperation.
Chapter 13: Creating a User Interface Service 305 Example: Changing a Property Value This example creates a user interface service named SrvExample, which displays a dialog that allows the user to change the NAME property of the currently selected iTool component. The SrvExample user interface service is launched by an IDLitDataOperation named opName. This example is intended as a demonstration of the techniques used to create a user interface service.
Chapter 13: Creating a User Interface Service ; a new name. newName = wdSrvExample(NAME = origName, $ GROUP_LEADER = groupLeader) ; Set the property value. oRequester->SetProperty, NAME = newName ; Return success RETURN, 1 END Discussion The function that implements this example service follows the pattern outlined in “Creating the UI Service Routine” on page 297.
Chapter 13: Creating a User Interface Service 307 ; Create the dialog.
Chapter 13: Creating a User Interface Service Discussion It is beyond the scope of this chapter to discuss the IDL widget programming techniques used in this example. For more information on widget programming, see the Building IDL Applications manual. Several points are worth noting, however. • The widget ID of the top-level base retrieved in the SrvExample routine is passed to this routine, and used as the value of the GROUP_LEADER keyword to WIDGET_BASE.
Chapter 13: Creating a User Interface Service 309 Discussion When the user clicks the OK button, the current value of the editable text widget is placed in the pointer stored in the state structure’s pName field. Creating an Operation that Calls the Service In order to launch the SrvExample user interface service, the user must be able to select an operation that calls the DoUIService method.
Chapter 13: Creating a User Interface Service PRO opName__define struct = {opName, $ inherits IDLitDataOperation $ } END Discussion Only two methods are required: Init and DoExecuteUI. Since this operation is based on the IDLitDataOperation class, all interaction with the iTools undo/redo system is automated.
Chapter 14 Creating a User Interface Panel This chapter describes the process of creating a user interface panel. Overview of the iTool UI Panel . . . . . . . . . 312 Creating a UI Panel Interface . . . . . . . . . . 313 Creating Callback Routines . . . . . . . . . . . . 318 iTool Developer’s Guide Registering a UI Panel . . . . . . . . . . . . . . . 320 Example: A Simple UI Panel . . . . . . . . . .
Chapter 14: Creating a User Interface Panel Overview of the iTool UI Panel A UI Panel is a collection of user interface elements displayed in one or more tabs located on the right, left, or bottom edge of an iTool window. The UI panel interface makes it easy to attach a set of controls chosen by the iTool developer to the standard iTool interface. Note In the initial iTools release, only one user interface style is supplied: the IDL widget interface toolkit.
Chapter 14: Creating a User Interface Panel 313 Creating a UI Panel Interface It is beyond the scope of this manual to provide general information on the creation of user interfaces. For information on creating a user interface using the IDL widget toolkit, see “Creating Graphical User Interfaces in IDL” (Building IDL Applications). Keep the following points in mind when creating IDL widget interface code for iTool user interface panels.
Chapter 14: Creating a User Interface Panel Use the widget ID of the panel widget to set the title of the tab that appears at the top of the panel. For example the following lines might occur at the beginning of a routine that builds a user interface panel: PRO ExamplePanel, wPanel, oUI ; Set the title used on the panel's tab. WIDGET_CONTROL, wPanel, BASE_SET_TITLE='Example Panel' ... more panel code.
Chapter 14: Creating a User Interface Panel 315 Adding Observers For notification messages to be passed to the correct callback routine, an OnNotifyObserver must be established by calling the AddOnNotifyObserver method of the IDLitUI object. The AddOnNotifyObserver method takes as its arguments the ID created by the call to the RegisterWidget method (as discussed in the previous section) and the component object identifier of the iTool component to observe.
Chapter 14: Creating a User Interface Panel | - Base widget | - other widgets Since the widget ID of the panel widget is supplied as an argument to the panel creation routine, all that is left is to create a base widget with the panel widget as its parent, and to populate the base widgets with other widgets as necessary. Passing State Information State information can be passed between widget creation routines and widget event handling routines in several different ways.
Chapter 14: Creating a User Interface Panel 317 The following statement retrieves an array of object references to all of the currently selected items in the iTool: oTargets = state.oTool->GetSelectedItems(COUNT = nTarg) Note Note that this example assumes that a reference to the iTool object is stored in the oTool field of the state structure variable. The COUNT keyword to the GetSelectedItems method returns the number of items selected.
Chapter 14: Creating a User Interface Panel Creating Callback Routines User interface panel callback routines are executed when an iTool component, for which the panel has created an observer, generates a notification message. The callback routine then uses the value of the notification message to determine what action to take. Observers are created as described in “Adding Observers” on page 315.
Chapter 14: Creating a User Interface Panel 319 For example, if you have saved a state structure containing widget information in the user value of the first child widget of the panel widget, code similar to the following would allow you to retrieve that state structure: ; Make sure we have a valid widget ID. IF ~ WIDGET_INFO(wPanel, /VALID) THEN RETURN ; Retrieve the widget ID of the first child widget of ; the UI panel.
Chapter 14: Creating a User Interface Panel Registering a UI Panel User interface panels are registered with the iTool system using the ITREGISTER procedure. Once a UI panel has been registered, it will be displayed for any iTool whose TYPE property matches the string specified via the TYPES keyword when registering the panel.
Chapter 14: Creating a User Interface Panel 321 To set the TYPE property of a visualization, use a statement like this in the visualization’s Init method: self->IDLitVisualization::Init(_EXTRA = _extra, TYPE = panelType) where panelType is a string that matches the string used as the value of the TYPES keyword to ITREGISTER.
Chapter 14: Creating a User Interface Panel Example: A Simple UI Panel The following example creates a simple user interface panel consisting of two buttons: Rotate and Hide/Show. The Rotate button rotates the selected iTool component 90 degrees, if possible. The Hide/Show button toggles the value of the HIDE property of the selected object. Figure 14-1: The example panel. Note This example is intended to demonstrate the concepts involved in creating a user interface panel.
Chapter 14: Creating a User Interface Panel 323 distribution. Run the example procedure by entering example4_panel at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT example4_panel.pro. Panel Creation Routine The user interface panel creation routine (beginning with the line PRO Example4_panel, wPanel, oUI) does the work of displaying the IDL widgets that make up the UI panel display. PRO Example4_panel, wPanel, oUI ; Set the title used on the panel's tab.
Chapter 14: Creating a User Interface Panel oUI->AddOnNotifyObserver, strObserverIdentifier, idRotate ENDIF ELSE $ idRotate = 0 wHide = WIDGET_BUTTON(wBase, VALUE = "Show/Hide Item", $ UVALUE = "HIDE") ; Pack up the state structure and store in first child.
Chapter 14: Creating a User Interface Panel 325 • The example uses the GetTool method of the IDLitUI object to retrieve an object reference to the iTool with which the panel is associated. This reference is later used to retrieve a reference to the IDLitOperation object that performs the Rotate Left operation, placing it in the variable oRotate. • If the Rotate Left operation is available to the iTool, the example places the Rotate button on the user interface panel.
Chapter 14: Creating a User Interface Panel oTargets = state.oTool->GetSelectedItems(count = nTarg) IF nTarg GT 0 THEN BEGIN ; If there are selected items, use only the last item ; selected, which is stored in the first element of ; the returned array. oTarget = oTargets[0] ; Get the iTool identifier of the selected item. name = oTarget->GetFullIdentifier() ; Retrieve the setting of the HIDE property.
Chapter 14: Creating a User Interface Panel • 327 • Use the DoSetProperty method of the IDLitTool object to toggle the value of the HIDE property for the selected item. • Commit the property change in the undo/redo transaction buffer using the CommitActions method of the IDLitTool object. After the iTool display has been changed, call the RefreshCurrentWindow method of the IDLitTool object to redraw the iTool window.
Chapter 14: Creating a User Interface Panel oSel = state.oTool->GetSelectedItems() oSel = oSel[0] ; If the last item selected is not a visualization, ; desensitize the "Hide/Show" and "Rotate" buttons. IF (~OBJ_ISA(oSel, 'IDLITVISUALIZATION')) THEN BEGIN WIDGET_CONTROL, state.wHide, SENSITIVE = 0 WIDGET_CONTROL, state.wRotate, SENSITIVE = 0 ENDIF ELSE BEGIN ; If the selected object is a visualization, sensitize ; the "Hide/Show" and "Rotate" buttons. WIDGET_CONTROL, state.
Chapter 14: Creating a User Interface Panel 329 1. The UI panel must be registered, using the ITREGISTER procedure. 2. A tool with the appropriate TYPE must be created. For the purposes of this example, we will create an iTool named example4tool, with a launch routine named example4tool.pro, and an iTool object definition routine named example4tool__define.pro. Example Code Both example4tool.pro, and example4tool__define.pro are included in the examples/doc/itools subdirectory of the IDL distribution.
Example: A Simple UI Panel Chapter 14: Creating a User Interface Panel iTool Developer’s Guide
Chapter 15 Creating a Custom iTool Widget Interface This chapter describes the process of creating an iTool user interface using IDL widgets. About Custom iTool Widget Interfaces . . . Overview of Creating an iTool Interface . . iTool Widget Interface Concepts . . . . . . . . Creating the Interface Routine . . . . . . . . . . Adding Menus . . . . . . . . . . . . . . . . . . . . . . Adding a Toolbar . . . . . . . . . . . . . . . . . . . . Adding an iTool Window . . . . . . . . . . . . .
Chapter 15: Creating a Custom iTool Widget Interface About Custom iTool Widget Interfaces The standard interface to the iTools included with IDL is constructed from IDL widgets, using a number of special compound widgets designed to work with the iTool system. Other chapters in this section of the iTool Developer’s Guide describe how to use the user interface display mechanisms of the iTool system to add functionality to your own iTools within the constraints of the standard iTool interface.
Chapter 15: Creating a Custom iTool Widget Interface 333 the traditional draw widget with an iTool draw widget will require substantial revisions to your existing code, but making the revisions may be more efficient than recreating your application using only the iTool framework. Your application has a complex interface — Your application may require a more complex user interface than is possible to implement using iTool framework methods.
Chapter 15: Creating a Custom iTool Widget Interface • Use of the iTool compound widgets (see Appendix B, “iTool Compound Widgets”). What You Will Need to Create To build a custom iTool user interface, you will need to create a minimum of two new .pro files: • The widget interface definition. This file creates the widget interface, defines event handlers and callbacks, takes care of widget resizing and cleanup, and registers the widgets with a user interface object. • A launch routine.
Chapter 15: Creating a Custom iTool Widget Interface 335 Overview of Creating an iTool Interface This section provides a brief outline of the steps necessary to create a custom iTool interface. The topics introduced here are discussed in greater detail in later sections of this chapter. To create a custom iTool interface, you will do the following: 1. Create or Choose an iTool 2. Create the Widget Interface 3. Create Event Handlers 4. Create Callback Routines 5. Create a Cleanup Routine 6.
Chapter 15: Creating a Custom iTool Widget Interface Create Event Handlers While you do not need to handle the widget events that are internal to the iTool compound widgets, you will need to create event handlers for any other widgets you include in your interface. You will also need to provide event-handling code for the following: • Resizing of the iTool compound widgets. This is generally accomplished by calling the _RESIZE procedure associated with the compound widget.
Chapter 15: Creating a Custom iTool Widget Interface 337 • Registers your custom user interface with the iTool system, using the ITREGISTER procedure with the USER_INTERFACE keyword. • Calls the IDLITSYS_CREATETOOL function with the USER_INTERFACE keyword set equal to the name of your custom interface, as registered with the iTool system.
Chapter 15: Creating a Custom iTool Widget Interface iTool Widget Interface Concepts It is beyond the scope of this chapter to discuss the creation of IDL widget interfaces in general; see Chapter 2, “Creating Widget Applications” (Widget Application Programming) for a complete discussion. This section describes some things you will need to know about working with the iTool compound widgets that encapsulate the iTool components you can insert into your custom interface.
Chapter 15: Creating a Custom iTool Widget Interface 339 • require an object reference to an iTool user interface object on creation. • do not generate widget events. • do not have a value that can be retrieved or set. • are able to receive and respond to selected messages from the iTool messaging system.
Chapter 15: Creating a Custom iTool Widget Interface 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” on page 360.
Chapter 15: Creating a Custom iTool Widget Interface 341 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.
Chapter 15: Creating a Custom iTool Widget Interface 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.
Chapter 15: Creating a Custom iTool Widget Interface 343 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” on page 356.
Chapter 15: Creating a Custom iTool Widget Interface Adding Menus iTool menus are created using the CW_ITMENU compound widget. The signature of the CW_ITMENU function is: Result = CW_ITMENU(Parent, UI, Target [, KEYWORDS]) where: • Parent is the widget ID of the base widget on which the menu will be displayed. • UI is the user interface object associated with the interface.
Chapter 15: Creating a Custom iTool Widget Interface 345 1. If you register a new operation in one of the standard menu containers, it will appear on the menu for your iTool, and be sensitized and desensitized according to the same rules as the other items. 2. If you unregister an operation from one of the standard menu containers, it will be removed from the menu for your iTool. Operations are generally registered and unregistered in the Init method of an iTool creation routine.
Chapter 15: Creating a Custom iTool Widget Interface Adding a Toolbar iTool toolbars are created using the CW_ITTOOLBAR compound widget. The signature of the CW_ITTOOLBAR function is: Result = CW_ITTOOLBAR(Parent, UI, Target [, KEYWORDS]) where: • Parent is the widget ID of the base widget on which the toolbar will be displayed. • UI is the user interface object associated with the interface.
Chapter 15: Creating a Custom iTool Widget Interface 347 in the Operations/File container: New, Open, Save, and Print. Proxies are described in “Registering Components” on page 38. • The EXCLUSIVE keyword is passed through the CW_ITTOOLBAR function to the underlying widget base via the keyword inheritance mechanism. See the description under WIDGET_BASE for details. Modifying Toolbar Contents Each iTool toolbar contains an entry for each item that is registered in the container.
Chapter 15: Creating a Custom iTool Widget Interface Adding an iTool Window An iTool drawable area, or window, is created using the CW_ITWINDOW compound widget. The iTool window can display iTool visualizations and atomic IDL graphics objects, provides a mechanism for the display of the iTools property sheet interface, and makes it easy to perform tasks including translation, rotation, and scaling of visualizations using standard iTool manipulators.
Chapter 15: Creating a Custom iTool Widget Interface • 349 by interactively importing new data and creating new visualizations using the iTool Data Import Wizard or Insert Visualization dialog. These methods are standard to all iTools, and are discussed in the iTool User’s Guide. The contents of the iTool window can also be manipulated programmatically from “outside” the iTool framework in various ways: • by applying an operation using the iTool object’s DoAction method.
Chapter 15: Creating a Custom iTool Widget Interface Adding a Status Bar iTool status bars are created using the CW_ITSTATUSBAR compound widget. Statusbars can be used to display any type of information, but are commonly used to provide user feedback or information about the item underneath the mouse cursor. See “Status Messages” on page 287 for additional information on status bars.
Chapter 15: Creating a Custom iTool Widget Interface 351 Adding a User Interface Panel iTool user interface panels are created using the CW_ITPANEL compound widget. User interface panels can be used to display a selection of widgets in a tab interface on one side of the iTool interface. Note If you are creating a custom iTool user interface that includes both regular IDL widgets and iTool compound widgets in a standard base widget, it is unlikely that you will also need to create a user interface panel.
Chapter 15: Creating a Custom iTool Widget Interface Handling Callbacks User interface callback routines are executed when an iTool component, for which the user interface has created an observer, generates a notification message. The callback routine then uses the value of the notification message to determine what action to take. Observers are created as described in “User Interface Registration” on page 342. The iTool messaging system itself is discussed in “iTool Messaging System” on page 41.
Chapter 15: Creating a Custom iTool Widget Interface 353 PRO example2_wdtool_callback, wBase, strID, messageIn, userdata ; Retrieve a pointer to the state structure. wChild = WIDGET_INFO(wBase, /CHILD) WIDGET_CONTROL, wChild, GET_UVALUE = pState ; Handle the message that was passed in. CASE STRUPCASE(messageIn) OF 'FILENAME': BEGIN filename = FILE_BASENAME(userdata) newTitle = (*pState).
Chapter 15: Creating a Custom iTool Widget Interface Handling Resize Events It is beyond the scope of this chapter to discuss resizing of widget interfaces in general; see “Widget Sizing” (Chapter 3, Widget Application Programming) for a discussion of widget sizing issues. This section describes some things you will need to know in order to make your custom iTool widget interface resize properly.
Chapter 15: Creating a Custom iTool Widget Interface 355 handled based on the layout and desired behavior of the interface. Aside from the techniques discussed in “Widget Sizing” (Chapter 3, Widget Application Programming), keep the following in mind when writing your resizing routine: • Use the supplied *_RESIZE procedures defined by the iTool compound widget routines to resize the compound widgets, when they are available. See the reference pages for the CW_IT* widgets for details.
Chapter 15: Creating a Custom iTool Widget Interface Handling Shutdown Events Because your custom interface is associated with an iTool, destruction of the interface may entail shutting down and cleaning up the entire iTools system. This means that in addition to normal cleanup of pointers and objects used by the interface, you will need to instruct the iTools system to shut itself down when your interface is destroyed.
Chapter 15: Creating a Custom iTool Widget Interface 357 Your code should not assume that the top-level base widget will actually be destroyed, because the user may decide to cancel the close operation. Since the process of actually destroying the widget hierarchy is divorced from the generation of the WIDGET_KILL_REQUEST event, you may also need to supply a cleanup routine that is invoked only when the widget hierarchy is actually destroyed.
Chapter 15: Creating a Custom iTool Widget Interface Creating an iTool Launch Routine Once you have created your custom iTool widget interface, you must create a way to launch an iTool using the interface. To do this, you will most often create a custom iTool launch routine. iTool launch routines are discussed in detail in “Creating an iTool Launch Routine” on page 103.
Chapter 15: Creating a Custom iTool Widget Interface 359 ITREGISTER, 'Example2_UI', 'example2_wdtool', /USER_INTERFACE IPLOT, USER_INTERFACE='Example2_UI' These lines will create an iPlot tool using our custom user interface. This approach may be worthwhile when an existing launch routine handles data specified on the command line in a way that suits your needs.
Chapter 15: Creating a Custom iTool Widget Interface Example: a Custom iTool Interface This example creates a custom iTool interface that incorporates several standard IDL widgets to the left of the drawable area and displays a subset of the menus and toolbars that appear in a standard iTool. A button widget inserts a plot line created from random data, and several controls allow the user to change the number of points used to create the line, the line thickness, and the line color.
Chapter 15: Creating a Custom iTool Widget Interface 361 Note The code for this example is provided in the IDL distribution, in the examples/doc/itools subdirectory of the main IDL directory. You can run the example code directly by entering example2tool at the IDL prompt. Widget Interface Creation Routine This section describes the widget interface creation routine for the example interface. Example Code The example consists of several routines and is quite long.
Chapter 15: Creating a Custom iTool Widget Interface you are not familiar with this concept, inspect the example2_wdtool routine before reading the event handling and callback routines. Note We store our state variable in the user value of the first child widget, rather than the user value of the top-level base, as a matter of programming style. You could also choose to store the variable in the user value of the top-level base.
Chapter 15: Creating a Custom iTool Widget Interface 363 Discussion The FILENAME message and the rest of the callback routine are discussed in “Example Callback Routine” on page 352. example2_wdtool_resize The widget resizing routine for our example interface is shown below. It accepts three arguments: a pointer to the widget interface state structure, an integer representing the change in width (in pixels), and an integer representing the change in height (also in pixels).
Chapter 15: Creating a Custom iTool Widget Interface THEN BEGIN CW_ITWINDOW_RESIZE, (*pState).wDraw, newVisW, newVisH ENDIF ; Update the width of the toolbar base. WIDGET_CONTROL, (*pState).wToolbar, $ SCR_XSIZE = toolbarGeom.scr_xsize+deltaW ; Update the status bar to be the same width as the toolbar. CW_ITSTATUSBAR_RESIZE, (*pState).wStatus, $ toolbarGeom.scr_xsize+deltaW ; Turn UPDATE back on if we turned it off. IF (isUpdate && ~WIDGET_INFO((*pState).
Chapter 15: Creating a Custom iTool Widget Interface 365 example2_wdtool_cleanup The cleanup routine for our interface is simple; it frees the pointer used to hold the widget interface’s state structure. The complete code for the cleanup routine is shown below. PRO example2_wdtool_cleanup, wChild ; Make sure we have a valid widget ID. IF (~WIDGET_INFO(wChild, /VALID)) THEN $ RETURN ; Retrieve the pointer to the state structure, and ; free it.
Chapter 15: Creating a Custom iTool Widget Interface ; Destroy the widget. 'WIDGET_KILL_REQUEST': BEGIN ; Get the shutdown service and call DoAction. ; This code must be here, and not in the _cleanup routine, ; because the tool may not actually be killed. (For example ; the user may be asked if they want to save, and they may ; hit "Cancel" instead.) IF OBJ_VALID((*pState).oUI) THEN BEGIN oTool = (*pState).oUI->GetTool() oShutdown = oTool->GetService('SHUTDOWN') void=(*pState).
Chapter 15: Creating a Custom iTool Widget Interface 367 The WIDGET_KBRD_FOCUS event arrives when the user clicks “into” or “out of” the widget interface. We are concerned only with events generated when the user selects the widget interface, because in this case we need to inform the iTool system object that our iTool has become the “current” tool.
Chapter 15: Creating a Custom iTool Widget Interface ; Call IPLOT to create a plot of random values, replacing the ; data used in the iTool's window. IPLOT, RANDOMU(seed, points), THICK=linesize, $ COLOR=newcolor, VIEW_NUMBER=1 END Discussion This routine uses mostly standard widget programming techniques. Two points are worth noting, however: 1. We must be sure that our iTool is set as the current tool.
Chapter 15: Creating a Custom iTool Widget Interface 369 ; Set the THICK property on the plot line and commit the change. void = (*pState).oTool->DoSetProperty(plotID, 'THICK', $ linesize) (*pState).oTool->CommitActions END Discussion This routine uses the same technique as the draw_plot_event routine to ensure that our iTool is the current tool. It then retrieves the identifier of the plot line, ensures that the line itself is selected, and sets the THICK property on the line.
Chapter 15: Creating a Custom iTool Widget Interface ; Set the COLOR property on the plot line and commit the change. void = (*pState).oTool->DoSetProperty(plotID, 'COLOR', $ newcolor) (*pState).oTool->CommitActions END Discussion This routine uses the same technique as the draw_plot_event routine to ensure that our iTool is the current tool. It then retrieves the identifier of the plot line, ensures that the line itself is selected, and sets the COLOR property on the line.
Chapter 15: Creating a Custom iTool Widget Interface 371 END Discussion This routine uses the same technique as the draw_plot_event routine to ensure that our iTool is the current tool. It then retrieves the identifier of the plot line and the Median operation, selects the line, calls the DoAction method to apply the Median filter to the selected plot line.
Chapter 15: Creating a Custom iTool Widget Interface ; iTool menubars are created using the CW_ITMENU compound ; widget. The following statements create the standard iTool ; menus, pointing at the standard iTool operations containers. ; Note that if the iTool to which this user interface is applied ; has registered new operations in these containers, those ; operations will show up automatically.
Chapter 15: Creating a Custom iTool Widget Interface 373 ; interface. We create the widget layout in the usual way, ; incorporating iTool compound widgets and "traditional" ; widgets in the desired locations. ; Create a base to hold the controls and iTool draw window. wBaseUI = WIDGET_BASE(wBase, /ROW) ; Put controls in the left-hand base.
Chapter 15: Creating a Custom iTool Widget Interface location = [(screen[0] - baseGeom.xsize)/2 - 10, $ ((screen[1] - baseGeom.ysize)/2 - 100) > 10] ENDIF WIDGET_CONTROL, wBase, MAP = 0, $ TLB_SET_XOFFSET = location[0], $ TLB_SET_YOFFSET = location[1] ; Get the widget ID of the first child widget of our ; base widget. We'll use the child widget's user value ; to store our widget state structure.
Chapter 15: Creating a Custom iTool Widget Interface 375 oUI->AddOnNotifyObserver, myID, oTool->GetFullIdentifier() ; Specify how to handle destruction of the widget interface. WIDGET_CONTROL, wChild, KILL_NOTIFY = "example2_wdtool_cleanup" ; Display the iTool widget interface. WIDGET_CONTROL, wBase, /MAP ; Start event processing. XMANAGER, 'example2_wdtool', wBase, /NO_BLOCK END Discussion Most of the important sections of this routine have been discussed in previous sections.
Chapter 15: Creating a Custom iTool Widget Interface view the file in an IDL Editor window by entering .EDIT example2tool__define.pro. FUNCTION example2tool::Init, _REF_EXTRA = _extra ; Call our super class. IF ( self->IDLitToolbase::Init(_EXTRA = _extra) EQ 0) THEN $ RETURN, 0 ; This tool removes several of the standard iTool operations ; and manipulators.
Chapter 15: Creating a Custom iTool Widget Interface 377 iTool Launch Routine Discussion Our iTool launch routine simply registers the example2tool iTool class and the example2_wdtool interface definition, then creates an instance of the Example 2 Tool iTool using the Example2_UI interface. Example Code This iTool launch is defined in the file example2tool.pro in the examples/doc/itools subdirectory of the IDL distribution.
Example: a Custom iTool Interface Chapter 15: Creating a Custom iTool Widget Interface iTool Developer’s Guide
Appendix A Controlling iTools from the IDL Command Line This appendix describes mechanisms that allow you to control an existing iTool from the IDL command line. Overview of iTool Programmatic Control . Retrieving an iTool Object Reference . . . . Retrieving Component Identifiers . . . . . . . Retrieving Property Information . . . . . . . . iTool Developer’s Guide 380 381 382 385 Changing Property Values . . . . . . . . . . . . Running Operations . . . . . . . . . . . . . . . . .
Appendix A: Controlling iTools from the IDL Command Line Overview of iTool Programmatic Control The iTool framework is designed to let you create tools that are used interactively, in real time. Furthermore, one of the main goals of the iTools framework is to make it easier to create a standard graphical user interface that allows end-users to manipulate tools using a mouse and keyboard.
Appendix A: Controlling iTools from the IDL Command Line 381 Retrieving an iTool Object Reference In order to change an existing iTool from the IDL command line (or from a non-iTool routine), you must first retrieve an object reference to the iTool you wish to change.
Appendix A: Controlling iTools from the IDL Command Line Retrieving Component Identifiers In order to affect an item within an iTool — change a property of a visualization, for example, or apply an operation — you must first retrieve the identifier for the item. iTool identifiers are described in detail in “iTool Object Identifiers” on page 28.
Appendix A: Controlling iTools from the IDL Command Line 383 ISURFACE, DIST(40) The full object identifier for this surface visualization looks something like: /TOOLS/SURFACE TOOL/WINDOW/VIEW_1/VISUALIZATION LAYER/DATA SPACE/SURFACE If you retrieve an object reference to our surface tool using the following statement: void = ITGETCURRENT(TOOL=surfaceTool) you might suppose that the following statement would return the identifier string shown above: PRINT, surfaceTool->FindIdentifiers('surface') In fac
Appendix A: Controlling iTools from the IDL Command Line which is the identifier for the plot line just created. Note that if your iTool contained more than one surface visualization, identifiers for each surface would be returned. Similarly, suppose you wanted the object identifier for the New Surface operation.
Appendix A: Controlling iTools from the IDL Command Line 385 Retrieving Property Information While it is possible to execute an iTool operation with just the operation’s component identifier (as described in “Running Operations” on page 391), in many cases you will want to modify the operation’s properties before execution. In other cases you may not wish to execute an operation at all — you may only be interested in changing the value of one or more properties of a given component object.
Appendix A: Controlling iTools from the IDL Command Line Property Attribute Information Knowing the property identifier for the property you wish to change is often enough, if you are already familiar with the property, its data type, and range of possible values. For example, suppose you want to change the line thickness of a plot line.
Appendix A: Controlling iTools from the IDL Command Line 387 IF success THEN PRINT, 'Width is: ', width_value ELSE $ PRINT, 'No value returned' IDL prints: Width is: 3 The GetPropertyByIdentifier function method returns a value of 1 (one) if the property value was retrieved successfully, or 0 (zero) otherwise. In the example, the property value of 3 is successfully retrieved.
Appendix A: Controlling iTools from the IDL Command Line SHOW_EXECUTION_UI WIDTH Show dialog Width BOOLEAN INTEGER Note The itpropertyreport utility produces formatted text output in the IDL output log. This output will be correctly aligned only if the command log uses a fixedwidth font.
Appendix A: Controlling iTools from the IDL Command Line 389 Changing Property Values Given the object identifier for a property, there are two ways to change the property value: using the DoSetProperty method of the IDLitTool class, and using the SetProperty method of the IDLitComponent class. When changing the value of a registered property, in most cases, it is better to use the DoSetProperty method.
Appendix A: Controlling iTools from the IDL Command Line Visualization Browser property sheet. Methods for finding property identifiers are discussed in detail in “Retrieving Property Information” on page 385. The third argument to the DoSetProperty method is the new value for the property. Techniques for determining the data type and allowed values for a given property are described in “Property Attribute Information” on page 386.
Appendix A: Controlling iTools from the IDL Command Line 391 Running Operations Use the DoAction method of the IDLitTool class to execute an operation on the currently selected item in the currently selected iTool.
Appendix A: Controlling iTools from the IDL Command Line When executing operations using the mechanisms described in this chapter, you may want to set the SHOW_EXECUTION_UI property to 0 (False), since leaving it set to True will require user interaction.
Appendix A: Controlling iTools from the IDL Command Line 393 Selecting Items in the iTool When you execute an operation in an iTool, the operation will be applied to the currently selected item. You can use the Select method of the IDLitVisualization class to ensure that the correct item is selected. To select an item, do the following: 1. Find the object’s full identifier as described in “Retrieving Component Identifiers” on page 382. Note that only visualizations and annotations can be selected. 2.
Appendix A: Controlling iTools from the IDL Command Line Replacing Data in an iTool You can replace or update data in an existing iTool using either of two methods: using the iTool’s creation routine and one of the VIEW keywords, or by retrieving the data object and calling the SetData method. Both methods will change the data stored in the Data Manager and will cause the display to be updated automatically.
Appendix A: Controlling iTools from the IDL Command Line 395 Note If the currently-active iTool contains only one view, setting the VIEW_NEXT keyword has the same effect as setting VIEW_NUMBER=1. Using the SetData Method You can replace the data that underlies a visualization using the SetData method of the IDLitData class. This technique has the advantage of preserving other changes you may have made to your visualization (property changes, etc.
Appendix A: Controlling iTools from the IDL Command Line class to insert new data into the parameter.
Appendix B iTool Compound Widgets This appendix contains reference documentation for IDL compound widgets used by the iTools. Overview of iTools Compound Widgets . . 398 CW_ITMENU . . . . . . . . . . . . . . . . . . . . . . 399 CW_ITPANEL . . . . . . . . . . . . . . . . . . . . . 404 iTool Developer’s Guide CW_ITSTATUSBAR . . . . . . . . . . . . . . . . 408 CW_ITTOOLBAR . . . . . . . . . . . . . . . . . . 411 CW_ITWINDOW . . . . . . . . . . . . . . . . . .
Appendix B: iTool Compound Widgets Overview of iTools Compound Widgets The compound widgets described in this appendix provide the base functionality needed to create an iTool user interface using IDL widgets. These widgets are useful only in the context of creating an iTool interface; they require the presence of the iTools system object to function properly. Attempts to use these widgets outside the context of the iTools will not succeed.
Appendix B: iTool Compound Widgets 399 CW_ITMENU The CW_ITMENU function creates a top-level pulldown menu compound widget. The menu items in the pulldown menu correspond to the operations contained in a specified container object within the OPERATIONS container of the associated iTool. (See “iTool Object Hierarchy” on page 31 for a description of the iTool object hierarchy.) Warning This routine can only be used in the context of a user-created iTool.
Appendix B: iTool Compound Widgets automatically update itself. The CW_ITMENU widget listens for the following messages: Message Value Description / Result ADDITEMS Object identifier An object was added to the container. New menu and submenu items are added as necessary. REMOVEITEMS Object identifier An object was removed from the container. Menu and submenu items are removed as necessary. SELECT 0 or 1 For checked menu items, the menu item is displayed as checked (1) or unchecked (0).
Appendix B: iTool Compound Widgets 401 Arguments Parent The widget ID of the parent for the new menu. The parent must be one of the following: 1. A base widget. 2. A widget created using the MBAR keyword on a top-level base. 3. A button widget which has the MENU keyword set. 4. If the CONTEXT_MENU keyword is set, a widget that supports context events. UI An object reference to the IDLitUI object associated with the iTool.
Appendix B: iTool Compound Widgets UNAME Set this keyword to a string that can be used to identify the widget in your code. You can associate a name with each widget in a specific hierarchy, and then use that name to query the widget hierarchy and get the correct widget ID. To query the widget hierarchy, use the WIDGET_INFO function with the FIND_BY_UNAME keyword.
Appendix B: iTool Compound Widgets 403 See Also Chapter 15, “Creating a Custom iTool Widget Interface”, CW_ITPANEL, CW_ITSTATUSBAR, CW_ITTOOLBAR, CW_ITWINDOW iTool Developer’s Guide CW_ITMENU
Appendix B: iTool Compound Widgets CW_ITPANEL The CW_ITPANEL function creates an iTool base compound widget that will contain any user interface panels registered with the specified IDLitUI object’s associated iTool. See Chapter 14, “Creating a User Interface Panel” for information on user interface panels. Warning This routine can only be used in the context of a user-created iTool. See “Overview of iTools Compound Widgets” on page 398 for details.
Appendix B: iTool Compound Widgets 405 call the CW_ITPANEL_RESIZE procedure to specify the new size. The CW_ITPANEL_RESIZE procedure has the following interface: CW_ITPANEL_RESIZE, Widget_ID, Ysize where Widget_ID is the CW_ITPANEL widget ID, and Ysize is the new height of the panel. Syntax Result = CW_ITPANEL(Parent, UI [, ORIENTATION=[0 | 1]] [, UNAME=string] [, UVALUE=value] ) Return Value This function returns the widget ID of the newly-created panel widget.
Appendix B: iTool Compound Widgets Note The ORIENTATION keyword does not affect where the panel widget is placed; it only controls how the panel show/hide button is displayed. Place the panel on the left or right side of the widget interface using normal widget layout techniques. UNAME Set this keyword to a string that can be used to identify the widget in your code.
Appendix B: iTool Compound Widgets 407 Widget Events Returned by the CW_ITPANEL Widget CW_IT* compound widgets do not return widget events. All interaction with the iTool user interface is accomplished via the iTool messaging system and the callback mechanism implemented in the user interface creation routine. Version History Introduced: 6.
Appendix B: iTool Compound Widgets CW_ITSTATUSBAR The CW_ITSTATUSBAR function creates an iTool status bar compound widget that will contain any status bars registered with the specified IDLitUI object’s associated iTool. See “Status Messages” on page 287 for additional details on status bars. Warning This routine can only be used in the context of a user-created iTool. See “Overview of iTools Compound Widgets” on page 398 for details.
Appendix B: iTool Compound Widgets 409 where Widget_ID is the CW_ITSTATUSBAR widget ID, and Xsize is the new width of the status bar. Syntax Result = CW_ITSTATUSBAR(Parent, UI [, UNAME=string] [, UVALUE=value] [, XSIZE=integer] ) Return Value This function returns the widget ID of the newly-created status bar base widget. Arguments Parent The widget ID of the parent base widget. UI An object reference of the IDLitUI object associated with the iTool.
Appendix B: iTool Compound Widgets The user value for a widget can be accessed and modified at any time by using the GET_UVALUE and SET_UVALUE keywords to the WIDGET_CONTROL procedure. XSIZE Set this keyword to an integer specifying the initial width of the status bar. See “Resizing CW_ITSTATUSBAR Widgets” on page 408 for additional details. The default XSIZE is 640 pixels.
Appendix B: iTool Compound Widgets 411 CW_ITTOOLBAR The CW_ITTOOLBAR function creates a toolbar base compound widget. The items in the toolbar correspond to the operations or manipulators contained in a specified container object within the OPERATIONS container of the associated iTool. (See “iTool Object Hierarchy” on page 31 for a description of the iTool object hierarchy.) Warning This routine can only be used in the context of a user-created iTool.
Appendix B: iTool Compound Widgets automatically update itself. The CW_ITTOOLBAR widget listens for the following messages: Message Value Description / Result ADDITEMS Object identifier An object was added to the container. New buttons or droplists are added to the toolbar as necessary. REMOVEITEMS Object identifier An object was removed from the container. Buttons or droplists are removed from the toolbar as necessary.
Appendix B: iTool Compound Widgets 413 Syntax Result = CW_ITTOOLBAR(Parent, UI, Target [, /EXCLUSIVE] [, ROW=integer] [, UNAME=string] [, UVALUE=value] ) Return Value This function returns the widget ID of the newly-created toolbar base. Arguments Parent The widget ID of the parent base for the new toolbar. UI An object reference of the IDLitUI object associated with the iTool. See “User Interface Object” on page 341 for information on creating user interface objects.
Appendix B: iTool Compound Widgets ROW Set this keyword equal to an integer specifying the number of rows used for laying out the toolbar buttons and droplists. The default is 1. Tip To create a vertical toolbar, set ROW equal to the number of children in the container specified by Target. UNAME Set this keyword to a string that can be used to identify the widget in your code.
Appendix B: iTool Compound Widgets 415 Widget CW_IT* compound widgets do not return widget events. All interaction with the iTool user interface is accomplished via the iTool messaging system and the callback mechanism implemented in the user interface creation routine. Version History Introduced: 6.
Appendix B: iTool Compound Widgets CW_ITWINDOW The CW_ITWINDOW function creates an iTool draw widget that contains an IDLitWindow object. Warning This routine can only be used in the context of a user-created iTool. See “Overview of iTools Compound Widgets” on page 398 for details. The CW_ITWINDOW widget automatically performs the following actions: 1. Creates a scrolling draw widget with the specified dimensions. 2. Adds itself as an observer of the underlying IDLitWindow object.
Appendix B: iTool Compound Widgets 417 Return Value This function returns the widget ID of the newly-created iTool draw widget. Arguments Parent The widget ID of the parent base widget. UI An object reference of the IDLitUI object associated with the iTool. See “User Interface Object” on page 341 for information on creating user interface objects. Keywords DIMENSIONS Set this keyword to a two-element vector containing the initial width and height of the visible portion of the draw widget.
Appendix B: iTool Compound Widgets VIRTUAL_DIMENSIONS Set this keyword to a two-element vector containing the width and height of the virtual canvas. The default is to use the same values as DIMENSIONS.
Index Symbols _EXTRA keyword, 104 of iTools, 19 attributes, 78 automatic data type matching (iTools), 63 A Add method, 81 AddByIdentifier method, 53 adding data to data manager, 53 AddOnNotifyObserver method IDLitIMessaging, 43 IDLitUI, 283, 315 AGGREGATE keyword, 81 Aggregate method using, 81 aggregation of properties, 70, 81 architecture iTool Developer’s Guide B base class file reader, 237 file writer, 261 iTool, 95 operation, 156, 169 visualization, 125 bitmaps icon location, 44 Boolean property data
ButtonPress, 204 CW_ITWINDOW function, 416 C D callback routines creating, 318, 352 for user interface panel, 312 observers, 315 registering, 318, 352 Cleanup method data operation, 158 file reader, 240 file writer, 264 generalized operation, 171 manipulator, 212 visualization, 130 COLOR property data type, 71 command line arguments, 103 component framework See framework component registration, 38 components.
DESCRIPTION property, 223 DESCRIPTION property attribute, 79 DoAction method generalized operation, 172 running operations, 391 user interface element, 283 documented classes, 13 DoExecuteUI method about, 160 DoSetProperty method about, 389 drawable area in iTools, 348 E enumerated list properties, 73 ENUMLIST property attribute, 79 property data type, 73 error handling, 105 ErrorMessage method, 291 example1_readtiff__define.pro, 248 example1_visimagecontour__define.
IDLitReadTIFF, 233 IDLitReadWAV, 233 predefined, 231 preferences, 85 registering, 98, 245 standard base class, 237 unregistering, 246 file writers about, 254 creating, 254 example, 272 IDLitWriteASCII, 255 IDLitWriteBinary, 255 IDLitWriteBMP, 255 IDLitWriteEMF, 256 IDLitWriteEPS, 256 IDLitWriteISV, 256 IDLitWriteJPEG, 256 IDLitWriteJPEG2000, 257 IDLitWritePICT, 257 IDLitWritePNG, 257 IDLitWriteTiff, 257 predefined, 255 preferences, 85 registering, 98, 269 standard base class, 261 unregistering, 270 Fin
IDLitDataIDLPolyvertex data object, 59 IDLitDataIDLVector data object, 60 IDLitDataOperation creating object, 152 subclassing, 153, 156 IDLitIMessaging feedback mechanism, 286 messaging system, 41 IDLitManipulator CommitUndoValues calling, 216 described, 203 RecordUndoValues calling, 214, 218 described, 203 subclassing, 207 IDLitOpBytscl operation, 148 IDLitOpConvolution operation, 148 IDLitOpCurvefitting operation, 148 IDLitOperation subclassing, 166, 169 IDLitOpSmooth operation, 148 IDLitParameterSet
IDLitWriteJPEG file writer, 256 IDLitWriteJPEG2000 file writer, 257 IDLitWritePICT file writer, 257 IDLitWritePNG file writer, 257 IDLitWriter subclassing, 258, 261 IDLitWriteTIFF file writer, 257 IDLOPACITY_TABLE data type, 55 IDLPALETTE data type, 55 IDLPOLYVERTEX data type, 55 IDLVECTOR data type, 55 IDLVERTEX data type, 55 informational messages, 291 INITIAL_DATA keyword, 104 initializing superclasses, 94, 124, 155, 168, 209, 236, 260 INTEGER property data type, 71 Intelligent Tool See iTool inters
L legalities, 2 LINESTYLE property data type, 72 locating iTool bitmap resources, 44 M macros iTool support in custom operations, 181 manipulators about, 194 associated operation, 202 creating, 197 cursors custom, 220 predefined, 212 mouse events, 213 predefined, 198 public instance data, 204 status bar message, 223 toolbar icon, 224 transient, 212 undo/redo support, 202 wheel events, 216 menus iTool, 344 messages from iTool observers, 43 informational, 291 iTool notification, 42 iTool status, 287 mes
P panel widget, 313 parameters data types, 52, 61 defined, 61 names, 61 registered, 61 registering, 125 preferences file readers, 85 file writers, 85 iTool, 68 iTool system, 85 system, 85 pre-registered properties, 75 presentation layer, 20 ProbeStatusMessage method about, 287 programmatic control of iTools, 380 prompt iTool prompt dialogs, 289 PromptUserText method, 290 PromptUserYesNo method, 289 properties aggregation, 70, 81, 126 attribute values, 386 attributes about, 78 changing, 127 DESCRIPTION,
reference documentation for iTool classes, 12 REGISTER_PROPERTIES keyword, 75 registered parameter, 61 RegisterFileReader method about, 245 RegisterFileWriter method about, 269 registering an iTool class, 101 callback routines, 318, 352 file readers, 98, 245 file writers, 98, 269 manipulators, 223 operations, 96, 182 parameters, 125 properties, 74, 125 user interface panels, 314, 320 user interface services, 302 visualizations, 95 RegisterManipulator method about, 223 RegisterOperation method about, 18
THICKNESS property data type, 73 toolbars iTool, 346 trademarks, 2 TYPE property, 320 property attribute, 79 TYPES property, 183, 224 U UI panel See user interface panel UI service See user interface service UNDEFINED property attribute, 79 undo/redo system, 150 undocumented classes, 13 UndoExecute method using, 164 UndoOperation method using, 178 union of aggregated properties, 82 unregistering components, 100 file readers, 246 file writers, 270 generic component, 100 operation, 184 visualization typ
IDLitVisPlot, 118 IDLitVisPlot3D, 118 IDLitVisPlotProfile, 118 IDLitVisPolygon, 118 IDLitVisPolyline, 119 IDLitVisRoi, 119 IDLitVisSurface, 120 IDLitVisText, 120 IDLitVisVolume, 120 predefined, 115 registering, 95, 136 ShapePoint, 119 standard base class, 125 iTool Developer’s Guide unregistering, 138 VISUALIZATION_TYPE keyword, 107 W wheel events iTool manipulators, 216 widgets in iTools, 20 custom interface, 332 interface, 280 Index
Index iTool Developer’s Guide