Previous Next Contents Index Doc Set Home


User-Defined Widgets

14



14.1 Introduction

WorkShop Visual is pre-configured with the Motif widget set and can be extended to support widgets from any other Xt toolkit in addition to the default set. Widgets added to WorkShop Visual are called user-defined widgets. They appear in the WorkShop Visual widget palette and users can create them, set their resources and generate code for designs that include them.

WorkShop Visual comes with a utility, visu_config, which helps you provide the information WorkShop Visual needs to support user-defined widgets. You specify which widgets you want to use and provide information about any nonstandard resource types defined by the widgets. visu_config generates two C files that serve as a bridge between WorkShop Visual and the user-defined widgets.

After generating the visu_config files, you build a new version of WorkShop Visual from the following components:

Icons are recommended but not required. Handwritten code is only required if you want to provide customized popup dialogs, or if you have widgets with special problems described in the Configuration Functions section on page 518.

To help you get started, WorkShop Visual is distributed with an example configuration file for the Athena widgets, Athena.xdc. There are also pre-built configuration files for various commercial widgets. Look in the WorkShop Visual release directory for the latest set of supported widget integrations.


14.2 Requirements

User-defined widgets must build and run against the X11 Release 5 X Toolkit Intrinsics. For each widget class you need the public header file and the object file that implements the widget class. Both of these are provided by your widget supplier. The object file may be in an archive library. You may also need the private header file for the widget class.

You need access to the standard UNIX development tools, including the C compiler, linker and make.

visu_config requires standard widget information such as the widget class pointer. You should therefore have the widget documentation on hand. If your widget has non-standard resource types, or if you want to supply customized popup dialogs, you may also need to refer to the header files or widget source code to get the required information. See the Getting Widget Information section on page 476.

14.2.1 UIL Restriction

UIL code compiles correctly only for designs restricted to the default set of Motif widgets. C or C++ generated code must be used for designs containing user-defined widgets.

14.2.2 Caveats

Since WorkShop Visual's dynamic display works by creating actual instances of the widget, any widget you build into WorkShop Visual becomes part of the tool. If the widget doesn't function as expected, WorkShop Visual may fail when the user adds the widget to a design. Any memory leaks in the widget can affect WorkShop Visual and may cause a gradual degradation of performance or a core dump. Even widely-used widgets from standard vendors can have problems. You should therefore test widgets thoroughly before adding them to WorkShop Visual.


14.3 Prerequisites

To configure WorkShop Visual, you need some knowledge of C and an understanding of common UNIX development tools such as make. You don't have to be an expert on X but you need some knowledge of X and the X Toolkit Intrinsics. visu_config requires you to supply information about the widget, such as the widget class pointer and symbolic constants representing resource types. For suggestions on how to get the required information from the widget documentation or source code, see the Getting Widget Information section on page 476.


14.4 How WorkShop Visual Works

Before you start configuring a widget, it is helpful to understand how WorkShop Visual uses widgets in the dynamic display. This section describes some aspects of how WorkShop Visual works internally.

14.4.1 Creating Widgets

WorkShop Visual builds its dynamic display with real widgets, not simulations. It creates widgets by passing the widget class pointer to XtCreateWidget(). The widget class pointer also gives access to information about the widget's resources and their types so that WorkShop Visual can build a resource panel for the widget.

The order in which widgets are created and managed in the dynamic display is different from the typical order of operations in an application. When the user clicks on an icon to add a widget to the hierarchy, WorkShop Visual creates an instance of the widget, realizes it and manages it before any resources are set. When WorkShop Visual reads a hierarchy from a file, however, the hierarchy is created from the bottom up. Each widget is first created, its resources are set and finally it is managed. In either case, create-only resources can't be set ordinarily in the dynamic display since WorkShop Visual creates widgets before setting resources.

Some widgets, such as the Athena Form widget, require resources to be set at creation time or don't behave well when managed without children. In these cases, you can customize WorkShop Visual's procedure for adding the widget to the hierarchy by specifying a Realize function in visu_config. (For more information, see the Realize Function section on page 518.


Note - Neither of these problems occur in the generated code. WorkShop Visual generates code that creates the hierarchy from the bottom up and sets all resources at creation time.

14.4.2 Highlighting Selected Widget

When the user selects a widget in the tree, WorkShop Visual highlights that widget's icon in the tree. It also highlights the widget itself in the dynamic display by swapping the widget's foreground and background colors. Highlighting the widget may cause problems if the widget has a create-only foreground resource. In this case, you can disable foreground swapping on the Widget Edit Dialog, as described in the Widget Attributes section on page 483.

14.4.3 Preventing Invalid Hierarchies

WorkShop Visual prevents invalid hierarchies by disabling all palette icons for widgets that are not valid children for the selected widget. Also, when a new widget is added to the hierarchy, WorkShop Visual doesn't automatically select it if it can't have children.

For user-defined widgets, WorkShop Visual looks at the widget's superclasses to determine valid hierarchies. You can also specify configuration functions to customize a widget's requirements for valid child and parent widgets. For more information, see the Configuration Functions section on page 518.

14.4.4 Building the Resource Panel

WorkShop Visual builds a resource panel for the widget based on resource names and resource types in the widget class record. Resources inherited from a known superclass, such as the Core widget or a Motif parent class, are left off the resource panel and can be set on the resource panel for the superclass.

WorkShop Visual automatically assigns resources of standard types to appropriate pages on the resource panel. They can however be explicitly assigned to other pages if required. Most widget resources fall into one of the standard categories; for a summary, see the Resources section on page 488.

When the resource panel is displayed, WorkShop Visual uses XtGetValues() to get the current values of all resources for the widget. All resources except enumerations are converted to text strings and displayed in text fields on the resource panel. The user can set the resource by editing a text string. In some cases, such as fonts, colors and callbacks, the user can supply text indirectly through a popup dialog. For resources that don't already have a popup dialog in WorkShop Visual, you can supply a popup; see the Popups section on page 500.

14.4.5 Setting Resources

When the user applies a new resource value, WorkShop Visual converts the text string to a value and applies it to the widget with XtSetValues(). It then immediately calls XtGetValues() to retrieve all resource values for the widget, converts the values back to text and displays them in the resource panel. This procedure shows immediately whether the toolkit accepted the new value and whether the new value caused other resources to change.

A function called a resource converter is used to translate a text string to a resource value and back. For standard resource types, the converter functions are built in and you don't have to do anything in visu_config. If your widget has a resource of a non-standard type, visu_config lets you specify information about the converter function. For details, see the Converters section on page 498. If you don't provide this information, the user can type a text string to set the resource in the generated code or resource file but WorkShop Visual can't set it in the dynamic display because it can't convert the text string to a value.

For enumeration resources, WorkShop Visual builds an option menu which, by default, is placed on the "Settings" page of the resource panel. WorkShop Visual can handle Boolean enumeration resources for user-defined widgets. For other enumerations, you must provide a list of valid values in visu_config so that WorkShop Visual can build an option menu. For details, see the Enumerations section on page 492.

14.4.6 Saving Designs and Code Generation

Saving designs and parsing save files is straightforward. For resource settings, WorkShop Visual writes the resource name and the text representation of its value to the .xd file. The resource name and value are saved as they appear on the resource panel.

When it generates code, WorkShop Visual uses two versions of every resource name. In the generated X resource file, resources are identified by a name such as label. WorkShop Visual gets resource names from the widget class record. In generated code, resources are identified by a defined name such as XtNlabel. WorkShop Visual constructs the defined name by adding an XtN prefix to the resource name. If your widget doesn't follow this naming convention, visu_config lets you specify a function to construct the defined name. For details, see the Configuration Functions section on page 518.

For enumerations, WorkShop Visual also uses two versions of each possible value: a resource file symbol such as center and a code symbol such as XtJustifyCenter. When you configure an enumeration, you must provide both versions of each value.

When WorkShop Visual generates code for any widget class, it generates an #include for that class's public header file. visu_config lets you specify an #include file for each user-defined widget class.


14.5 Getting Widget Information

To configure your widget, you may have to supply one or more variable names and symbolic constants from the widget code. This section summarizes the information you may have to provide. Most of the information you need should be available in the documentation for the widget. If not, you can get it from the widget's public and private header file, from the widget source code (if available), or from your widget supplier's technical support service.

In the following paragraphs we mention naming conventions that are observed by many widget suppliers. However, naming conventions are not invariable rules. Always check the names in the documentation or source code.

14.5.1 The Widget Class Pointer

When you add a widget class in visu_config, you need to supply the widget class pointer. The widget class pointer is the name of a pointer variable of type WidgetClass. This pointer gives access to a structure containing information about the widget class, including a list of resources and their types. WorkShop Visual uses this information to build a resource panel for the widget class. By convention, widget class pointers have names of the form <classname>WidgetClass.

If you cannot find the widget class pointer in the documentation, look in the public header file for a line such as:

externalref WidgetClass fredWidgetClass
or
extern WidgetClass fredWidgetClass
In either case, the widget class pointer is fredWidgetClass.

14.5.2 Resource Information

The resource name is a character string used to identify the resource in generated X resource files and on the resource panel. WorkShop Visual gets this name directly from the widget class record and so you don't need to supply it. This string is usually a straightforward name without a prefix, such as label.

The defined name is a symbolic constant used to identify the resource name in source code. By convention, the defined name has the form <Prefix>N<name>, where <name> is the resource name. To find defined names, look in the widget documentation, or look in the public header file for #define directives. For example, the following lines from the Athena Form header file identify the defined names XtNtop and XtNbottom:

#define XtNtop "top"
#define XtNbottom "bottom"

14.5.3 Non-Standard Resource Types

To configure resources of non-standard types, you need to know the resource type. This is not a type such as unsigned char but a symbolic constant defined as a string by which the widget class knows the resource type. By convention, resource types have the form <Prefix>R<Type>. For non-standard resource types, especially enumerations, <Type> may be the same as the resource name.

If the documentation for your widget gives a resource type as foo, look for a line like the following in the public header file:

#define XtRFoo "foo"
In this example, you would enter XtRFoo whenever visu_config asks for a resource type. The resource type can also be found in the source code for the widget. The following structure defines a resource whose resource type is XtRFoo. Note that you can also get the resource's defined name, XtNfoo, from this structure.

{
	XtNfoo, XtCFoo, XtRFoo,
	sizeof(foo), XtOffset( FooWidget, foo),
	XtRImmediate, (XtPointer) NULL,
}

14.5.4 Non-Standard Enumerations

If your widget has non-standard enumeration resources, you need to specify a list of possible values. In some cases you may have to read the source code to get the names you need. For instructions, see the Enumerations section on page 492.


14.6 visu_config - the Main Dialog

Run visu_config:

visu_config
The main dialog shown in Figure 14-1 is displayed.

Figure  14-1 The Main visu_config Dialog

14.6.1 Menu Commands

The visu_config File Menu has options to save and read files containing your configuration data. By convention, these files have the suffix .xdc. Use "Open" to open an existing widget specification file; "Read" to merge another file with the one you are currently editing; "Save" and "Save As..." to save your file and "New" to clear the editing area.

The Edit Menu is used to display the Stop List dialog which lets you remove selected Motif widgets from the WorkShop Visual palette. This is discussed in the Motif Widgets Stop List section on page 511.

The Generate Menu contains options to generate the two code files needed to build WorkShop Visual with the added widgets. For information on generating code from visu_config and building WorkShop Visual, see the Generating and Compiling Code section on page 513.

14.6.2 Families

The main dialog displays a list of families. Families are groups of widgets that are displayed together in the widget palette. The list is empty when you start the program. Figure 14-1 shows the dialog after loading the Athena.xdc file supplied with WorkShop Visual. We recommend that you open this file and inspect it as you read.

You can organize user-defined widgets into families in any way. Grouping widgets into families has two purposes. First, it keeps the WorkShop Visual widget palette to a reasonable size. At any given time, WorkShop Visual displays the icons for the default Motif widgets plus one user-defined widget family. An option menu lets the user switch from one family to another as with the pages of a resource panel. Second, grouping widgets into families also makes it easy to generate versions of WorkShop Visual with different sets of families. At code generation time, you can select any group of families from your list. This lets you customize WorkShop Visual to support users with different needs and skill levels.

14.6.3 Editing the Family List

To add a new family to the list, type a name for the family in the "Selection" field, then click on "Add". The family can have any name you choose. It is used to identify the family in visu_config and in the option menu in the WorkShop Visual widget palette.

To delete a family, select it in the list and click on "Delete". To reorder the list, select a family and use the arrow buttons to move it up and down. The order of the list determines the order of the items in the option menu in the WorkShop Visual widget palette.

14.6.4 Suggestions for Organizing Families

You can include the same widget class in more than one family. For example, in Athena.xdc, the family named "Athena" contains all the Athena widgets and each of the two smaller families, "Composites" and "Primitives", contains a subset of the Athena group. When you generate code from visu_config, you can decide how you want the widget palette to appear. You can either use the large family to display all the Athena widgets on the palette at the same time, or use either of the two smaller families to display a subset of the Athena widgets.

You might want to include a frequently-used widget in more than one family so that the user has access to it at all times regardless of what page of the palette is displayed. To do this, however, you have to enter and maintain two separate copies of the widget configuration information and you should test the icon separately on each page of the palette.

When you generate code from visu_config, you can select any group of families from the currently open file but you can't select families from other files. To configure WorkShop Visual with widget families from multiple .xdc files, use the "Read" option to merge the files before generating code.

14.6.5 Adding and Editing Widgets In a Family

To add or configure widgets in any family, select the family and then click on "Edit" to display the Family Edit dialog. The Family Edit Dialog lets you:

The Family Edit dialog has several pages, which you can select from the View Menu. The name of the currently selected family is displayed in the dialog's title bar.

For details about the Family Edit dialog, see the following sections.


14.7 Widget Classes

To display a list of widget classes in this family, select "Widgets" from the View Menu. Figure 14-2 shows the "Widgets" page for the Athena Composites family.

Figure  14-2 The "Widgets" Page of the Family Edit Dialog

14.7.1 Adding a Widget Class

To add a new widget class to the family, enter the widget class pointer in the "Selection" field and click on "Add". To complete the process, specify attributes for the class as described in the Widget Attributes section below.

14.7.2 Editing the Widget Class List

To delete a widget class from the family, select it in the list and click on "Delete". To reorder the list, select an item and use the arrow buttons to move it up or down. The order of the widget class list determines the order of widgets in the palette.


14.8 Widget Attributes

To specify attributes of a widget class, select the widget class in the Family Edit Dialog and click on "Edit". This displays the Widget Edit Dialog, shown in Figure 14-3. The title bar displays the name of the widget class you are editing.

This section discusses the attributes set on the left side of the Widget Edit dialog. The right side is used to assign resources to existing or new pages, to specify custom popup dialogs for widget resources, and to override the default resource memory management. For details, see the Resources section on page 488.

14.8.1 Applying Changes

When you finish entering widget attributes, click on "Apply" to set the new values. "Undo" reverts to the last applied changes.

Figure  14-3 The Widget Edit Dialog with Attributes for Athena Form

14.8.2 Include File

In the "Include file" field specify the name of the public header file for the widget class. Enter the file name (usually relative to /usr/include) without quotes or angle brackets. This file is included in two places: in the code file generated by visu_config and in application code generated by WorkShop Visual.

14.8.3 Icons

An icon is an X pixmap or bitmap that represents a user-defined widget in the WorkShop Visual widget palette and design hierarchy. For each widget, you can specify both a pixmap and a bitmap. Icon pixmaps are stored in separate files and specified via an entry in the WorkShop Visual resource file.

Icon bitmaps are built into WorkShop Visual and are used only if the pixmap resource is not set or the pixmap file cannot be found. If you don't provide an icon in either bitmap or pixmap form, or the specified icon cannot be found, WorkShop Visual displays a button with the widget class name in the widget palette and a crossed square icon in the hierarchy.

To reduce color usage it is recommended that you use the same color palette that WorkShop Visual uses for its icons. Read the following file into the Pixmap editor by selecting "Read palette" from the "Palette" menu:

$VISUROOT/lib/palettes/icons.xpm
where VISUROOT is the install directory of your WorkShop Visual. See the Pixmap Editor Palette Menu section on page 167 for more information on reading palettes into the Pixmap editor.

14.8.4 Pixmap Resource

Use the "Pixmap resource" field to specify a name for the pixmap resource. After building WorkShop Visual, you can set this resource to specify the pixmap file.

For example, if you specify myWidgetPixmap as the pixmap resource for a user-defined widget, you can specify a pixmap in the WorkShop Visual resource file using the following entry:

visu.myWidgetPixmap: /usr/local/newwidget.xpm
This specifies /usr/local/newwidget.xpm as the location of the XPM file. You can use either an absolute or a relative pathname. For details on how to use the pixmap resource, see the Palette Icons section on page 617.

14.8.5 Bitmap

To specify a built-in icon bitmap, you must provide two items of information: the name of the bitmap and the name of the corresponding bitmap file. To specify an icon for the large-screen (workstation) version of WorkShop Visual, use the "Large icon" and "Large icon file" fields. For the small-screen (VGA) version, use the "Small icon" and "Small icon file" fields. You can provide an icon for either version of WorkShop Visual, both, or neither.

The large-screen icon must be a 32 by 32 pixel X bitmap and the small-screen icon must be 20 by 20 pixels. You can create icon bitmaps using a tool such as the X bitmap utility. Pixmaps cannot be used for this purpose.

Enter the bitmap name in the "Large icon" or "Small icon" field. The bitmap name is defined in the first line of the bitmap file, as shown below:

#define <bitmap_name>_width 32
Enter the icon file name in the "Large icon file" or "Small icon file" field without quotes or angle brackets. Because this file is included when you build WorkShop Visual, your WorkShop Visual makefile must reference (-I) the directory where it is stored. This file does not have to be available to end users.

14.8.6 Help

These attributes let you specify on-line help that is displayed when the user invokes help for the widget on the palette or from the widget's resource panel. For each help item, you specify a document (without any suffix) and a tag if the help for this widget is contained within a larger document. The WorkShop Visual help system searches the path list specifed by the visu.helpDir resource to locate the appropriate file. The file name must have a ".html" suffix. The tag refers to an HTML hypertext anchor within the document.

14.8.7 Configuration Functions

There are four fields for specifying configuration functions: a Defined Name function, a Can Add Child function, an Appropriate Parent function and a Realize function. These functions can be used to fine-tune the way WorkShop Visual handles the widget in the dynamic display. If your widget uses a configuration function, type the name of the function in the corresponding text field.

The configuration functions perform the following tasks:

The Can Add Child and Appropriate Parent functions are required only for widgets that have special requirements for valid hierarchies. Often these functions aren't needed. If you don't supply them, WorkShop Visual uses the rules for the first known ancestor of the widget class. For example, if a user-defined widget is derived from the Primitive class, WorkShop Visual uses the rules for the Primitive class and doesn't let the user add children to the widget.

For full definitions, synopses and examples of configuration functions, see the Configuration Functions section on page 518. Note that many widgets do not require configuration functions.

14.8.8 Disable Foreground Swapping

Normally, WorkShop Visual highlights the currently selected widget in the dynamic display. To disable highlighting for this widget class, turn on the "Disable Foreground Swapping" toggle. Do this only if the widget class has a foreground resource that cannot be set after widget creation time. This is required because WorkShop Visual's highlighting procedure can cause problems with such widgets. In all other cases, leave the toggle off.

14.8.9 Can Create Widgets

When the "Can Create Widgets" toggle is on, users can build the widget directly into hierarchies. Leave this toggle on if you want the widget's icon to appear in the palette.

Turn the toggle off to make the widget class an invisible superclass like the Core widget. If you turn the toggle off, the widget doesn't appear in the widget palette and users can't create instances of it directly. WorkShop Visual creates a separate resource panel for the class. The resource panel can be accessed by any derived widget classes.


14.9 Resources

By default, when WorkShop Visual creates the resource dialog for a widget, it gets the name and type of the resource directly from the widget code and builds a resource panel. It assigns each resource to a page of the resource panel (based on the resource type) and assigns a popup dialog for certain types. For example, resources of type XtRPixel are put on the Display page of the resource panel, with a button to pop up the WorkShop Visual color editor.

You do not have to do anything to configure a resource unless you want to change this default behavior or unless the resource is not of a type listed in the table of standard types shown below.

14.9.1 Default Handling of Standard Resource Types

Resources of standard types are assigned to pages of the resource panel as shown in the following table:

Table  14-1 WorkShop Visual Standard Resource Types

Resource type symbol
Value
Page

XmRDimension

"Dimension"

Margins

XmRFontStruct

"FontStruct"

Display

XmRHorizontalDimension

"HorizontalDimension"

Margins

XmRInt

"Int"

Margins

XmRPixel

"Pixel"

Display

XmRPixmap

"Pixmap"

Display

XmRPosition

"Position"

Margins

XmRPrimForegroundPixmap

"PrimForegroundPixmap"

Display

XmRShort

"Short"

Margins

XmRString

"String"

Display

XmRVerticalDimension

"VerticalDimension"

Margins

XmRWidget

"Widget"

Display

XmRXmString

"XmString"

Display

XtRBoolean

"Boolean"

Settings

XtRCallback

"Callback"

Callbacks

XtRUnsignedChar

"UnsignedChar"

Settings

XmRFontList

"FontList"

Display

XtRFontStruct

"FontStruct"

Settings

XmRXmStringTable

"XmStringTable"

Display

14.9.2 Changing Widget Attributes

The right side of the Widget Edit dialog lets you do the following things for individual widget resources:

To customize the attributes of a resource, type the resource name in the Resource field. This should be the defined name, such as XtNcursorName.

To remove the resource from the resource panel, turn off the "Visible" toggle.

To specify a different page of the resource panel, click on the "Page" button to display the current list of pages. The list is preset with the default WorkShop Visual pages. To add a page, type the name of the new page in the "Page name" field and then click on "Update". To assign the current resource to a page, select the page in the list and then click on "Apply".

visu_config automatically invokes the WorkShop Visual predefined popups for some types of resources, as shown in the following table. You don't have to specify a popup explicitly to use these popups for resources of these types:

Table  14-2 Standard Resource Popups

Resource Type
Popup

XmRFontList

Font selector

XtRFontStruct

Font selector

XmRPixel

Color selector

XmRPixmap

Pixmap editor

XmRPrimForegroundPixmap

Pixmap editor

XmRXmString

Compound String editor

XtRCallback

Callback dialog

You can specify a popup dialog for any resource. You can select one of the predefined popups or create your own. For more information, see the Popups section on page 500.

14.9.3 Nonstandard Resource Types

By default, resources of types not in the table of WorkShop Visual standard resource types are placed on the "Miscellaneous" page of the resource panel. The user can set them by typing strings into text fields. The strings are generated into the code exactly as the user types them and resource settings take effect when the generated code is compiled.

This default behavior has some disadvantages. WorkShop Visual doesn't recognize the resource type, so it cannot set the resource in the dynamic display. Enumeration values must be spelled and capitalized correctly (including any prefix) or the generated code will not compile.

visu_config offers several ways to refine the way WorkShop Visual handles nonstandard resource types:

The following sections give detailed instructions for these procedures.


14.10 Aliases

If your widget uses a resource type that is not in the standard list but has the same semantics as a standard type, you can tell visu_config that your type is an alias for the standard type. For example, if you define a type XtRDegrees as an integer from 0 to 359, you can set up an alias to specify that XtRDegrees is equivalent to XmRShort. The user can then set any XtRDegrees resource on the "Margins" page of the resource panel and see the results immediately in the dynamic display.

14.10.1 Requirements

The new resource type must have the same semantics as the standard type. Specifically, the process by which a text string is converted to a resource value and back again must be the same for both types.

14.10.2 Specifying an Alias

On the Family Edit Dialog, pull down the View Menu and select "Aliases" to display the dialog shown in Figure 14-4.

Figure  14-4 The "Aliases" Page of the Family Edit Dialog
To specify an alias, enter the non-standard resource type in the "Selection" field and the name of the corresponding standard in the "Equivalent" field. Click on "Apply" to register the alias.


14.11 Enumerations

Enumeration resources are resources with a fixed set of possible values. You can determine if a widget has enumeration resources by inspecting the documentation. If the documentation lists all possible values for a resource, it is an enumeration. Note that enumerations of type XtRBoolean are handled automatically and don't require the configuration procedure described in this section.

By default, WorkShop Visual treats all other enumerations as it treats any unknown resource type. It places them on the "Miscellaneous" page of the resource panel and the user can set them by typing a new value in a text field. The setting is passed to the generated code but has no effect in the dynamic display.

Use the instructions in this section to give WorkShop Visual the information it needs to build an option menu for the resource on the "Settings" page of the resource panel and set the resource in the dynamic display.

14.11.1 Configuring an Enumeration

Select "Enumerations" from the View Menu in the Family Edit Dialog to display the "Enumerations" page. Figure 14-5 shows the list of enumerations for the Athena Primitives family.

Figure  14-5 The "Enumerations" Page of the Family Edit Dialog
To add a new enumeration, enter a name in the "Selection" field and click on "Add". This name is only for your convenience in visu_config. You can use the resource name from the widget documentation or any other string that helps you identify the resource. Since all enumerations for the family are kept together in one list, it may be useful to include the widget name as well as the resource name.

14.11.2 Configuring Enumeration Values

To complete the process, you need to provide the following information about the enumeration resource:

Suggestions for getting the code symbol and resource file symbol are given at the end of this section. To configure an enumeration, select it in the list of enumerations and click on "Edit". This displays the Enumerations Entry Dialog, shown in Figure 14-6. The title bar displays the name of the enumeration.

Figure  14-6 The Enumerations Entry Dialog
Specify the resource type and configure each value as described below. When you finish, click on "Apply" to set the new values.

14.11.3 Specifying the Type

Enter the resource type in the "Type" field.

14.11.4 Specifying Values

To get a list of values for an enumeration, look in the widget documentation or the public header file. Make an entry in the "Entries" list for each possible value vis the "Enumerations" page. Entries in the list are only used in the option menu on the resource panel and can be any names you want. WorkShop Visual uses names that are meaningful to the user, such as Horizontal rather than XmHORIZONTAL.

For each value, type the name in the "Selection" field and click on "Add". Note that omitting a value isn't fatal but the user won't be able to set that value.

14.11.5 Configuring Values

For each value, you must specify the code symbol and the resource file symbol in the Enumerations Entry dialog. The code symbol is a symbolic constant that denotes the value in generated code. The resource file symbol is a string that denotes the value in resource files.

To find the code symbol, look at the list of values in the widget documentation or the widget source code. Type the code symbol in the "Code symbol" field.

Type the resource file symbol for the value in the "Resource file symbol" field. Often, the resource file symbol is the code symbol, converted to lower case and stripped of any prefix, but this is not an invariable rule. For example, the resource file symbol for XtJustifyCenter is center.

The resource file symbol is not always listed in widget documentation. If it isn't, you may be able to get it from an example resource file or from the widget supplier's technical support service. If you have source code for the resource converter, you can get the resource file symbol from the code, as described in the Getting the Resource File Symbol section on page 497.

14.11.6 Specifying the Default Value

The first entry in the list of values on the "Enumerations" page is reserved for the default value. This entry is used to indicate a resource that is not set explicitly. The option menu should also contain an entry for the same value set explicitly. By convention, the default value is distinguished by putting its name in parentheses, as shown in the following list:

(Center)
Center
Left
Right
Specify the same code and resource symbols as for the corresponding explicit value.

Note that WorkShop Visual builds one option menu for the each enumeration type. If your widget has multiple resources of the same enumeration type, they share an option menu. If the resources have different default values, a suggested approach is to enter a generic default value, (Default), on the option menu.

Enter code and resource symbols for any one of the possible default values. This does not result in errors in the generated code or when widgets are initially created in the dynamic display. The dynamic display may be incorrect if the user explicitly sets this resource and then explicitly requests the default value. However, any such problem disappears after the widget is reset.

14.11.7 Specifying Order of Entries

The order of entries in the list on the "Enumerations" page controls the order in which they appear in the option menu on the resource panel. Entries can be listed in any order as long as the default value is listed first. To move an entry to a different position, select it in the list and use the arrow buttons to move it up or down.

14.11.8 Getting the Resource File Symbol

This section explains how to get the resource file symbol you need to enter on the Enumerations Entry Dialog from the resource converter code for the widget. The resource converter is a function used to convert a string read from the resource file to the corresponding value. A simple converter may contain fragments like this:

if (StringsAreEqual (in_str, "vertical"))
	i = XmVERTICAL;
else if (StringsAreEqual (in_str, "horizontal"))
	i = XmHORIZONTAL;
In this example, the string "horizontal" is converted to the value XmHORIZONTAL and "vertical" is converted to XmVERTICAL. horizontal and vertical are the resource file symbols; XmHORIZONTAL and XmVERTICAL are the code symbols.

You may find it done more indirectly, as shown in the following code:

if (!haveQuarks) {
	XtQEhorizontal = XrmStringToQuark(XtEhorizontal);
	XtQEvertical = XrmStringToQuark(XtEvertical);
	haveQuarks = 1;
}
XmuCopyISOLatin1Lowered(lowerName, (char *)fromVal->addr);
q = XrmStringToQuark(lowerName);
if (q == XtQEhorizontal) {
	orient = XtorientHorizontal;
	done(&orient, XtOrientation);
	return;
}
if (q == XtQEvertical) {
	orient = XtorientVertical;
	done(&orient, XtOrientation);
	return;
}
In this code, the resource file symbols are represented by the symbolic constants XtEhorizontal and XtEvertical. To get the resource file symbols, horizontal and vertical, examine the related header files for lines such as:

#define XtEhorizontal "horizontal"
#define XtEvertical "vertical"
The code file symbols, XtorientHorizontal and XtorientVertical, are the end result of the conversion. Note that in this example there is an intermediate step: the strings are converted to quarks and the quarks are used for the comparison. The mechanics of the conversion procedure do not affect visu_config.


14.12 Converters

If your user-defined widget has resources of non-standard types other than enumerations, WorkShop Visual places them on the "Miscellaneous" page of the resource panel by default. The resources can be allocated to other pages from the Widget Edit Dialog. The user can set these resources by typing a string into a text field. By default, the string is generated into the code or resource file but WorkShop Visual doesn't set it in the dynamic display. To make the resource work in the dynamic display, you can configure WorkShop Visual with a converter function for this resource. The converter function is a function that converts a text string to a resource value.

To configure the converter, select "Converters" from the View Menu. This displays the page shown in Figure 14-7. The "Entries" list contains a list of resource types in this family for which converters have been specified.

Figure  14-7 The "Converters" Page of the Family Edit Dialog

14.12.1 Resource Type

Enter the resource type in the "Selection" field and click on "Add".

14.12.2 Converters Added Internally

Many widgets add their own converters internally when the class is initialized. If this is the case, all you have to do is add the resource type to the list on the "Converters" page. Adding the resource type to the list informs WorkShop Visual that the converter is available; otherwise WorkShop Visual doesn't attempt to set the resource in the dynamic display.

To find out whether the widget class adds its own converter, look in the widget documentation or look for a call to XtSetTypeConverter() in the code for the widget's Class Initialize method. If the converter is not added internally or if you are in doubt, instruct WorkShop Visual to add the converter explicitly, as described below.

14.12.3 Converters Added Explicitly

If the widget doesn't add converters internally, you can instruct WorkShop Visual to add them explicitly. To do this, specify the name of the converter function in the "Converter" box. The converter must be a function of type XtTypeConverter. Toggles are provided to add the converter explicitly either in WorkShop Visual (for use in the dynamic display), in the generated code, or in both. In general, if you have to add the converter explicitly, both toggles should be on.

14.12.4 Popup Dialog

The "Popup" button lets you specify a popup dialog to be used for setting all resources of this type. For details, see the Popups section below.


14.13 Popups

Resource popups are dialogs used to set a resource, such as WorkShop Visual's color and font selectors. For resources that have popups, WorkShop Visual creates a button on the resource panel to invoke the popup, in addition to the usual text field. Figure 14-8 shows popup buttons on the WorkShop Visual Core resource panel.

Figure  14-8 Popup Buttons on Core Resource Panel

14.13.1 Popups for Individual Resources

You can specify a popup dialog for any individual resource. To do this, use the right side of the Widget Edit Dialog, shown in Figure 14-9. Select the name of the resource in the list. If you haven't yet added the resource to the list, enter the defined name of the resource, such as XtNresourceName, in the "Resource" field and click on "Update".

Figure  14-9 Popup Portion of Widget Edit Dialog
This dialog uses resource names and not resource types. Therefore, you can specify different popups for different resources of the same type. For example, if you specify a popup dialog for a specific resource of type XmRInt, that popup is not displayed for other resources of that type.

After you enter the resource name, click on the "Popup" button to display the Popups Dialog. Select a popup using the instructions in The Popups Dialog section below.

14.13.2 Popups for Resource Types

If you specify a converter for a resource type, you can specify a popup dialog for that type. To do this, click on "Popups" on the "Converters" page of the Family Edit dialog. This displays the Popups Dialog. Select a popup using the instructions in the following section.

14.13.3 The Popups Dialog

The Popups Dialog is shown in Figure 14-10.

Figure  14-10 The Popups Dialog
The Popups Dialog displays the current list of popups. The list is preset with the built-in WorkShop Visual popup creation functions:

Table  14-3 Built-In Popups

Creation Function
Popup

xd_colour_dialog_create

Color selector

xd_font_dialog_create

Font selector

xd_fsb_dialog_create

File selection dialog

xd_pixmap_dialog_create

Pixmap editor

xd_string_dialog_create

Compound String editor

To apply an existing popup to the currently selected individual resource or converter type, select the popup creations function in the list and click on "Apply". Note that all popup dialogs return the resource value in the form of a string such as "red" or "<big_font>". Therefore they work for resources that are declared as strings but are used to specify fonts, colors, or filenames.

14.13.4 Custom Popup Dialogs

You can create your own popup dialog, add it to the list and apply it to any resource or converter type. Three functions are required for each popup dialog: a create function, an initialize function and an update function. Enter the name of each function in the appropriate text field and then click on "Update" to add the popup to the list.

14.13.5 Code Requirements

The popup functions are invoked at different points in WorkShop Visual, as shown below:

Function
Called

create function

When the dialog is first popped up.

initialize function

Each time the user clicks on the resource button.

update function

Each time a new widget is selected.

Add callbacks on widgets in your popup dialog to furnish hooks for additional functionality such as setting the new value, editing the value, accessing help and popping down the dialog. Your dialog should have at least the following standard callbacks:

Callback
Functionality

Apply callback

Sets new resource value in source text widget.

Close callback

Pops down the dialog by unmanaging it.

The Text or TextField widget on the resource panel (called the source text widget) is used to pass information from the dialog to the resource panel. When the user sets a value on the popup dialog, the value should be converted to text and set into the source text widget. The user can then click on "Apply" on the resource panel to set the value in the dynamic display, just as if the text had been typed by hand.

You can build your dialog in WorkShop Visual or code it by hand. The example at the end of this section shows a popup dialog that was built in WorkShop Visual.

14.13.6 Create Function

The create function is called the first time the user clicks on the resource button to pop up the dialog. This function should create the widget hierarchy for the dialog.

void popup_create ( Widget parent )
The parent parameter is the Application Shell widget for WorkShop Visual, to be used as the parent widget for the dialog. This parameter is required to call functions such as XmCreateDialogShell(). You can build popup dialogs in WorkShop Visual and use WorkShop Visual's generated creation procedure as the create function, or write a create function that calls it. In this case, pass parent on to the function generated by WorkShop Visual.

Note that the initialize function is called immediately after the create function and so you don't have to manage the widgets if you do it in the initialize function.

14.13.7 Initialize Function

The initialize function is called every time the user clicks on the resource button to pop up the dialog. The first time the dialog is invoked, the initialize function is called after the create function. The function should make the dialog visible by managing it and initialize any fields in it. The initialize function is passed the source text widget, the currently selected widget and the resource name.

void popup_initialize( Widget source_text, Widget current, char 
*resource_name)
The source_text parameter is the source text widget on the resource panel. This widget can be used to obtain the resource value currently displayed on the resource panel. Since the source text widget is used to pass back the new value from the dialog, the initialize function should also save the source text widget in a static variable so that it is available later.

current represents the currently selected widget. The initialize function should check whether the currently selected widget has the expected resource because the user can invoke the popup dialog from the resource panel after selecting a widget of a different type. Note that current is NULL if the user has deleted all widgets in the hierarchy.

resource_name contains the resource name (a string such as "label"), not the defined name. This parameter is especially useful when you use the same popup to set more than one resource.

14.13.8 Update Function

The update function is called for every popup dialog each time the selection changes in the widget hierarchy.

void popup_update( Widget current )
current represents the newly selected widget. The update function should make the "Apply" button insensitive if the newly selected widget is of a different class, or if current is NULL. If you use the same dialog to set multiple resources, the safest approach is to make the "Apply" button insensitive in all cases. The user then has to click on the resource button again in order to use the popup. This extra step invokes the initialize function and ensures that the intended resource is set.

14.13.9 Popup Example

This example shows a simple resource popup consisting of a slider that is used to select an integer value. When the user clicks on "Apply" in the popup, the slider's value is converted to a text string and placed into the text widget in the resource panel.

The dialog itself was built in WorkShop Visual. The Shell for the dialog was designated a Data Structure resulting in the structure shown below. Named widgets in the dialog are easy to access through the structure pointer foo_dialog. For example, foo_dialog->scale accesses the Scale widget.

typedef struct foo_dialog_s {
	Widget foo_dialog;
	Widget form;
	Widget scale;
	Widget apply;
	Widget close;
} foo_dialog_t, *foo_dialog_p;
static foo_dialog_p foo_dialog = (foo_dialog_p) NULL;
The following function is generated to create the Shell and all its children. The body of the generated function is omitted.

foo_dialog_p create_foo_dialog (Widget parent)
{
/* WorkShop Visual generated code to create the dialog omitted here.*/

}
In the module prelude a static variable is created to hold the source text widget. The initialize function provides the source text widget.

static Widget source_text;
The dialog has an "Apply" button and a "Close" button, each with an Activate callback. The "Apply" button invokes the callback function shown below. This callback function gets the current value of the Scale, converts it to a text string and sets it into the source text widget. Note that this doesn't set the resource; the user must still click on "Apply" on the resource panel.

static void
foo_do_apply (Widget w, XtPointer client_data, XtPointer 
call_data )
{
	int i;
	char buf[52];
	XmScaleGetValue ( foo_dialog->scale, &i );
	sprintf ( buf, "%d", i );
	XmTextSetString ( source_text, buf );
}
The dialog also has a "Close" button. The Activate callback function on this button simply unmanages the child of the dialog's Shell widget.

static void
foo_do_close (Widget w, XtPointer client_data, XtPointer 
call_data )
{
	XtUnmanageChild ( foo_dialog->form );
}
The create function calls the WorkShop Visual generated creation function and saves the widget structure.

foo_create( Widget parent )
{
	foo_dialog = create_foo_dialog( parent );
}
The initialize function extracts the text from the source text field, converts it to an integer and sets the Scale to reflect the current value. It saves the source text field and so the new value set using the Scale can be applied to the source text field. It enables or disables the "Apply" button depending on the class of the current widget and makes the dialog visible.

foo_initialize( Widget text, Widget current)
{
	char *source_value;
	int i;
	source_text = text;
	source_value = XmTextGetString( source_text );
	i = atoi( source_value );
	XtFree( source_value );
	XmScaleSetValue( foo_dialog->scale, i );
	XtSetSensitive( foo_dialog->apply, 
current && XtIsSubclass (current, fooWidgetClass ) );
	XtManageChild( foo_dialog->form );
}
The update function enables or disables the "Apply" button, depending on the class of the current widget.

foo_update( Widget current )
{
 	XtSetSensitive( foo_dialog->apply,
current && XtIsSubclass( current, fooWidgetClass ) );
}


14.14 Resource Memory Management

WorkShop Visual assumes a default memory management model for XmString and String (char *) type resources. For XmString type resources this model assumes that the widget will copy the XmString both on SetValues and on GetValues (i.e. the application can free the XmString after a GetValues or SetValues).

For String resources it is assumed that the widget copies the String on SetValues but not on GetValues (i.e. the application only frees a String after a SetValues). If you have a resource that does not conform to this model (typically an XmString resource that is not copied by the widget on GetValues), then you can override WorkShop Visual's default behavior using the two Option Menus in the resource section. Where an XmString is not copied on GetValues, you should set the GetValues Option Menu to "Don't Free" in the Widget Edit dialog. Similarly, if you have a String resource that is copied by the widget on GetValues (for example XmNmnemonicCharset in a Label Widget) then you should set the GetValues Option Menu to "Free".

If you wish WorkShop Visual always to default to not freeing the resources, set the "Default means Don't Free" toggle.

It is important to make sure that WorkShop Visual does not free memory that it should not free as this will cause WorkShop Visual to crash. It is less important if WorkShop Visual is not freeing memory that it should free, as this will simply accumulate as a memory leak.


14.15 XmStringTable Resources

For WorkShop Visual to handle XmStringTable resources correctly, you must also specify the integer type resource which is used as a count for the number of entries in the table. Add a resource specification for the XmStringTable.


14.16 Headers

visu_config generates two code modules, the Config file and the Code file. visu_config lets you specify a list of headers for each of these files. To specify headers, use the Family Edit Dialog. Select "Headers" from the View Menu to display the "Headers" page, shown in Figure 14-11.

Figure  14-11 The "Headers" Page of the Family Edit Dialog
There is a separate list of headers for each file. To add a header, type the filename, without quotes or angle brackets and click on "Add". To delete a header, select it and click on "Delete". To reorder a list, select any entry and use the arrow buttons to move it up or down.

The Code file defines the widget class records for user-defined widget classes. visu_config automatically generates a #include for the widget class header file which it takes from the Widget Edit dialog. Often no additional Code headers are needed.

The Config file contains a list of user-defined widgets, enumerations, and aliases. Widget headers for user-defined classes aren't automatically generated to this file. If you configure visu_config with non-standard enumerations or resource types, include the header file in which they are defined.

The easiest way to find out what headers are needed is to generate and compile the code. If the compiler returns an undefined reference, find out which header contains the necessary definition and add it to the header list for that file. Then regenerate the code and try again.


14.17 Motif Widgets Stop List

You can use visu_config to stop selected Motif widgets from appearing in WorkShop Visual. Stopped widgets do not appear in the widget palette. They work correctly if read in from an existing design file but cannot be selected in the hierarchy or created interactively. For example, you can use this feature to prevent users from using the PanedWindow widget if it isn't in your company's style guide.

To stop a widget, pull down the Edit Menu in the main visu_config dialog and select "Stop list" to display the dialog shown in Figure 14-12:

Figure  14-12 The Stopped Motif Widgets Dialogs
To remove a Motif widget from the widget palette, set the appropriate toggle and click on "Apply".

Widgets can also be stopped by setting the visu.stopList resource, as described in the Configuration section on page 732. Note that widgets stopped using the resource can be reactivated easily using the resource file, while widgets stopped in visu_config can only be reactivated by rebuilding WorkShop Visual.

User-defined widgets cannot be stopped using this dialog. You can select which user-defined families to make available in WorkShop Visual via the visu_config Generate dialog, as discussed in the following section.


14.18 Generating and Compiling Code

The Generate Menu has two options, Config and Code which are used to generate the two configuration files. The pages displayed for each option are similar, as shown in Figure 14-13. Use the toggle buttons to select the families you want to include. Generate both files, using the same set of families for each.

Figure  14-13 The Config and Code Generate Dialogs

14.18.1 Compiling

The example makefile in $VISUROOT/user_widgets/Athena1 compiles a Config file named config.c, a Code file named Athena.c and a file containing configuration functions, Athenaextras.c. These files and all the Athena icon bitmaps, are located in $VISUROOT/user_widgets/Athena. You can use this makefile to compile the Athena example. The result is an executable file called visu.bin.

When you configure with other widgets, use the example makefile as a starting point. Make sure that the makefile references all directories containing icon bitmap files and required header files.

If the compilation fails, inspect the generated code to find the problem. The cause may be a missing header. You can supply additional headers on the Headers page of the Family Edit dialog. The compiler also catches any misspellings in any of the visu_config dialogs. Fix the problem, regenerate the Code and Config files, then recompile.

Note that the linker detects any misspelled function names. If the misspelling occurred in visu_config, correct the problem, regenerate the Code and Config files, then recompile.

14.18.2 Invoking WorkShop Visual

The executable file is invoked with the correct environment by setting the environment variable USER_WIDGETS to the name of the user widgets directory (in this example "Athena") and invoking the standard visu command in $VISUROOT/bin. This causes the local bitmaps or color_icons directories to be added to $XBMLANGPATH and the local app-defaults directory to replace $VISUROOT/lib/locale/<LANG>/app-defaults in $XFILESEARCHPATH.

A site-wide default can be set up by making a symbolic link called "local" in $VISUROOT/user_widgets to the user widgets directory of choice. In this case all users will get that version of WorkShop Visual by default unless they explicitly override it with a setting of USER_WIDGETS. When USER_WIDGETS contains a value that is not recognized, or the visu.bin in that user widgets directory has not been built, the site default, if configured, or original "vanilla" WorkShop Visual is invoked instead.


14.19 Testing the Configuration

This section describes a recommended testing procedure for the WorkShop Visual interface for a user-defined widget. Use visu_config as suggested to fix any problems. Note that these tests are designed to detect problems with the way in which the widget was configured into WorkShop Visual; they do not test the widget itself.

14.19.1 Creating a Widget


Note - This test is not appropriate if you turned off the "Can create widgets" toggle in the widget attributes panel.
Run WorkShop Visual and verify that the icon for the user-defined widget is correct. If you use the small screen WorkShop Visual, invoke WorkShop Visual with the name small_visu and verify that the icon is correct in this case, too.

Create a hierarchy that contains an instance of your widget. If WorkShop Visual fails when the widget is added, you may need a Realize function. For details, see the Configuration Functions section on page 518. If the failure is accompanied by an X error message about zero height/width windows, try using sizedCreate() (found in Athenaextras.c) as the Realize function for the widget.

If this does not work, try setting the "Disable foreground swapping" toggle in visu_config.

14.19.2 Foreground Swapping

If you have not disabled foreground swapping, create a hierarchy containing the user-defined widget. Select the Shell in the hierarchy and then select the user-defined widget. Verify that the widget in the dynamic display highlights correctly when selected. If this causes a problem, set the "Disable foreground swapping" toggle in visu_config.

14.19.3 Defined Name

Create a dialog containing an instance of the user-defined widget with every resource set. Generate C from WorkShop Visual and compile it. If it fails to compile, you may get a message like this:

XtNfoo undefined
If you get such a message, first verify that the generated code includes the right public header for the widget class. If it doesn't, correct the header in the "Include file" field of visu_config's Widget Edit dialog.

If the header is being generated correctly but you still have compilation problems, you may need a Defined Name function. Look in the public header for a line such as:

#define <something> "foo"
If <something> is not XtNfoo, you need a Defined Name function. For details, see the Configuration Functions section on page 518.

14.19.4 Pages

If you have specified that resources for the user-defined widget should appear on specific pages, verify that they do and that all the required pages are present.

14.19.5 Converters

Display the "Miscellaneous" page of the resource panel for the user-defined widget. Verify that you can type valid resource values into the text widgets and that they are correctly applied to the widget. If you get a message indicating that there is no resource converter, you need to use the "Add in WorkShop Visual" setting in visu_config.

14.19.6 Enumerations

Display the "Settings" page of the resource panel for the user-defined widget. Make sure the option menus all have the default value in parentheses at the top of their menus.

Display the "Miscellaneous" page if there is one. Enumeration resources appear on this page if they weren't configured in visu_config. If enumeration resources do appear on this page, go back and add them using visu_config.

Set each value for the enumeration in turn, including the default. Verify that each value works as expected in the dynamic display and that the generated code compiles correctly.

14.19.7 Popup Dialogs

If you specified custom popup dialogs for any resources, display the page of the resource panel on which each resource appears. Verify that the resource panel displays a button for each resource with a popup dialog. Click on the button. Verify that the dialog appears and is correctly initialized with the current value for that resource.

Set the resource in your dialog. Verify that the text widget on the resource panel updates correctly. Apply the setting from the resource panel and verify the result in the dynamic display.

If your dialog has a "Close" button, verify that it works as expected and that the dialog reappears when you click on the button on the resource panel.

14.19.8 Code Inspection

Finally, verify that the generated code is correct. To check the generated code, set each resource in turn, generate a C code file and an X resource file and inspect them to see that you get what you expect.

Code inspection for all the Motif widgets forms part of the WorkShop Visual release process. Therefore if you have a user-defined widget that is derived from a Motif widget, you can concentrate on testing resources that are specific to the user-defined widget. This is also true if you have a user-defined widget that is derived from another user-defined widget that you have already tested.


14.20 Configuration Functions

visu_config lets you provide configuration functions to customize WorkShop Visual's handling of user-defined widgets. This section provides definitions and examples of the configuration functions.

To add a configuration function, specify the name of the function on visu_config's Widget Edit dialog for the widget class, then regenerate the Code and Config files from visu_config. Edit your makefile to compile and link the file containing the code for your configuration functions.

For examples of the configuration functions that were used to integrate the Athena widgets into WorkShop Visual, see:

$VISUROOT/user_widgets/Athenaextras.c2.

14.20.1 Realize Function

By default, WorkShop Visual creates widgets in the dynamic display by calling XtCreateWidget(). You can supply a Realize function to substitute for this. A Realize function is only needed for widgets that cause problems when created in WorkShop Visual.

14.20.2 Realize Function Prototype

The Realize function has the following form. Note that it takes the same parameters and returns the same result as XtCreateWidget().

Widget realize( char *name, WidgetClass class, Widget parent, 		
ArgList args, Cardinal arg_count )
The ArgList passed to a Realize function is always empty.

14.20.3 Realize Function Example

Some composite widgets, such as the Athena Form widget, cannot be realized without children unless their dimensions are explicitly set at creation time. Otherwise the widget is created at zero size, causing an X error. To solve this problem in the dynamic display, you can supply a Realize function like the one shown below, found in Athenaextras.c. This function initializes the widget's width and height resources to non-zero values, then calls XtCreateWidget() and returns the result.

WidgetsizedCreate( char *name, WidgetClass class, Widget parent, 
ArgList args, Cardinal arg_count )
{
	Arg al[2];
	int ac=0;
	XtSetArg(al[ac], XtNheight, 20); ac++;
	XtSetArg(al[ac], XtNwidth, 20); ac++;
	return XtCreateWidget ( name, class, parent, al, ac);
}
The Realize function is only used when WorkShop Visual creates the widget in the dynamic display. It has no effect in the generated code.

14.20.4 Defined Name Function

In order to generate both code files and X resource files, WorkShop Visual uses both the resource name, such as label, and the corresponding defined name, such as XtNlabel. WorkShop Visual gets the name directly from the widget class record. By default, WorkShop Visual derives the symbolic constant from the name by adding an XtN prefix.

If your widget doesn't follow this convention, you can configure WorkShop Visual with a Defined Name function. The Defined Name function is a custom procedure that converts a resource name to its corresponding symbolic constant. To find out whether a widget needs a Defined Name function, look in the public header for the widget class. The header file contains lines like the following that define the symbolic constant and its value:

#define XtNlabel "label"
#define XtNfont "font"
#define XtNinternalWidth "internalWidth"
You need a Defined Name function if any of the defined names don't follow the naming convention. For example, many widget toolkits, including Motif, use a different prefix:

#define XmNbuttons "buttons"
#define XmNbuttonSet "buttonSet"
#define XmNbuttonType "buttonType"

14.20.5 Defined Name Function Prototype

The Defined Name function has the following form:

char *defined_name ( char *name )
The Defined Name function is passed a character string containing a resource name and should return a character string containing the corresponding defined name. Your Defined Name function can refer to WorkShop Visual's internal Defined Name function, def_defined_name(). This function simply adds the default XtN prefix to the resource name.


Note - The function names defined_name and def_defined_name are already used by WorkShop Visual so you should make sure that you do not use these names.

14.20.6 Defined Name Function Example

The defined name for the Athena Clock widget resource hands is not XtNhands but XtNhand. Therefore, the Clock widget needs the following Defined Name function:

char *clock_defined_name( char *name )
{
	/*
	 * XtNhand is defined as hands, so can't just put
* XtN on the front
	 */
	if ( strcmp ( name, "hands" ) == 0 )
		return "XtNhand";
	return def_defined_name ( name );
}
All Clock resources except hands follow the naming convention and so def_defined_name() is used to convert them.

14.20.7 Can Add Child and Appropriate Parent Functions

You can supply Appropriate Parent and Can Add Child functions to define the rules for valid parent-child relationships involving user-defined widgets. These rules control WorkShop Visual features such as graying-out of palette icons, automatic selection of newly created widgets and dragging icons in the construction area.

Often these functions aren't needed. If you don't supply them, WorkShop Visual uses the rules for the first known ancestor of the widget class. For example, if a user-defined widget is derived from the Primitive class, WorkShop Visual uses the rules for the Primitive class and doesn't let the user add children to the widget.

The Appropriate Parent and Can Add Child functions are combined with rules for other widgets. For example, WorkShop Visual already has a rule that MenuBar widgets can only have CascadeButtons as children, so you don't need an Appropriate Parent function to prevent the user from making your widget a child of a MenuBar. You only need to supply functions if your widget class has additional rules.

If you configure WorkShop Visual with a non-Motif composite widget, the widget class should have a Can Add Child function to prevent it from having Motif children. Motif widgets assume that their parents are Motif widgets and WorkShop Visual may core dump if a Motif widget is made a child of a non-Motif widget.

14.20.8 Appropriate Parent Function Prototype

The Appropriate Parent function is called when the user tries to add a widget of the user-defined class to the hierarchy, or tries to drag or copy the user-defined widget to another parent. This function determines whether the user-defined widget can be added as a child of the selected widget.

The Appropriate Parent function has the following form:

Boolean is_appropriate_parent ( Widget parent, WidgetClass 														
childclass )
The first parameter is an instance of a widget in the hierarchy that is a proposed parent widget; the second is a pointer to your new widget class. The function should return TRUE if it is valid to add a child of your new class to the proposed parent widget and FALSE otherwise.

Because the Appropriate Parent function is passed the instance of the proposed parent widget, you can make rules based on either the class or the state of the parent widget. For example, you can check the parent widget's dimensions, ancestor widgets, or other children before letting the user add a new child of your user-defined class.

14.20.9 Appropriate Parent Function Example

By default, WorkShop Visual lets Motif Manager widgets, such as the Form and Row Column, have children of any type. Appropriate Parent functions let you restrict the widget to being a child of only certain classes. For example, if your widget can only be a child of a DrawingArea, supply an Appropriate Parent function that returns TRUE if the proposed parent widget is a DrawingArea and FALSE if not. The code for this case is very simple:

Boolean drawing_area_parent ( Widget w, WidgetClass class )
{
	if ( XtClass ( w ) == xmDrawingAreaWidgetClass )
		return True;
	return False;
}

14.20.10 Can Add Child Function Prototype

The Can Add Child function has the following form:

Boolean can_add_child (XWidget_p parent, WidgetClass childclass)
{
...
}
This function is used for two purposes. WorkShop Visual calls the Can Add Child function to determine whether a widget of a specific class is a valid child of the user-defined widget and calls the Can Add Child function to determine whether it should automatically select a newly created instance of the user-defined widget.

The first parameter is a pointer to an existing instance of the user-defined widget class. The parent widget instance is passed as an XWidget_s structure, an internal WorkShop Visual data type that represents a widget instance. One field of this structure is a pointer to the widget instance. For documentation on the XWidget_s structure, see $VISUROOT/user_widgets/hdrs/xwidget.h.

The second parameter may be a pointer to a proposed child widget class, or may be NULL. If the second parameter is non-NULL, WorkShop Visual is inquiring about a proposed child class. The function should return TRUE if the child can be added and FALSE if not. Note that you have a pointer to the parent instance but not to the child class because the child widget hasn't been instantiated. Your function may make rules based on the current state of the instance of the user-defined widget. For example, you can write a function that lets your widget accept only a limited number of children. If the second parameter is NULL, the user has just created a widget of this class.

If the Can Add Child function returns TRUE, WorkShop Visual selects the newly created widget in the hierarchy; otherwise, the parent widget remains selected. In this case, the Can Add Child function should usually return TRUE if the widget can have children of any type and FALSE otherwise.

14.20.11 Can Add Child Example

The following example shows a Can Add Child function.

Boolean paned_can_add_child ( XWidget_p xw, WidgetClass class ) {
/* For newly created instance of this widget class, make the newly created widget the currently selected widget in the hierarchy. */

if (class == NULL)
	return TRUE;
/* Allow all children except Drawing Area and ScrollBar. */

if	( class == xmDrawingAreaWidgetClass ||
	  class == xmScrollBarWidgetClass )
	return False;
else
	return True;
}

Previous Next Contents Index Doc Set Home


1 $ is the path to the installation root directory.

2 $ is the path to the installation root directory.