Builder Xcessory 5.0 User's Guide

Builder Xcessory 5.0

User's Guide

Copyright © 1998 Integrated Computer Solutions, Inc.
Integrated Computer Solutions, Inc.
Trademarks

 

Documentation: 

Activating Your Interface

Overview

Builder Xcessory facilitates creating the initial layout of your UI, but that's only part of the development process. Most interfaces are dynamic and include elements that change during the session, usually in response to the use of the application. This chapter examines how to use Builder Xcessory to build this behavior into your application.

Initializing Resources at Run Time

Using variables as resource values

The simplest way to be able to set resources at run time is to use variables as resource values. Builder Xcessory provides three easy methods of using variables as resource values:

· Constants

· Identifiers

· Expressions

Constants

Constants are Builder Xcessory representations of compile-time constants, that is, #defines . When setting a resource value, select Constant from the Resource Placement menu to the right of the Extended Editor button. You are presented with a choice of constants that you've already defined, and <New>. Choosing <New> brings up the Constant Editor with which you can define a new constant. Builder Xcessory includes this definition in the generated source code.

Constant Manager

You can work with your constants by using the Constant Manager (select Constants from the Browser Managers menu). Refer to Constant Manager for more information.


Note: Because constants have values, using them has an immediate effect in Builder Xcessory. Whenever you change the value of a constant with the Constant Editor, all resources that use the constant are immediately updated.

Identifiers

Identifiers are variables that are valid within the scope of the creation routine. When setting a resource value, select Identifier from the Resource Placement menu to the right of the Extended Editor button. You are presented with a choice of identifiers that you have already defined, and <New>.

Choosing <New> brings up the Identifier Editor, with which you can define a new identifier:

Identifier Editor


Note: You must declare your identifiers in the application code, either in a user code block, or in an include file. You must also be sure that the identifier is declared prior to the creation of the object that references it.

Identifiers are not necessarily simple variables. You can define an identifier that is a call to a function or a method, with the appropriate return type. You can work with your identifiers by using the Identifier Manager (select Identifiers from the Browser Managers menu). See Identifier Manager for more information.


Note: Because identifiers are given values only at run time, modifying an identifier with the Identifier Editor has no immediate effect on your Builder Xcessory application.

Expressions

Expressions can be used to specify an integer value for a resource. Type the expression into the value field or in the Integer Editor, as appropriate. The Placement Menu changes to reflect the presence of an expression. Expressions cannot be over-ridden by the X resource manager at run time. In this way they are functionally equivalent to Code Placement.

The syntax for a Builder Xcessory expression is:

expression ::= integer_value
| constant_name
| expression + expression
| expression - expression
| expression * expression
| expression / expression
| ( expression )
| - expression

Expressions are evaluated from left to right. Standard order of precedence is enforced for binary operator expressions.


Note: If an expression depends on a Constant that is cut or deleted (with the Constant Manager), the expression is converted to its previously evaluated value, and written out as an integer. The Placement Menu is changed from Expr to Code to indicate this.

Callbacks with XtSetValues Calls

You can dynamically change a resource value using the X Toolkit call, XtSetValues. Builder Xcessory includes the predefined callback BxSetValuesCB, which takes the following string as its parameter:

"<instance_name>.<resource>=<value>
<instance_name>.<resource>=<value>
...
<instance_name>.<resource>=<value>"

When the callback is called, the resources of the designated object are set to the specified values by using the function XtSetValues.

Example

The following example demonstrates a simple use of BxSetValuesCB:

1. Create a BulletinBoard with two PushButton children.

2. Set the activateCallback resource of pushButton to BxSetValuesCB("bulletinBoard.background=red").

3. Set the activateCallback resource of pushButton1 to BxSetValuesCB("bulletinBoard.background=white").

4. Enter Play Mode(Browser:View).

5. To test the interface, click the PushButtons.

The BulletinBoard toggles between red and white as each call to BxSetValuesCB resets the background resource.

Note: Use unique instance names for objects that are referenced by callbacks. Predefined callbacks rely on the instance name remaining the same each time the widget is created, and the default instance names assigned by Builder Xcessory may change when you edit the instance hierarchy.

Accessing Objects at Run Time

To manipulate an object at run time, you must have access to it. How you choose to access the object depends on the language in which you plan to generate code.

In C++, ViewKit, and Java, objects are declared by default as protected class members and are easy to access from within a class. To access an object from outside the class, you must define a public method, though you most likely want your method to perform any manipulation, rather than passing a widget ID out. Follow good object oriented programming practices.

In C, you can use one of the following methods:

· Set the storage location

· Set createCallback

· Use the class record

· Call Xt functions

If you are generating UIL, you can specify the widget ID with the widget name using MrmFetchWidget.

Setting the storage location

How you access widget IDs when using C depends on whether the widget storage location is already declared or if you want Builder Xcessory to declare the storage location for you. If you set the storage location to Other on the Storage Location dialog (Resource Editor:Component), you are responsible for declaring and allocating the variable in your code, such as in a User Code Block, or in another file.

When you use Other storage, it is good practice to create a structure in which to store the desired widget IDs (and any other useful data). You can then pass a pointer to this structure through to the creation routine and assign the widget ID storage to the appropriate structure members. You can also pass this structure member as client_data to your callback functions, which gives you an easy way to access various widget IDs from those callback functions.

Declaring storage location in Builder Xcessory

If you want Builder Xcessory to declare global storage, follow these steps:

1. Select Storage Location from the Resource Editor Code menu.

2. Select Global from the Storage Location option menu.

Selecting Global tells Builder Xcessory to set up the widget storage location, as well as assign the widget ID's value. This also causes the constants file to be generated.


Note: All globally-defined widget IDs are stored in the constants header file.

Declaring storage location in code

If you have declared the storage location in the code, follow these steps:

1. Select Storage Location from the Resource Editor Component menu to display the Storage Location dialog:

Storage Location Dialog

2. Select Other from the Scope text field on the Storage Location dialog

3. Enter the variable to which Builder Xcessory should assign the ID.


Note: This variable is not generated by Builder Xcessory in the source code. It is assumed to be accessible within the scope of where it is referenced. In C, this is the creation routine, in UIL, the main routine. ViewKit, C++, and Java do not allow you to set a storage location for an internal class member.

Setting createCallback

You can also save the widget ID by using a createCallback. A createCallback is similar to an actual Xt widget callback, but is called from the main file after the widget is created. The parameters passed to a createCallback are the same as those passed to an Xt callback, and allow you to access the widget ID.

You may want to use this method of accessing a widget ID if you want to perform an action immediately after a widget is created. If this is not important, declaring a Local Storage Location is a simpler method.

Example

A creation callback might look like the following:

void createCallback(Widget w,
XtPointer client_data,
XtPointer call_data)
{
Widget *assign=(Widget*)client_data;
*assign=w;
}

where:

client_data is a variable or structure in which the widget ID is stored.

w is the widget that has just been created.

assign passes the address in which the widget's ID is stored.


Note: Using createCallback in this way is similar to selecting Other from the Storage Location option menu (when you have already declared the storage location). These two methods accomplish the same task.

Using the Class Record

You can access widget IDs by using the structure that Builder Xcessory generates for each class when you are working in C.


Hint: Accessing class member widgets from a function or method that is not part of the class is possible, but not recommended as it breaks the object oriented model.

Calls to Xt Functions

You can also use the Xt function, XtNameToWidget, to obtain the widget ID. Although inefficient, this method is an effective way of obtaining the widget ID of a compound widget child.

MrmFetchWidget

If you are generating UIL, you can obtain the widget ID by calling MrmFetchWidget on the widget name.

Managing and Unmanaging Objects

Frequently, some objects are displayed only for short periods during the application's execution. For example, when a dialog is displayed for a particular user action and then immediately dismissed. In these cases you might want to start your application with these objects initially unmanaged, so that the application manages them only as necessary.

Setting dialogs as initially unmanaged

To set dialogs as initially unmanaged, follow these steps:

1. Select Code Generation Preferences from the Browser Options menu to display the Code Generation Preferences dialog (Application Panel on the C Generation Preferences Dialog ).

2. Click on the Application tab ( Application Panel on the C Generation Preferences Dialog ).

3. Set (Parented) Dialog Shells Initially Unmanaged.

Parented dialogs are now unmanaged by default.

Note: This affects code generation only. The dialogs remain managed during your Build sessions.

Note: To unmanage objects on a case-by-case basis, select Hide on any object in the Resource Editor (Resource Editor:Component).

Application Panel on the C Generation Preferences Dialog

Callback Procedures and Event Methods

To connect your interface to the rest of your application, you must add callback procedures (for Motif) or event methods (for Java). These callbacks and event methods respond to various actions, or events, on the interface, such as a key press or window exposure.

Adding callbacks and methods

You add a callback procedure or an event method by assigning its name to one of an object's callback or event resources. You can then edit the resource using the Resource Editor as you edit any other resource.

To add a callback as the activateCallback of a push button, follow these steps:

1. Update the Resource Editor for the push button.

2. Click the (...) button to the right of the activateCallback text field to display the Callback Editor:

Callback Editor

3. Enter the Procedure Name, select a Parameter Type, and enter the Parameter Name in the appropriate fields, hitting enter to apply the value to the callbacks list. After adding whatever other callbacks you wish to associated with the activateCallback, press Apply.

4. To add code to the callback, select it in the Callback List and press Edit. Builder Xcessory generates code and brings up your favorite editor with the correct file loaded and positioned at your new callback.


Note: You can edit only procedures that have been applied.

Adding an event method

To add an event method for the ActionEvent of a Java push button, follow these steps:

1. Update the Resource Editor for the push button.

2. Bring up the extended editor for the ActionEvent resource ( ActionEvent Editor ).

ActionEvent Editor

3. Enter the procedure name in the ActionEvent Editor's text field, and apply the value to the resource (Apply).

4. To edit the code for the method, be sure that the method name has been applied, then press the Edit button to the right of the text field. Builder Xcessory generates Java code and brings up your favorite editor with the correct file loaded and positioned at your new method.

Predefined Callbacks

Click on the arrow button to the right of the Procedure Name field to display the list of predefined callbacks. Predefined callbacks are provided for common operations such as setting values, managing and unmanaging windows, etc. These predefined callbacks also behave correctly when Builder Xcessory is in Play Mode, allowing you to test the look of the interface without building the application. For more detailed information on these callbacks, refer to the Builder Xcessory Reference Manual .

Using Classes predefined callbacks

To set a callback resource to a predefined callback, follow these steps:

1. Display the Callback Editor for the appropriate resource.

2. Click on the arrow button to display the list of predefined callbacks.

3. Click on a predefined callback on the list.

4. Apply the contents of the Callback Editor to the resource.

Predefined callbacks are especially useful for rapidly prototyping your application. They allow you to preview many common actions that are performed in your interface, during the development process when the efficient execution of the application is not as important.

Using Callbacks in C++ Classes

For a general introduction to classes, refer to Classes . For more detailed information about using exposed resources and methods, refer to Exposing Resources and Exposing Callbacks and Event Methods .

Adding callbacks to classes

Whenever you add a callback to an object within a class, Builder Xcessory generates two methods:

· A private static method assigned to the widget using XtAddCallback() . This is static because Xt is a C library, and thus cannot use a non-static method. This method is automatically named your_callback_name Callback(Widget, XtPointer, XtPointer) .

· A protected virtual method containing the actual code for your callback. This method is given the name you specified for the callback, your_callback_name (Widget, XtPointer, XtPointer) .

The static method is passed a structure pointer that contains a pointer to the instance of the class that initiated the callback and a pointer to any client data that you specified for the callback. The static method then calls the actual class method (the real callback) and passes all of the standard Xt callback parameters ( w , client_data , call_data ).

Exposing callbacks

When you expose a callback in a class, Builder Xcessory generates the two methods described previously, and a public method that adds additional callback functions to the widget. This method's name incorporates the widget's instance name and callback resource name. It uses XtAddCallback() to optionally append to, or replace, the existing callback list. Appending or replacing is controlled with the Remove Overridden Exposed Callbacks toggle on the Code Generation tab (Browser:Options:Language Settings).

Builder Xcessory also allows you to set callbacks defined by the various ViewKit components (ViewKit Callbacks). In the Resource Editor, these callbacks appear identical to Xt callbacks. However, during code generation, these ViewKit callbacks are generated only as methods of the ViewKit component and are added using VkAddCallbackMethod().

Using Event Methods in Java Classes

For a general introduction to classes, refer to Classes . For a detailed discussion of using exposed resources and methods, refer to Exposing Resources and Exposing Callbacks and Event Methods .

Adding event methods to classes

When you add an event method to an object within a class, Builder Xcessory adds your routine as a public method.

Exposing event methods

When you expose an event method in a class, you can then specify an additional method (on a per instance basis) to be called in response to the event.


Note: Exposing methods in Java is meaningful only if the original event method, specified in the class definition, allows the event to propagate up the instance chain to the parent (original event method returns "false"). Refer to you Java documentation for more information on AWT event processing.

Using Timers, Event Handlers, and Translations

You can register and use timer procedures, work procedures, event handlers, and translations using special editors provided by Builder Xcessory. These elements are managed similarly within Builder Xcessory.

Timer Procedures

A timer procedure is a procedure invoked when a specified interval of time elapses. When a timeout event occurs, the timer callback procedure is invoked, and the callback is removed. Consequently, timeout events are invoked only once.

In ViewKit code generation, specifying a timer procedure causes Builder Xcessory to create an instance of the VkPeriodic class. This class calls the timer procedure repeatedly until your application stops it. For more information on this class, refer to the VkPeriodic manpage.

Using timer procedures

Use a timer procedure for an event that you want to happen after a specific time interval. When the timer procedure is registered, Xt first waits for at least the interval you specified, and then calls the timer procedure. Builder Xcessory generates code to register the timeout in the main program.

Refer to O'Reilly & Associates, Definitive Guides to the X Window System, Volumes 4 and 5 for a full description of timer procedures and the XtAppAddTimeOut call.

Adding timer procedures

To add a timer procedure, follow these steps:

1. Select Application from the Browser Managers menu to display the Application Manager.

2. Click on the (...) button next to the Timer Procedures input field in the Application Manager to display the Application Timer Procedures Editor:

Application Timer Procedures Editor

3. Click on New.

4. Enter the name of the timer procedure to be called after the interval expires, along with the interval, the parameter type, and the parameter (data) in their associated fields.

Interval specifies the number of milliseconds that should elapse before this function is invoked. After this period elapses, the procedure's callback is invoked by the Xt Intrinsics. The Parameter field specifies client data to pass to the procedure XtAppAddTimeOut.

5. Click on Apply to register the timer procedure.

All current timer procedures are displayed in the window above these fields.

Removing timer procedures

To remove a timer procedure, follow these steps:

1. Select the procedure from the list displayed in the Application Timer Procedures Editor

2. Click Delete.

The procedure is removed from the list and from your application.

Work Procedures

A work procedure is a callback that provides a limited form of background processing. The Xt Intrinsics invoke a work procedure whenever there are no events pending. Thus whenever the application is not drawing to the display or responding to user actions, the work procedure is called.


Note: Although you can define multiple work procedures, only the most recently registered is called.

Using work procedures

Use a work procedure to specify a function to call when no other events are pending. Once a work procedure is called, the program cannot process any events until the procedure returns. Therefore, any work procedure should be a function that executes quickly.

Example

To perform a long calculation with work procedures, set the calculation as an iterative process so that a small portion of the calculation can be done each time the work procedure is called. This approach avoids freezing the interface.

When you specify work procedures and generate code for ViewKit, Builder Xcessory creates a subclass of the VkBackground component for each work procedure you have specified. Each work procedure class is instantiated and started in the main() routine, before the call to VkApp::run().

Refer to O'Reilly & Associates, Definitive Guides to the X Window System, Volumes Four and Five for a full description of work procedures and the XtAppAddWorkProc call.

Adding work procedures

To add a work procedure, follow these steps:

1. Select Application from the Browser Managers menu to display the Application Manager.

2. Click on the (...) button next to the Work Procedures input field in the Application Manager to display the Application Work Procedures Editor:

:

Application Work Procedures Editor

3. Click on New.

4. Enter the name of the WorkProcedure, the Parameter Type, and the Parameter Value in their associated fields.

5. Click on Apply to register the work procedure.

All current work procedures are displayed in the scrolled window above these fields.

Registering a work procedure causes a call to XtAppAddWorkProc to be inserted in the main program.

For ViewKit code generation, a VkBackground subclass is instantiated.

Removing work procedures

To remove a work procedure, follow these steps:

1. Select Application from the Browser Managers menu to display the Application Manager.

2. Select the work procedure from the list displayed in the Application Work Procedures Editor.

3. Click on Delete.

The work procedure is removed from the list and from your application.

Event Handlers

An event handler specifies functions called when an X/Motif event is received by the window associated with the object for which the event handler is set.

Example

Sometimes an object does not provide a callback for an X event that you want to respond to in your application. For example, the XmDrawingArea widget does not have a callback for when the user moves the mouse with a mouse button held down. You must add an event handler to the eventHandler resource on the XmDrawingArea object.

Refer to O'Reilly & Associates, Definitive Guides to the X Window System, Volumes Four and Five for a full description of event handlers and the XtAddEventHandler call.

Adding event handlers

To add an event handler, follow these steps:

1. Click on the (...) button next to the eventHandler resource on the Resource Editor to display the Event Handler Editor:

Event Handler Editor

2. Click on New.

3. Enter the Handler Name, the Event Mask, the value of Non-Maskable, and the Parameter Type and Value in their associated fields. The Event Mask specifies the events that trigger the event handler. Non-Maskable is True if the handler is to be triggered on non-maskable events (that is, events that cannot be specified by the Event Mask, for example, GraphicsExpose, SelectionNotify, or ClientMessage), and is otherwise False. The Parameter specifies client data to pass to the procedure XtAppAddTimeOut.

4. Click on Apply to register the event handler.

Builder Xcessory inserts a call to XtAddEventHandler in the file in which the widget is created. All current event handlers are displayed in the scrolled window above these fields.

Removing event handlers

To remove an event handler, follow these steps:

1. Select the event handler from the list displayed in the Event Handler Editor.

2. Click Delete.

The event handler is removed from the list and from your application.

Translations

A translation links a sequence of one or more events to an action, the function called when these events are received. You can add translations that include actions already registered for the object, or you can add a translation based on additional actions that you must register in your code before creating any object that references them.

Using translations

Most objects provide a large number of actions that are triggered by key presses, mouse actions, and so forth. In most cases, you only add translations to an object to augment its behavior.

Example

Support for Motif drag and drop is added to objects with an action. You must modify a new object's translation table to add drag and drop support.

Adding translations

To add a translation to an object, use one of the following methods:

· Enter the translation in the translations resource text field on the Resource Editor.

· Click the (...) button to the right of the translations resource's text field to display the Translation Table Editor (Translation Table Editor), and enter the translation.

Translation Table Editor

When you apply the contents of the Translation Table Editor to an object's translations resource, Builder Xcessory replaces the object's Translation Table with the translations you have provided.


Note: Builder Xcessory displays a warning if you modify an object's Translation Table and reference an action that you plan to add. However, the action works correctly in your code, provided that the action is registered before you create the object whose translation table references it.

 

Documentation: 

BX PRO 5 Getting Started

Builder Xcessory Overview

Builder Xcessory is a WYSIWYG ("what you see is what you get") visual development environment for user interfaces. Builder Xcessory has an extensible palette of user interface (UI) objects with which you construct your interface, and includes the following features:

· Generates source code in the high-level programming languages UIL, C, C++, ViewKit, and Java.

· Integrates with your existing development environment. You can use SunSoft Workshop, SGI Developer Magic, DEC FUSE, or stand-alone components such as Purify, ClearCASE, XRunner, CodeCenter, ObjectCenter, RCS, or SCCS.

Direct manipulation

Using Builder Xcessory, you interactively create your application's graphical user interface using Motif widgets, ViewKit Components,user-defined components, or Java classes. With Builder Xcessory, you directly manipulate your interface. For example, to resize a pushbutton, select the pushbutton with the mouse and stretch it. If you want to move the pushbutton, select it with the mouse and move it.

Builder Xcessory also has specialized editors to simplify working with the various Motif and Java layout objects by visually representing abstract constraints, attachments, and records. You can directly manipulate these layouts. For example, to connect the resize behavior of a pushbutton to the size of its parent window, select the pushbutton attachment with the mouse and drag it to the edge of the container. When you change an object's attributes, whether it's a layout record or a background color, you see the result immediately.

High-level object reuse

Builder Xcessory takes advantage of the object-oriented nature of today's user interface systems, Motif and Java AWT. While you develop your interface, Builder Xcessory helps you create high-level UI objects to store, share, and reuse .

Rather than building an interface from pushbuttons and scrollbars, you work toward building your application from dialogs and screens. Builder Xcessory simplifies creation of new UI classes and saves them in locations accessible to all developers in your group and in your organization. You can extend these classes by subclassing.

Starting Builder Xcessory

After installing Builder Xcessory on your system, enter the following command at the command line:

% {BX}/bin/bx50

where {BX} is the directory where you installed Builder Xcessory.

If your system administrator copied the bx50 script to another location, enter the following command at the command line:

% bx50

Note: Refer to the BX PRO Installation Notes for complete installation instructions.

Startup Panel

While loading, Builder Xcessory displays the following Startup Panel:

ICS Builder Xcessory Startup Panel

Startup Panel

The Startup Panel appears each time you start a Builder Xcessory session. As Builder Xcessory initializes, status messages are displayed at the bottom of the window, and a random tip is displayed in the "Did You Know?" field. The "Next Tip" button is active only when Builder Xcessory finishes loading ("System Ready" is displayed at the bottom of the window).

Closing the Startup Panel

Once Builder Xcessory is loaded, the Builder Xcessory main windows are displayed, with the Startup Panel in the foreground. Click on the Next Tip button to read more tips, or click on Dismiss to close the window.

Dismissing the Startup Panel automatically

To dismiss the Startup Panel automatically when the system is ready, enable the Auto Dismiss Startup Panel toggle on the Behavior tab of the Browser User Preferences dialog.


Note: In your first Builder Xcessory session, the "Next Tip" button is not active until Builder Xcessory finishes loading and you select a default language. See the next section, Language Dialog for more information.

Language Dialog

In your first Builder Xcessory session, the following Language Dialog window also appears in the foreground:

Language Dialog

Selecting a default language

You must select a default language before proceeding. The language you select determines the available UI objects and the contents of the Builder Xcessory menus and dialogs. The language is saved in your .bxrc file, and becomes the default language for subsequent Builder Xcessory sessions.

You can change the language for each application, or change the default language at any time by selecting Choose A Language from the Browser Options menu. See Choose A Language for more information.

Exit button

The Exit button exits Builder Xcessory without saving a default language with your .bxrc file. The Language Dialog will appear the next time you start Builder Xcessory.


Note: The Language Dialog appears during your first Builder Xcessory session only. Subsequent Builder Xcessory sessions use the default language, as specified in your .bxrc file.

Note: When you select UIL as your default language, Builder Xcessory generates UIL to implement the interface and C code to implement the application.

Builder Xcessory Main Windows

Once you select a language at the beginning of your session, Builder Xcessory's three main windows are displayed:

Builder Xcessory Main Windows

Using Builder Xcessory windows

The way you use these windows is described in the following sections. Typically, you will use them in the following sequence:

1. Select an object from the Palette and drag it to the desktop.

2. Modify the object with the Resource Editor.

3. Use the Browser window to test the modified object in Play Mode and generate code in your chosen default language.

Browser

Overview

The Browser ( Builder Xcessory Browser ) is your primary control window while you are building your interface. With the Browser menus you open and save interface files, customize your views of Builder Xcessory and your interface, interact with other tools in your development environment, control your code generation, access special Builder Xcessory managers, and access on-line help.

Builder Xcessory Browser

The Browser displays the logical structure of your interface. This parent-child hierarchy of UI objects is displayed as a tree showing parents on the left and children on the right. You have the choice of viewing the Instance hierarchy of your interface, or you can view the Class hierarchy, the structure of all the high-level UI objects that you've created or imported for your interface.

A Simple UI and Corresponding Browser Display Area shows a simple UI and the corresponding Browser display area:

A Simple UI and Corresponding Browser Display Area

In addition to viewing your UI elements, you can manipulate these abstract representations directly with the mouse, using the Browser as a construction area.

Refer to Browser for more detailed information about the Browser.

Browser Menus

File menu

Allows you to control your files by performing the following operations:

· Create new user interface files

· Open and save user interface files

· Read one user interface file into another

· Load and save high-level UI classes

· Generate source code for your interface

· Print your interface object hierarchy

From the File menu, you can also exit Builder Xcessory.

Edit menu

Allows you to manipulate the objects in your interface by performing the following operations:

· Cut, copy, paste, or delete an object

· Copy an object to the Palette

· Revert UI to previous saved state

· Raise and lower objects, both in terms of visibility on the screen, and in terms of position in your instance hierarchy

· Control the size and position of the UI objects, in particular alignment

· Create high-level classes from groups of your UI objects

· Designate a member of a class as the receptor for the class

View menu

Allows you to modify the appearance of the Browser by performing the following operations:

· Control the view of some complex UI objects (such as compound Motif widgets and menu structures)

· Select the parent of the currently selected widget

· Force any widget created later to become a child of the currently selected widget

· Force each selected widget to align itself with the underlying placement grid if it is moved or resized

· View or hide the message area, the search area, the Toolbar, and your high-level Class hierarchy

Project menu

Allows you to interact with the other tools in your development environment by performing the following operations:

· Put your interface in Play Mode to test its dynamic behavior

· Debug your interface code

· Build the application for which you are creating an interface

· Check a file in or out of your source control system

· Edit a file

Options menu

Allows you to customize the Builder Xcessory environment and behavior by performing the following operations:

· Choose a default programming language

· Set code generation behavior

· Control the Builder Xcessory user interface

· Control interaction with other development tools

· Customize GIL import options

Managers menu

Provides access to the Builder Xcessory managers, which help you organize and effectively use different elements of your project. You can access the following managers:

Manager

Description

Application

Create timer or work procedures for your application.

Styles

View and edit the hierarchy of styles in your project and apply styles to objects.

Constants

Define or modify constants.

Procedures

Create, edit, and delete elements of callback and creation routines.

Identifiers

Define, view, and manipulate identifiers available in your project.

Types

Define, view, and manipulate parameter types available in your project.

UIL files

View and manipulate UIL output files for your project.

Windows menu

Helps you manage your entire work area by performing the following operations:

· Iconify or deiconify all windows (Builder Xcessory and your UI)

· Raise any of the Builder Xcessory windows to the top of your desktop

Help menu

Provides access to the online, hypertext help system, as well as version and copyright information.

MB3 Quick Access menu

Invoked by pressing MB3 while the mouse pointer is over a UI object, or its representation in the Browser window. This menu contains actions appropriate to the item under the mouse. You can apply all the items from the Browser Edit menu and also perform the following actions:

· Add an object from the Palette

· Select the parent of the current widget

Toolbar

The Toolbar, optionally shown with the Browser View menu, allows you to place frequently used menu items within easy reach.

Adding an item to the Toolbar

To place an item on the Toolbar, hold the Shift key down while selecting the desired menu item.

Removing an item from the Toolbar

To remove an item from the Toolbar, hold the Shift key down while selecting the desired Toolbar item.

Message Area

The Message Area, optionally shown with the Browser View menu, displays status and error messages from Builder Xcessory. The types of messages you can expect include confirmation of file generation and reports of attempted illegal user operations.

Interface Hierarchy

Display area and Instances/ Classes view combination box

The display area in the Builder Xcessory Browser allows you to view your interface hierarchy and to manipulate that hierarchy. Depending on the view selected with the Instances/Classes view combination box on the left of the Browser, you can view and manipulate the instance or class hierarchy of your interface.

Panner

Navigate through the display area with the Panner, located in the upper left- hand corner of the Browser. The Panner functions as a two-dimensional scrollbar.

Top-Level Object List

The Top-Level Object List at the left of the Browser permits you to view or hide both an interface window and its Browser representation by clicking on the object name with MB1 to select or deselect it.

Collapsing/ expanding sections of display area

To collapse or expand a section of your instance or class tree in the display area, with the corresponding interface window visible and available for work, click on the folder icon at the desired node of the tree.

Instances view

When the Browser is in Instances view (default), the display area shows the instance hierarchy of your interface, that is, the parent-child relationships of all the UI objects in your interface. You can work directly with the UI objects in their respective windows, or you can work with their representations in the display area by performing the following operations:

· Drag objects from the Palette and drop them directly onto the display representations

· Drag a display representation from one position to another, reparenting that object

· Drag objects between their respective windows and the display area

· Edit objects using the Browser Edit menu or the MB3 Quick Access menu

Classes view

When the Browser is in Classes view, the display area shows the contents of each of the high-level objects, or classes, that you have built or imported and are using. Only in this view can you edit a class after it has been initially built. In Classes view you have the same drag and drop capabilities as you have in Instance view.

For more information on classes, see Classes and Methods .

Selecting and Deselecting Objects

When working with UI objects, Builder Xcessory maintains the notion of selected objects. In your interface window, the border of the selected object is darkened and divided into corners and edges, making resize operations easier. In the display area, the pushbutton representation of the object appears to be depressed.

Selecting objects

Use one of the following methods to select an object, or objects:

· Click directly on the object or its display area representation.

· In the Browser Search/Select area, select Instance or Class from the option menu, then enter an instance or class name. Press the return key when you finish typing. You can type in a partial instance or class name to match multiple objects, or just to save time. All objects matching your entry are selected. To select one object, scroll through the possible matches by using the arrow buttons until the appropriate object is selected.


Hint: You can type any portion of the instance or class name into the Search/Select area. (The search is not case sensitive.) For example, typing "iew" would match all objects with "View" in their name. This is very helpful when you are not sure of a precise object name, or when you are selecting multiple objects with similar names.

· Hold down Ctrl and click on each interface object or representation. With Ctrl held down, each object you click on is added to the set of selected objects. This works in your interface windows and in the display area.

· Hold down Shift and MB1 and drag the cursor to draw a square around the objects (or their representations). Release MB1 and Shift. All objects entirely within the square are selected. This technique is referred to as " rubber-banding". This works in your interface windows and in the display area.

· Hold down Shift and click on a display area representation. This selects the object and all of its descendants in the instance hierarchy. This works only in the display area.


Note: Choose Select Parent from the Browser View menu or the MB3 Quick Access menu to select the parent of the currently selected object. This capability can be useful when the parent is not visible.

Deselecting multiple objects

To deselect multiple objects, use one of the following methods:

· Click anywhere on any unselected object or representation. All other objects are deselected.

· Hold down Shift and click on a selected display area representation. The object and all objects descending from it are deselected. This works only in the display area.

Deselecting one object within a group

To deselect one object within a group of selected objects, hold down Ctrl and click on that object. The other selected objects remain selected.

Palette

Palette object icons

The Palette displays labeled, iconic representations of the UI objects with which you build your interface. Depending upon the currently selected language and the platform on which you are running Builder Xcessory, the Palette icons correspond to the following objects:

· Motif Xm widgets

· ViewKit ObjectPak Vk objects

· EnhancementPak Xi widgets

· Java AWT objects

· DEC Dxm widgets (available only on DEC UNIX platforms)

· SGI Sgm widgets (available only on SGI platforms)

· Common Desktop Environment (CDE) Dt widgets (available only on platforms with CDE and BX CDE support)

The Palette also includes collections of objects and classes that you build, as well as any third-party or platform-specific widgets or classes you add to Builder Xcessory.

For more information about the Palette, refer to Palette . For more detailed information about the Palette objects, refer to Palette Objects .

EPak widgets

To include EnhancementPak widgets on the Palette, use the Start with EPak Widgets toggle button on the User Preferences dialog of the Browser Options menu. For more detailed information, see Behavior toggle options .


Note: To compile an interface that uses EPak widgets, you must have the EnhancementPak library installed on your system. The EnhancementPak library is included with BX PRO.

ViewKit objects

The ViewKit ObjectPak objects are automatically included on the Palette when you select ViewKit as your default language. For more detailed information, see Choose A Language .


Note: TTo compile an interface that uses ViewKit objects, you must have ViewKit installed on your system. ViewKit is included with BX PRO.

Palette views

The Palette can be viewed in outline or tabbed form (Figures Builder Xcessory Palette (Outline View) and Builder Xcessory Palette (Tabbed View) ):

Builder Xcessory Palette (Outline View)

Builder Xcessory Palette (Tabbed View)

Palette Groups

On the Palette, UI objects are divided into groups. The groups and their contents vary depending upon the selected language. For a description of the standard Palette groups, see Palette Groups . For more detailed descriptions of each object on the Palette, refer toPalette Objects

Nesting groups

You can nest groups by creating a new group as part of another group. For example, create a "ViewKit' group and move all ViewKit-related groups into the "ViewKit" group. You can then hide all the ViewKit items by closing just the single group.

Hiding/
displaying groups

To hide a group, click on the folder icon to the left of the group name. Click again on the icon to restore the view of the group.

Creating a top-level group

To create a new top-level group, select New Group from the Palette Edit menu.

Creating subordinate groups

To create a new group subordinate to an existing group, select New Group from the Palette MB3 Quick Access menu.

Groups common to all Palettes

In addition to the platform- and language-dependent groups, the Palette displays the following groups:

· Project Classes

High-level UI objects you create or for a project when you open a project save file.

· Private Classes

High-level UI objects that are stored in the following directory:
${HOME}/.builderXcessory/classes directory
These objects appear each time you use Builder Xcessory.

· Public Classes

High-level objects that are stored in the following directory:
{BX}/XCESSORY /classes directory.
These objects appear on every Builder Xcessory user's Palette.

Palette Menus

Palette menu

Allows you to control the Palette's appearance by performing the following operations:

· Create a new Palette

· Show the Palette in full or reduced (tabbed) view

· Display the Palette icons with only pixmaps, only labels, or both

Catalog menu

Allows you to manipulate the Palette by performing the following operations:

· Create a new catalog

· Load an existing catalog

· Merge a catalog with the current catalog

· Save the current Palette catalog

· Save the Palette catalog to a different file

· Change the display name for the Palette

Edit menu

Allows you to rearrange the Palette by performing the following operations:

· Move objects from one group to another

· Change the order of the objects within a group

· Create a new group

MB3 Quick Access menu

Invoked by pressing MB3 while the mouse pointer is positioned over a Palette icon or a Palette group name. This menu provides many of the Edit menu functions. From the Quick Access menu you can perform the following operations:

· Move or delete the selected object(s)

· Create a new group

· Modify the properties of an object icon

Using the Palette

Builder Xcessory allows you to create, manipulate, and reuse different types of UI objects, including the following:

· Motif widgets and widget collections

· C++ Motif classes and subclasses

· ViewKit classes and subclasses

· Java AWT classes and subclasses

Creating Objects

Creating UI objects is the same for all object types. The following sections describe two methods for selecting an object from the Palette and placing the object in your interface.

Using MB1

1. With MB1, click on the desired object.

A rectangular outline of the object appears, indicating the size that the object will be when created.

2. Position the upper left-hand corner of the object where you want to place it, and click again with MB1.


Note: Instead of clicking, you can press MB1 and drag the lower right-hand corner of the rectangular outline to any size desired. Release MB1 and your object is created. Additionally, the Palette remembers the last size you choose, and uses that as the default size for that object for the remainder of your Builder Xcessory session. You can change the default size by repeating this procedure.

Using MB2

1. With MB2, drag the desired object out of the Palette.

2. Drop it at the location where you would like it to be created.

The object is created with the current default size (that you can reset, as described in Using MB1 ).

Canceling a create operation

To cancel a create operation, press the Escape (Esc) key.

Parents and Children

Creating child objects

As you build your interface, usually you create UI objects as children of other objects. To create objects as children of other objects, drag the child object over the object that is to become the parent. You can do this either on the actual object or in the Browser display area.

If the potential parent is not a legal parent, Builder Xcessory searches up the object hierarchy until a legal parent is found.

If there is no legal parent, or if you do not create the new object directly over an existing object, Builder Xcessory automatically creates the appropriate top-level object for you. This can be a Motif top-level shell, a dialog shell, etc.

Creating multiple children of a single parent

You can create more than one child for a single parent object by selecting the Keep Parent item on the Browser View menu. You can then create a series of child objects by double-clicking on the objects on the Palette. For more information on Keep Parent, see Using Keep Parent or "Keep Parent" on page 63 of the Builder Xcessory Reference Manual.


Note: When creating objects, you frequently place them as children of container, or geometry manager objects. These parents often control the size and position of their children. In many cases, notably with the Java containers, you cannot directly control the position or size of the new objects with the mouse. Instead you must edit attributes, or resources, of the objects involved, using the Resource Editor (see Resource Editor ).

Resource Editor

Overview

From the Resource Editor ( Builder Xcessory Resource Editor ), you view and edit the resources and attributes of currently selected UI object to control both the appearance and behavior of your application and its interface. You can edit attributes such as color, font, layout policy and object position, resize behavior, and application actions (callbacks, class methods, or both, depending on your choice of language). Changes made to your object attributes are immediately visible. Refer to Resource Editor for a complete description of the Resource Editor.


Note: In this manual, the term "resource" includes Java attributes.

Builder Xcessory Resource Editor

Resource Editor Menus

Component

Allows you to modify several basic characteristics of the selected object by performing the following operations:

· Set the default state of the selected objects to be visible or hidden

· With Motif, specify whether the selected object(s) should be created as a widget or as a gadget

· With C, specify a creation routine for the selected object and control the scope of the widget ID (local, global, or other).

View

Allows you to control the appearance of the Resource Editor by performing the following operations:

· Update the Edit/Display Area to show the resources for the currently selected object

· Show/hide the different areas of the Resource Editor

· Select the set of resources displayed by the Resource Editor

Options

The Options Menu allows you to perform the following operations:

· Control whether the Resource Editor automatically updates itself when a new object is selected, or waits for you to manually update it from the View menu or from a Toolbar button. Disabling automatic updates can save time on a slower computer system.


Hint: Double-clicking on an object or its Browser representation updates the Resource Editor.

· Arrange the resources in alphabetical order or according to type.

· With Motif, set the default resource placement (see Resource placement ) on a per resource-type basis. This allows you to automatically place all Color resources, for example, in an app-defaults file.

Toolbar

The Toolbar, optionally shown with the Resource Editor View menu, allows you to place frequently used menu items within easy reach.

Adding an item to the Toolbar

To place an item on the Toolbar, hold the Shift key down while selecting the desired menu item.

Removing an item from the Toolbar

To remove an item from the Toolbar, hold the Shift key down while selecting the desired Toolbar item.

Header Data

Instance Name

The Instance Name text field displays the instance name of the currently selected object. Type directly into the field to change the name. Builder Xcessory automatically assigns a default name to every object instance as it is created, typically a lower-case version of the class name appended with a number.


Note: You should assign your own instance name to every object in your interface. Not only does this simplify development documentation and application maintenance, but it guarantees that Builder Xcessory will not reassign and change the instance name during subsequent work sessions.

Class Name

The Class Name text field displays the class name of the currently selected object. You can edit this field to change the type of UI object. Builder Xcessory automatically checks to ensure that the new class exists and is allowed. For example, it does not allow you to change a container with children into an object that does not allow children.

Style

The Style text field displays the name of the style, if any, currently applied to the selected object(s). You can enter a style name into this field, applying the style to the currently selected UI object(s). A style is a collection of resource:value pairs that you create. Styles allow you to set resources on arbitrary groups of objects, and change all objects simultaneously by editing the style definition. Styles are created in parent-child relationships giving you considerable power and flexibility. The style manager is accessed with the Browser Managers menu. For more on styles, see Styles .

Interface File Menu

Builder Xcessory allows you to place UI objects, constants, resources, procedures and styles in different files. This feature is very useful when working with large projects, simplifying development and maintenance.

The Interface File menu in the upper right-hand corner of the Resource Editor allows you to select the file in which to save the object information. Select the proper file from the menu. Use the File Manager (Browser:Managers:UIL Files) to create new files and view and manipulate your existing file system. For more information, see UIL File Manager .

Edit/Display Area

Resources

This area displays the values of resources, which can be edited. The Resource Editor displays resource values for a single object, or for a group of objects. Next to the resource name is one of the following:

· Text field

· Pulldown menu

· Toggle buttons

To edit the resource value, type into the field, or select a value as appropriate. You can also set a resource value with a Builder Xcessory extended editor (see the section Extended editors ).


Note: When displaying values for a group of objects, Builder Xcessory adds a " !=" (not equal) symbol to every resource that differs among the objects in the selected group. Click on this symbol for a list of all the differing values for that resource.

Search area

To rapidly locate a particular resource, type a portion of the resource name into the search area at the base of the Resource Editor window. Pressing the Return key cycles through all of the resources that match your entry. You can also cycle through them by clicking on the arrow keys at the right-hand side of the search area.


Hint: Type any portion of the resource name into the search area. For example, typing " man" matches resources such asAutoUnmanage . This is very helpful when you are not sure of the precise resource name.

Extended editors

In addition to directly entering a resource value, Builder Xcessory has extended editors that provide additional ways of selecting a value. The editors are accessed by clicking the pushbutton labeled with an ellipsis (...), located to the right of the resource value. As long as an extended editor remains open, you can use it to change that resource on multiple objects without updating the Resource Editor. This makes it easy to set, for example, the label string on a number of different objects, even if they are of differing class types.

Refer to Extended Editors for more detailed information about the extended editors.

Resource placement

This option menu is located on the right side of the Edit/Display area. It allows you to use a constant, identifier, or expression as the resource value. It also allows you to reset the value to the object's default ( None ), to the Class default ( Class ), or to the Style default ( Style ). When creating or editing classes, this menu also allows you to specify a resource as eligible for modification on a per instance basis ( Expose ).

With Motif, this menu allows you to specify, on a per resource basis, whether to write the value to an X Resource file ( App ), or hardcode the value into your application ( Code ). You can also set the default placement on a per resource-type basis with the Resource Editor Options menu.

Using the Resource Editor

Customizing objects

When building a user interface with Builder Xcessory, you spend much of your time using the Resource Editor to customize your UI objects.

Changing default resource values

To change the default resource values for a Palette object:

1. Create an instance of the object.

2. Set the resource values to your desired defaults.

3. Drag the object instance, with MB2, back onto the Palette.

This object remains on the Palette for you to use in all of your Builder Xcessory sessions.

The three primary methods of setting resources are to set resources with the display area, the extended editors, and styles. Each has its own strengths for different situations.

Using the Resource Editor Edit/ Display area

Use the Resource Editor Edit/Display area under the following conditions:

· To quickly set simple resources on one or more selected objects.

· To set a value for a group of selected objects that currently have different values for a resource.

· When working with a group of resources, perhaps a customized list, accessed through the Resource Editor View menu.

Using the extended editors

Use the extended editors under the following conditions:

· When choosing a complex resource value such as an X11 font name,
or pixmap.

· When choosing from a known set of values such as predefined routines or object siblings.

· When setting differing values of a single resource on many objects.

Using styles

Use styles under the following conditions:

· When working with a style guide, or corporate "look and feel".

· When setting identical values of a resource on many objects.

· When working with a group of objects that should appear or behave similarly to each other.

Example: A Simple Color Selector

The following sections present two examples of a simple color selector. The first example uses Builder Xcessory to build a Motif application. The second uses Builder Xcessory to build a Java application ( Java Example ). The sequential steps are divided into labeled sections for your convenience. You can perform the steps in the order provided, or browse through the sections.

Motif Example

In this example, we'll construct a very simple color selector. The finished application will allow the user to choose a color and see it displayed. Additionally, we will include a simple dialog. A Simple Motif Color Selector shows the finished color selector:

A Simple Motif Color Selector

Project language

For this example, you can work with UIL, C, C++, or ViewKit as your project language.


Note: A Java example follows later in this chapter ( Java Example ).

Preparing for a Work Session

Starting Builder Xcessory

1. Start Builder Xcessory.

If you have been using Builder Xcessory, select New from the Browser File menu to begin a fresh session.

2. Select either UIL, C, C++, or ViewKit as your language from the Choose a Language dialog of the Browser Options menu.

The following discussion assumes that you have chosen standard (ANSI) C as your programming language. Significant differences for other languages are noted as appropriate.

Note: Complete code files for this example are available in the directory {BX}/xcessory/examples/UsersGuide/Chap1 on the BX PRO CD-ROM or from the ICS Website (http:://www.ics.com) for the following languages: C, C++, UIL, or ViewKit.

Creating Widgets

To create widgets, use the following procedure:

Creating a MainWindow

1. Create a MainWindow about three inches wide and two inches high.

Click on the MainWindow Palette icon with MB1. A widget outline appears. Move this to a convenient screen location and with MB1, drag the rectangle out to the desired size. (Refer to Using the Palette for review.)
If you are using ViewKit, create a VkWindow rather than a MainWindow. When prompted for a class name, enter "MainWindow". After creating the object, change to Classes view by clicking on the arrow button of the Instances/Classes view combination box and selecting Classes from the drop-down list.

Creating a MenuBar

2. Create a MenuBar and place it as a child of the MainWindow, using one of the following methods:

· Click on the MenuBar Palette icon and click again on top of the MainWindow.
· Drag the MenuBar Palette icon from the Palette and drop it on the MainWindow.
· Drag the MenuBar Palette icon from the Palette and drop it on the MainWindow instance representation in the Browser Display Area. (Refer to Display area and Instances/ Classes view combination box for review.)

Note: The MainWindow recognizes the MenuBar widget and automatically moves the MenuBar to the top of the window and resizes it to span the entire width of the MainWindow. Most widgets must be resized manually to fit the MainWindow.
Builder Xcessory automatically creates a MenuBar with many common menu entries when you create a VkWindow subclass. To keep the C and ViewKit interfaces parallel in this example, delete all of these items except the Help menu (helpPane). For the helpPane menu, delete all of its children except helpVersionMenuItem, which we will use later.

Creating a BulletinBoard

3. Create a BulletinBoard and place it as a child of the MainWindow, using one of the methods in the previous step. Resize the BulletinBoard as you place it, using one of the methods described in Creating Objects . The MainWindow automatically resizes itself to encompass the BulletinBoard.


Hint: The first time you create and place an object, it's usually best to resize it as you place it. Otherwise you are likely to end up with a widget that is too small to easily deal with. If this happens, select Enlarge from the Browser Edit menu, or from the MB3 Quick Access menu.

Creating a Scale

4. Create a Scale and place it as a child of the BulletinBoard.

Copying Widgets

1. Copy the Scale and paste two copies as Bulletin Board children, for a total of three scales. Use one of the following methods (check that Scale is currently selected, or select it by clicking on the Scale or its Browser representation):

· Select Copy from the Browser Edit menu. Then select Paste from the same menu. You are presented with an outline of the Scale. Place it into the BulletinBoard. Select Paste a second time and place the next scale into the BulletinBoard.
· Select Copy from the MB3 Quick Access menu by pressing MB3 while the cursor is over the Scale or its Browser representation. Then select Paste from the same menu. You are presented with an outline of the Scale. Place it into the BulletinBoard. Select Paste a second time and place the next Scale into the BulletinBoard.

Shortcut

· While holding down the Control key (Ctrl), drag the Scale with MB2 to another location in the BulletinBoard and drop it. Repeat to create the third Scale. You can also perform this Ctrl-MB2 drag operation with the Browser representations.

Hint: Be careful not to drop a new scale onto another scale. That creates the new scale as a child of the existing scale. If this happens, use MB2 (without Ctrl) to drag the new scale out and onto the BulletinBoard.

Creating a Drawing Area

2. Create a DrawingArea and place it as a child of the BulletinBoard.

This is the area in which the user will view the selected color. It should be about 1" wide and 1.5" high.

Your Interface in Progress shows the result of the preceding steps:

Your Interface in Progress

Setting Instance Names

Using your own instance names when working with Builder Xcessory is good practice. There's no guarantee that the default names will be maintained from session to session. (Besides, imagine sitting down to maintain your application months later and trying to figure out what pushButton73 is supposed to do...)

1. Assign instance names to the existing widgets.

To save time, we'll only assign names to widgets that will be directly referenced in our code.

2. Select each widget and enter the new name in the Instance Name field at the top of the Resource Editor. Use the following names:

scale -> redScale
scale1 -> greenScale
scale2 -> blueScale
drawingArea -> colorArea

Note: When generating C++ or ViewKit code, Builder Xcessory automatically prepends an underscore character to all instance names to construct the class data member used to store the object ID (following accepted convention). So the object named redScale is referenced as _redScale in all generated code.

Working with Multiple Widgets

Now that we have created the basic widgets, we'll begin customizing the widgets and designing the layout.

Setting Scale resources

First, we'll set a number of resources on the Scale widgets:

1. Select all of the scales, using one of the following methods:

· Select the first widget to ensure that no other widgets are accidentally included. Select the other widgets, each in turn, with Ctrl-MB1. You can perform this operation directly on your interface, or in the Browser by clicking on the instance representations.
· Using Shift-MB1, drag out a rectangle, enclosing all of the desired widgets. Any widget entirely within the rectangle is selected. You can circle the widgets directly, or you can circle their Browser representations.

2. Update the Resource Editor by selecting Update from the Resource Editor View menu, or from the Update toolbar icon.

3. Set the following resources (check that All Resources is selected from the Resource Editor View menu):

orientation: XmVERTICAL
We'll be using vertical scales.
maximum: 255
minimum: 0
value: 255
We'll start off at white.
showValue: True
This forces the scale to display its current value as a label
next to its scroll thumb.

Hint: Use the search area of the Resource Editor to quickly locate each of the resources. (See Search area for review.)

4. Set the following resource on the DrawingArea widget:

background: white
We want to ensure that all settings start out in synch,
so make the color display match the scale values.

Moving and Resizing Widgets

Now that we have the Scale widgets oriented properly, we'll work on the layout.

1. Move each of the Scale widgets and the DrawingArea to their intended positions (don't worry about exact positions, we'll use the Alignment Editor to fine-tune the layout).

To move one or more widgets, select the widget(s) and using MB1, position the cursor inside the border of the widget(s) and drag to the new position. During the drag operation, you are presented with a rectangular outline of the widget(s).

Hint: To move a manager and all of its children, select the container and its children, and drag with MB1.

2. Resize each of the Scales so they are the same width, and resize the Scales and the DrawingArea so that they are the same height.

First, select all of the Scales and set their widths. Next, add the DrawingArea to the group of selected widgets by clicking on it with Ctrl-MB1 and set the heights. You have a choice as to how to resize the widgets:
· Selected widgets have grey borders separated into sides and corners. Grab a section of the border with MB1 and drag to the desired size.

Hint: Increasing the size of the layout grid makes it easier to resize and align objects with the mouse. The default value is a 10-pixel resolution. (See Placing Objects with the Layout Grid for more information.)
· With all of the widgets selected, use the Resource Editor to set the width and height resources on the selected widgets. If you have one widget width or height already correct, you can click on the "!=" symbol to the left of the resource to display a list of values for the selected widgets. You can then select a value from the list and apply it to the entire group of widgets.

Using the Alignment Editor

3. Use the Alignment Editor to align and distribute the widgets.

Bring up the Alignment Editor (Browser:Edit:Align:Alignment Editor) and set the following values:
Align: Left/Right: As Is
Align: Top/Bottom: Top
Distribute: Horizontal: Edge Gap: 10 pixels
Distribute: Vertical: As Is
With all the widgets still selected, you can now move them as a group into an attractive position, resizing the top-level shell as necessary by using your normal window manager controls.

Your Interface in Progress shows the result of the preceding steps:

Your Interface in Progress

Adding Action to Your Interface

In this section, we add callbacks to various widgets so that when the user adjusts the scales, something actually happens. We will deal with X color capabilities. If you are not familiar with color manipulation in X, consult your Xlib or Motif programming manuals.

Looking ahead, we will need to access the widget IDs for the Scales and the DrawingArea. We'll do this using one method for UIL and C, and using a different method for C++.

Making object IDs accessible

You can make the necessary object IDs accessible using one of the following methods:


Note: The example code for this example uses the third method below, so you should not take any action at this time.

· Global Storage

Select the widgets, then select the Storage Location option from the Resource Editor Code menu. Choose Global from the dialog that appears, and apply and dismiss the dialog by selecting the OK button.

Note: This method is not recommended. As a general rule, avoid global variables in your code.

· Other Storage

With most applications, instead of declaring a large number of widgets globally, you typically create your own structure with which to keep track of global data. In these cases, you would select Other as a storage location. See Storage Location for more information.

· Local Storage

In many cases, you can retrieve widget IDs dynamically by using the intrinsics function XtNameToWidget. The C code for this example uses this method rather than creating global variables.
With C++, we can get to the widget instances very easily. In C++, all widget instances are automatically declared as protected members of the class and are thus accessible from class instances.

Creating an application as a single class

For simplicity's sake, we will create our example application as a single class, as follows:

1. Select the MainWindow widget.

2. Using either the MB3 Quick Access menu or the Browser Edit menu, choose Make Class.

3. When prompted for the class name, enter "MainWindow".

4. Once you have created your class, change to Classes view by selecting Classes from the Instances/Classes view combination box on the left side of the Browser.

We need to keep track of two pieces of data, the colormap and the colormap entry index. We use a variable of type Pixel that we call _ pixelVal and a variable of type Colormap called _cmap , and declare them as private member variables in our class. We can declare this with Builder Xcessory, using the Resource Editor, or by adding it directly to the right header file. Because discussion of class creation and manipulation is covered later in this manual ( Classes and Methods ), we will add this directly to the .h file later in the example.

Note: To access widget instances from outside a class, add a public method to the class definition. See Adding Methods and Data Members for more information.

Working with Callbacks

Now we'll set up a number of callbacks and use some Builder Xcessory editors to complete them.

1. Set the following resources on all of the Scale widgets.

dragCallback: setColorCallback()
valueChangedCallback: setColorCallback()
Any time the scale widgets' values have changed, 
we want to set the color on the Drawing Area.
When you set the valueChangedCallback, rather than typing the procedure name directly into the Resource Editor, use the extended editor (click with MB1 on the button labeled ". . ." to the right of the resource input field). Enter setColorCallback into the Procedure Name field of the extended editor. The procedure appears in the Callback List at the top of the Callback Editor. Use the Apply button to apply this to the Scale widgets.

2. Add the code for the setColorCallback procedure using one of the following methods:


Note: The example file callbacks-c.c contains all the code for setColorCallback.

Note: In order to add code to a file, the file must exist. Builder Xcessory automatically generates code when you edit a callback from the Callback Editor. It's a good habit to be sure that you are in the correct working directory so that your files will be in the right place. Use the Filenames tab in the Code Generation Preferences dialog (Browser:Options: Code Generation Preferences) to set your working directory. Performing a Save, Save As, or Open operation (Browser:File) also sets your working directory.

Callback Editor

· Write the setColorCallback code using the Builder Xcessory Callback Editor. Bring this up by clicking on the Edit button to the right of the Callback List in the extended editor. This starts the configured editor with the correct file loaded in at the appropriate User Code Block.

If this is your first time using the Callback Edit feature, you must specify an editor to use, such as emacs or vi. You can do this without dismissing the Callback Editor. Choose an editor from the Options menu (Browser:Options:Tools Preferences:Editor). SeeUsing emacsclient for more information on Emacs.

Generating code

· Add your callback code by generating code (Browser:File:Generate) and editing the appropriate file from outside the scope of Builder Xcessory.

User Code Blocks

In either case, you insert code into a User Code Block. User Code Blocks are present in many different locations in all Builder Xcessory-generated files. Any code that you insert into a User Code Block is preserved by Builder Xcessory whenever source code is generated.

Note: If you add code to any of the files outside of these User Code Blocks, it will be lost when you generate new versions of these files with Builder Xcessory.

Note: When generating C code, the file callbacks-c.c is not generated with User Code Blocks. Instead, this file is scanned each time code is generated and any new functions are appended to it. For this reason, you can make any changes you want to the file without losing them at the next code generation.

The function setColorCallback performs the following operations:

· Accesses the widget to determine current settings
· Allocates a color cell the first time it is called (we will keep this color cell and reuse it later)
· Gets/sets values from the Scale widgets

The first two operations vary slightly from language to language, but the final operation is the same for all languages.

Here is the code for the final step of the setColorCallback procedure:

XtVaGetValues(redScale, XmNvalue, &redVal, NULL);
XtVaGetValues(greenScale, XmNvalue, &greenVal, NULL);
XtVaGetValues(blueScale, XmNvalue, &blueVal, NULL);
col.red = redVal << 8;
col.blue = blueVal << 8;
col.green = greenVal << 8;
col.pixel = pixelVal;
col.flags = DoRed | DoGreen | DoBlue;
XStoreColor(XtDisplay(w), cmap, &col);
XtVaSetValues(colorArea, XmNbackground, pixelVal, NULL);

For C++ code, you must edit the file <classname>.C . In our example, this is MainWindow.C .

We mentioned earlier that we would be using variables of type Colormap and Pixel to store the currently selected color. Place the following code in the private User Code Block in the MainWindow.h file.

// Begin user code block <private>
Pixel _pixelVal;
Colormap _cmap;
// End user code block <private>

Note: Builder Xcessory makes it easy to specify public/protected/private member data using the Resource Editor, rather than directly editing the header files. See Adding Methods and Data Members for more information.

In addition to modifying the callback code, we'll need to initialize the colormap and color cell:

In C++, we'll use the User Code Block at the end of the create routine.

In C, we'll do the initialization in the callback, but protected such that the code is only executed once.

In all cases, the code to initialize the colormap and color cell looks like the following:

XtVaGetValues(_colorArea, XmNcolormap, &_cmap, NULL);
XAllocColorCells(XtDisplay(_colorArea), _cmap, False,
NULL, 0, &_pixelVal, 1);

Working with Menus

Now that we have taken care of the basics of our application, we'll fill in the gaps by adding menus and a simple dialog window.

1. Create a File menu.

Drag a PulldownMenu onto the MenuBar in your MainWindow. Builder Xcessory automatically creates a CascadeButton, aPulldownMenu, and n PushButton (a single menu item).
Use a VkSubMenu if you are generating ViewKit code.

2. Set the following resources on the CascadeButton (VkSubMenu):

instance name: fileCascade
labelString: File
mnemonic: F

3. Set the following resources on the PushButton (VkMenuAction) menu item:

instance name: exitButton
labelString: Exit

Note: When you select the CascadeButton, all menu items are displayed in your interface. You can control this display by turning Show Menu Children (Browser:View) on or off while the CascadeButton is selected. With the menu items posted, you can select any number of them in the usual manner.
For the next resource, use the extended editor to bring up the Callback Editor.
activateCallback: BxExitCB(0)
In the extended editor, click on the combination box arrow for the Procedure Name. This drops down a list of predefined callbacks and procedures. From this list, select BxExitCB(). In the Parameter Name field, enter 0. For a description of all the Builder Xcessory predefined callbacks, see Predefined Callbacks . You can also add your own procedures to this list. For more information on this process, see See Adding Predefined Callbacks .
Apply this callback with the Apply button.

4. Create a Help menu and apply the following resources to the Cascade:

instance name: helpCascade
labelString: Help
mnemonic: H
To move the Help menu to the right, set the following resource on the MenuBar:
menuHelpWidget: helpCascade

This step is unnecessary with ViewKit. The Help menu is automatically created and placed by the VkWindow class.

5. Set the following resources on the PushButton (VkMenuAction) menu item:

instance name: aboutButton
labelString: About...
activateCallback: BxManageCB("aboutBulletin")
Another one of the built-in callbacks. This one "takes"
a string (a widget instance name), and generates a 
function that manages the widget. Notice that the
generated function actually uses a widget ID, not a string.
We'll create the aboutBulletin widget later.

Do not add the callback or change the instance name in ViewKit; change only the labelString.

Working with Dialogs

1. Create a BulletinBoard as a child of a DialogShell, in turn a child of your MainWindow.

To create a widget as a child of a DialogShell, click on a Palette icon (BulletinBoard, in this case), but rather than placing it by clicking again with MB1, click (and optionally drag to desired size) with MB3. Create this as a child of your MainWindow by locating the cursor over the parent (your MainWindow) when placing with MB3.
You can control the type of Motif Shell created at any given time with the Shells options (Browser:Options:User Preferences:Shells). For more information, see Shells .
Creating dialogs in ViewKit is a different procedure. You must create a subclass of VkGenericDialog by dragging out the VkGenericDialog object from the Palette. When prompted for the class name, enter "AboutBulletin".

2. Set the following resource on the BulletinBoard:

instance name: aboutBulletin
Create an instance of your AboutBulletin class as a child of the VkWindow. Resize the AboutBulletin if necessary, so that it is about 2" wide by 1.5" high.

3. Create a Label as a child of the BulletinBoard (genericDialog) and set the following resources:

labelString: Motif Color Editor
Version 1.0, Created by <your name>
Use the labelString extended editor to create a multiline label.
alignment: center
recomputeSize: true
We want the widget to resize itself to hold the labelString.

4. Create a PushButton as a child of the BulletinBoard and set the following resources:

instance name: okButton
labelString: OK
recomputeSize: true
We want the widget to resize itself to hold the labelString.
activateCallback: BxManageCB("aboutBulletin")
Just like the menu item that popped it up, this uses a built-in callback that unmanages ("pops down") the dialog's shell.

Skip this step for ViewKit. The dialog classes will handle all this automatically. We will connect this dialog to the Help menu item using VkApp::setAboutDialog(). Add this code to the <endcreate> User Code Block of MainWindow.C:

theApplication->setAboutDialog(_aboutBulletin);
Additionally, add the following lines to the <constructor> User Code Block of AboutBulletin.C:
_showCancel=False;
_showApply=False;
_allowMultipleDialogs=False;
No other changes are necessary to display the aboutBulletin.

5. Resize and position the Dialog and its contents to create an attractive window.

Your Interface in Progress shows the result of adding the menus and Dialog:

Your Interface in Progress

Depending on the project language you are using, the object instance hierarchy shown on your Browser display should look likeYour Interface in Browser Display (Using C) or Your Interface in Browser Display (Using ViewKit) .

Your Interface in Browser Display (Using C)

Your Interface in Browser Display (Using ViewKit)

Testing Your Application

We've now reached a point where we would like to test our application and its interface.

Saving the interface

1. Save the interface.(Browser:File).

The first time you save a new project, you'll be presented with a Motif file selection dialog. To change filenames for subsequent save or generate code operations, use the Save As option (Browser:File). Open, Save, Save As, and Generate Code operations all set your working directory for subsequent save and generate operations.

Play Mode

2. Enter Play Mode (Browser:Project) and test your interface.

In Play Mode, you can try out your interface. Click the OK button on the About dialog to dismiss the dialog. (Select Help:About from your application.) The dialog you created should reappear. Test the Scales; you'll see the result of the showValue resource. The labels should change as you move the sliders. Notice, however, the color of the DrawingArea did not change. In Play Mode, all predefined callbacks are active, hence the dialog behavior. Callbacks you've written, however, are not active.
Because the connection between the menu item and dialog is made in User Code Blocks, the dialog does not display in Play Mode.

Testing callbacks

To test callbacks, use one of the following methods:
· Generate Code (Browser:File), compile, link, and run. Using the UNIX command line is still the preferred method for many developers. Builder Xcessory generates both Imake and Makefiles for you.
See Working with Source Code for more information.
· Use an integrated environment (such as WorkShop, Developer Magic, FUSE, etc.).
Make Application (Browser:Project) sends a message to your environment's build tool to have it build your application.
Debug Mode (Browser:Project) runs your application through your environment's interpreter. This has the advantage of providing you with a full debugging environment for the code you've written.
See Integrating Builder Xcessory with Your Environment for more information on integrating Builder Xcessory with other tools.

3. When you are finished testing, re-enter Build Mode (Browser:Project).

Creating a Uniform Look and Feel for Your Application

There are many attributes, such as colors, fonts, and so forth, that contribute to an application's personality, or look and feel. Builder Xcessory helps you to define a total look and feel by building style sheets that can be reused and shared with other developers. You can use system styles to help all of your developers conform to a corporate style guide, clearly identifying all of your applications as part of a single family, and reducing the learning curve for your end-users.

A Builder Xcessory style is basically a collection of resource:value pairs that you define. Styles are related to one another as parents and children. Substyles inherit the resource values of their ancestors while overriding any ancestral values that are specifically re-defined in the substyle.

In this section, we'll build a very simple set of styles for your color selector.

Bringing up the Style Manager

1. Bring up the Style Manager (Browser:Managers:Styles).

In the Style Manager you see a style named "BaseStyle". This is the root style and serves as a placeholder. Notice the padlock symbol next to the name. This style, and any style with the padlock symbol, including system styles you create, cannot be edited.

Creating a new style

2. Create a new style.

Select Create Substyle from the Style Manager:Edit menu. This creates a new style as a child of the currently selected style, in this case as a child of BaseStyle.

Note: Just as with other UI objects, styles can be cut and copied or manipulated with the mouse, including all drag and drop operations, reparenting, and so forth.

Defining a new style

3. Define the new style.

Select the style (BaseStyle1). Select Edit Substyle from the Style Manager:Edit menu to bring up the Style Editor. You can also double-click on the style to invoke the Style Editor.

Creating a list of resources

First create a list of the resources you want to define in this style, using one of the following methods:
· Click on the Resources combination box arrow. This drops down a scrollable list of all available resources. Click on one or more resources to select them. You can deselect a resource by clicking on it a second time. When satisfied, click again on the combination box arrow.
· Type the resource names into the Resources combination box text field, separating multiple resources with commas. Enter Return to terminate the list.
Your selected resources appear below the combination box, where you can set their values just as you would in the Resource Editor.

You can add or delete resources from a style at any time. This affects all objects using the style.

Adding resources

Add the following resource:value pairs to the style:
background: blue
foreground: yellow
fontList:-*-helvetica-bold-r-*-*-*-100-*-*-*-*-iso8859-1
It's easiest to use the extended editor to select the font.
The font above is Helvetica, bold, 10 point. Choose any values you prefer.
See Extended Editors for more information.

Applying new definitions

Use the Apply button in the Style Editor to set the style definition.

Applying a style to an entire interface

4. Apply the style to your entire interface, preserving the background value of the DrawingArea widget.

You can apply a style to part, or all, of your interface by using one of the following methods:
· Select Apply from the Style Manager to apply the selected style to the selected object or to the selected object and all of its descendants. Force overrides any resource values already set on the affected objects. Otherwise, the resource values are preserved. Don't force the style in this case to maintain the white background of the Drawing Area.
· Dragging a style onto an object or its Browser representation with MB2 forces the style to the object, overriding any duplicated resource values.
· Dragging a style onto an object or its Browser representation with Ctrl-MB2 forces the style to the widget and all of its descendants, overriding any duplicated resource values.
· Selecting any group of widgets and entering the style name into the Style field of the Resource Editor applies the style to all of the selected widgets, preserving any resource values already set.

Note: Styles applied to classes while in Instances view are ignored. To apply a style to a class, you must be in Classes view.

5. Create a second style as a child of BaseStyle1 (the style we've created above).

Select the intended parent style, then select Create Substyle from the Edit menu of the Style Manager.

6. Add the following resource:value pairs to the style:

foreground: red
fontList: -*-times-bold-r-*-*-*-100-*-*-*-*-iso8859-1
It's easiest to use the extended editor to select the font.
The font above is Times, bold, 10 point.

7. Apply (force) this style to your DialogShell and its children.

Your new style has inherited the blue background from its parent.

8. Edit the first style you created (BaseStyle1), changing the value of the following resource:

background: black
Apply the change in the Style Editor. Note that each widget using that style immediately reflects the change and that each widget using a descendant of this style (including your dialog) also reflects the change.

For more information about styles, including the creation of system styles, refer to Styles .

Working with Source Code

You can generate source code and run your application at any point in the development process.


Note: Builder Xcessory always generates code that compiles and runs, generating stubs where your routines will placed. However, if you have begun adding incomplete routines such as callbacks, methods, and so forth, they may prevent your application from executing.

Creating source code

To create source code with Builder Xcessory, perform the following steps:

1. Customize your makefile to use your compiler of choice and reflect the library locations of your system (Browser:Options:Code Generation Preferences).

Be sure that your working directory is set correctly with the File Names tab sheet in the dialog. Use the Makefile tab panel to set up your makefile (specify your compiler, library locations, and so on).
You can also add your own include information, customize filenames, and turn on and off generation of any particular file.
See Code Generation Preferences for more information on these dialogs.

2. Generate source code (Browser:File:Generate).

3. Build and run your application.

You can build your application by using one of the following methods:
· Use the Make Application item on the Browser:Project menu. This sends a message to your environment's build tool (WorkShop, Developer Magic, FUSE, etc.) to have it build your application.
· Use the Make or Imake files that Builder Xcessory creates in your normal build process.

You can now run your color selector. This concludes our Motif example.

Additional work

Feel free to continue to explore Builder Xcessory's capabilities. Some ideas for additional work include:

· Experiment with Resource Placement in the Resource Editor and with your styles. With an app-defaults file, your end-user can change various attributes at start-up time with customized resource files, or with the X Toolkit command line options. See Resource placement and Resource Settings for a Widget Instance .

· Experiment with some advanced geometry management. Use the Resource Editor `Class Name' field and change the BulletinBoard to a Form. Edit the Constraint Resources of the Form's children with the Resource Editor to control the application's resize behavior. See XmForm for more information on the Form.

· Place the color sliders into a RowColumn widget. Drag the RowColumn along with its children to the Palette. Reuse the collection in another interface.

· Add mnemonics to the menus and test them in Play Mode.

· Do the tutorials in Appendix C Tutorials .

· Refer to the examples on the BX PRO CD-ROM in the directory {BX}/xcessory/examples/UsersGuide/Chap1 or the ICS Website (http:://www.ics.com) for samples of different programming languages.

Java Example

In this example, we will work with Java to construct a very simple color selector. The finished application will allow the user to choose a color and see it displayed. Additionally, we will include a simple dialog. The finished JAVA color selector is shown in A Simple Java Color Selector .

You have a choice of creating a program that runs as a Java Application, or as an Applet. You can make this choice at any time during the development cycle, and you can easily change your mind at any time as well.


Note: We will postpone work with the Abstract Window Toolkit (AWT) advanced layout classes, and classes in general, until later in this guide ( Classes and Methods and Java Layouts ).

A Simple Java Color Selector

Preparing for a Work Session

Starting Builder Xcessory

1. Start Builder Xcessory.

If you have been using Builder Xcessory, select New from the Browser File menu to begin a fresh session.

2. Select Java as your language from the Choose a Language dialog of the Browser Options menu.

Applets and Applications

1. Create your main window about three inches wide and two inches high.

You have a choice of creating a Java Application or Applet. To create an Application, use a Frame. To create an Applet, use the Applet. We'll be building a menu system in this example, so create a Frame.

2. Click on the Frame Palette icon. You are presented with a rectangular outline of the object. Move this to a convenient screen location and with MB1, drag the rectangle out to the desired size. (See Using the Palette for review.)


Note: From this point forward, we will refer to your top-level object, in this case, a Frame, as your "main window."

Creating Objects

1. Create a MenuBar and place it as a child of the main window, using one of the following methods:

· Click on the MenuBar Palette icon and click again on top of the main window.
· Drag the MenuBar Palette icon from the Palette and drop it on the main window.
· Drag the MenuBar Palette icon from the Palette and drop it on the main window instance representation in the Browser display area. (See Display area and Instances/ Classes view combination box for review.)

Note: The AWT Frame is the only container that accepts a Menu Bar as a child. It "knows" about MenuBar objects and automatically moves the MenuBar to the top of the window and resizes it to span the entire width of the container.

2. Create a Label and place it as a child of the main window.


Note: The first time you create and place an object, it is usually best to resize it as you place it. Otherwise you are likely to end up with a widget that is too small to easily deal with. If this happens, select Enlarge from the Browser:Edit menu, or from the MB3 Quick Access menu.

3. Create a Scrollbar and place it as a child of the main window.

Selecting Multiple Objects

Select both the Label and the Scrollbar in preparation for copying, using one of the following methods:

· Select the first object normally to ensure that no other objects are accidentally included. Select the other objects, each in turn, with Ctrl-MB1. You can perform this operation directly on your interface, or in the Browser clicking on the instance representations.

· Using Shift-MB1, drag out a rectangle, enclosing all of the desired objects. Any object entirely within the rectangle is selected. You can circle the objects directly, or you can circle their Browser representations.

Copying Objects

1. Copy the Label and Scrollbar, and paste two copies as main window children, for a total of three Label/Scrollbar groups. Use one of the following methods (check that both objects are currently selected, or select them by clicking on the objects or their Browser representations):

· Select Copy from the Browser Edit menu. Then select Paste from the same menu. You are presented with an outline of the object. Place it into the main window. Select Paste a second time and place the next object into the main window.
· Select Copy from the MB3 Quick Access menu by pressing MB3 while the cursor is over any of the objects or its Browser representation. Then select Paste from the same menu. You are presented with an outline of the object. Place it into the main window. Select Paste a second time and place the next object group into the main window.

Shortcut

· While holding down the Control-key, drag the objects with MB2 to another location in the main window and drop them. Repeat to create the third group. You can also perform this Ctrl-MB2 drag operation with the Browser representations.

Hint: Be careful not to drop a new scale onto another scale. That creates the new scale as a child of the existing scale. If this happens, use MB2 (without Ctrl) to drag the new scale out and onto the BulletinBoard.

Creating a Canvas

2. Create a Canvas and place it as a child of the main window.

This is the area in which the user will view the selected color. It should be about 1" wide and 1.5" high.

Your Interface in Progress shows the result of the preceding steps:

Your Interface in Progress

Setting Instance Names

Using your own instance names when working with Builder Xcessory is good practice. There's no guarantee that the default names will be maintained from session to session. (Besides, imagine sitting down to maintain your application months later and trying to figure out what pushButton73 is supposed to do...)

1. Assign instance names to the existing objects.

To save time, we'll only assign names to objects that are directly referenced in our code.

2. Select each object and enter the new name in the Instance Name field at the top of the Resource Editor. Use the following names:

label -> redLabel
label1 -> greenLabel
label2 -> blueLabel
scrollbar -> redScrollbar
scrollbar1 -> greenScrollbar
scrollbar2 -> blueScrollbar
canvas -> colorArea

Note: When generating Java source code, Builder Xcessory automatically prepends an underscore character to all instance names (following accepted convention). So redLabel appears as _redLabel in all generated code.

Working with Multiple Objects

Now that we have created the basic objects, we'll begin customizing them and designing the layout.

Setting resources

We'll begin this stage by setting a number of resources.

1. Select all of the Scrollbars using one of the following methods:

· Select the first object normally to ensure that no other objects are accidentally included. Select the other objects, each in turn, with Ctrl-MB1. You can perform this operation directly on your interface, or in the Browser by clicking on the instance representations.
· Using Shift-MB1, drag out a rectangle, enclosing all of the desired objects. Any object entirely within the rectangle is selected. You can circle the objects directly, or you can circle their Browser representations.

2. Update the Resource Editor using one of the following methods:

· Select Update from the Resource Editor View menu.
· Click on the Update toolbar icon.
· Double-click on the selected object or its Browser representation.

3. Set the following resources (check that All Resources is selected from the Resource Editor View menu):

maximum: 255
minimum: 0
Java deals with 8 bits of precision in each color, thus the range of 0 - 255
value: 255
We'll start off at white.
increment: 1
The increment value represents how much the scrollbar's value is changed when its end is clicked once. It represents the minimum change that can be made to the value. Here, and in most cases, we want this to be 1.
visible: 1
The visible value represents the "page size" of the scrollbar, or how much of the minimum-maximum range is represented by the visible area of the scrollbar. It controls the size of the scrollbar thumb. Here, where we are using the scrollbars to control single values, and not a scrolled area, the visible resource is not particularly meaningful. Setting it to one insures that the scrollbar thumb is as small as possible.

Hint: Use the search area of the Resource Editor to quickly locate each of the resources. (See Search area for review.)

4. Set the following resources on all the Labels:

label: 255
The label resource should match the value of the scrollbars at start-up.

5. Set the following resources on the Canvas:

background: white
We want to make sure all the settings start out in synch, so make the color display match the scale values.
height: 150
weight: 150
Canvas components have no default size, so we set a value here so the layout manager knows how much space to allow.

Java Layouts

Now we'll work on the layout. Java layout objects can be fairly complex to use. Builder Xcessory simplifies this by hiding the actual layout objects from you during the Builder Xcessory session. To specify a layout, you set an attribute on the container using the Resource Editor. For layout policies that allow you to specify positions for the container's children, you set constraint resources on each child using the Resource Editor. Builder Xcessory takes care of synthesizing this information and creating the proper layout and constraint objects for you. For discussion of the various layouts and how to use them, see Java Layouts .

Flow Layout

In our example, we will use the simplest layout, the Flow Layout. This allows our main window to manage each of its children into rows. Each child keeping its preferred size.

1. Set the following resource on your main window (Frame):

layout: FlowLayout

At this point, you'll notice that Builder Xcessory immediately applies the new layout policy to your interface. You can see that the labels, scrollbars, and canvas have all been placed into a row. You'll also notice that you cannot move or resize the children. This is because Java layout objects, for the most part, do not permit resizing.

Working with the Flow Layout

Your labels and scrollbars may not be in the proper order. The FlowLayout object manages its children in the order that they are created, from left to right, one row at a time. To change the order of creation, select an object and use one of the following methods:

· Use the Raise and Lower options from the Browser:Edit menu.

· Use the Raise and Lower options from the MB3 Quick Access menu.

Your Interface in Progress shows the result of the preceding steps:

Your Interface in Progress

Adding Action to your Interface

In this section, we add methods to various objects so that when the user adjusts the scrollbars, something actually happens. Some methods we will write, others are already part of the AWT classes.

1. Set the following resources on all of the Scrollbars.

scrollAbsolute: setColor()
scrollLineDown: setColor()
scrollLineUp: setColor()
scrollPageDown: setColor()
scrollPageUp: setColor()
An AdjustmentEvent argument is added automatically to the setColor() function when the code is generated.
For the last value that you set, use the Builder Xcessory extended editor, invoked by clicking on the button labelled... to the right of the resource field in the Resource Editor. We will use this editor in the next step.

2. Add the code for the setColor method using one of the following methods:


Note: In order to add code to a file, the file must exist. Builder Xcessory automatically generates code when you bring up the Method (or Callback) Editor. It's a good habit to be sure that you are in the correct working directory so that your files will be in the right place. Use the File Names tab panel (Browser:Options:Code Generation Preferences) to set your working directory. Performing a Save, Save As, or Open operation (Browser:File) also sets your working directory.

Callback Editor

· Write the setColor code using the Builder Xcessory Callback Editor. Bring this up by clicking on the Edit button to the right of the method name in the extended editor. This starts up the configured editor with the correct file loaded in at the appropriate User Code Block.

If this is your first time using the Callback Edit feature, you must specify an editor to use, such as emacs or vi. You can do this without dismissing the Callback Editor. Choose an editor from the Options menu (Browser:Options:Tools Preferences:Editor). See Using emacsclient for information on Emacs.

Generating code

· Add your callback code by generating code (Browser:File:Generate) and editing the appropriate file from outside the scope of Builder Xcessory.

User code blocks

In either case, you insert code into a User Code Block. User Code Blocks are present in many different locations in all Builder Xcessory-generated files. Any code that you insert into a User Code Block is preserved by Builder Xcessory whenever source code is generated.

Note: If you add code to any of the files outside of these User Code Blocks, it will be lost when you generate new versions of these files with Builder Xcessory.

Insert the following code into the setColor method User Code Block in the AwtFrame.java file.

// Begin user code block <setColor>
int red = _redScrollbar.getValue();
int green = _greenScrollbar.getValue();
int blue = _blueScrollbar.getValue();
_colorArea.setBackground(new Color(red,green,blue));
// The Windows Java ports don't update the canvas
// after setting the background, so we have to do a
// repaint here.
_colorArea.repaint();
_redLabel.setText(Integer.toString(red));
_greenLabel.setText(Integer.toString(green));
_blueLabel.setText(Integer.toString(blue));
// Don't pass this event any further. 
// It's been handled.
return(true);
// End user code block <setColor>

Working with Menus

Now that we have taken care of the basics of our application, we'll fill in the gaps by adding menus and a simple dialog window.

1. Create a File menu.

Drag a Menu onto the MenuBar. Builder Xcessory automatically creates a Menu object, a MenuPane object, and your first Menu Item.

Note: When you select the Menu, all of the menu items are displayed in your interface. You can control this display by turning Show Menu Children (Browser:View) on or off while the Menu is selected. With menu items posted, you can select any number of them in the usual manner, drag and drop, raise and lower them, and so forth.

2. Set the following resources on the Menu:

instance name: fileMenu
labelString: File

3. Set the following resources on the Menu Item:

instance name: exitButton
labelString: Exit

4. Create an Exit method for the Exit Menu Item:

For the next resource, use the extended editor to bring up the callback editor.
actionEvent: exitApp()
Using the Edit button on the extended editor, add the following line to the User Code Block:

Note: You must "Apply" the procedure name before editing it.
// Begin user code block <exitApp>
System.exit(0);
// Don't pass this event any further.
// It's been handled.
return(true);
// End user code block <exitApp>
An ActionEvent argument is added automatically to the exitApp() function when the code is generated.
Save the file and apply this method with the Apply button on the extended editor.

5. Create a Dialogs menu and apply the following resources to the Menu:

instance name: dialogMenu
labelString: Dialogs

6. Set the following resources on the Menu Item:

instance name: aboutButton
labelString: "About..."
actionEvent: popupAbout()
// Begin user code block <popupAbout>
_aboutDialog.show();
// Don't pass this event any further.
// It's been handled.
return(true);
// End user code block <popupAbout>
An ActionEvent argument is added automatically to the popupAbout() function when the code is generated.
We'll create the aboutDialog in the next section.

Working with Dialogs

1. Create a Dialog as a child of your main window.

When creating Dialogs, you are prompted for a class name. Specify the desired name.

2. Set the following resource on the Dialog:

instance name: aboutDialog
Resize the Dialog, if necessary, so that it is about 2" wide by 1.5" high.

3. Create the Dialog contents.

Because the Dialog is now a class, you cannot modify its instance directly. You need to enter Builder Xcessory Classes view. Select Classes from the combination box located under the Browser Panner. (See Builder Xcessory Browser .)
Once in Classes view, you can edit the object(s) directly.

4. Prepare the Dialog layout.

For this section, we'll use a new layout policy, Border. The Border layout places its children into North, South, East, West, and Center positions. (See Border .) Set the following resource on the Dialog:
layout: Border

5. Add two Labels to the Dialog. (Java does not directly support multiline labels.) Set the following resources:

label: Java Color Editor
alignment: Center
direction: North
label1:
label: Version 1.0, Created by <your name>
alignment: Center
direction: Center

6. Create a Panel as a child of the Dialog.

The Border layout policy resizes each child to entirely fill their specified region. We will add a "Dismiss" button to the dialog and do not want it to resize. Placing the button in the Panel prevents this. Set the following resources:
layout: Flow
direction: South

7. Create a PushButton as a child of the Panel and set the following resources:

label: OK
actionEvent: popdownDialog()
// Begin user code block <popdownDialog>
if(e.getActionCommand().equals("Ok"))this.setVisible(false);
// Don't pass this event any further.
// It's been handled.
return(true);
// End user code block <popdownDialog>

8. Enter Instances view.

Now that we've finished the Dialog, select Instances from the Browser combination box.

Your Interface in Progress shows the result of the preceding steps:

Your Interface in Progress

Testing Your Application

We've now reached a point where we would like to test our application and specifically, its interface.

1. Save the interface (Browser:File:Save).

The first time you save a new project, you'll be presented with a file selection dialog. To change filenames for subsequent save or generate code operations, use the Save As option (Browser:File). Open, Save, Save As, and Generate Code operations all set your working directory for subsequent save and generate operations.

2. Enter Play Mode (Browser:Project:Play Mode) and test your interface.

In Play Mode, you can try out your interface. Your menus will post, buttons will push, and so forth. You can test all of your resize behavior. Methods you've written, however, are not active. To test these methods, generate code by selecting Generate Code from the Browser File menu, compile, and run.

Note: Using the UNIX command line is still the preferred method for many developers. Builder Xcessory generates both Imake and Makefiles for you. See Working with Source Code for more information.

3. When you are finished testing, re-enter Build Mode (Browser:Project).

Creating a Uniform Look and Feel for Your Application

There are many attributes, such as colors, fonts, and so forth, that contribute to an application's personality, or look and feel. Builder Xcessory helps you to define a total look and feel by building style sheets that can be reused and shared with other developers. You can use system styles to help all of your developers conform to a corporate style guide, clearly identifying all of your applications as part of a single family, and reducing the learning curve for your end-users.

A Builder Xcessory style is basically a collection of resource:value pairs that you define. Styles are related to one another as parents and children. Substyles inherit the resource values of their ancestors while overriding any ancestral values that are specifically re-defined in the substyle.

In this section, we'll build a very simple set of styles for your color selector.

Bringing up the Style Manager

1. Bring up the Style Manager (Browser:Managers:Styles).

In the Style Manager you see a style named "BaseStyle". This is the root style and serves as a placeholder. Notice the padlock symbol next to the name. This style, and any style with the padlock symbol, including system styles you create, cannot be edited.

Creating a new style

2. Create a new style.

Select Create Substyle from the Style Manager:Edit menu. This creates a new style as a child of the currently selected style, in this case as a child of BaseStyle.

Note: Just as with other UI objects, styles can be cut and copied or manipulated with the mouse, including all drag and drop operations, reparenting, and so forth.

Defining a new style

3. Define the new style.

Select the style (BaseStyle1). Select Edit Substyle from the Style Manager:Edit menu to bring up the Style Editor. You can also double-click on the style to invoke the Style Editor.

Creating a list of resources

First create a list of the resources you want to define in this style, using one of the following methods:
· Click on the Resources combination box arrow. This drops down a scrollable list of all available resources. Click on one or more resources to select them. You can deselect a resource by clicking on it a second time. When satisfied, click again on the combination box arrow.
· Type the resource names into the Resources combination box text field, separating multiple resources with commas. Enter Return to terminate the list.
Your selected resources appear below the combination box, where you can set their values just as you would in the Resource Editor.

You can add or delete resources from a style at any time. This affects all objects using the style.

Adding resources

Add the following resource:value pairs to the style:
background: blue
foreground: yellow
fontList:-*-helvetica-bold-r-*-*-*-100-*-*-*-*-iso8859-1
It's easiest to use the extended editor to select the font.
The font above is Helvetica, bold, 10 point. Choose any values you prefer.
See Extended Editors for more information.

Applying new definitions

Use the Apply button in the Style Editor to set the style definition.

Applying a style to an entire interface

4. Apply the style to your entire interface, preserving the background value of the Canvas widget.

You can apply a style to part, or all, of your interface by using one of the following methods:
· Select Apply from the Style Manager to apply the selected style to the selected object or to the selected object and all of its descendants. Force overrides any resource values already set on the affected objects. Otherwise, the resource values are preserved. Don't force the style in this case to maintain the white background of the Canvas.
· Dragging a style onto an object or its Browser representation with MB2 forces the style to the object, overriding any duplicated resource values.
· Dragging a style onto an object or its Browser representation with Ctrl-MB2 forces the style to the widget and all of its descendants, overriding any duplicated resource values.
· Selecting any group of widgets and entering the style name into the Style field of the Resource Editor applies the style to all of the selected widgets, preserving any resource values already set.

Note: Styles applied to classes while in Instances view are ignored. To apply a style to a class, you must be in Classes view.

5. Create a second style as a child of BaseStyle1 (the style we've created above).

Select the intended parent style, then select Create Substyle from the Edit menu of the Style Manager.

6. Add the following resource:value pairs to the style:

foreground: red
fontList: -*-times-bold-r-*-*-*-100-*-*-*-*-iso8859-1
It's easiest to use the extended editor to select the font.
The font above is Times, bold, 10 point.

7. Apply (force) this style to your DialogShell and its children.

Your new style has inherited the blue background from its parent.

8. Edit the first style you created (BaseStyle1), changing the value of the following resource:

background: black
Apply the change in the Style Editor. Note that each widget using that style immediately reflects the change and that each widget using a descendant of this style (including your dialog) also reflects the change.

For more information about styles, including the creation of system styles, refer to Styles .


Note: Bugs in the current Windows implementation of AWT prevent the java.awt.Panel class from behaving correctly, particularly with regard to the background resource. If you display this example application on a Windows system, this will be evident.

Working with Source Code

You can generate source code and run your application at any point in the development process.


Note: Builder Xcessory always generates code that compiles and runs, generating stubs where your routines will be placed. However, if you have begun adding incomplete routines such as callbacks, methods, and so forth, they may prevent your application from executing.

Creating source code

To create source code with Builder Xcessory, perform the following steps:

1. Customize your makefile to use your compiler of choice and reflect the library locations of your system (Browser:Options:Code Generation Preferences).

Be sure that your working directory is set correctly with the File Names tab sheet in the dialog. Use the Makefile tab panel to set up your makefile (specify your compiler, library locations, and so on).
You can also add your own include information, customize filenames, and turn on and off generation of any particular file.
See Code Generation Preferences for more information on these dialogs.

2. Generate source code (Browser:File:Generate).

3. Build and run your application.

Use the Make or Imake files that Builder Xcessory creates from the UNIX command line, your normal build process. Builder Xcessory also generates an HTML file for you. You can load this file into your favorite Java-enabled web browser and run your Java application from there.

Note: Though you can launch a Java application from your browser, keep in mind that many common application-oriented methods, such as System.exit() generate security violations in a browser environment. In this case, it would mean that the only way to exit the application would be to exit the browser.

You can now run your color selector. This concludes our Java example.

Additional work

Feel free to continue to explore Builder Xcessory' capabilities. Some ideas for additional work include:

· Experiment with the GridBag layout.

One major problem with using the Flow layout is that the default size for Java scrollbars is very small. Simply setting their height resource does not work, as it does for the Canvas class (you'll have to ask Sun why this is so). Getting a reasonable size for the scrollbars requires using a layout manager that controls the size of its children. FlowLayout does not; it merely asks each component for its preferred size and tries its best to lay them out as they like. One idea would be to use a GridBag, with the components laid out along row 0. The fill for the scrollbars would be set to vertical, while the canvas would be filled along both axes. The labels would most likely want a center anchor.
(See GridBag for more information.)

· Allow the user to enter an RGB value directly.

The labels might be replaced with TextField components. The actionEvent method must first verify that a valid number had been typed (perhaps warning the user with another dialog), then ensure that the scrollbars and labels are in sync, and then call the setColor() method.

 

Documentation: 

Builder Xcessory 5.0 Users Guide: Table of Contents

Notation Conventions

Definitions

Prerequisite Knowledge

Builder Xcessory Overview

Starting Builder Xcessory

Startup Panel

Language Dialog

Builder Xcessory Main Windows

Browser

Browser Menus

Toolbar

Message Area

Interface Hierarchy

Selecting and Deselecting Objects

Palette

Palette Groups

Palette Menus

Using the Palette

Creating Objects

Parents and Children

Resource Editor

Resource Editor Menus

Toolbar

Header Data

Interface File Menu

Edit/Display Area

Using the Resource Editor

Example: A Simple Color Selector

Motif Example

Preparing for a Work Session

Creating Widgets

Copying Widgets

Setting Instance Names

Working with Multiple Widgets

Moving and Resizing Widgets

Adding Action to Your Interface

Working with Callbacks

Working with Menus

Working with Dialogs

Testing Your Application

Creating a Uniform Look and Feel for Your Application

Working with Source Code

Java Example

Preparing for a Work Session

Applets and Applications

Creating Objects

Selecting Multiple Objects

Copying Objects

Setting Instance Names

Working with Multiple Objects

Java Layouts

Working with the Flow Layout

Adding Action to your Interface

Working with Menus

Working with Dialogs

Testing Your Application

Creating a Uniform Look and Feel for Your Application

Working with Source Code

Classes

Creating a Class with Builder Xcessory

Adding Methods and Data Members

Class Member Editor

Exposing Resources

Exposing Callbacks and Event Methods

Exposing Callbacks

Callback Source Code

Subclassing and Receptors

Subclassing

Receptors

Saving and Sharing Classes

Saving Classes

Sharing Classes

Sharing Class Libraries

Moving Classes Between Groups

Reading Classes

Specifying Include Files

Code Generation

C Code Generation

C++ Code Generation

UIL Code Generation

ViewKit Code Generation

Java Code Generation

Managing Your UI Layout

Aligning and Distributing Objects

Additional Layout Techniques

Reordering Menu Items

Placing Objects without Setting width and height

Using Motif Geometry Managers

Simple Motif Managers

Complex Motif Managers

EPak Manager Widgets

Java Layouts

Using Java Layouts

No Layout

Flow

Border

Card

Grid

GridBag

Initializing Resources at Run Time

Constants

Identifiers

Expressions

Callbacks with XtSetValues Calls

Accessing Objects at Run Time

Managing and Unmanaging Objects

Callback Procedures and Event Methods

Predefined Callbacks

Using Callbacks in C++ Classes

Using Event Methods in Java Classes

Using Timers, Event Handlers, and Translations

Timer Procedures

Work Procedures

Event Handlers

Translations

Integrating Builder Xcessory with Your Environment

Using Builder Xcessory with Your Tools

Designing Your Application in an Integrated Environment

Using a Debugger

Accessing Source Code Control Systems

Selecting a Source Code Control System

Editing the Commands for Source Code Control

Using a Source Code Control System

Using a Memory-Access Error-Checking Tool

Using Builder Xcessory with Emacs

Internationalizing Your Application

Character Sets and Code Sets

X and Motif I18N Support

Application Coding

Locales

Locales in Builder Xcessory

Placing Resource Values in Resource or UIL Files

Generating Multiple UIL Files

Text Input

Text Output

Setting Up Localized Output

Compound Strings

Creating Multifont and Multidirectional Strings

Generating Localized Files

Generating UIL

Generating C and C++

Designing Your Own Message Catalog

Suggested Reading

Porting GIL Interfaces to Motif

GIL Version Information

GIL Options

Strategies for Importing Your GIL Documents

Groups

Glyphs

Devguide List

Actions

Non-converted Objects

Conversion Conventions

Numeric Textfields

OPEN LOOK Menus

Help Text

Building an Interface

Using the Tutorials

Setting Up Tutorial Directories

Changing the Destination Directory

Notation of Wrapped Code

Tutorial One: Simple Actions

Tutorial Two: Simple Objects

Tutorial Three: Creating a Dialog

Tutorial Four: Using Resource Styles

Tutorial Five: Advanced Techniques

Tutorial Six: Compound Strings and Font Lists

Tutorial Seven: Classes

Tutorial Eight: Creating Classes and Subclasses

Tutorial Nine: Creating a Java Applet or Application

 

Documentation: 

Building an Interface

 

In building and testing an interface with Builder Xcessory, use the following procedure:

  1. Create the objects that comprise your interface.
  2. Specify values for the widget resources, including the callback resources that control the functionality of the interface.
  3. Test the appearance of the interface.
  4. Save the interface and generate code.
  5. Edit the output files, especially those containing the callbacks structures, in order to connect the functionality of the interface.
  6. Compile the interface (or debug without compiling using Builder Xcessory's connection to the CenterLine CodeCenter and ObjectCenter interpreters).
  7. Test the functionality of the interface.

Documentation: 

Classes and Methods

Classes

Overview

When you create an interface with Builder Xcessory, you will often find that you repeatedly create certain combinations of objects, for example, a label, a text area, and a button that acts on the value entered in the text field. Rather than recreate all three objects each time, you can combine them into a class. This class can then be treated as a single object. By planning and creating a library of high-level, reusable classes, you can improve the quality, development time, and maintainability of your applications.


Note: A Builder Xcessory class should not be confused with a C++ or Java class, although the code is generated using language classes.

Designing and Planning Classes

Plan and design your classes to implement them in the most efficient manner. One of the major benefits of working with high-level objects is the ability to reuse them. Before you begin your project, identify the obvious and the non-obvious elements of your application. Think about how the elements will be used in subsequent applications, and use Builder Xcessory to develop the latest additions to your class library or application framework. As you progress through the development of your application, additional classes will undoubtedly become obvious. Builder Xcessory allows you to create new classes at any point in your development cycle.

Creating a Class with Builder Xcessory

When creating a class, you work with all three main Builder Xcessory windows. With the Browser, you switch between Instance and Classes views of your interface, viewing and manipulating the objects within your classes. With the Resource Editor, you customize the look and feel of your classes, setting resources, callbacks and event methods. With the Palette, you create the objects comprising your classes, and use, store, and share the classes themselves.

Creating a class

To create a class, use one of the following methods:

· In Instances view, select the top-level object of the hierarchy that you wish to make a class. Then select Make Class from the Browser:Edit menu (or MB3 Quick Access menu). You are prompted for the name of the new class.

· In Classes view, drag an object from the Palette and place it on the display. You are automatically prompted for the name of the new class. If you drag a widget, your class consists of only that widget. If you drag another class object, the new class is a subclass of the specified object.

Once you supply a class name in the dialog displayed for that purpose, the class is automatically included in the Project Classes group of the Palette.

For example, you might want to create a class that combines a label and text field within a form.

Example:
Creating an object

First, create the objects by following these steps:

1. Create a form.

2. Place a label and a text field within the form as shown in the following figure:

Widget Hierarchy

3. You can use the Form Editor and Ctrl+MB1 on the attachment handles to set any appropriate constraint resources. The collection should now look something like the following figure:

LabelField Widget Collection

Example:
Making a collection of objects into a class

To make this collection of objects into a class, follow these steps:

1. Select the container widget (the form) by clicking on its instance name in the Browser widget hierarchy.

2. Select Make Class from the Browser Edit menu, or from the MB3 Quick Access menu.

3. In the Name field, enter LabelField. The new class is automatically
added to the Palette in the Project Classes group as shown in the following figure:

LabelField Class on Palette

The collection is now collapsed into a class instance on the Browser as shown in the following figure:

Class Instance labelField

Switch the Browser to Classes view. The class is now expanded on the Browser and you can view its entire membership as shown in the following figure:

LabelField Widget Hierarchy

Editing resources and adding callbacks and event methods

When Builder Xcessory is in Classes view, any component of the class can be modified and any component's widget resource can be exposed. Select the component or components in question and edit the resource values, using the Resource Editor, extended editors, or styles. Callbacks and event methods are treated just as any other resource. Changes made to the class propagate to all instances of the class and its subclasses throughout the interface.


Note: One of the most powerful properties of classes is that changes to the class definition propagate to pre-existing class instances.

Callbacks for class members (Motif) are generated in source code as two separate methods, described in detail in Object-Oriented Programming with C++ and OSF/Motif (Prentice Hall, 1995, 2nd Ed. ISBN 0-13-209255-7) by Doug Young. Exposing a callback results in a third, public method.

See Using Callbacks in C++ Classes for detailed information on these methods.

Creating class instances

You create class instances in the same manner in which you would instantiate any other Palette object, that is, select it on the Palette and drag it to the interface window. Refer to Using the Palette .

Reusing classes

Once saved in the Palette Private Classes or Public Classes group, a class is available each time you start Builder Xcessory. You can also read a previously saved class file into an interface.

Additionally, as with widgets, you can add VkComponent and UIComponent subclasses to the Palette, allowing you to completely code a class and its methods and interact with the fully-working object in Play Mode. For more information on Play Mode see Using Play Mode . For information on adding classes to the Palette, see Permanently Placing Classes on the Palette .

Subclassing

Classes can also be subclassed, furthering the re-usability and usefulness of classes. Subclasses can be modified by adding additional widgets, adding methods and data members, and changing resources.

Adding Methods and Data Members

Methods

In addition to their component objects, classes include methods and the data on which they operate. You can add additional class members from the Resource Editor in Classes view (see Resource Editor in Classes View ). Both methods and data are displayed in a list sorted by item type and scope. Parameter argument types are displayed for methods only.

Resource Editor in Classes View

Buttons

You can operate on the items using the following three buttons:

· New

Creates a new class member.

· Edit

Available only for methods. Invokes the code generator and configured editor for this method.

· Delete

Deletes the class member.

Adding members

To add a member to a class, follow these steps:

1. Switch the Browser to Classes view.

2. Select the desired class.

3. Update the Resource Editor.

4. Select the New button.

Builder Xcessory provides an extended editor, the Class Member Editor, to help specify methods and data. (For more details, see Class Member Editor .)

A method or data member specified in the class definition is available to each class instance.


Note: The methods and data you specify on the class itself are in addition to any methods created by Builder Xcessory for callbacks, widget IDs, or event methods that you specify elsewhere.

Class Member Editor

Class Member Editor illustrates the Class Member Editor for a class method:

Class Member Editor

Data/Method

Use the toggles at the top of the window to select Data or Method.

Other fields and toggles allow you to assign the type, name, and other attributes such as the member's scope. The attribute selections represented by the tabbed panels vary depending on the code generation language. Also, some cross checking of selections occurs so that inappropriate selections are disabled. For example, if you are using C++ code generation, an initial static value is unavailable for methods and is disabled.

For methods, the parameter fields allow you to enter argument types, parameter names, and (for C++ code generation) default values.

For data, the parameter entry areas and list are hidden. Static data members can provide initial values.

For more information on the Class Member Editor, see Class Member Editor


Note: The Class Member Editor is a valuable tool for specifying language-specific attributes to each added class member. However, even though some cross-checking is performed to confirm the compatibility of your selections, it is not complete and is not meant to be a robust language checker.

User Code Blocks

Member methods and data can also be inserted directly into the User Code Blocks of the class file. These edits are not visible or editable in the Resource Editor. Because they are inside User Code Blocks, they are retained when the files are regenerated.

Exposing Resources

When designing a class with reuse in mind, you must decide what aspects of the class will be customizable on a per instance basis. Within Builder Xcessory, you can do this by exposing resources .

A resource on a component object is exposed when its default value can be overridden for a particular instance of the class. Ordinarily, you expose resources when you wish to vary a resource value for different instances of a class. For example, you might want to allow users of the LabelField class described at the beginning of this chapter to set the value of the labelString resource for each instance of the class.


Note: For any resource that you want to expose within a class, you must specify a default resource value in the class definition.

Exposing a resource

To expose a resource, follow these steps:

1. Switch the Browser to Classes view.

2. Update the Resource Editor for the desired component object.

3. Scroll the Resource Editor to the desired resource.

4. Set the resource to the value that you wish each instance to take by default.

5. Select Expose from the option menu to the right of the resource text field.


Note: Exposed resources are designated on the Resource Editor with an "open eye" icon to the left of the option menu. The option menu continues to display the resource placement setting (for example, "Code" or "App").

Editing the value of an exposed resource

To edit the value of an exposed resource on a class instance, follow these steps:

1. Select a class instance (Be sure to be in Browser:Instance view).

2. Update the Resource Editor.

The Resource Editor now displays exposed resources with the notation:
<element_name>.<resource>

3. Scroll the Resource Editor to the desired resource.

4. Edit and apply the resource value as you would any other resource value.

Only the currently selected instance takes this resource value. The default resource value in the class definition is unchanged.


Hint: To temporarily turn off display of the element's instance name in an exposed resource name (that is, display background instead of myElementInstance.background ), hold MB1 down while the cursor is over the name. To locate a particular resource quickly, use the Resource Editor Search Area.

Exposing Callbacks and Event Methods

In addition to customizing the appearance of your class, you might also want to customize its behavior. The behavior, or interaction between your UI and the rest of your application is generally controlled with callbacks in Motif, and with event methods in Java. For more information, see Callback Procedures and Event Methods .

As you build your classes, you build a great deal of functionality into your UI classes using the callbacks and event methods for the class elements and the methods, (public, private, and protected) for the class itself.

You can give instances of a class access to the callbacks or event methods of its elements by exposing them just as you would any other resource. The process with which you do this is identical regardless of the language you are using. The results, however, differ slightly.


Note: This is an area where it is very easy to break "good" object-oriented programming practice. Consider very carefully whether you want to use an exposed callback or event method, or whether you should use a subclass instead.

Note: In ViewKit, it is better practice to use ViewKit's callback mechanism, provided by VkCallbackObject, rather than exposed callback resources.

Exposing Callbacks

Exposing a resource

To expose a callback or event method, follow these steps:

1. Switch the Browser to Classes view.

2. Update the Resource Editor for the desired component object.

3. Scroll the Resource Editor to the desired callback or event method.

4. Set the resource to the value that you want each instance to take by default.

5. Select Expose from the option menu to the right of the resource text field.


Note: Exposed resources are designated on the Resource Editor with an "open eye" icon to the left of the option menu.

Callback Source Code

With Motif, you can choose whether the instance callback routine augments or replaces the class's exposed callback. This is controlled by the Remove Overridden Exposed Callbacks toggle on the Code Generation tab of the Code Generation Preferences dialog (Browser:Options). Refer to Toggle options for more information.

Callbacks for class members (Motif) are generated in source code as two separate methods, described in detail in Object-Oriented Programming with C++ and OSF/Motif (Prentice Hall, 1995, 2nd Ed. ISBN 0-13-209255-7) by Doug Young. Exposing a callback results in a third, public method.

See Using Callbacks in C++ Classes for detailed information on these methods.

Subclassing and Receptors

When designing your classes with reuse in mind, you must strike a balance between power and flexibility. If a class has too little functionality, you have little incentive to use and reuse it, and if a class has too much functionality, it often becomes overly specific and difficult to use in other situations. If a class has too much flexibility (through exposed resources and methods), it might be reused, but maintenance benefits to the application are lost.

Subclassing helps to balance functionality, flexibility, and power. Creating a new class by subclassing an existing class allows you to adapt the class to a specific situation, while allowing other developers to leverage their knowledge of the often-reused parent class. Builder Xcessory makes it extremely simple to create subclasses.

Subclassing

All classes created within Builder Xcessory can also be subclassed. A subclass is a class created from another class, which inherits all of the objects, resources, methods, and data members of the superclass while also adding its own.

Making a subclass

To make a subclass, follow these steps:

1. Place Builder Xcessory in Classes view (Browser:Classes view).

2. Select the class you want to subclass.

3. Select Make Subclass from the Browser Edit (or MB3 Quick Access) menu. You are prompted to name the subclass. A new class is created and displayed in the Browser.

Example: 
Make a subclass ToggleField

To continue the example that began on Example: Creating an object , you might want to make a subclass ToggleField from the class LabelField, which consists of a form container with a label and a text field as children.

To make a subclass ToggleField from the class LabelField, follow these steps:

1. Confirm the Browser is in Classes view.

2. Select LabelField on the instance hierarchy.

3. Select Make Subclass from the Browser Edit (MB3) menu.

4. You are prompted to name the subclass. Name it ToggleField. The new class is created and displayed in the Browser ( Superclass LabelField and Subclass ToggleField ):

Superclass LabelField and Subclass ToggleField


Note: Note that LabelField appears in ToggleField's hierarchy with a colon designating it as the superclass of ToggleField.

5. You can now add methods and data members to your new subclass using the Resource Editor and the Member Editor. (See Adding Methods and Data Members for review.)

Editing superclasses

You can edit any of the exposed resources of the parent, or superclass. Edits made to the superclass propagate to all subclasses. Likewise, in each subclass instance, the default value of an exposed resource can be overridden, as can methods and data members.

Overriding exposed resources

To override the exposed resources of a superclass, use the Browser to select the :superclass object, then use the Resource Editor to specify the new resource values. ( :LabelField is an example superclass in Superclass LabelField and Subclass ToggleField .)

Receptors

Frequently, a major element of a new subclass is one or more additional children. Builder Xcessory allows you to add children when subclassing by designating a container in your superclass as the receptor . Specifying a receptor on a class allows you to extend the object hierarchy of an existing class through its subclasses while not affecting the original class and its class instances.

Making receptors

To specify a receptor (only one is allowed per class), follow these steps:

1. Confirm the Browser is in Classes view.

2. Select the component object that you want to designate as the receptor.

3. Select Make Receptor from the Browser Edit (Quick Access MB3) menu. A small icon, consisting of a square within a square, is placed to the left of the object in the Browser class hierarchy, designating the object as the receptor (for example, see Receptor ).

Any objects subsequently added to a subclass automatically become children of the receptor.

Example: Making the Form widget a receptor

Continuing the previous example, you might want to add to the subclass ToggleField a toggle button not part of the superclass LabelField. The toggle button has the LabelField class's form widget as its parent; therefore, you make the form the receptor.

To make the Form widget a receptor, follow these steps:

1. Confirm that the Browser is in Classes view.

2. Select the Form component within the LabelField hierarchy.

3. Select Make Receptor from the Browser Edit (MB3 Quick Access) menu. The result is shown in the following figure:

Receptor

Once you make a component object of a class a receptor, you can add children to any of that class's subclasses.

Adding children to subclasses

To add a child to a subclass, follow these steps:

1. Confirm the Browser is in Classes view.

2. Using MB2, drag the child widget from the Palette and drop it on the object with instance name ":<SuperclassName>" on the desired subclass's instance hierarchy.

The superclass's receptor is the designated parent of any objects added to a subclass.

Adding a toggle button

Continuing the LabelField example, assume you want to include a toggle button to the subclass ToggleField.

Saving and Sharing Classes

An important part of reuse is making the classes easily available to other developers. Builder Xcessory enables you to store and share classes with other Builder Xcessory users.


Note: Individual reuse is useful only when entire groups and organizations reuse the same objects.

Saving Classes

When you make a class, the class is added automatically to the Project Classes group at the bottom of the Palette. Classes in the Project Classes group are saved with your project, allowing other developers to access those classes. To use the class in other projects, or move it to the Private or Public Classes group, you must save it to a separate file.

Saving a class

To save a class, follow these steps:

1. Confirm the Browser is in Classes view.

2. Select the desired class.

3. Select Save Class from the Browser File menu to display a file selection dialog:

File Selection Dialog

4. Enter the file name and directory path, and click OK to save the class.

Sharing Classes

Before you can share a class, you must save the class UIL file separately from the rest of the project. This separates the class definition from any given interface.

Conditions for sharing classes

You can share classes under the following conditions:

· By manually placing classes into locations accessible to all developers, and then importing the classes manually

· By using the Builder Xcessory Palette.

Sharing Class Libraries

You can also share a library of classes among a group of users.

Building a class library

To build a class library:

1. Generate code for your classes and build your library.

2. After generating the class files, deselect the Generate Class toggle (Resource Editor:Component) for each class in your library and save the classes into separate files using Save Class (Browser:File:Class).

3. Move the classes to the Public Classes group.

4. Move the header files and library to the desired location. Save the source files to preserve any user code blocks for future modifications.

Preparing a library for sharing

Now, when you use the class in an application, Generate Code is deselected by default. You still need to do a couple of things:

1. If you are generating C++ and included the BX-generated UIComponent in your library, deselect the Class Tree Root toggle button in the File Names tab (Browser:Options:Code Generation Settings).


Note: If you always want to include the UIComponent in your library, click the Save As Default button on the File Names tab. The UIComponent will not be generated in the future by default.

2. Add the include path for the class header files and library containing the class to the application Makefile and select the Don't Include Ungenerated Class Files toggle button on the Makefile tab (Browser:Options:Code Generation Settings).


Note: If you always want to include the library and its header file path in the Makefile, click the Save As Default button on the Makefile tab.

Moving Classes Between Groups

Dragging classes

Once you save the class, you can drag the class from the Project Classes group to either the Private or Public Class section on the Palette.


Note: You must be in Outline view to drag classes from one group to another.

· If you leave the class in the Project Class group, the class appears on the Palette when the project file is loaded.

· If you move the class into the Private Class group, the class is saved into the .builderXcessory directory in your home directory and appears on the Palette each time you start Builder Xcessory.

· If moved into the Public Class group, the class is saved into the {BX}/xcessory/classes system directory and appears on the Palette of all Builder Xcessory users in your organization.


Note: Classes moved into either the Private or Public groups are locked by default. You cannot edit these classes, regardless of directory permissions. Unlock classes by selecting Unlock Class from the Class menu of the Browser File menu.

Reading Classes

Reading a class

You can read classes that you or other developers saved. To read a class, follow these steps:

1. Select Read Class from the Class menu of the Browser File menu. A file selection dialog is displayed ( File Selection Dialog ).

2. Enter the file and directory of the class, and click OK.

Specifying Include Files

Each class can have its own set of include files, which can be specified from the Resource Editor when Builder Xcessory is in Classes view. When the class is selected, the Resource Editor includes a section labeled Class File Include Information that in turn includes two subsections: Base Class Includes and Derived Class Includes (see Class Includes Sections ).


Note: Derived Classes are available only when you choose C++ as your default language.

Resource Editor:

Class Includes Sections

The two sections are scrollable text regions. The contents of the text regions are included verbatim into the base and derived class .hfiles. This allows you to specify different include file information for each class that you create.


Note: Derived Classes are supported for backward compatibility only. We do not recommend using Derived Classes.

 

To add the toggle button to ToggleField, follow these steps:

1. Confirm the Browser is in Classes view.

2. Drag the toggle button from the Palette.

3. Place the toggle button on the LabelField object on ToggleField's instance hierarchy ( Subclass with Child ):

Code Generation

The following sections describe the files generated by Builder Xcessory for each language.

C Code Generation

Builder Xcessory generates the following files (see files generated for C for more information):

· main-c.c contains function calls necessary for any application.

· creation-c.c contains the code to initialize and create all widgets in the application.

· creation-c.h contains include information, constant definitions, and pixmap specifications.

· callbacks-c.c contains code for all callbacks specified.

· bxutils-c.c contains functions used by Builder Xcessory-generated code.

· makefile-c and Imakefile allow the generated code to be built into the application.

When using classes, Builder Xcessory generates the same files and adds some new ones. The differences are listed as follows:

· creation-c.c is the same for all widgets not part of a class. For each instance of a class, this file has a call to a function to create and initialize the widgets comprising that class. This results in a smaller file.

· creation-c.h also includes the <class>.h files for each class <class> that is generated.

· makefile-c and Imakefile contain the same targets, but include the additional class files to compile and link in to create the targets.

In addition, the following files are created for every class, <class>, created in Builder Xcessory:

· <class>.c contains the code to create and initialize the widgets comprising the class.

· <class>.h contains a data type that is a structure of the widget ID's of all widgets that are part of the class.

C++ Code Generation

If you do not have any classes when you generate the C++ code, the contents of each TopLevelShell are generated as a class and named using the instance name of the shell's immediate child.

In all cases, the following files are generated (see Files generated for C++ for more information):

· main-C.C contains function calls necessary for any application and calls the constructor of each generated top-level class.

· <class_name>.C contains the code for the constructor and destructor for each class generated. In the constructor, all the objects in the application are created (similar in C code to the creation-c.c file).

· <class_name>.h defines the class created by <class_name>.C and any required structures.

· UIComponent.C contains the base class for all objects created.

· UIComponent.h contains the definition of the UIComponent base class and any required structures.

· callbacks-C.C contains code for all callbacks specified on top-level shells and on other elements that are not specific class members.

· bxutils-C.C contains functions called in the other generated files.

· defs-C.h contains definitions of constants, pixmaps, and global instances of widgets or classes used in the application.

· makefile-C and Imakefile allow the generated code to be built into the application.

UIL Code Generation

Builder Xcessory generates the following files (see Files generated for UIL for more information):

· main-uil.c contains function calls necessary for any application.

· uil.uil contains a description of the widgets.

· callbacks-uil.c contains code for all callbacks specified.

· main-uil.h contains declarations of constants, and global instances of widgets or classes used in the interface.

· bxutils-uil.c contains functions used by Builder Xcessory code.

· makefile-uil and Imakefile allow the generated code to be built into the application. Imakefile specifies both UIL and C imake information. Makefile has targets for UIL as well as the associated C files.

· app-defaults includes all resources with app-defaults value set to App.

ViewKit Code Generation

Builder Xcessory divides ViewKit code generation into the following files (see Files generated for ViewKit for more information):

· main-vk.C contains function calls necessary for any application. VkApp is instantiated here along with other application level classes, such as your top-level window classes.

· <class_name>.C contains the code for the constructor and destructor for each class you created. In the constructor, all objects in the application are created (similar in C code to the creation-c.c file). The constructor also binds any callbacks assigned to widgets and contains the methods for those callbacks.

· <class_name>.h defines the class created by <class_name>.C and any structures that it needs.

· defs-vk.h contains the constants registered in your interface.

· callbacks-vk.C contains code for all callbacks specified on elements that are not specific class members.

· bxutils-vk.C contains functions for Builder Xcessory-generated code calls.

· makefile-vk and Imakefile allow the generated code to be built into the application.

Builder Xcessory automatically subclasses from VkWindow, VkSimpleWindow, and VkComponent as appropriate. Additionally, Builder Xcessory subclasses any classes you create from Motif widgets from VkComponent.

Java Code Generation

Builder Xcessory divides Java code generation into the following files (see Files generated for Java for more information):

· MainApp.java creates an instance of each top-level class in your program. If you have only one top-level class, you might not need to use this class. (This is similar to the C language file main.c .)

· MainApp.html is an HTML file in which your applet is embedded, or with which you can launch your application using the Java Virtual Machine in your browser.

· <class_name>.java contains the code for each class you created.

· Defs.java contains the constants registered in your interface.

· makefile-java allows the generated code to be built into the application or applet.


Note: All generated files have comments generated in the JavaDoc format.

Java application attributes

Builder Xcessory allows you to create Java applications or Java applets. Java applications have the following attributes:

· Contain a single main() method

· Execute in a stand-alone fashion

· Do not require a browser

Java applet attributes

A Java applet runs from a browser. Rather than having a single main() method, an applet implements a set of methods that control how it is initialized, drawn, handles events, and so forth. Java applets have the following attributes:

· Require a Java-enabled browser or applet viewer

· Must be embedded in an HTML page

· Typically subject to restrictions, depending upon the browser, due to security issues relating to the transfer of code


Note: Due to security restrictions present in most web browsers, many commonly used system methods, such as System.exit()cannot be used.

 

Documentation: 

Definitions

 

This document uses the following terms:

Click

Press and immediately release a mouse button. When the button is unspecified, assume mouse button one (typically the left mouse button).

Collection

A group of related UI objects saved to the Builder Xcessory Palette for reuse. Collections can include any UI object supported by Builder Xcessory, including widgets, gadgets, C++ classes, ViewKit components, or Java (AWT) classes.

Component

A user interface object, generally used in the context of ViewKit classes. ViewKit components generally consist of collections of Motif widgets along with code to implement general or specific functionality, encapsulated into a C++ class subclassed from an element of the ViewKit application framework.

Cursor

A graphical image appearing on the screen which reacts to the movements of a mouse or other pointing device. In the Builder Xcessory, the cursor appears as an angle bracket when creating a widget, and an arrow when selecting a pull-down menu or menu item. During a drag and drop operation, it appears as an icon reflecting the type of object dragged and the target over which it is positioned.

Drag

Press a mouse button, then move the mouse without releasing the button. Typically followed with a drop operation. The phrase, "drag on to" indicates a drag and drop operation. Use MB2 to perform a drag and drop operation, unless otherwise specified.

Drop

Release the mouse button after positioning the mouse (and screen object) as desired. Typically follows a drag operation. The phrase, "drop on to" indicates a drag and drop operation. Use MB2 to perform a drag and drop operation, unless otherwise specified.

Enter

Type a new value and press the Enter key.

Gadget

A user interface object built upon the Xt Intrinsics (the X Toolkit). Similar to a widget, a gadget lacks certain data structures (such as a window) contained in a widget. The gadget maintains this data on the client side, rather than on the server, as does a widget. Although seldom used with today's server performance levels, gadgets remain supported by Builder Xcessory.

{lang}

Specifies the current language (that is, the default language you select at the beginning of your BX session).

MB1, MB2 and MB3

Mouse buttons one, two, and three. Typically, MB1 is the left-most button, MB3, the right-most. On a two-button mouse, MB2 is most commonly emulated by pressing both buttons simultaneously. For actions described as "click," assume MB1.

MB3 Quick Access menu

This menu is invoked by pressing MB3 while the mouse pointer is positioned over an object on the display. The contents of the menu depend on the type of object pointed to and the window in which you access the menu.

Object
UI object

A reusable software entity with a user interface (UI), or visible, aspect. A generic term for the various objects that are manipulated with Builder Xcessory. UI objects include widgets, related collections of widgets, C++ classes, ViewKit components, and Java (AWT) classes. The term object and the term UI object are interchangeable.

Paste buffer

Cache into which a cut or copied object is placed. Often known as a cut buffer.

Resize

To change the height and/or width of an object.

Resource

A user preference specification that controls elements of an application that can be customized by the user.

Note: In this manual, the term "resource" includes Java attributes.

Select

To choose an object to be acted upon or an action to be performed; accomplished by clicking mouse button one on an object or menu item.

Session

A single, continuous working session, from the time you start Builder Xcessory from the command line, or from another tool, to the time you select Exit from the Browser's File menu.

Widget

A user interface object built upon the Xt Intrinsics (the X Toolkit). Motif user interface objects are widgets.

 

Documentation: 

Extending Builder Xcessory

Overview

Builder Xcessory tailors itself to your development environment, and is just one of the many tools that you use during the design, implementation, and maintenance of your application. This section describes how to integrate Builder Xcessory with other tools.

Integrating Builder Xcessory with Your Environment

Builder Xcessory is one of many tools that can be used in the design and implementation of an application. Rather than attempting to provide the entire environment for application development, Builder Xcessory integrates with the tools in your own environment.

Sun, SGI, and DEC

If you use SunSoft Workshop, Silicon Graphics Developer Magic or DEC FUSE you can install Builder Xcessory into your environment. You can then access the tools in your environment from within Builder Xcessory. Integrating with these tools greatly expands the capabilities and usefulness of Builder Xcessory when used throughout a project cycle.

Environment services

The following table provides an overview of the environment services available from Builder Xcessory and the conditions under which they are available:

Environment

Services

BX Command 
Line Flag

SunSoft Workshop 2.0 Tools

MakeTool, Debugger, test tools, error checking tools, Source Code Control, Code Center/Object Center

-workshop

DEC FUSE 2.0 (or later) Tools

Builder, Code Manager, test tools, error checking tools, Source Code Control

(none)

SGI Developer Magic 2.4 (or later)

Build Analyzer, Debugger, test tools, error checking tools, Source Code Control

-devmagic

custom environment

Test tools, error checking tools, Source Code Control, Code Center/Object Center

N/A

Once installed in your development environment, you can start Builder Xcessory, use Builder Xcessory to work on user interface design, and access other development tools in your environment directly from Builder Xcessory. For example, you might start up Builder Xcessory from your environment and design a small portion of a user interface, test it in Play Mode, use your environment's debugger to debug it, and then return to Builder Xcessory to continue working on your user interface design.

Using Builder Xcessory with Your Tools

Before you can use Builder Xcessory with the tools in your development environment, you must first install Builder Xcessory into your environment. Refer to the Builder Xcessory Installation Notes for a detailed description of the installation process.

Using Builder Xcessory with DEC FUSE Tools

The DEC FUSE tools are launched from a small control panel. The tools use DEC MCMS (MultiCasting Message Service) as the underlying message layer.

To use Builder Xcessory with DEC FUSE tools, select Builder Xcessory from the control panel Tools menu.


Note: If you wish to use Builder Xcessory with DEC FUSE tools, you must start Builder Xcessory from the DEC FUSE control panel. There is no command-line switch to allow Builder Xcessory to initialize DEC FUSE communication.

Using Builder Xcessory with SunSoft Workshop Tools

The SunSoft Workshop tools can be used separately or from a small tool control panel. The tools use ToolTalk as a system for passing messages.

To start Builder Xcessory with SunSoft Workshop tools, use one of the following methods:

· Double-click on the Builder Xcessory icon in the Workshop Manager.

· Start Builder Xcessory from the command line with the -workshop flag. This flag tells Builder Xcessory to initialize ToolTalk messaging with the Workshop messages.


Note: When working with Workshop, you need to launch Builder Xcessory from Workshop in order to control the Builder Xcessory windows from the Workshop Manager.

Using Builder Xcessory with Developer Magic

The SGI Developer Magic tools can be invoked separately or from a small tool control panel. The tools use ToolTalk as a system for passing messages. For example, the debugger can tell the editor to load a file.

To start Builder Xcessory with Developer Magic, use one of the following methods:

· Select Builder Xcessory from the Launch menu of any of the Developer Magic tools.

· Start Builder Xcessory from the command line with the -devmagic flag. This flag tells Builder Xcessory to initialize ToolTalk messaging with the Developer Magic messages.

From your environment manager, you can stop, iconify, and deiconify Builder Xcessory. You can also raise Builder Xcessory windows.


Note: Unless otherwise noted, all customization options are saved between invocations of Builder Xcessory.

Designing Your Application in an Integrated Environment

The steps for building an application are basically the same, regardless of whether you use Builder Xcessory from a development environment or whether you use Builder Xcessory independently:

· When using Builder Xcessory with a development environment, you can use that environment's build or make tool.

· When using Builder Xcessory independently, you can use Code/ObjectCenter on Sun platforms to manage the make. Otherwise, you must manually run the make command at a UNIX prompt.

Selecting a build or make tool

When developing an application in Builder Xcessory, you can use your environment's build or make tool at any time. You must tell Builder Xcessory which tool you want to use, verify that your makefile parameters are correct, and then execute a build of your application.

To use your environment's build or make tool, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog.

2. If you use your environment's build or make tool, skip to step 4.

3. If you want to use CodeCenter or ObjectCenter to manage the build instead of the environment-provided tool, select Use CenterLine Tools from the Debugger and Build Manager tab (see Debugger & Build Manager with Centerline Defaults ).

Debugger & Build Manager with Centerline Defaults


Note: If you are using a CenterLine tool to manage the build, the language you chose specifies the command line used to start the tool. (Generating C or UIL/C uses the C command. Generating C++ or ViewKit uses the C++ command.)

4. Verify the make parameters by selecting Code Generation Preferences from the Browser Options menu to display the Code Generation Preferences dialog, and then clicking the Makefile tab ( Makefile Tab on the Language Settings Dialog ).

Makefile Tab on the Language Settings Dialog

5. Change any incorrect parameters.

6. To execute a build of your application, select Make Application from the Browser Project menu.


Note: If you are using Builder Xcessory outside of a development environment and Code/ObjectCenter is not available on your platform, Make Application is not available. Instead, you must run the make command manually.

Builder Xcessory actions

When you perform the preceding steps, Builder Xcessory:

· Generates all source code and files in the language you specified.

· Tells your environment to begin a build through that environment's build manager or make tool.

· Reports the status of the build in the Browser message window.

Example

This example assumes you are using Builder Xcessory with DEC FUSE, Developer Magic, or Workshop, and you are ready to execute a build of your application in C. (The procedure is similar in other languages.)

To execute the build, follow these steps:

1. Select Code Generation Preferences from the Browser Options menu to display the Code Generation Preferences dialog.

2. Click on the Makefile tab.

3. Verify the parameters on the Makefile Customization dialog.

4. Select Make Application from the Browser Project menu.


Note: If the DEC FUSE Builder is not already running, it starts automatically. The first time it runs, you must enter the Makefile name in the configuration dialog. In any subsequent session it is not necessary to enter the Makefile name.

While your application is building, any related messages are displayed in the message area of the DEC FUSE Builder, Developer Magic Build View, or Workshop MakeTool.

Example

This example assumes you are using Builder Xcessory without a development environment, and you are ready to execute a build of your application in C++. (The procedure is similar in other languages.)

To execute the build, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog.

2. Click on the Debugger & Manager tab ( Debugger & Build Manager Tab on the Tools Customization Dialog ):

Debugger & Build Manager Tab on the Tools Customization Dialog

3. Select Use CenterLine Tools from the Debugger & Build Manager tab.

4. Select Code Generation Preferences from the Browser Options menu to display the Code Generation Preferences dialog.

5. Click on the Makefile tab ( Makefile Tab on the Language Settings Dialog ):

Makefile Tab on the Language Settings Dialog

6. Verify the C++ parameters on the Makefile tab.

7. Select Make Application from the Browser Project menu.

8. Use Code/ObjectCenter to manage the make.


Note: On platforms that support Code/ObjectCenter, you can use Code/ObjectCenter instead of the environment's make manager.

While your application is building, messages are displayed in the Browser message area.

Using a Debugger

While you are developing your application, you can debug it at any time without leaving Builder Xcessory.

If you are using Builder Xcessory with SunSoft Workshop or Silicon Graphics Developer Magic, you can access that environment's debugging tool or a CenterLine debugger.

If you are using Builder Xcessory on HP-UX platforms, CenterLine is the only debugger available.

Using your environment's debugger

To start your environment's debugger from Builder Xcessory, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog.

2. Click on the Debugger & Build Manager tab.

3. On the Debugger & Build Manager tab, choose Use Environment Tools from the option menu.


Note: Select Use CenterLine Tools if you prefer to use CodeCenter or ObjectCenter rather than your environment's debugger.

4. To start your debugger, select Debug Mode from the Browser Project menu.

When you perform this procedure, Builder Xcessory:

· Generates all source code and files in the language you specified.

· Builds the code.

When the build is complete, Builder Xcessory loads the executable file into your environment's debugger, which is displayed on your screen.

Example

This example assumes you are using Builder Xcessory with SunSoft Workshop, and you are ready to execute a build of your application in C++.

To execute the build, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog:

Tools Customization Dialog

2. Select Use Environment Tools from the Debugger option menu.

3. Select Debug Mode from the Browser Project menu.

Builder Xcessory generates the code and files in C++, and causes the code to be built. The executable file is then loaded into Workshop' Debugger and displayed on your screen.

Using the CenterLine debugger

To start either of the CenterLine debuggers from Builder Xcessory, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog.

2. Click on the Debugger and Build Manager tab.

3. In the Debugger & Build Manager section of the Tools Customization dialog, set the Execute CenterLine Command toggle to the desired value.

Setting the toggle causes Builder Xcessory to try to start a CenterLine tool if Builder Xcessory cannot communicate with a currently running process.
Unsetting the toggle causes Builder Xcessory to cease attempting to communicate with a currently running process.

4. Check the message and command input fields and make any changes.

5. To start either of the CenterLine debuggers, select Debug Mode from the Browser Project menu.

When you perform this procedure, Builder Xcessory:

· Generates all necessary source code and files in the language specified.

· Sends the C or C++ Message to Code/ObjectCenter, which by default causes Code/ObjectCenter to load and run the application.

Accessing Source Code Control Systems

While using Builder Xcessory, you can check out and check in files from a source code control system without exiting Builder Xcessory. If you are using Builder Xcessory from a development environment, you can access that environment's source code control system. If using Builder Xcessory as a stand-alone program, you can use RCS, CMS, SCCS, ClearCase, or a system you specify. If properly configured, Builder Xcessory can automatically check out UIL files under Source Control.

Regardless of whether you are using Builder Xcessory with a development environment or not, the steps you take to select and use a source code control system are the same.

Selecting a Source Code Control System

To select a source code control system from Builder Xcessory, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog ( Tools Customization Dialog).

2. On the Source Code Control tab of the Tools Customization dialog, choose the name of the system you want to use from the option menu. The default option is Unset .

If you are using Builder Xcessory with FUSE, select Use Environment Manager from the option menu.

3. If you want Builder Xcessory to automatically ask you whether or not to try to check out read-only UIL files when they are read in, set the Check Out Read- Only Files toggle. Otherwise, Builder Xcessory will read the file but not overwrite it.

4. Check that the commands displayed on this dialog are correct. If you want to make any changes, enter them directly in each input field.


Note: The commands text fields are only sensitive if the Source Code Control option is set to a source control system . For more information, see Editing the Commands for Source Code Control .

5. Dismiss the Tools Customization dialog.

Editing the Commands for Source Code Control

If you have chosen a Source Code Control option, the text fields for the source code control commands will be sensitive. This section describes the edits you may want to make to those commands.

Any commands you enter in the command text fields should be suitable for passing to sh -c . The commands should also require no user intervention.

Builder Xcessory processes the command before executing it, in order to substitute any options you set on the Check In and Check Out dialogs (Browser:Project). (These dialogs are discussed in detail in Using a Source Code Control System .)

Entering a new source control command

Use the following notation to enter a new source code control command:

%file[option_specification %s]
%overwrite[option_specification]
%version[option_specification %s]
%keep[option_specification]
%comments[option_specification %s]

Builder Xcessory will copy option_specification and add the text in %s when one of the above options is indicated from the Check In or Check Out dialogs.

Example

For example, you can specify a version string for a file in both the Check In or Check Out dialogs. How this string is passed to the source code control commands varies from system to system. Suppose the check out command for the source code control system you are using is check_out , and in order to specify a version to check out you would enter:

check_out -v "version_string"

In Builder Xcessory you would enter:

check_out %version[-v "%s"]

When Builder Xcessory attempts to check out a file, it looks for %version in the command string. If you have specified a version string in the dialog, Builder Xcessory will add the option you specified within the square brackets and replace the %s with the string entered in the Check Out dialog.

Using a Source Code Control System

This section describes first how to check a file out of source code control, then how to check it back in.

Checking a 
file out

To check a file out of source code control, follow these steps:

1. Select Check Out Source from the Browser Project menu to display the Check Out dialog:

Check Out Dialog

2. Set or remove any check out options you want.

You can choose one of the following options:
· Lock a file when you check it out
· Check out a read-only version
· Remove a lock that you have set
In addition, you can specify a version string number, or overwrite a read-write version of a file that is currently checked out.

3. Navigate through your directory structure in the Directories window of the dialog, if the directory you want is not already displayed.

4. Select the file you want to check out from the Files window in the dialog. The full pathname of the file you selected is now displayed in the Selection input field.

5. To check out the file, click on Apply .

Checking a 
file in

Once you have finished modifying a file, you will need to check the updated version back into your source code control system. To do so, follow these steps:

1. Select Check In Source from the Browser Project menu. This displays the Check In dialog, as shown in Check In Dialog .

Check In Dialog

2. Select the file name you want to check in from the list of files displayed.

3. Specify comments for your modifications in the comments field.

4. If you want to keep a read-only copy of the file, set the Keep File Copy toggle.

5. To check the file back in, click on Apply .

Example

This example assumes you are using Builder Xcessory without an external development environment, and you are ready to check a file out of SCCS, modify the file, and check it back into SCCS.

Selecting SCCS as the source code control system

To select SCCS as your source code control system, use the following steps:

1. Select Tools Preferences from the Browser Options menu.

2. In the Source Code Control option menu, choose Use SCCS .

3. Check that the commands displayed on this dialog are correct.

4. Dismiss the Tools Customization dialog.

Checking a file out of SCCS

To check a file out of SCCS, use the following steps:

1. Select Check Out Source from the Browser Project menu.

2. Set the Check Out Locked toggle on the Check Out dialog.

3. Set the Overwrite Existing File toggle on the Check Out dialog.

4. Navigate through your directory structure in the Directories window of the dialog, if the directory you want is not already displayed.

5. Select the file you want to check out from the Files window in the dialog.

6. To check the file out, click on Apply .

Checking a file in to SCCS

After modifying the file, use the following steps to check in back into SCCS:

1. Select Check In Source from the Browser Project menu.

2. Select the file name you want to check in from the list of files displayed.

3. Document the changes you have made to the file in the comments field.

4. To check the file back in, click on Apply .

Using a Memory-Access Error-Checking Tool

You can also specify a memory error-checking tool to use with your code.


Note: The only error-checking tools currently available for Builder Xcessory are Purify and MemAdvisor.

Selecting an error-checking tool

To specify an error-checking tool, follow these steps:

1. Select Tools Preferences from the Browser Options menu to display the Tools Customization dialog.

2. Click on the Test Tools tab ( Test Tools Panel on the Tools Customization Dialog ):

Test Tools Panel on the Tools Customization Dialog

3. On the Test Tools tab of the Tools Customization dialog, select Purify Command, MemAdvisor Command, or Other Command.

4. Set the toggle to select that tool.

Connecting 
to an error-
checking tool

When you select a test tool, Builder Xcessory adds targets for that tool to the makefile. When you build your code, you can use the pure target to build an instrumented version of your application. When you run your application, the error-checking tool provides information about memory usage and errors in the object code. The executable provides information about memory leaks and accesses.

Using Builder Xcessory with Emacs

Using emacsclient

Builder Xcessory uses the tool emacsclient to tell Emacs to load a file and display the buffer. Emacs must be running. Builder Xcessory issues a request of this "Edit Server". By default, Emacs is not configured to run as a server. In order for the emacsclienttool to work, you must add the following Emacs Lisp command to your .emacs file (the file that emacs runs at startup):

(server-start)

Enter this line exactly as shown, including parentheses. Once Emacs loads and executes the .emacs file again (usually when it starts), it recognizes edit requests from emacsclient .

Running Emacs with emacsclient requires that the emacsclient executable and Emacs executable be run on the same machine. The socket that emacsclient uses to communicate with emacs is a local socket.

Using gnuclient

To enable emacs to run on one system and the client program to make edit requests from another system, you can use gnuclient. gnuclient works similarly to emacsclient , but also includes the following features:

· The -q option forces gnuclient to send its edit request but not wait for the request to complete. The gnuclient process exits as soon as it sends the edit request.

· The gnuclient software includes the ability to specify another host on which emacs is running and to make the edit request on that machine.

The gnuclient software is available with FTP from most GNU Emacs Lisp archive sites. To use gnuclient / gnuserv , include the following in the .emacs file:

(load "gnuserv")
(server-start)

 

Documentation: 

Internationalizing Applications

Overview

This chapter reviews the concepts of internationalization (I18N). For more detailed information, we recommend Chapter 11 of the OSF Motif Programmer's Guide, Release 1.2 . For additional documentation on the underlying X and Xt support for localized applications, refer to Chapters 10 and 11 of the XLib Programming Manual from O'Reilly & Associates, Inc.

Note: This chapter assumes that you are using Motif 1.2 or later. Earlier versions do not support locales.

 

Internationalizing Your Application

Internationalization (I18N) is the development of applications that can be run in different language environments (Japanese, Spanish, English, and so forth) without code revision or recompilation. The code is free of dependencies on language, character set, or special data representations (for example, currency and time formats).

Localization

Any language-specific information required by the application must be kept separate from the application source code. Typically, this information includes:

· Data Presentation Format

· Collation Order

· Numeric Format

· Currency Format

· Time Format

· Date Format

· Bitmaps

· Icons

· Geometry

· All strings to be displayed to the user

Localization is the process by which this information is prepared for access by the application in the context of a given language.


Note: Not everything can be localized. Source code elements such as identifiers, resource names, and instance names must remain C-readable.

In the course of writing an application that will work in different languages, you must make decisions concerning coding, input techniques, and output methods and formats. Builder Xcessory has several features that assist you in producing an internationalized application.

Character Sets and Code Sets

The practical problem with I18N arises from the different representation methods used by languages to build their respective linguistic elements. Most especially, ideographic languages, which can contain literally thousands of individual glyphs, cannot be fully represented using standard 8-bit code sets.

Character set

A character set is the set of all the characters required to represent the words in the language.

Code set

A code set is the set of binary values required to represent the character set of a language.

ISO8859-1/ Latin-1

ISO8859-1 (also called Latin-1), which contains the ASCII codes, is the standard code set for the representation of English, as well as several other alphabetic languages.

Code sets correspond to various languages or areas. For example:

Language or Area

Code Set

English, Western Europe

ISO8859-1

Eastern Europe

ISO8859-2

Northern Europe

ISO8859-3

Cyrillic

ISO8859-5

Hebrew

ISO8859-6

Greek

ISO8859-7,8,9

Japan

JIS X 0201

JIS X 0208

JIS X 0212

Korea

KSC5601.1987-0

 

X and Motif I18N Support

When X11R5 and Motif 1.2 were released, they contained new data types, function calls, fonts, and modifications to widgets to handle the localization of graphical user interface (GUI) applications. These additions provide a method by which you can create applications, with one set of source code, that can run in any one of several alternative languages, depending on the locale. Although these additions enable I18N and localization, they do not facilitate them.

Types of problems

When internationalizing an application, there are three broad types of problem:

· File processing problems

How are characters encoded; how does your application deal with storage formats for dates, addresses, currency, and so on?

· Input problems

How are the characters of a complex character set (for example, ideographic sets) actually entered when it is impractical to construct a physical keyboard capable of representing every one of those characters?

· Output problems

How are characters of different languages displayed within the application, especially within the same text area?

Note: Builder Xcessory uses the same features supported in generated code, so you can choose to run Builder Xcessory in another locale. This allows strings to be input with that locale's input method.

Note: A Japanese version is available. Contact your ICS Sales Representative.

Application Coding

An I18N program must operate regardless of the encoding of the characters in the user's language. A program that ignores or truncates the eighth bit of every character (as some English-based applications do) will not work in Europe, which requires eight bits to represent accented characters. Similarly, an application that assumes that every character is eight bits long will not work in Japan, where there are many thousands of ideographic characters. In addition, you cannot assume a single character size, because Japanese commonly intermixes 16-bit Japanese characters with 8-bit Latin characters.

Adding Localization Calls to the Code

Xt support of internationalization is trivial in most applications: the only code required is a call to XtSetLanguageProc() just before the call to XtAppInitialize(). This one function call does all the set-up necessary for an Xt-based application. Some additional work is required if your application is to support internationalized text output or input (as explained in Input methods ).

Builder Xcessory makes the XtSetLanguageProc() function call in the code generated if you set the Initialize Localization Support toggle in the Code Generation Preferences dialog.

Localization support is always enabled in ViewKit applications.

 

Locales

A locale is the language environment determined by the application at run time. The X/Open Portability Guide, Issue 3 (XPG3)defines locale as a means of specifying three characteristics of a language environment that might be required for localization:

· Language

· Territory

· Code set

These elements are represented by many systems in the following format:

<language>_<TERRITORY> . <code set> .

For example, ja_JP.ujis is the representation for Japanese, as used in Japan with the UJIS code set.

Using locales

At start-up, the application must find the correct UID file in either the DECW$USER_DEFAULTS or DECW$SYSTEM_DEFAULTS directories. See the DECwindows Motif Release Notes for more information.

As an example of using locales, assume you have an application with two different language versions. You set yourXUSERFILESEARCHPATH (see Static output ) to the following (all of which should appear on one line):

/usr/lib/X11/app-defaults/%l/%t/%c/%N:
/usr/lib/X11/app-defaults/%l/%t/%N:
/usr/lib/X11/app-defaults/%l/%N:
/usr/lib/X11/app-defaults/%L/%N:
/usr/lib/X11/app-defaults/%N

This search path allows your application to search from the most specific designation of the locale to the least specific, allowing you a high degree of flexibility in configuring your application. See the explanation of "XtResolvePathname" in Vol. 5 of the O'Reilly & Assoc. X Toolkit Intrinsics Reference Manual for an explanation of the various substitutions and how they relate to the locale designation.

Most vendors' implementations of X automatically include locale-specific searches in the default search path environment variables, so setting these variables is usually unnecessary.

Example

If you are using UIL for your application, you can use a similar mechanism to search for the compiled UIL (UID) files.

Set UIDPATH to the following (all of which should appear on one line):

<pathname>/%l/%t/%c/%U:<pathname>/%l/%t/%U:
<pathname>/%l/%U:<pathname>/%L/%U:
<pathname>/%U:

At start-up, the application finds the correct UID file based on how your UIDPATH is set. See the description of MrmOpenHierarchyin the 
OSF Motif 1.2 Programmer's Reference for further details.

Locales in Builder Xcessory

The application must have a way of recognizing the language environment in which it is running. Based on this information, the application can then make adjustments such as allowing the display of strings in the appropriate language. Builder Xcessory provides a code generation option to enable this support in your application.


Note: ViewKit applications always have localization support enabled by the VkApp object.

Enabling localization

To enable localization, follow these steps:

1. Select Code Generation Preferences from the Browser Options menu.

2. Click the Application tab on the Code Generation Preferences dialog ( Code Generation Preferences Dialog ).

3. Set the Initialize Localization Support toggle, and dismiss the dialog.

When the main C or C++ file is written, the following line is included:

(void) XtSetLanguageProc (NULL,
(XtLanguageProc)NULL,
NULL);

Builder Xcessory inserts code into the main routine to initialize the toolkit I18N features. When the code is compiled and run, the toolkit examines the LANG environment variable to determine the current locale, and then initialize its internal routines to deal with locale-specific issues.

For example, if the user has set the LANG environment variable to ja_JP . ujis , the application automatically initializes support for Japanese language character input and display, as well as monetary and date output, and so forth.

Code Generation Preferences Dialog

Setting locales

If the Initialize Localization Support toggle is not set, you can manually set the locale in your application using the ANSI C functionsetlocale . The function setlocale (LC_ALL,"") sets all locale-specific information to the default (the LANG environment variable). The function 
setlocale(LC_COLLATE,"ja_JP.ujis") sets only the collation order to that of the Japanese UJIS code set.

The function setlocale() is called from the default language procedure installed by XtSetLanguageProc() , described in detail in Asente, Converse, Swick's X Window System Toolkit . XtSetLanguageProc() also initializes the toolkit internationalization techniques, connects to the input method (if necessary), and sets various defaults for the current locale, as specified by the LANG environment variable.


Note: The default language procedure can be replaced using XtSetLanguageProc() with arguments other than NULL. Refer to O'Reilly & Associates' X Window System , Volumes 4 and 5 for a more detailed discussion of Xt language procedures.

Locale-friendly coding

When coding an application to be run in multiple locales, consider the following issues:

· Use ANSI C or C++; Kernigan & Ritchie 1 implementations may not support locale-aware string manipulation.

· Use strcoll() rather than strcmp() for string comparisons.
strcmp() routine assumes an ASCII character set when doing string comparisons; strcoll() has no such limitation and can deal with locale-specific character encoding and sorting order.

· Do not make assumptions about word order in strings, and do not make comparisons to specific, hardcoded, characters.

· Use strftime() rather than ctime() or asctime().
strftime()
 formats time and dates according to locale; both ctime() and asctime() are of limited flexibility.

· Use ctype(3) library routines to identify character ranges.

· Use wchar_t , rather than char as the type for string processing.
The char type allocates a fixed size (8 or 16 bit, depending on the architecture) for a character. This is not enough to hold the characters of some locales, particularly the idiographic languages. The wchar_t type allocates size sufficient to hold the largest character in the current locale. This can be grossly inefficient, so you should only use wchar_t for operations that index arrays of characters.

· Do not hardcode decimal separators in parsing or arithmetic operations. Some languages use a comma rather than a period for a decimal separator.

· Do not embed pixmap graphics in code; specific colors and graphics can have different meanings from locale to locale.

Placing Resource Values in Resource or UIL Files

Your application should not explicitly code any language-dependent information. 2 This includes strings, fonts, and language-dependent pixmaps. In order to do this, the Open Group (formerly OSF) suggests that these resources be placed in message catalogs, resource files or UIL files.

Builder Xcessory allows resources to be placed in resource files. Once a resource is set, you can choose (on an individual resource or resource class basis) whether that resource is set in the code or in a resource file.

Individually, this choice is made with the Resource Placement menu, to the right of the text field used to enter the resource value (seeResource Editor Placement Settings ).

Code

· Code indicates that the resource is hard-coded with calls to XtSetValues, and is the default.

App

· App indicates that the resource is placed in an app-defaults file, which can be edited to produce localized versions of the application.

Resource Editor Placement Settings

Resource values can also be placed in a resource file on a type basis by setting the resource's default resource placement. In the placement window, types can be specified to be put, by default, into Code or App (resource file).

Example

For example, if you want to place all compound strings and fonts into resource files, follow these steps:

1. Select Default Resource Placement from the Resource Editor Options menu to display the Default Resource Type dialog:

Default Resource Type Dialog

2. Scroll the dialog to find the Compound String and Font types, and set the App toggle for each (see Default Resource Type Settings).

Default Resource Type Settings

Generating Multiple UIL Files

Builder Xcessory also allows you to generate single or multiple UIL files, providing another language-independent way of specifying resource values that can be used to internationalize an application. To save resources in a UIL file, set the resource to be saved into code and when generating code, generate UIL instead of C or C++.


Note: You can only generate UIL files if generating an application in C (not in C++).

Once you generate a resource (or UIL) file, you must make copies of the file for each language supported and modify the contents accordingly. Then, using the locale of the machine and the environment variables LANG, UIDPATH, and XUSERFILESEARCHPATH, the different resource or UIL files are read and used by the application at run time.

For more information on this topic, refer to the OSF/Motif Programmer's Guide, Release 1.2, pages 11-26 to 11-31 and in the X Window System Toolkit, pages 433-436.


1. Kernigan, Brian & Ritchie, Dennis. The C Programming Language, 2nd ed. (Englewood Cliffs, NJ: Prentice Hall PTR, 1988).

2. OSF/Motif Programmer's Guide, Release 1.2, page 11-21; PTR Prentice Hall, Englewood Cliffs, New Jersey 07632

Text Input

An internationalized program must be able to display all the characters used in the user's language, and must allow the user to specify all those characters as input. When there are more characters in a language than there are keys on a keyboard, some sort of "input method" is required to convert multiple keystrokes to single characters.

Input methods

An input method is a mapping between keyboard input and the text data passed to the application. Such a mapping exists even within the familiar context of ISO8859-1 where, for example, the combination of the <Ctrl> or <Alt> key and a letter translates into a letter with a special accent mark: ü, é, and so forth.


Note: Within the 7- bit ASCII characters, there are no accented characters. However, ISO8859-1 is a superset of ASCII extending the code set to 8 bits, and includes accented characters and symbols.

The concept of an input method is especially important for ideographic languages. Review Chapter 11 of the OSF/Motif Programmer's Guide , Release 1.2 for a detailed discussion of the different aspects of input methods and how they are supported by Motif.

Motif support of input methods

Builder Xcessory assumes that you have access to an input method. Input methods are available in Motif 1.2. Prior to Motif 1.2 and X11R5, input methods were proprietary additions, and no standard existed. Builder Xcessory supports the use of X11R5-style input methods exclusively.

Using input methods

Input methods allow your users to enter text in their native language. There are several input methods available from hardware vendors and third party software vendors. The X source code distribution also includes a few sample implementations. They run as separate processes alongside the internationalized applications.


Note: Multiple input methods can run simultaneously for any number of internationalized applications.

Integrating with an input method

To allow your application to use a currently running input method, follow these steps:

1. Make sure that your locale is set correctly. Many platforms have dialogs to simplify this process, but usually setting the LANG environment variable is sufficient.

2. Make certain your application calls XtSetLanguageProc() before it calls XtAppInitialize(). This ensures that X/Motif localization support is properly initialized.

3. Create an application defaults file for your application that sets the font list resources to the font set appropriate for your locale.

4. Start your application.

The input method, with the locale set and the correct X11R5 calls in your application, communicates with your application automatically.

Text Output

An internationalized application displays all text in the user's chosen language. This includes prompts, error messages, and text on buttons, menus, and other widgets. The simplest approach to this requirement is to remove all strings that are to be displayed from the source code of the application and store them in a file that will be read when the application starts up. That file can then be translated into various languages, with the appropriate version being read at start-up.

In addition, an internationalized application must display times, dates, numbers, and so on, in the format that the user expects. For example, Americans expect dates in the form month/day/year, English expect day/month/year, and Germans expect day.month.year.

Setting Up Localized Output

Most languages use words from different languages and some require the word's native character set to be used. For example, a Japanese application might require error messages with a mix of Hirigana, Katakana, and Kanji characters, as well as some technical terms that require a Latin character set. This means that in one string there could be 5 words using Kanji characters and one word using Latin characters, requiring 2 different fonts.


Note: It is possible to display characters of multiple character sets within the same output string using compound strings and font lists.

Compound Strings

A compound string is a byte stream in ASN.1 encoding, consisting of tag-length-value segments.

Motif uses compound strings in many widgets. A compound string is used to set labels on label and button widgets as well as the contents of lists in Motif. These compound strings hold all information related to a string, including the text, direction and font used to display the string.

Compound string components

A compound string can contain the following components:

· Text of the string

· Separators (or line breaks)

· Font list tags

· Direction identifiers

Compound String Editor

The Compound String Editor allows strings to have multiple fonts and direction, and allows for a connection to an X input method. For more information on the Compound String Editor, refer to Compound String Editor .

Motif does not supply a String-to- XmString converter that understands font list tags or direction information. Builder Xcessory provides a String-to-XmString converter in the bxutils file, which supports Builder Xcessory style ASCII representations of compound strings.

Template code

The template code for the converter is in the file:

{BX}/xcessory/gen/common/bxutils.c

ASCII compound string format

The ASCII compound string format is:

:: [#tag][:t][:r]["xxxxx"]

where:

tag is font tag (or charset).

:t is set when a separator is requested.

:r is set when the string is displayed from right to left.

"xxxxx" is the text portion of the string.

Creating Multifont and Multidirectional Strings

A font list is a resource type that can be a single font or a font set. Font sets were introduced in X11R5 and Motif 1.2 (as the XFontSet). A font set is treated as a single entry in a font list, but contains all the fonts required to display all the characters of a locale. Internal X, Motif, and C routines are used to encode the font information for displaying a given string.

Font List Editor

The Font List Editor in Builder Xcessory supports the specification of font sets as well as regular Fonts (see Font List Editor ). For more information on the Font List Editor, refer to Font List Editor .

Font List Editor

You create the different font sets and tag them, so that they can be used in defining multifont strings.


Note: A font set is defined by the locale in which the program is running. For example, a font set that works in a Korean locale will not work in a Japanese locale.

Each font set member can use a different encoding, family, size, and so forth, and there are no limits on how many fonts can be defined for a given font set.

Once a font set has been added to a font list, it can be used like any other entry in the list. Motif and X control how to use the various fonts in the font set.

bxutils file

Although Motif 1.2 supports multiple entry font lists containing both fonts and font sets, Motif does not supply a String-to- XmString converter that understands font list tags or direction information. Builder Xcessory provides such a converter in the bxutils file. This converter is installed in your application by a call to RegisterBxConverters(). The converter supports a special textual representation of all the information encoded in a compound string: font tag, direction, etc. This allows you to quickly create multifont and multidirectional strings and use them with the Motif widget set, even though they are not supported in Motif 1.2. This code is completely portable and OS independent.

Generating Localized Files

The following sections discuss the generation of files for an internationalized application. Static and dynamic output are considered for both UIL and C/C++ generation. In static output, strings are created when the source code is generated. In dynamic output, strings are incorporated at run time by reference to a separate source.

Generating UIL

Static and dynamic output

Static and dynamic output are handled in the same manner when generating UIL. Typically, App-defaults files are not used. Instead, the application maintains a list of messages in a separate UIL file for each locale. When the application is built, the appropriate UIL is compiled into a UID and then used.

Use the Constant Manager and File Manager to create each of the locale-specific UIL files:

· Code all output (for example, warning, error, and informational messages) as constants.

· Set the file placement for this output to the appropriate UIL file. The application then fetches the value of the constant from the UID at run time.

Generating C and C++

Your application handles static and dynamic output differently in C/C++.

Static output

When generating C/C++, save Strings and XmStrings, as well as other locale-specific information such as fonts and colors, in app-defaults. To do this, you can take advantage of the X environment variables XFILESEARCHPATH andXUSERFILESEARCHPATH.

The following table lists the substitutions X and Motif allow in these paths:

Platform

Substitution

Description

X

%N

Value of the filename parameter, or the application's class name if filename is NULL

%T

Value of the type parameter

%S

Value of the suffix parameter

%L

Language string associated with the specified display

%l

Language part of the display's string

%t

Territory part of the display's string

%c

Code set part of the display's string

Motif

%U

Value of the UID filename parameter

See the section "Finding File Names" in X Window System Toolkit by Paul J. Asente and Ralph R. Swick (p. 860 in ISBN 1-55558-051-3) for further details.

Dynamic output

If you plan to use C or C++ instead of UIL to handle string output, write your application so that dynamic output uses a message catalog. A message catalog is a method for storing and fetching strings to/from external sources.

Message catalog options

You have three options for a message catalog:

· Use the MNLS standard

· Use the XPG standard

· Design your own


Note: To use one of the first two methods, your operating system must support it. Different operating systems require different storage locations for the catalog.

Designing Your Own Message Catalog

Designing your own message catalog is your only choice if you plan to run on a set of operating systems that do not share a common standard.

Example

The following procedure is one of many ways of designing your message catalog:

1. Use the Berkeley DBM library, which, given a key or a tag string, fetches the corresponding message string.

2. Represent the tag string in Builder Xcessory as constants.

3. Use the DBM string fetching routines, passing the tag string and a default message string as parameters. If the lookup of the message catalog yields no match for the tag string, display the default message string.

Suggested Reading

There are many considerations when designing an internationalized application. The following documents are useful references for I18N design issues:

· OSF/Motif Programmer's Guide, pp. 11-21. Prentice-Hall, 1993. 
(ISBN 0-13-643107-0)

· O'Donnell, Sandra Martin. Programming for the World: A Guide to Internationalization. Prentice Hall, 1994. (ISBN 0-13-722190-8)

· Scheifler, Robert W. and James Gettys. X Window System-Extension Libraries. Digital Press, 1997. (ISBN 1-55558-146-3)

· X/Open Portability Guide . 3rd ed. Prentice Hall, 1989. (ISBN 0-13-685868-6)

· Tuthill, Bill and David Smallberg. Creating Worldwide Software: Solaris International Developer's Guide. Prentice Hall, 1997. (ISBN 0-13-031063-8)

· Aldersey-Williams, Hugh. Nationalism and Globalism in Design . Rizzoli International Publications, 1992. (ISBN 0-84-781461-0)

· Nye, Adrian. Xlib Programming Manual . 3rd ed. O'Reilly and Associates, 1992. Volume 1 in the O'Reilly X Series. (ISBN 1-56-592002-3)

· Nye, Adrian and Tim O'Reilly. X Toolkit Intrinsics Programming Manual, Motif Edition. O'Reilly and Associates, 1992. Volume 4 in the O'Reilly X Series. (ISBN 1-56-592013-9)

· Heller, Dan and Paula M. Ferguson. Motif Programming Manual. 2nd ed. O'Reilly and Associates, 1994. Volume 6A in the O'Reilly X Series. (ISBN 1-56-592016-3)

· Asente, Paul, Donna Converse, and Ralph Swick. X Window System Toolkit. Digital Press, 1997. (ISBN 1-55558-178-1)

 

Documentation: 

Layouts and Geometry

Overview

Builder Xcessory facilitates working with layout and geometry management objects. With combinations of direct manipulation and specialized editors, Builder Xcessory provides WYSIWYG ("What You See Is What You Get") access to the powerful, but complex and otherwise difficult to use manager widgets-- most notably the Motif Form widget and the Java AWT objects with their various layout policies such as the GridBag.

Managing Your UI Layout

As you plan the layout of your user interface, you spend a large percentage of your time allowing for changes the end-user will make to the interface. These changes can be as simple as resizing a window, or as complex as changing fonts, the language used in your labels, and menus.

Generally, you can cede a certain amount of control to a container with a powerful (and typically complex) layout policy, or you can retain control over the layout. The latter approach results in a great deal of work on your part, or an interface with very limited flexibility. In practice, you will find some situations where you want to limit the flexibility and some situations where you want to use as much of the power from your UI toolkit as possible by using the more complex containers and layout policies.

Placing Objects with the Layout Grid

Builder Xcessory has an invisible object placement grid that makes it easier to place and resize objects so that they are aligned. When you place, or move, an object into your interface, its upper-left hand corner snaps to the nearest grid point. When you use the mouse to resize an object in your interface, the edge that you are moving snaps to the nearest grid point.

Setting the Layout Grid Size

To change the size, or resolution, of the Layout Grid, select the General tab of the User Preferences dialog (Browser:Options), and specify a value (in pixels) for the grid size in the Grid Units field.

Disabling the Layout Grid

To turn off the Layout Grid, deselect the Snap To Grid toggle from the Browser View menu.

 

Note: Changing the Grid size, or disabling the Grid has no effect on objects already placed in your interface.

Aligning and Distributing Objects

Aligning

When you align a set of selected objects, you line up one edge or the center of the selected objects with that of some reference object. For example, to make a horizontal left alignment is to line up the left edges of all selected objects with the left edge of the object located farthest to the left on the interface. The selected objects are moved so that the left edge of every object lines up with that of the left-most object.

Distributing

When you distribute a set of objects, you space them evenly without moving the outermost objects. For example, to distribute horizontal centers is to space the horizontal centers of all selected objects equally between the center of the left-most object and the center of the right-most object.

When you choose Java as your code generation language, you can only directly move or align objects (with the mouse, the Alignment Editor, etc.) if you have selected No Layout (in source code terms, foo.setLayout(null); ) for the parent. In all other cases, the layout policies of the parent object dictate the size and placement of the object.

 

Note: Frequently, geometry management policies of an object's parent dictate the size of the object. In these cases, the mouse, the placement grid, and the alignment menus and editors are all ignored.

Aligning Existing Objects

You can rapidly align any set of existing objects with Builder Xcessory using the Align item from the Browser Edit menu (and also the MB3 Quick Access menu).

1. Select the objects you want to align with one of the following methods:

· Search/Select Area in the Browser
· Shift-MB1 Drag to circle the objects in the Browser, or your interface
· Ctrl-MB1 to select or deselect individual objects

2. Select Align from the Browser Edit menu or MB3.

3. Select the desired alignment from the resulting menu.

· Left, Right, Top, Bottom, Horizontal Center, Vertical Center
· Alignment Editor
Using the Alignment Editor

The Alignment Editor provides extensive control over the positions of your objects. You can both align and distribute your objects. The Alignment Editor also displays an example of your alignment and distribution options, allowing you to view the effects of your changes before you commit them.

Alignment Editor describes the elements of the Alignment Editor window:

 
Alignment Editor Additional Layout Techniques

The following sections describe other techniques for layouts.

Reordering Menu Items

To reorder the items in a menu, select Raise or Lower from the Browser Edit (or MB3 Quick Access) menu. The selected option moves up or down within its menu.

Placing Objects without Setting width and height

Place an object with Ctrl held down to create the object without setting its width and height resources. The object is sized according to a complex algorithm governed by its own sizing policies. For these policies, refer to the object's description in See Palette Objects .

You can also remove explicit height and width settings from an existing object by selecting Natural Size from Browser:Edit or the MB3 Quick Access menu.

Using Motif Geometry Managers

OSF/Motif contains a number of geometry managers that govern the layout and resize behavior of their children. They range from the straightforward and easy-to-use XmBulletinBoard, to the complex and difficult-to-use XmForm. Builder Xcessory helps you use these managers effectively, from experimenting with different managers, to selecting the appropriate manager, to fine-tuning your final choice of resource settings.

Simple Motif Managers

In general, to use the simple managers described in the following section, you create the manager, create the children, and, depending on the particular manager, move and resize the children directly with the mouse, or set resources on the manager using the Resource Editor.

XmBulletinBoard

The Motif BulletinBoard is the simplest of the Motif managers, and does not control the size or the position of its children. When you use a BulletinBoard with Builder Xcessory, you can take maximum advantage of direct manipulation. Using the mouse, the Layout Grid, and Alignment facilities with the BulletinBoard, what you see is exactly what you get. The flip side of this ease-of-use is that you'll need to manage the x, y, width, and height of all the children in your application code to deal with resize actions from the user. The BulletinBoard is most commonly used when such actions are disallowed, for example, in dialogs.

 

Hint: Many Builder Xcessory users begin a layout with a BulletinBoard, rather than paper and pencil, to get an initial idea of the screen. They then change the BulletinBoard (by editing the Class Name in the Resource Editor) to a more sophisticated container, such as a Form, and continue work on resize behavior. By changing the class, you maintain the rest of your interface.

XmScrolledWindow

The ScrolledWindow is typically used to provide a viewing area onto a larger widget. Its scrollbars are easily controlled from the Resource Editor.

 

Hint: It is often easier to create the ScrolledWindow's child before placing it in the ScrolledWindow, because Builder Xcessory does not allow scrolling in Build Mode. To reparent a widget, see Copying and Reparenting Widgets .

XmMainWindow

The MainWindow is frequently used as a top-level window and is designed to manage a MenuBar, a work area with scrollbars, a command area, and a message area. All of these children are optional. The MainWindow manages the size and position of these children, placing the menu bar at the top of the window, stretched to its full width, and placing the message area child at the base of the window, again stretching to its full width. The MainWindow places the command area child above, or below the work area child, and creates and manages the scrollbars on the work area for you.

MenuBars

The MainWindow automatically recognizes and manages the MenuBar. When you create a MenuBar, size does not matter, as a child of a MainWindow, Builder Xcessory automatically manages and sizes it correctly. Add PulldownMenus to the MenuBar and the MenuBar size is again set correctly.

Work, Message, and Command Children

The various MainWindow children are easy to handle with Builder Xcessory. Create the desired objects and place them as children of the MainWindow. Then use the Resource Editor to set resource values on the MainWindow to specify which child belongs in which area. For example, set the value of the workWindow resource to the desired widget instance name by typing the name directly into the field, or using an extended editor to choose the name from a list of the MainWindow children.

VkWindow and VkSimpleWindow

The ViewKit Application Framework supports the notion of a primary, or main window for an application. Specifically, it provides two classes, VkWindow and VkSimpleWindow. The basic element in both of these classes is the XmMainWindow widget, with the VkWindow also including a menu bar with several pre-built menus.

Typically, you never instantiate a VkWindow or VkSimpleWindow directly, rather, you build and use subclasses. If you use a Motif MainWindow directly from the Palette, rather than a ViewKit component, Builder Xcessory automatically detects this when generating ViewKit code and outputs a VkWindow or VkSimpleWindow as appropriate.

XmRowColumn, XmRadioBox, and Menus

The Motif RowColumn manages its children into rows and columns. There are a number of resources, easily accessed through the Builder Xcessory Resource Editor, that control the exact layout.

In addition to the straightforward row-column layout, there are a number of special cases of the RowColumn, (some of which involve additional widgets) including the RadioBox, MenuBar, PulldownMenu, and PopupMenu. Builder Xcessory facilitates using these variations by providing individual Palette icons. Selecting the PulldownMenu Palette icon, for instance, automatically creates a CascadeButton, a RowColumn configured as a PushButton menu item.

 

Hint: To reorder the items in a RowColumn (any variation, including menus) use the Raise/Lower menu items on the Browser Edit menu or use the MB3 Quick Access menu.

Using Menus

Builder Xcessory helps you work effectively with menus. It automatically creates all of the necessary constituent parts for you, along with an initial PushButton. Then, whenever you have a menu selected, Builder Xcessory posts all of the menu items upon which you are able to perform normal Builder Xcessory functions, including drag and drop. This includes the PopupMenu, which is normally invisible.

You can disable this behavior with the Show Menu Children toggle on the Browser View menu.

Complex Motif Managers

Generally speaking, to use the managers described in the following sections (complex managers), you create the manager, create the children, and use the Resource Editor to set resources on both the manager, and the children . To simplify use of the most complex of these managers, the Form, Builder Xcessory graphically shows the constraints, or attachments, of all Form children and allows you to directly manipulate the attachments with the mouse.

 

Note: Constraint Resources are always listed after the normal resources in the Resource Editor. If the selected widget is not currently a child of a complex manager, no constraint resources are listed.

XmFrame

The Frame widget manages a WorkArea child and a Label child. The WorkArea child is surrounded by the Frame; the Label child is placed above the WorkArea child. The Frame automatically resizes itself to contain its WorkArea child. You specify which child is the label and which the WorkArea child by means of constraint resources on the children.

XmPanedWindow

The PanedWindow places each of its children into its own vertically tiled region. Constraint resources on its children control their positions and preferred sizes.

 

Hint: Use the Resource Manager Widget menu to show and hide particular panes in the PanedWindow by managing and unmanaging the Pane's children.

XmForm

The Form widget is probably the most powerful, but most complex Motif manager. It allows you to manage the layout and resize behavior of its children by setting constraint resources on its children. The large number of possible values for these constraints, and the interactions between them, are what make this widget difficult to use.

Builder Xcessory simplifies this for you by graphically depicting these constraints and allowing you to manipulate them directly with the mouse. You can also set them with the Resource Editor and its extended editors.

Setting Form constraint resources

Each child of a Form widget has four constraint resources (attachment, offset, position, widget) for each of its four sides (left, right, top, bottom). These sixteen resources (for example, leftAttachment or bottomPosition) determine how the object behaves when the Form parent is resized.

Builder Xcessory provides attachment handles and the Attachment Editor (see Attachment Editor ) to assist you in setting Form constraint resources, as described in the following sections.

 
Attachment Editor
 

Hint: Save the interface before using the Attachment Editor. If unexpected changes occur when you make large changes in geometry, select Revert from the Browser Edit menu to reload the last saved version of your interface.

Attachments

An attachment is a resource that binds an edge of an object to either an edge of another object or to a position in the Form.

When working with a Form widget, the order of the creation of its children can affect the resizing properties. For example, when attaching widgets side-to-side, the last widget created resizes when the Form resizes. Use Raise and Lower (from the Browser Edit menu or MB3) to alter the creation order of objects.

Setting and changing attachments

To change the attachment of an object edge, use one of the following methods:

· Click on an attachment handle, drag the attachment to the edge of another child of the form, and release MB1 to set the attachment.

· Hold down MB3 on an attachment handle and choose an attachment from the popup menu. Only attachments for the appropriate edge of the object are displayed.

· Select the object, update the Resource Editor, and set the constraint resources in their respective text fields.

Offsets

A side's offset is the distance maintained between that side and its attachment.

Positions

A side's position is the relative x or y location to which that side is explicitly attached, and is expressed as a ratio with respect to theXmNfractionBase resource.

 

Note: The position can only be set if attachment is set to XmATTACH_POSITION.

Displaying offsets and positions

To display the constraint resource values for an edge of any Form's child, follow these steps:

1. Hold down Ctrl.

2. Move the cursor over the Form child's attachment icon until the cursor takes the shape of the icon.

3. Hold down MB3.

Any attachment, offset, position and widget values not set to NULL are displayed.

Changing offsets and positions

To change the offset or position of an edge of an object that is the child of a Form, follow these steps:

1. Move the cursor over the object's attachment icon until the cursor takes the shape of the icon.

2. Hold down Ctrl + MB3.

3. Move the cursor to the left or right for a left or right edge, or up or down for a top or bottom edge. The value of the position or offset increments or decrements, depending on the edge being set and the direction the cursor is moved.

EPak Manager Widgets

The EnhancementPak widget set, part of the BX PRO product, provides a number of manager widgets that simplify many geometry management tasks. Virtually all of the EnhancementPak widgets are used in the Builder Xcessory interface.

 

Note: You can experiment with the EnhancementPak widgets at any time by setting the Start with EPak Widgets toggle on the Behavior tab (Browser:Options: User Preferences), but you must license the libraries to compile and use an application built with them.

See See Palette Objects for more detailed information about EPak widgets.

XiButtonBox

Combines some of the features of RowColumn and Form, evenly distributing its children into a single row or column. ButtonBoxknows how to center a child. ButtonBoxes are used throughout Builder Xcessory and are found in most of its dialogs and extended editors.

XiColumn

Combines child objects with optional labels in separate columns, and allows you to specify their relative position.

XiIconBox

Similar to RowColumn, IconBox adds the concept of an absolute cell position.

XiOutline

Manages its children into an indented list form. It is a class sibling of the Tree widget. The various icon groups on the Palette are managed by an Outline widget.

 

Note: Using the Outline widget for the Palette allows the user to hide a group.

XiPaned

Similar to the Motif PanedWindow, but allows horizontally-tiled panes in addition to vertically-tiled panes. Paned is used in the Browser and Resource Editor to control the layout of those windows.

XiPlotter

A special purpose manager, Plotter manages any number of the various Plot types (Pie Plot, Bar Plot, etc.) included in EnhancementPak.

XiPorthole

Similar to Motif ScrolledWindow, but used in conjunction with the Panner to provide two-dimensional scrolling, a more efficient way to navigate around a viewing region. Porthole is used in the Browser, allowing you to navigate through your instance and class trees.

XiStretch

Similar to Frame, Stretch provides the added functionality of allowing the end-user to resize the Stretch widget and its child with the mouse. Stretch is used in the Builder Xcessory Browser, allowing you to resize the Panner.

XiTabstack

This container is a simple manager with the visual appearance of a stack of manila folders, and allows you to fit multiple interfaces into a limited space. Tabstack is used extensively in Builder Xcessory's preference dialogs and is seen frequently in Microsoft Windows interfaces.

XiToolbar

Similar to Motif RowColumn, Toolbar adds the notion of toolbar groups, the ability for you to group sets of children together, and the Popup Labels feature, similar to Microsoft's WinTips. Toolbars are used in the Browser and the Resource Editor.

XiTree

Manages its children into a tree layout, optionally giving the user the ability to collapse and expand sections of the tree. Tree is used in the Browser Interface hierarchy display area. This is evident in the Browser and several of the Manager windows.

Java Layouts

A number of layouts are available in AWT for arranging components in your application. Builder Xcessory allows you to work with these layouts intuitively.

Programming Java layouts manually

When programming Java manually, use the following procedure to lay out and manage the objects in your interface:

1. Create the parent object (the container).

2. Create the children (the objects to be managed).

3. Create a layout object.

4. Pass the layout object to the parent.

5. Pass the children to the parent.

Programming Java layouts when using GridBagLayout

However, when using the powerful and flexible GridBagLayout, programming manually becomes time-consuming, as follows:

1. Create the parent object (the container).

2. Create the children (the objects to be managed).

3. Create the GridBagLayout (GBL) object.

4. Pass the GBL to the parent.

5. Create a GridBagConstraints (GBC) object.

6. Set the GBC values for a particular child.

7. Pass the GBC and the child to the GridBagLayout object.

8. Pass the child to the parent.

9. Repeat steps 5-8 for each child to be managed.

Programming Java layouts with Builder Xcessory

With Builder Xcessory, this is considerably simpler. With any layout, including the GridBagLayout, use the following procedure:

1. Create the parent object (the container) and the children (the objects to be managed).

2. Use the Resource Editor to set the desired layout (on the parent).

3. Use the Resource Editor to set the desired constraints (on each of the children).

Builder Xcessory automatically synthesizes all of this information to create the appropriate layout objects for you. You can change the layout, add children of any type at any time, or nest layouts. All changes are reflected immediately and automatically in your interface so you can see the results of your changes as you make them.

Using Java Layouts

AWT containers

The four AWT containers for which you can specify a layout policy include:

· Frame

· Panel

· Applet

· Dialog

Builder Xcessory uses a default layout policy of No Layout for all four containers to help you when creating and placing children. In nearly all cases, you will select a specific layout policy. These policies are described briefly in the following sections.

Generally with Builder Xcessory, the container (or parent) has resources corresponding to the type of layout object created, and any information passed to the layout object's constructor. The children typically have resources related to the position or resize behavior of that particular child. These resources are treated as constraints and are listed last in the Resource Editor.

No Layout

It is possible, though rare, to create a Java application that does not use a layout manager (similar to using a Motif Bulletin Board). Any object you place into a container with No Layout specified remains in its initial position and size. With Builder Xcessory, this is the only layout policy where you can manipulate objects directly with the mouse and various alignment facilities. The AWT method:

setBounds(int x, int y, int width, int height)

allows you to move and resize objects programmatically.

Flow

The Flow layout causes the container to line up its children horizontally. When room on one line is exhausted, the Flow layout creates an additional line for its children. You can specify how the Flow positions the children on each line: centered, left aligned, or right aligned.

Resizing the container results in the (possible) rearrangement of the children into however many rows are appropriate, but children are not resized.

Set the following resources for the container:

Layout: Flow Layout
Alignment: center|left|right

Children have the following constraints:

None
Border

The Border layout causes the container to place its children into five areas: north, south, east, west, and center (see Border Layout ). The borders are set first, with the remaining space taken up by the center child. Each area can have only one visible child.

Resizing the container does not change the thickness of the borders, but changes both the height and width of the "center" child.

Set the following resources for the container:

Layout: Border Layout

Children have the following constraints:

Direction:center|north|east|south|west
 
Border Layout
Card

The Card layout causes the container to place its children atop one another, providing show , first , last , next , and previousmethods to control which child is visible.

The card layout sizes its child to fill the entire space of the container. Resizing the container resizes its children.

Set the following resources for the container:

Layout: Card Layout

Children have the following constraints:

None
Grid

The Grid layout causes the container to manage its children into rows and columns. You specify how many rows and columns to create. Children are placed into the rows from left to right, one row at a time, in the order in which you add them to the container. All children are identically sized. Resizing the container resizes its children.

Set the following resources for the container:

Layout: Grid Layout
Columns: [integer]
Rows: [integer]

Children have the following constraints:

None
 

Hint: To change the order in which the children are laid out, use the Raise/Lower operations (Browser:Edit or MB3 Quick Access menu).

GridBag

The GridBag is the most powerful and the most complex layout in the AWT (the only AWT layout object that requires its own, distinct constraints object). With the GridBag, you can control where each individual child is placed, how it is moved, and how it is resized.

Each child is placed at a cell position with the gridx and gridy resources. You can then specify how many columns wide and how many rows high each child is with the gridwidth and gridheight resources. The GridBag automatically calculates the total number of rows and columns.

 

Note: The GridBag automatically uses the fewest possible number of rows and columns. Specifying particular gridy and gridxvalues does not guarantee that the GridBag will work with that number of rows or columns.

Within each allocated position, you can specify whether or not the child should grow to fill extra space in the grid cell with the fillresource. This extra space might be present because the default size of the child is smaller than the cell size, or the space might become available when the container is resized. If a child is not set to fill the entire area available, you use the anchor resource to align the child within its grid cell.

Partial fills

For partial fills, use the resources ipadx , ipady , and the various insets . The ipad resources specify internal padding, that is, how much bigger than its default size the child should be. The insets specify external padding, in other words, margins.

The two most powerful constraints for GridBag children are weightx and weighty . While fill controls how the children grow to fill a grid cell, weightx and weighty control how the actual grid cells grow (or shrink) when the container is resized, that is, how new space is apportioned to the grid cells. Values for weightx and weighty are proportional. A value of 0.0 indicates that the cell does not grow (or shrink). A cell with a weight of 10 grows twice as much as a cell with a weight of 5. Cells with identical weights grow the same amount.

Set the following resources for the container:

Layout: GridBag Layout

Children have the following constraints:

Gridx: [integer]
Gridy: [integer]
Gridwidth: [integer]
Gridheight: [integer]
Fill: horizontal|vertical|both|none
Anchor:center|east|north|northeast|northwest|south|
southeast|southwest|west
Ipadx: [integer]
Ipady: [integer]
TopInset: [integer]
RightInset: [integer]
BottomInset: [integer]
LeftInset: [integer]
Weightx: [double]
Weighty: [double]

Figures GridBag After Resize with All Weights Equal to Zero and GridBag After Resize with Weights as Indicated show the results of resizing a GridBag with weights set to 0 and non-zero, respectively.

 
GridBag After Resize with All Weights Equal to Zero

Notice that with all the weights set to zero, the GridBag does not increase the size of any of its cells, but maintains the grid centered in the container.

When you add weights , the grid resizes in accordance to the weight values. Notice that fills now come into play, along withanchor positions.

 
GridBag After Resize with Weights as Indicated

Examining the weightx values, we see that objects A and D do not resize at all, but objects B and C do. Because neither B nor C is in column 0, that column does not resize. Column 1 resizes to take up all of the remaining space. Notice that B and C have different values for weightx . Because they are proportional to the other columns (column 0), the difference becomes irrelevant.

Looking at the weighty values, we see that the sole object (D) in the bottom row does not resize, but all others do resize. The rows occupied by object A take up 100% of the new space. The rows occupied by objects B and C share the new space equally.

The weight values are also be used by the GridBag, along with the object sizes, to calculate the initial row heights and column widths.

 

Documentation: 

Notation Conventions

 

This document uses the following notation conventions:

{BX}

The syntax {BX} r7fers to the directory into which Builder Xcessory is installed. The default directory is the following:

/usr/ics

Index

Most index entries are in lowercase:

messages
hiding and viewing 15
message area 16

Entries capitalized in Builder Xcessory are capitalized in the index:

Build Mode 15
Force to Selected Tree 161

Languages

Builder Xcessory supports multiple programming languages. Not all explanations or examples are applicable to all languages. The following icons indicate sections specific to particular languages:

 

 

Note: Information that applies to all Motif environments does not use icons. In text, Motif refers to C, C++, ViewKit, and UIL, but not Java.

Lists

The following two types of lists present procedures:

1. Numbered lists present steps to perform in sequence.

· Bulleted lists present alternate methods.

Objects

Objects are indicated as follows:

· Palette collection names are capitalized words with intercaps:
Form or PushButton

· Instance names are lowercase words with intercaps:
form or pushButton

· Class names are capitalized words with intercaps:
Test or MyClass

Menu Notation

To indicate menus and menu options, the following format is sometimes used:

BX_window_name : menu_name : menu_item(or dialog_selection)

For example, Browser:File:Exit is the Exit selection from the File menu of the Browser window.

Text

· Literals such as file names, directory paths, code and text as typed on the command line are printed in Courier font:

.bxrc
XmAnyCallbackStruct *acs = (XmAnyCallbackStruct*)call_data;

· Text preceded by a % denotes text to enter on the command line:

% bx

· Book titles, chapter names, and section names appear in italic:

Builder Xcessory Reference Manual
"Tutorial One: Simple Actions" on page 162

· The main windows of Builder Xcessory are capitalized as follows:

Palette
Browser
Resource Editor

 

Porting GIL to Motif

Overview

Guide Interface Language (GIL) is the save format used by the Sun Microsystems product Devguide.

Porting GIL Interfaces to Motif

Builder Xcessory reads GIL files and imports the interface generated from Devguide into a Motif interface. However, Devguide is a tool for developing OPEN LOOK interfaces, and many differences between the interface objects provided by OPEN LOOK and those provided by Motif prevent the conversion from being completely automated.

GIL Version Information

Builder Xcessory's Import GIL option (Browser:File) reads GIL version 3 (GIL-3) files exclusively.

Converting GIL-2 files to GIL-3

If you have GIL-2 files, you can convert them to GIL-3 by reading them into Devguide Version 3, and then saving them. To determine the version of your GIL file, examine the first line of the file, which contains the following characters:

;GIL-n

where n is the version number.

GIL Options

Builder Xcessory imports a GIL file similarly to the way it reads a UIL file. The interface is added to the interface currently in Builder Xcessory. You can also customize certain options when importing a GIL file.

Setting GIL options

Select GIL Options from the Browser Options menu to display the GIL Options dialog:

GIL Options Dialog

The GIL Customization dialog allows you to set the following options:

Look and feel

Builder Xcessory attempts to match the GIL file to either a Motif or an OPEN LOOK appearance and behavior.

Reposition

When set to Yes, Builder Xcessory attempts to lay out the interface based on the size changes encountered in the Motif versions of OPEN LOOK objects.

Strategies for Importing Your GIL Documents

When you import a GIL file, you must decide whether to port the interface with as few changes as possible (thus saving a Motif program that mostly conforms to the OPEN LOOK style guide) or to allow Builder Xcessory to match the interface as closely as possible to Motif look and feel. The Import GIL dialog allows you to specify whether to match the interface to Motif or OPEN LOOK look and feel.

Matching interface geometry

The Motif versions of OPEN LOOK objects also alter the geometry of the GIL interface. The GIL Options dialog allows you to specify whether Builder Xcessory should try to lay out the interface based on the size changes.

Inserting Motif manager widgets

Both options are likely to result in some overlapping or misaligned objects, but you can easily reposition the objects from within Builder Xcessory. In many cases, the best way to align and position objects is to insert managers such as Forms and RowColumns into the hierarchy. A good understanding of how the different Motif managers work is necessary.

Groups

In Devguide, you can use Groups to group objects together. Builder Xcessory imports Groups as Motif bulletin boards.

Editing class names

For the cases in which you do not want the groups mapped to a Motif BulletinBoard, you can edit the Class Name field in the Resource Editor and change the group's Class Name. Also change the instance name to reflect the new Class name or the object's function in the interface.

Inserting form widget parents

When the interface is imported, group anchors (attachments to other groups or objects) are ignored. In many cases, you will want to create a Motif Form widget as the parent of the group and set the attachments on the form widget's children to handle resizing properly.

Glyphs

When there are glyphs in the GIL file that are stored in the Sun Microsystems, Inc. Icon format, Builder Xcessory automatically imports the Icon files in an XBM format. If Builder Xcessory cannot find the Icon file to be converted, a message specifies the commands required to convert the file, once you locate it.

Installing utilities

Builder Xcessory uses the following two PBM-Plus utilities:

· icontopbm

· pbmtoxbm .

These utilities are installed in the Builder Xcessory bin directory, which must be in your path. If Builder Xcessory cannot findicontopbm and pbmtoxbm , it displays a warning message.

Devguide List

Certain Devguide objects map well to collections of Motif 1.2 widgets. The Devguide List with a label maps to a frame widget with scrolled list and label children. However, Motif 1.1 does not support multiple children of a Frame widget. If you are using Motif 1.1, use a form widget in place of the frame. Builder Xcessory does the Motif 1.2 version of the import by default, unless you have specified Motif 1.1 code generation on the General tab of the User Preferences dialog.

Actions

Devguide actions are imported as Motif callbacks when possible. User-defined actions in Devguide are imported as the equivalent predefined callback. For example, "Show" is imported as BxManageCB.

Builder Xcessory displays a warning when it attempts to import Devguide actions that do not correspond to an equivalent Motif callback.

Non-converted Objects

Drop targets and group anchors are ignored when a GIL file is imported by Builder Xcessory. The differences between Devguide/OPEN LOOK and Motif are significant enough that importing these objects is not useful.

A number of OPEN LOOK features are not provided in Motif. Builder Xcessory ignores the following features during the import:

· The label-bold field for labels

· The label attribute on menus

· Glyphs in lists

· XView and PostScript drawing models for canvases

Conversion Conventions

You should also be aware of the conversion conventions described in the following sections.

Numeric Textfields

Numeric textfields are created as Motif text field widgets with a modifyVerify callback set to BxVerifyNumericCB. This callback allows only digits to be entered into the text field. It does not support Devguide attributes such as minimum and maximum range, nor the increment and decrement arrow buttons.

OPEN LOOK Menus

Builder Xcessory creates a MenuBar for every OPEN LOOK menu that it encounters, because menus under the OPEN LOOK Style Guide are commonly distributed throughout an interface. Motif interfaces typically have all of their menus in a single menu bar at the top of the window.

Consequently, after importing a GIL file the first thing that you will often do is to combine the various MenuBar/CascadeButton combinations into a single MenuBar with multiple cascadeButton children. Also consider creating a single MainWindow widget at the top of your object instance hierarchy and having it contain the main MenuBar and a manager widget that controls all of the other widgets in the window.

Help Text

The help text attribute on Devguide objects is imported as the predefined callback BxHelpCB assigned to the corresponding Motif widget's XmNhelpCallback. This predefined callback creates and manages a dialog containing the help text and a dismiss button.

 

 

Documentation: 

Prerequisite Knowledge

 

This document assumes that you are familiar with the X Window System and OSF/Motif. If you are developing with Java AWT and/or ViewKit objects, this document assumes that you are familiar with these toolkits. Consult the following documentation lists for recommended references.

OSF/Motif documentation

For detailed descriptions of OSF/Motif and X, refer to the following documentation:

· OSF/Motif Programmer's Reference. Prentice-Hall, 1993. 
(ISBN 0-13-643115-1)

· OSF/Motif Style Guide. Prentice-Hall, 1993. 
(ISBN 0-13-643123-2)

· OSF/Motif Programmer's Guide. Prentice-Hall, 1993. 
(ISBN 0-13-643107-0)

X Window System documentation

· Asente, Paul, Donna Converse, and Ralph Swick. X Window System Toolkit. Digital Press, 1997. (ISBN 1-55558-178-1)

· Scheifler, Robert W. and James Gettys. X Window System-Core Library and Standards. Digital Press, 1996. (ISBN 1-55558-154-4)

· Scheifler, Robert W. and James Gettys. X Window System-Extension Libraries. Digital Press, 1997. (ISBN 1-55558-146-3)

· Scheifler, Robert W. and James Gettys. X Window System-Core and Extension Protocols. Digital Press, 1997. (ISBN 1-55558-148-X)

Java documentation

For information about the AWT object set, we recommend the following document:

· Flanagan, David. Java in a Nutshell . O'Reilly and Associates, 1997. (ISBN 1-56592-183-6)

For more detailed information on the Java language, refer to the following documentation:

· Zukowski, John. Java AWT Reference . O'Reilly & Associates, 1997. (ISBN 1-56592-240-9)

· Grant, Mark. Java Language Reference. O'Reilly and Associates, 1997. (ISBN 1-56592-326-X)

· Deitel and Deitel. Java: How to Program. Prentice-Hall, 1998. 
(ISBN 0-13-899394-7)

CDE documentation

For information about the Common Desktop Environment (CDE) widgets, refer to the following documents:

· CDE 1.0 Programmer's Guide. Addison-Wesley, 1995. 
(ISBN 0-201-48954-6)

· CDE 1.0 User's Guide. Addison-Wesley, 1995. (ISBN 0-201-48951-1)

ViewKit documentation

For a description of ViewKit (VKit) classes, refer to the following documentation:

· ViewKit ObjectPak1.3 Programmer's Guide. Integrated Computer Solutions, 1996. (Included with the purchase of BX PRO .)

· IRIS ViewKit Programmer's Guide. Silicon Graphics, Inc. 1994. (Document Number 007-2124-002)

EPak documentation

For a description of EnhancementPak (EPak) widgets, refer to the following Integrated Computer Solution's documentation (included with BX PRO):

· EnhancementPak 3.0 Programmer's Reference. Integrated Computer Solutions, 1997.

· GraphPak Programmer's Reference. Integrated Computer Solutions, 1995.

Note: If you are using BX PRO, you can use and compile the EnhancementPak widgets and ViewKit objects in your interface. If you are using Builder Xcessory, you can use the EnhancementPak widgets and ViewKit objects in your interface, but you must purchase their respective libraries to compile any interface built with the EnhancementPak widgets or ViewKit objects. Contact your ICS Sales Representative for more information.

 

Documentation: 

Tutorial Eight: Creating Classes and Subclasses

 

Tutorial Eight: Creating Classes and Subclasses

In this tutorial, you will create the interface shown in the following figure:

MenuBar with File Menu

A Brief Overview of Classes and Subclasses

A group of widgets that make up a logical component of your user interface can be made into a class. This is a way to use Motif and C++, as described by Douglas A. Young in his book Object-Oriented Programming with C++ and OSF/Motif .

Classes are useful because they allow you to define the look and behavior of these widgets in one central place. Every time this component is used it automatically "inherits" the look and feel from the class definition. The code generated is also more efficient because the definition of these widgets is centralized. Classes can be reused within the same application, across multiple applications, and they can even be shared between users.

Subclasses allow you to build on a class that has already been created and specialize it for your needs. In turn, this new class has all the benefits of classes that are described above (efficient code, reusability, etc.). There are several ways to "specialize" a class once it is subclassed. You can override exposed resources (similar to class instances), add new widget children, and override callbacks. This tutorial gives an example of each of these tasks.

In this tutorial you are going to create a menu class and then specialize this menu class using subclassing. Both classes are useful objects that you may want to use in many different applications, so we will also demonstrate how to save classes as separate UIL files and how to put them on the Palette permanently.

Before You Begin This Tutorial

Make a new directory called Tut8 and change directories to Tut8 .

· If you have not started Builder Xcessory yet, enter the following at the prompt in the Tut8 directory:

% bx50

· If you are already running Builder Xcessory, clear the Builder Xcessory interface.

If you have questions about clearing the interface, review Clearing an Interface .

You are now ready to begin the tutorial.

The example you will build in the following tutorial is a PulldownMenu containing several menu items. This will hopefully contain meaningful menus that can serve as a template for the menus you use in your own applications.

Note: This tutorial assumes you have chosen C++ as your language.

Creating a Menu Class

In this section, you'll create a file menu class.

Click on the arrow next to Instance and select Classes.
  1. Change the Browser to Classes view.

Adding a PulldownMenu

When you create a PulldownMenu, this action actually creates 3 widget instances: a CascadeButton, which parents a PulldownMenu, which parents a PushButton. This hierarchy is reflected in the Browser.
For whatever widget instance is currently selected, the only widgets sensitized in the Palette are those that are valid children for that instance. Using Keep Parent makes it easier to add children to a widget instance, especially when that widget instance is a menu.
  1. Select the PulldownMenu from the Palette and drop it. A popup dialog asks for the name of the class, enter "File".
  2. Select Keep Parent from the Browser View menu.

Adding PushButtons

Because Keep Parent is selected, the new pushButton instance you have just created is parented by the currently-selected widget instance, in this case, pulldownMenu.
This adds 5 PushButtons to the menu (pulldownMenu). This menu should have a total of 6 PushButtons, as shown in the following figure:
  1. Select the pulldownMenu in the Browser.
  2. Add a PushButton to the pulldownMenu by double-clicking on the PushButton icon on the Palette.
  3. Using the previous step, add these items in this order: one PushButton, one Separator, two PushButtons, one Separator, and one PushButton.

File Menu

Renaming PushButtons

When you double-click on an instance of a class, its exposed resources are identified using the Instance Name. Renaming a class's widget instances makes it easier to remember which resource belongs to which widget instance.
The separator names can stay the same.
  1. Rename these instances so that they make more sense. Click on the first PushButton and change its Instance Name to newButton in the Resource Editor (see Editing the Instance Name ).
  2. Repeat the previous step for the remaining buttons. Change their Instance Names to openButton, readButton, saveButton, saveAsButton, and exitButton, respectively.

Editing the Instance Name

After changing the Instance Name of every PushButton, your interface should look like the one in the following figure:

Renaming the PushButtons

Notice that the changed Instance Names are reflected on the Browser.

After adding items to the menu, the next step is to make the menu look more attractive and easier to use.

Labeling the Menu and Menu Items

To label the menu, follow these steps:

This accomplishes two things: it selects cascadeButton, and it updates the Resource Editor so that it displays the resources associated with cascadeButton.
Type the first several letters in "labelString" in the Find Resource search field at the bottom of the Resource Editor until this resource is located.
The menu on the interface is now labeled "File".
  1. double-click on cascadeButton on the Browser.
  2. Find the labelString resource in the Resource Editor.
  3. Enter "File" (without the quotation marks) in the labelString input field.

To label the menu items, follow these steps:

  1. In the Browser, double-click on newButton.
  2. Enter "New" in the labelString input field.
  3. Repeat the above steps to change the labels of the remaining File menu PushButtons to "Open...", "Read...", "Save", "Save As...", and "Exit."

The menu and menu item labels on all three menus should now match the following figure:

Labeled Menu and Menu Items

In Labeled "New" Menu Item , notice that the changes you have made to the instances' labelString resources are shown on the interface, and the changes you have made to the Instance Names are still shown on the Browser.

Labeled "New" Menu Item

Adding Callbacks

At this point, you should add callbacks for every menu item.

  1. double-click on newButton.
  2. Find the activateCallback resource in the Resource Editor.
  3. Enter "DoNew" as the activateCallback procedure name.
  4. Note: Builder Xcessory automatically adds the () characters to your routine name. Note also that the placement is automatically set to Code in the Placement option menu to the right of the input field.

Refer to the Builder Xcessory Reference Manual for more information about adding callbacks. You can add callbacks to the remaining buttons, but it is not necessary for this tutorial.

Exposing Resources

At this point, you should expose some of the resources in the class. Any resources that you think users of your class may want to override should be "exposed". In this example we will expose the positionIndex of the pushButtons and separators, in case users of our File menu want to change the order of the menu items or add new ones.

The easiest way to do this is to select each instance on the Browser.
The default setting is None. To select Code, first hold down MB1 on the option menu to display its menu items. (Notice, as the menu items are displayed, that Expose is at the bottom of the menu but is desensitized at the moment.) Now, move the cursor over Code to select it, and release MB1. The Placement of the positionIndex resource for the currently- selected widget instances is now Code. That means when you generate code for this class, the value of the positionIndex resource for the currently-selected widget instances will be hard-coded, and cannot be changed by the application user.
A small eye icon appears next to Code. (After Code is selected, Expose is sensitized and can be selected on the Placement option menu. Widget instances that are members of a class are the only instances that can be exposed.)
Exposing a resource means that you can look at and edit that resource in instances or subclasses, which otherwise is not possible for the resources of class members.
  1. Holding the Ctrl key down, select each of the children of the PulldownMenu (the six PushButtons and two Separators).
  2. Update the Resource Editor by selecting Update from the View menu.
  3. Find the positionIndex resource.
  4. Select Code from the placement option menu located to the right of the positionIndex resource input field (see Exposed positionIndex Resource ).
  5. Expose the resource by selecting Expose in the Placement option menu.

Exposed positionIndex Resource

Subclassing the "File" Class

You have now finished creating the class "File". The following sections describe how to create a subclass from File.

Designating a receptor

Before creating a subclass, you should first edit the class and designate one of its widget instances as a receptor. This means that you can add children to the class, and whichever widget instance you designate as the receptor will act as the parent to any children you add. In this case, we'll designate pulldownMenu as the receptor.

Note: Any widgets you add to a subclass must have unique names (different from their corresponding superclass widgets) for the code to compile. Builder Xcessory takes care of this for you by automatically prepending the subclass name to the widget names. If you would rather take care of this yourself (by naming the new widgets with unique names on your own), set uniqueSubclassNames in your .bxrc to False, exit, and restart Builder Xcessory.

This tutorial assumes uniqueSubclassNames is set to False. If you choose otherwise, you will notice a difference in that any widget instances you add to a subclass is prepended with "sub_".

Make Receptor

  1. Select pulldownMenu in the Browser.
  2. Select Make Receptor from the Browser Edit menu. A white square appears next to pulldownMenu in the Browser to indicate a receptor (see PulldownMenu Designated as the "File" Class Receptor ).

PulldownMenu Designated as the "File" Class Receptor

Now you can create a subclass. When you add children to that subclass, they are automatically parented by pulldownMenu.

Creating a subclass

Creating a subclass is creating a variation on a theme. Suppose you plan to use the same menu structure you have just created for more than one reason. First, let's make a subclass to which you will add a "Print" menu button. Use the following steps to create a subclass:

You have now created a subclass called "FilePlus".
This does four things for you:
First, it creates a new interface with all the elements of the superclass (File).
Second, it adds the subclass name (FilePlus) to the list of classes displayed in the Browser window.
Third, it creates another tree in the Browser window, representing the subclass you have just created. This tree has a lone child, a widget that represents the superclass. You can now add children to that class by dropping them onto the subclass interface.
Fourth, it creates a new Palette icon for the new subclass FilePlus. This new icon is placed in the Project Classes group by default.
  1. Select the class widget (File) in the Browser.
  2. Select Make Subclass from the Browser Edit menu.
  3. Enter "FilePlus" in the popup dialog that prompts you to enter a name for the subclass you are creating.

In the next section, you will add children to the subclass you just created.

Adding Children to a Subclass

After creating a subclass, you should add whatever children will make it useful. In this case, add another separator and a new menu item.

When dragging a widget onto ":File", position the widget slightly lower and more to the right before dropping it. A partial outline of ":File" is displayed when ":File" becomes a valid drop target.
The interface should now look like the following figure:
  1. Turn off Keep Parent.
  2. Using MB2, drag a PushButton from the Palette into the FilePlus subclass, by dropping it on ":File".
  3. Repeat these steps to add a Separator.

Children Added to the Subclass FilePlus

Double-click on the pushButton instance to display its resources in the Resource Editor. At the top of the Resource Editor, change its instance name to "printButton". double-click on the separator instance, then change its instance name to "plusSeparator".
Update the Resource Editor for pushButton, find the labelString resource, and enter "Print" (without the quotes) in the labelString text input field.
  1. Change the widget instance names of the pushButton and separator to "printButton" and "plusSeparator", respectively.
  2. Change the labelString resource value of the pushButton to "Print".

Overriding Resources in a Subclass

After creating a subclass, you can override any of the exposed resources of the superclass. In this example we will override some of the positionIndex resources in order to place our new "Print" option.

The Resource Editor now displays all exposed resources and their current values.
It is a good idea to expose the same resource for each child you have added, in case you want to make changes later to the subclass or to an instance of the subclass.
  1. Double-click on the ":File" icon in the "FilePlus" tree in the Browser.
  2. Change the exitButton.positionIndex resource to "9".
  3. Double-click on the pushButton child of ":File" in the Browser to update the Resource Editor.
  4. Find the positionIndex resource.
  5. Select Code from the placement option menu to the far right of the resource.
  6. Select Expose from the placement option menu.
  7. Repeat steps 3 through 6 to expose the positionIndex resource for the separator child of ":File".

Overriding a Callback in a Subclass

After creating a subclass, you can override any of the callbacks of the superclass. To override a callback in C++, all you need to do is define a virtual method with the same name and parameters as the callback method.

This displays the Class Member Editor ( Defining a Virtual Method ).
  1. double-click on the FilePlus class icon in the Browser.
  2. In the Resource Editor, click on the "..." button next to the Class Methods and Data input field.
  3. Select the Scope tab.
  4. Select the Protected modifier toggle button.
  5. Select the Polymorphism tab.
  6. Enter "DoNew" in the Method Name field
  7. Enter None as the return type.
  8. Select the Virtual toggle button.
  9. Press the New button and enter three parameters of type Widget, XtPointer, and XtPointer with parameter names "w", "p1", and "p2", respectively (see Defining a Virtual Method ).

Defining a Virtual Method

  1. Click on Apply.
  2. Dismiss the dialog.

Saving Classes in a Separate File

You may want to use these classes in several applications. In order to do this you should save the classes in a separate include file.

To save the class, File:

The File Selection dialog is displayed.
  1. Select the File class icon in the Browser.
  2. Select Class -> Save Class from the Browser File menu.
  3. Enter the name of the file to save the class, file.uil in the File Name input field.
  4. Click on OK.

To save the subclass (FilePlus):

  1. Select the FilePlus class icon in the Browser.
  2. Select Class -> Save Class from the Browser File menu.
  3. Enter the name of the file to save the class, fileplus.uil in the File Name input field in the File Selection dialog.
  4. Click on OK.

Permanently Placing Classes on the Palette

You may want these classes to appear on your Palette automatically when you start up Builder Xcessory. Select one of the following two options:

· Copy the class into a system directory. This causes the class to appear on the Palette for all users.

· Copy the class into a local directory. This causes the class to appear on the Palette only when you start Builder Xcessory.

In this example we will copy one of the classes into your local directory (see Project, Private, and Public Classes ).

Notice that File and FilePlus class icons appear in the Project Classes group on the Palette. Just below this section, notice the Private Classes and Public Classes groups.
  1. Scroll to the bottom of the Palette.

Project, Private, and Public Classes

  1. With MB2, drag the File class icon from the section in the Palette called Project Classes into the section called Private Classes.

Using a Class in Your Application

Now you are ready to create your application.

  1. Change the Browser to Instances View. Notice that the display in the Browser clears. You created two classes in Classes view, and both were saved to the Palette. In Instances view, the Browser clears because you have not created an interface yet.
  2. Create a MainWindow from the Palette. Add a MenuBar from the Palette as a child of the MainWindow instance. The result should look like the following figure:

Partially-built Application

  1. Add an instance of your FilePlus class from the Palette as a child of the MenuBar instance (see Adding the Subclass FilePlus ).

Adding the Subclass FilePlus

Generating Code

Generate C++ and compile and run your program. Any code that you place inside the DoNew method in the file FilePlus.C is executed when the user presses the New button. If we had used the File object instead of the FilePlus object, the DoNew method in File.C would be executed. You have completed Tutorial Eight.

 

Documentation: 

Tutorial Five: Advanced Techniques

 

Tutorial Five: Advanced Techniques

In this example you will experiment with some advanced Builder Xcessory techniques. Topics covered include the following:

· Constraint resources

· Geometry management of the Form widget

· Adding header files

· Customizing the creation routine

· Editing the Main file

· Passing widget IDs between structures

The interface that you create will contain a Form widget and four children: two PushButtons, a Text widget, and a List widget. You will be able to enter text into the Text widget. Clicking one PushButton will add the contents of the Text widget into the List widget. Clicking the other PushButton will dismiss the window.

Constructing the Interface

If you have questions about the following procedures, review Clearing an Interface , Creating and Resizing a Widget Instance , Placing a Child Widget , or Placing an Automatically Resized Widget .

The Form widget will no longer resize to match the dimensions of its children.
Your interface should now look like Widget Collection :
  1. Clear the Builder Xcessory display by selecting New from the Browser File menu.
  2. Create a Form widget, resized to approximately two inches high and four inches wide.
  3. Set the resizePolicy resource to XmRESIZE_NONE.
  4. Place a List widget so that it fits within the topmost half of the Form.
  5. Place a Text widget within the Form and under the List.
  6. Resize the Text widget so that there is enough room underneath it within the Form to place a PushButton.
  7. Resize a PushButton to about one half inch high and one inch wide, and place it to occupy the leftmost third of the space under the Text widget within the Form.
  8. Place a second PushButton in the rightmost third of the space under the Text widget within the Form.

Widget Collection

Creating the Header File

Before setting callbacks, you must use a text editor to create the header file defs.h , which must contain the declarations of the structures WidStruct and Globals. Put this file in the directory to which you will write the tutorial output files.

Some of the callbacks that you set will need to access the widget IDs of each of the four widgets in your interface. The way to do this is to save the widget IDs in a global structure, WidStruct. In the sample file below, you also place WidStruct into the structure Globals. In a more complex interface, you would wish to include not only WidStruct but any other global structures within Globals.

typedef struct _WidStruct
{
Widget list;
Widget add;
Widget dismiss;
Widget text;
} WidStruct;
typedef struct _Globals
{
WidStruct wids;
/* any other global structures would go here */
} Globals;
  1. In a text editor, create the defs.h file:
  2. Save and close the file.

Setting the Resources

  1. Select the widget instance name list1 on the Browser, and update the Resource Editor.
  2. Confirm that the Resource Editor is displaying all of the resources of the currently selected widget by selecting All Resources from the Resource Editor Resources menu.
  3. Set the value of the visibleItemCount resource to 5.

Setting the createCallback resource

In the Procedure Name field, enter:
creation
Remember to press return or click the OK button.
Confirm that you wish to create a procedure.
In the Parameter Type field, enter:
Widget
Confirm that you wish to create a new user-defined type.
In the Parameter field, enter:
&(globals->wids.list)
Confirm that you wish to create a new identifier.
Click the Apply button at the bottom of the Callback Editor to apply this value to the createCallback resource for list1:
creation(&(globals->wids.list))
If you have questions about any of the above procedures, review Setting Callback Resources .
The callback that you have just created passes the address of the member of the data structure into which you will write the widget ID of the List widget.
  1. In the Callback Editor, set the createCallback resource for list1 as follows.

Using the Callback Editor

creation(&(globals->wids.text))
Edit the callback at this point by clicking the Edit button and then entering the code described in Editing the Callback Structures .
  1. Use the Callback Editor to set the createCallback resource for the widget instance "text" to the following:

Setting the activateCallback resource

In the Procedure Name field, enter:
AddWord
Remember to press return or click the OK button.
Confirm that you wish to create a procedure.
In the Parameter Type field, enter:
Globals*
Confirm that you wish to create a new user-defined type.
In the Parameter Name field, enter:
globals
Confirm that you wish to create a new identifier.
Click the Apply button at the bottom of the Callback Editor to apply this value to the activateCallback resource for pushButton:
AddWord(globals)
If you have questions about any of the above procedures, review Setting Callback Resources .
Edit the callback at this point by clicking the Edit button and then entering the code described in Editing the Callback Structures .
  1. In the Callback Editor, set the activateCallback resource for pushButton as follows.

Setting resources for pushButton

activateCallback = AddWord(globals)
createCallback = creation(&(globals->wids.add))
labelString = ADD
The activateCallback value passes the pointer to the entire list, since you need both the Text and List widget IDs.
activateCallback = Dismiss()
createCallback = creation(&(globals->wids.dismiss))
labelString = DISMISS
Note that Builder Xcessory extended editors are specific to a given resource. For example, the Callback Editor for activateCallback is completely separate from those for createCallback.
  1. For pushButton, set:
  2. For pushButton1, set:

Setting Constraint Resources

Children of a Form widget possess constraint resources, which control geometry management within the Form. Constraint resources are displayed in the Resource Editor in a separate list at the bottom of the resource list.

For detailed information on geometry management with the Form widget, see the manpage in the OSF/Motif Programmers Reference .

Using Builder Xcessory extended editors, you will set the following constraint resources for the children of the Form widget. Note that some of these values may have been set by Builder Xcessory by default.

If you have questions about using the Form Editor, refer to See Form Editor .

bottomAttachment = XmATTACH_POSITION
bottom Position = 50
leftAttachment = XmATTACH_FORM
leftOffset = 10
rightAttachment = XmATTACH_FORM
rightOffset = 10
topAttachment = XmATTACH_FORM
topOffset = 10
bottomAttachment = XmATTACH_POSITION
bottomPosition = 70
leftAttachment = XmATTACH_FORM
leftOffset = 10
rightAttachment = XmATTACH_FORM
rightOffset = 10
topAttachment = XmATTACH_POSITION
topPosition = 55
bottomAttachment = XmATTACH_FORM
bottomOffset = 10
leftAttachment = XmATTACH_FORM
leftOffset = 10
rightAttachment = XmATTACH_POSITION
rightPosition = 33
topAttachment = XmATTACH_POSITION
topPosition = 75
bottomAttachment = XmATTACH_FORM
bottomOffset = 10
leftAttachment = XmATTACH_POSITION
leftPosition = 66
rightAttachment = XmATTACH_FORM
rightOffset = 10
topAttachment = XmATTACH_POSITION
topPosition = 75
Your interface should now appear like the following figure:
  1. For list1, set:
  2. For text, set:
  3. For pushButton, set:
  4. For pushButton1, set:
  5. Dismiss any extended editors that remain on your display, including the Callback Editor.

Interface with Resources Set

Customizing the Creation Routine

You can customize the creation output file without leaving Builder Xcessory. In this case, you will change the creation file so that the routine that creates the widget tree, createForm, is passed the parameter "globals" in addition to the default, "parent".

The Creation Routine dialog is displayed.
Procedure Name = createForm
Parameter Type = Globals*
Parameter Name = globals
Click the OK button to right of each text field. Then click Apply to set these values for Form.
  1. Select the Form widget instance on the Browser.
  2. Select Creation Routine from the Resource Editor Component menu.
  3. Enter the following values in their respective text fields:
  4. Click Dismiss to remove the Creation Routine dialog.

Adding Header Files

Some structures referred to in the callbacks above will be declared in a header file that you will write before compilation. You need to add the #include for this file before writing out code from Builder Xcessory.

The File Names tab of the Language Settings dialog is displayed.
#include "defs.h"
Make sure to click the OK button below the C Output Include Information field.
  1. Select Code Generation Preferences from the Browser Options menu.
  2. Select the Include Info tab. In the text field labeled C Output Include Information, type:
  3. Click Dismiss to remove the dialog.

Testing Look and Feel

The major windows of Builder Xcessory are desensitized, but you are still able to make selections from the Browser menus. You should be able to enter text in the Text widget and click the "ADD" and "DISMISS" PushButtons. The functionality of these callbacks has not yet been connected, however, so they will not execute the appropriate functions.
Because you have set the interior attachments to XmATTACH_POSITION, the list, text, and PushButton widgets that make up the interface should resize proportionally.
  1. Select Play Mode from the Browser Project menu.
  2. Resize the topLevelShell to test the geometry management of the children of the Form widget.
  3. Return to Build Mode from the Browser Project menu before continuing.

Generating Code

You will save the interface code by writing a combination of C and UIL files. Then you will edit the file containing the callback structures to connect the functionality of the interface.

Saving the interface

Save the UIL file and generate C code for your interface. If you have questions about these procedures, review Generating Code .

Editing the Callback Structures

  1. Load <tutorial_path>/Tut5/callbacks-c.c into a text editor.
  2. Note: Don't forget that if you have previously generated code, the file callback-c.c is not overwritten, but just appended to. For these tutorials, delete any earlier versions of callback-c.c before you generate code.

Note: The text that you entered in the Output Include Information text field of the Include Info tab, #include "defs.h" is included in the header of the file.

#include <Xm/Text.h>
Because the example uses the text widget, you need to include this header file in the callbacks-c.c file.
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
add the following:
Widget *setme = (Widget*)client_data;
*setme = w;
client_data is the generic name of the parameter sent to the callback. Recall that for each of the four callbacks, a pointer is passed to the location in which the widget ID is stored.
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
add the following:
Globals *globals=(Globals*)client_data;
char *textValue;
XmString xmTextValue;
textValue = XmTextGetString(globals->wids.text);
These lines place the string value in the text field into the variable textValue.
Then add:
xmTextValue = XmStringCreateSimple(textValue);
XmListAddItem(globals->wids.list,xmTextValue, 0);
These lines create an XmString value from the value in the text field and then place it at the end of the List widget, which expects its items to be of type XmString.
Then add:
XmStringFree(xmTextValue);
XtFree(textValue);
These lines free the data.
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
add the line:
exit(0);
  1. After the #include line, enter the following:
  2. Inside the procedure "creation", after the line:
  3. Inside the procedure AddWord, after the line:
  4. Inside the procedure Dismiss, after the line:

Reviewing the Edited Stubs

The callbacks-c.c stubs, with your additions marked in bold , should now look like this:

Creation stub

void creation(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
Widget *setme=(Widget*)client_data;
*setme = w;
}

AddWord stub

void
AddWord(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
Globals *globals=(Globals*)client_data;
char *textValue;
XmString xmTextValue;
textValue=XmTextGetString(globals->wids.text);
xmTextValue = XmStringCreateSimple(textValue);
XmListAddItem(globals->wids.list, 
xmTextValue,0);
XmStringFree(xmTextValue);
XtFree(textValue);
}

Dismiss stub

void
Dismiss(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
exit(0);
}
  • Save and close the file.

Adding a Declaration to the Main File

You will edit the main-c.c file to declare and allocate memory for the variable globals .

Globals *globals;
globals = (Globals*)XtCalloc(1,sizeof(Globals));
  1. Load <tutorial_path>/Tut5/main-c.c into a text editor.
  2. Inside the procedure main, inside the user code block <declarations>, add the following:
  3. Save and close the file.

Compiling and Running

Compile and run your program. If you have questions about these procedures, review Compiling and Running .

Testing the Interface

The application shell collection should appear on your display.

This displays the contents of the text field as the first item in the list above.
  1. Click MB1 within the text field and enter something.
  2. Click the ADD PushButton.
  3. Continue adding entries to the list.
  4. Note: The maximum number of entries that the list will display is five, because you have set the list's visibleItemCount resource to 5.
  1. Click the DISMISS PushButton to remove the window.

You have now completed Tutorial Five.

 

Documentation: 

Tutorial Four: Using Resource Styles

 

Tutorial Four: Using Resource Styles

In this tutorial, you will create a hierarchy of resource styles and apply them to the objects in a simple interface.

If you have questions about this procedure, review Clearing an Interface .
  1. Clear Builder Xcessory.
  2. Redirect the output files to the directory Tut4 .

Creating the Interface

If you have questions about this procedure, review Creating and Resizing a Widget Instance and Placing a Child Widget .
  1. Create a BulletinBoard with two PushButton children.

Using the Style Manager

Note: This tutorial assumes that you have not already created resource styles. Therefore, BaseStyle will be the only style that exists in the Style Manager, and the first style you create will be named BaseStyle1.

Creating substyles

The Style Manager appears. Since you cleared the resource style hierarchy when you began this tutorial, the style hierarchy is empty except for the BaseStyle.
Note that BaseStyle is "locked", that is, although you can bring up the Style Editor for BaseStyle in order to examine its contents, you can not add resources to the style.
BaseStyle remains highlighted while the Style Manager adds BaseStyle1 as its child. The fact that the parent remains highlighted enables you to create a set of sibling styles without repeatedly reselecting their common parent.
The new style is created as BaseStyle2.
The resource style hierarchy, displayed in the Style Manager, should now appear like the following figure:
  1. Select Styles from the Browser Managers menu.
  2. Select Create Substyle on the Style Manager Edit menu.
  3. Create another substyle of BaseStyle.
  4. Select BaseStyle2 by clicking on its name in the Style Manager.
  5. Create two substyles of BaseStyle2.

Style Hierarchy

Using the Style Editor

You use the Style Editor to assign resource values to a given style.

A pop-up menu identical to the Style Manager Edit menu appears.
The Style Editor is displayed for BaseStyle4.
You can also load a style into the Style Editor by dropping the style onto the Edit drop target on the Style Editor, or by double-clicking MB1 on the style name.
Note that BaseStyle1 is loaded into the Style Editor.
You can add a resource to a style either by entering the resource name directly into the Resources text field, or by clicking the arrow button and then selecting the resource name from the combination box.
  1. Move the cursor over BaseStyle4 and press MB3.
  2. Select Edit Style from this pop-up menu.
  3. Using MB2, drag BaseStyle1 to the Style Editor and drop it onto the Edit drop target.
  4. Click the arrow button to the right of the Resources label on the Style Editor.

Assigning Resources

You can make multiple selections from the combination box by clicking MB1 on each resource name in turn. Each selected resource is highlighted in the combination box. You can unselect a resource by clicking on its highlighted name in the combination box.

  1. Change the text in the Style Name field from "BaseStyle1" to "GreenObjects".
  2. Click the arrow button to the right of the Resources text field.
  3. Scroll down the resource selection box and select "background".
  4. Press the arrow button once again to unpost the list.

Editing the Resource Values List

The resources that you have selected for the edited style are displayed in a list in the Style Manager's main display area, directly under the Resources text field. Assign values to these resources either by entering the value directly into the resource text field or by calling up any of the extended editors by clicking the (...) button to the right of the resource text field.

Note: The style is not itself changed until you have clicked the apply button at the bottom of the Style Editor.

The resource "background" is displayed in the Resources text field. The resource is also displayed along with a text field, (...) button, and app-defaults toggle in the Style Editor's main window. The functions of these fields and buttons are analogous to their counterparts in the Resource Editor.

Setting resources

Set background to "green" either with the Color Editor or by directly entering the value into the resource text field.

If you have questions about this procedure, review Using an Extended Editor . The Color Editor is described in detail in Extended Editors .

Applying Resource Values to a Style

Click the Apply button at the bottom of the Style Editor.

This applies the resource "background", with value "green", as well as the style name "GreenObjects" to the style formerly named BaseStyle1.

Updating the Style Editor

The Style Editor is now updated for BaseStyle2.
  1. Move the cursor over BaseStyle2 on the Style Manager and press MB2.
  2. Drag the icon to the Edit drop target on the Style Editor and release the mouse button.

Setting Other Styles

  1. For BaseStyle2, change the Style Name to "GreyObjects".
  2. Set "background" to "grey".
  3. Apply these resource values to BaseStyle2.
  4. For BaseStyle3, set Style Name to "BlueForeground".

Selecting Multiple Resources

Selecting a resource in this way adds it to the Resources style list, but does not deselect the previously selected items in the list.
  1. Click the arrow button to the right of the Resources text field.
  2. Scroll down the resource selection box and select "background".
  3. Scroll down further until the resource "foreground" is displayed.
  4. Select "foreground" by clicking MB1 on the resource name.
  5. In the same fashion, add the resource "labelString" to the list.
  6. Click the arrow button to remove the combination box.

Completing the Hierarchy

background = "red"
foreground = "blue"
labelString = "Blue"
Remember to click Apply on the Style Editor to apply these resource values to BaseStyle3.
Style Name = "RedForeground"
foreground = "red"
labelString = "Red"
Remember to click Apply on the Style Editor to apply these resource values to BaseStyle4.
Your style hierarchy, displayed in the Style Manager, should now appear like Edited Style Hierarchy :
  1. Set the following resource values for BlueForeground (BaseStyle3):
  2. Set the following resource values to BaseStyle4:
  3. Click Dismiss to remove the Style Editor.

Edited Style Hierarchy

Applying Styles to Widgets

Now you will apply your styles to the objects in your interface.

Selecting objects

If you have questions about this procedure, review Selecting a Widget .
  1. Select the BulletinBoard.
  2. Select GreyObjects on the style hierarchy.

Applying styles to objects

The background color of the BulletinBoard changes to grey. The PushButtons are not affected because you applied the style to the BulletinBoard alone, and not its descendents.
  1. Select "To Selected" from the Style Manager Apply menu.
  2. With bulletinBoard still selected on the interface, select GreenObjects on the style hierarchy.

Applying styles to an instance tree

This time, the background color of all interface objects changes to green.
The foreground color of the PushButton changes to red. Note also that the background color of the PushButton changes to grey, reflecting the resource value defined in GreyObjects, the parent style of RedForeground.
The foreground color of the PushButton changes to blue. The background color of the PushButton changes to red. In this case, the value of the resource background defined in GreyObjects, "grey", is overridden by the value "red" set in BlueForeground itself.
  1. Select "To Selected Tree(s)" from the Style Manager Apply menu.
  2. Select pushButton on the interface and RedForeground on the style hierarchy.
  3. Select "To Selected" from the Style Manager Apply menu.
  4. Select pushButton1 on the interface and BlueForeground on the style hierarchy.
  5. Select "To Selected" from the Style Manager Apply menu.

Saving and Testing the Interface

Now that you have built your interface and applied your styles, you will write out files and edit the Callbacks file to implement the functionality of your interface. The implementation of these styles requires no addition of code.

Feel free to generate code and connect the functionality of your interface for practice.

You have now completed Tutorial Four.

 

Documentation: 

Tutorial Nine: Creating a Java Applet or Application

 

Tutorial Nine: Creating a Java Applet or Application

In this tutorial, you will create a set of classes that can be run as an applet or an application. (The finished application is shown in Example Java Application .) This tutorial moves along quickly. For more detailed information on creating and customizing objects, see the example, Java Example .

Example Java Application

Start Builder Xcessory

If you have been using Builder Xcessory, select New from the Browser File menu to begin a fresh session. Be sure that you have chosen Java as your language (Browser:Options:Choose a Language).
  1. Start Builder Xcessory.

Create container window

The menu bar snaps to the top of and stretches to the width of the frame container.
You can drop the menu on top of the menuBar instance name in the Browser.
  1. Instantiate a frame object.
  2. Change the "layout" resource to BorderLayout.
  3. Add an AwtMenuBar to the frame.
  4. Add an AwtMenu to the menuBar.
  5. Note: The "menu" is actually a collection consisting of menu, menuPane, and menuItem.
  • Rename the menuItem to "dialogButton" using the Instance Name field of Resource Editor, and set its label to "Dialog".
  • Add a menuSeparator below the dialogButton by dragging with MB2 and dropping on top of the menuPane.
  • Add another menuItem below the menuSeparator, renaming the instance "closeButton" and setting its label to "Close".
  • Add a Panel to the awtFrame, renaming the instance "mainContainer".
  • Select the awtFrame, and make it a class by selecting Make Class from the Edit menu.
  • Enter Classes view.
Set the label resource for the menu to "File".
The new instance, mainContainer, takes the default constraint resource of Center, resizing to fill the frame.
If you skip this step, Builder Xcessory still creates the awtFrame and its children as a single class in the generated code.
Enter "A" when you are prompted for a name for the class.
Most of our remaining edits will take place in Class view.

Working with Dialogs

Dialogs (and Frames) are automatically created as classes so that the events are handled correctly. Builder Xcessory generates a handleEvent() method that is placed on the top-level element of each class you create.
  1. Create a Dialog as child of an awtFrame. (For more information on creating a Dialog, see Tutorial Three: Creating a Dialog .)
  2. Place a Dialog as a child of the Frame.
  3. Enter "D" when you are prompted for the class name.
  4. Note: If a class contains AWT objects that are subclassed from the abstract class Window (Frame, Dialog, FileDialog), this can be a problem as they do not propagate events up the instance hierarchy. Therefore it is important that these objects are always created as classes with their own handle.Event() methods.
The hierarchy in Classes view now looks like Class View Hierarchy :
  1. Add a Button to the awtDialog, naming the instance "dismissButton", and set its label to "Dismiss".

Class View Hierarchy

Editing the Layout

Next, add children to the mainContainer.

Type

Instance Name

gridX

gridY

List

awtList

0

0

Choice

choice

2

0

Button

clearButton

2

1

Label

label

0

2

TextField

textField

1

2

Label

label1

0

3

Label

selectLabel

1

3

Instance Name

Resource

Value

awtList

fill

BOTH

gridHeight

2

gridWidth

2

choice

fill

HORIZONTAL

clearButton

fill

HORIZONTAL

selectLabel

fill

HORIZONTAL

gridWidth

2

textField

fill

HORIZONTAL

  1. Change the layout resource on the mainContainer to GridBagLayout.
  2. Add the following children to the mainContainer instance, naming them and editing their gridX and gridY resources using the extended editors:
  3. Set these additional GridBagLayout constraints for each of the mainContainer children as follows:

Refer to GridBag Layout Illustrated for an illustration of how these settings affect object layout:

· Resource gridX and gridY specify the location of the object on the grid.

· gridWidth and gridHeight specify the number of cells to span.

· Fill specifies the dimension in which to span the cell.

Note: Layout changes as you change the constraint resources.

Final layout

GridBag Layout Illustrated illustrates the final layout:

GridBag Layout Illustrated

4. Set the following resources:

Instance Name

Resource

Value

awtList

visibleRows

4

choice

items

Single Select

Multiple Select

clearButton

label

"Clear"

label

label

"Add Item:"

textField

columns

30

label1

label

Select Item(s):

selectLabel

label

nothing selected

Setting Font Styles

Now create a style for the font according to the following steps:

Creating the DefaultFont style

With BaseStyle selected, select Create Substyle from the Style Manager Edit (MB3 Quick Access) menu.
Double-click on the style or select Edit Style from the Style Manager Edit (MB3 Quick Access) menu.
  1. Display the Style Manager by selecting Styles from the Browser Managers menu.
  2. Create a substyle of the BaseStyle.
  3. Edit the new style.
  4. Change the Style Name to DefaultFont.
  5. Select "font" from the Resources combo box.
  6. Set "font" to "Helvetica-18" either by entering the value or using the extended editor.
  7. Apply the definition to the style.

Creating the ItemFont style

To create the ItemFont style:

  1. Create another substyle of BaseStyle.
  2. Change the new style's name to ItemFont.
  3. Select "font" from the Resources combo box.
  4. Set "font" to "Courier-22".

Apply styles to classes

To apply styles to classes:

Select "To selected Tree" from the Style Manager Apply menu. Note that the style can't be applied to the dialog instance "d". Instead, you should apply the style to the dialog class "D".
  1. Apply the definition to the style.
  2. Select DefaultFont in the Style Editor and select the awtFrame inside of class "A" and apply the DefaultFont style to the tree.
  3. Select ItemFont in the Style Editor and apply it to awtList.
  4. Apply the ItemFont style to selectItem.

Adding events

Add the following events using the Resource Editor:

Instance Name

Event

Value

awtList

listDeselect

select()

listSelect

select()

choice

stateChangedEvent

changeSelection()

clearButton

actionEvent

clear()

textField

actionEvent

addItem()

dialogButton

actionEvent

activateDialog()

closeButton

actionEvent

close()

dismissButton

actionEvent

dismissDialog()

Adding code to the events

Now add code to the events, as follows:

  1. Click the (...) button next to the event to bring up the Callback Editor.
  2. Select the Edit button and add the code to appropriate event.
  3. Note: You can generate the class file and load it into an editor to edit all the events at once. Refer to Generating and Compiling Java Code .

Code

All code should go into the User Code Blocks:

public boolean select(ItemEvent e)
{
// Begin user code block <select>
String str[] = _awtList.getSelectedItems();
String selItems;
int i;
System.out.println("Length = " + str.length);
if (str.length == 0)
{
_selectLabel.setText("nothing selected");
}
else {
selItems = str[0];
for (i = 1; i < str.length; i++) {
selItems += ", " + str[i];
}
_selectLabel.setText(selItems);
}
return true;
// End user code block <select>
}
public boolean changeSelection(ItemEvent e)
{
// Begin user code block <changeSelection>
_awtList.setMultipleMode(_choice.getSelectedIndex()==1);
return true;
// End user code block <changeSelection>
}
public boolean clear(ActionEvent e)
{
// Begin user code block <clear>
int count = 0;
int i;
count = _awtList.getItemCount();
for (i = 0; i <= count; i++) {
_awtList.deselect(i);
}
_selectLabel.setText("nothing selected");
return true;
// End user code block <clear>
}
public boolean addItem(ActionEvent e)
{
// Begin user code block <addItem>
_awtList.addItem(_textField.getText());
_textField.setText("");
return true;
// End user code block <addItem>
}
public boolean activateDialog(ActionEvent e)
{
// Begin user code block <activateDialog>
_d.show();
return true;
// End user code block <activateDialog>
}
public boolean close(ActionEvent e)
{
// Begin user code block <close>
if (e.getActionCommand().equals("Close")) System.exit(0);
return true;
// End user code block <close>
}
public boolean dismissDialog(ActionEvent e)
{
// Begin user code block <dismissDialog>
if (e.getActionCommand().equals("Dismiss"))
this.setVisible(false);
return true;
// End user code block <dismissDialog>
}

You have now finished building your Java application.

Save your interface

Save your interface (Browser:File:Save) and generate the code (Browser:File:Generate).

You are now ready to compile your Java source into byte codes and run the finished application.

Generating and Compiling Java Code

Compiling the application

To run this as an application, you can use the class A directly (because it has a main() routine), or run it from the MainApp class generated by Builder Xcessory.

Depending on which method you use, compile the code by entering on the command line:

javac MainApp.java

or

javac A.java

Since the Java code generator automatically creates a Makefile, you can also use the following command to compile your code:

make -f makefile-java

Running the application

To run the application, on the command line type either:

java MainApp

or

java A

Java Applet

If you are creating an applet that pops up the frame from within a browser, use the driver class created by Builder Xcessory (MainApp by default). To make the MainApp class an applet, select the Make Main File An Applet toggle button on the Application panel of the Java Generation Preferences dialog (Browser:Options:Code Generation Preferences).

To compile the java code, on the command line enter:

javac MainApp.java

Embedding the example in a browser

To embed this example within a browser, you cannot use the Frame class, the MenuBar, or the Dialog. Instead, you must start this tutorial by creating an Applet from the Palette.

Follow the directions for this tutorial from step Add a Panel to the awtFrame, renaming the instance "mainContainer". on Add a Panel to the awtFrame, renaming the instance "mainContainer". . Upon completion, deselect the Main and HTML toggles on the File Names panel of the Java Generation Preferences dialog (Browser:Options:Code Generation Preferences).

Compiling Java code

To compile the Java code enter:

javac MainContainer.java

Running Your Java Applet

Java Applet

To run this example as an applet that pops up the frame from within a browser, select one of the following methods:

· Start the browser and read the file MainApp.html .

· If you created an Applet from the Palette and named it MainContainer, read in the file MainContainer.html.

You have now completed Tutorial Nine.

 

Documentation: 

Tutorial One: Simple Actions

 

Tutorial One: Simple Actions

In this tutorial, you will create a BulletinBoard with two PushButtons. Clicking one PushButton displays an xterm, while clicking the other exits the application.

Starting Builder Xcessory

Start Builder Xcessory by entering the following command on the command line:

% bx50

Builder Xcessory, the Palette, Browser, and Resource Editor, are displayed. Refer to Starting Builder Xcessory for more detailed information about starting Builder Xcessory.

Note: By default, Builder Xcessory starts with an interface named uil.uil. If you are creating a new interface, you can keep this name or rename the interface upon saving it (Browser:File:Save As).

Clearing an Interface

If a current Builder Xcessory is already running, clear the interface as follows:

If you have any pixmaps, styles, procedures, identifiers, user-defined types, or literals that will be destroyed, Builder Xcessory displays a message dialog. Set the toggle if you wish to retain these items, then click the OK button to dismiss the dialog.
If an old interface exists, another dialog is displayed warning you that it will be destroyed. Click the OK button to dismiss the dialog.
  1. Select New from the Browser File menu.
  2. Select Choose a Language from the Options menu of the Browser.
  3. Select C and Save As Default.

The remainder of this example assumes you have chosen C.

Creating and Resizing a Widget Instance

To create and resize an instance of the BulletinBoard widget, use the following procedure:

An outline of a BulletinBoard appears with the resize cursor in its upper-left corner.
Notice that the resizing cursor has moved to the lower-right corner of the BulletinBoard widget.
Your interface now contains a single BulletinBoard:
  1. Select BulletinBoard by clicking MB1 on its image in the Containers group on the Palette.
  2. Using the pointing device, move the cursor to the position on the display where you wish to place the upper-left corner of the BulletinBoard.
  3. Press MB1, and move the cursor slightly to the right.
  4. With the mouse button still depressed, resize the BulletinBoard outline to approximately three inches square. Release the mouse button.

Resized BulletinBoard

Placing a Child Widget

  1. Select PushButton from the Primitives group on the Palette.
  2. Place the PushButton inside the BulletinBoard, resized to be about an inch square.
  3. Note: The Browser displays the widget instance pushButton as the child of bulletinBoard.

Placing an Automatically Resized Widget

Place a second PushButton, without resizing it, inside the BulletinBoard to the right of the first PushButton.

Notice that the second PushButton is created with the same height and width as pushButton. This is pushButton1. Your interface should look like the following figure:

BulletinBoard with Two PushButtons

Selecting a Widget

To make pushButton the currently selected widget, click MB1 on pushButton. You can click on the object either in the interface itself, or on the Browser display.

Updating the Resource Editor

To update the Resource Editor for pushButton1, double-click MB1 on pushButton1.

You can select the object either in the interface itself, or on the Browser display. You can also select Automatic Update from the Resource Editor Options menu, forcing the Resource Editor to update whenever a widget is selected. This is not recommended for very large interfaces, because it slows Builder Xcessory significantly.

Resource Editor Forms

You can customize the resources displayed on the Resource Editor by selecting an item from the View menu. Available options allow you to display All Resources, Simple Resources, Programmer Resources, Modified Resources, or Not Equal Resources. Refer to View Menu for a description of these categories.

Confirm that the Resource Editor is displaying all of the resources of the currently selected widget by selecting All Resources from the Resource Editor View menu.

Searching the Resource Editor

Confirm that pushButton1 is the currently selected widget. Its name should be displayed in the Resource Editor Instance Name field. Locate the labelString resource:

  1. If the Find Resource field is not already displayed at the bottom of the Resource Editor, position the cursor within the Resource Editor and press Ctrl+F to display it.
  2. Enter the name of the sought resource, labelString, into the Find Resource field.
  3. Note: The current value of this resource is pushButton1.

You can also locate a resource by using the scrollbar to the right of the Resource Editor.

Setting a Resource

Now that you have assembled the elements of the interface, the next step is to set the resources of these widgets.

You can set a widget resource with one of the following procedures:

· Type the value directly into the text window to the right of the resource name in the Resource Editor.

· Apply the value to the resource using the appropriate extended editor.

Using an Extended Editor

Setting a resource value

To set the value of the labelString resource of pushButton1 to "EXIT":

This displays the extended editor appropriate for the labelString resource, the XmString Editor. (The window title includes the name of the resource, in this case "labelString".)
Extended editors are discussed in Extended Editors in the Builder Xcessory Reference Manual .
For the XmString Editor, first click MB1 at the end of the text field. Drag the cursor the length of the field while holding down MB1. This highlights the contents of the field. Pressing the delete key deletes the highlighted contents of the text field.
Type "EXIT" (without quotes) in the XmString Editor text window. Do not press return when you finish typing; that would simply add another (blank) line to the label.
This applies the contents of the XmString Editor text window as the labelString resource of pushButton1. Note that the new value is displayed in the text field to the right of the labelString resource on the Resource Editor.
  1. Click the (...) button to the right of the labelString text field.
  2. Enter the new resource value, EXIT, in the text area of the extended editor. (The instance name is displayed in this text area by default.)
  3. Click the Apply button at the bottom of the Multiline Editor.

Setting a Resource in Multiple Widgets

A major advantage of extended editors is that they allow you to apply resource values to a series of widgets without updating the Resource Editor.

To set the value of the labelString resource of pushButton to XTERM:

  1. Without dismissing the extended editor, select pushButton.
  2. In the XmString Editor, delete EXIT, and type XTERM.
  3. Click Apply to apply the new resource value to pushButton.
  4. Click Dismiss to remove the XmString Editor.

Your interface should appear as follows:

Labeled PushButtons

Setting Callback Resources

Callback resources are set like any other resource in Builder Xcessory. You could type the callback information into the text window to the right of the resource in the Resource Editor. However, because you will change this resource for more than one widget, you should again use an extended editor, in this case, the Callback Editor.

Updating callback resources

This time start with the PushButton labeled XTERM, since it is the currently selected widget.

This displays the Callback Editor.
AppCallback
Click the OK button to the right of the text field. A dialog prompts you to confirm that you wish to declare AppCallback as a new procedure in the interface. Click OK to confirm this.
The new procedure was originally created with a default Parameter Type of Undeclared. You have changed the type to String.
"xterm&"
Remember to click the OK button to the right of the text field.
XmAnyCallbackStruct *acs=(XmAnyCallbackStruct*)call_data;
insert the line:
system((char*)client_data);
This command passes the input parameter, client_data , to the system call, system , which in turn passes its parameter to the operating system. This transaction is the same as typing the parameter on the command line, and results in an xterm being created when AppCallback is called.
  1. Update the Resource Editor for pushButton, the PushButton labeled XTERM.
  2. In the Resource Editor, locate the activateCallback resource.
  3. Click the (...) button to the right of the resource.
  4. In the Callback Editor, enter the following in the text field to the right of the Procedure Name label:
  5. Click on the arrow next to Parameter Type, and select String from the list of types.
  6. Enter (with quotes) the following in the Parameter Name text field:
  7. Click the Apply button to apply the contents of the Callback List as the resource value of activateCallback.
  8. Click Edit to display your pre-set editor (chosen from Browser:Options:Tools Preferences) with the callback stub loaded.
  9. After the line:

Do not dismiss the Callback Editor; you will use it for pushButton1.

Using Predefined Callbacks

Builder Xcessory has a number of predefined callbacks to save you the time and effort of continually rewriting certain common callbacks. Predefined callbacks are also active in Play Mode, enabling you to observe the effect of the callback without having to build the executable.

Setting a callback resource

To set the callback resource for the PushButton labeled EXIT:

Do so either by clicking Reset, which sets the list to the current (null) value of activateCallback for the EXIT PushButton, or by highlighting any callbacks appearing in the Callback List and then clicking Delete.
Display the list by clicking the arrow button to the right of the Procedure Name text field on the Callback Editor. Select an item by clicking on it in the list. The list is automatically unposted, and the selected item is displayed in the text field.
  1. Select pushButton1, the PushButton labeled EXIT.
  2. Clear the Callback List on the Callback Editor.
  3. Select BxExitCB from the list of predefined callbacks.
  4. Note: The Parameter Type is automatically associated with the default type for the selected callback, in this case, Integer for BxExitCB.
The value BxExitCB(0) should now be displayed for activateCallback in the Resource Editor.
You do not need to edit the BxExitCB procedure. As a predefined callback, it already contains all code necessary for it to function.
  1. Enter the value 0 in the Parameter Name text field on the Callback Editor.
  2. Apply the contents of the Callback List to pushButton1.
  3. Click Dismiss to remove the Callback Editor.

Generating Code

You have constructed the interface and set up the callbacks. The next step is to write out the code for the interface. You will then edit the code and test the interface.

You will probably wish to change the destination directory to Tut1 . If you have questions about how to do this, review Changing the Destination Directory .

This writes out the file uil . uil (the default interface name; see Starting Builder Xcessory ), which can be read back into Builder Xcessory to reconstruct the collection.
It is a good idea to regenerate the callbacks-c.c file each time.
  1. Select Save from the File menu on the Browser, then click OK.
  2. Select Generate from the Browser File menu.

Reviewing the Callback Structures

To review the callback structures, do the following:

The callbacks-c.c file should contain the following procedures (not necessarily in this order):
/* ARGSUSED */
void
AppCallback(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
system((char*)client_data);
}
void
BxExitCB ARGLIST((w, client, call))
UARG(Widget, w)
ARG(XtPointer, client)
GRAU(XtPointer, call)
{
int exitValue = (int)client;
exit(exitValue);
}
  1. Load <tutorial_path>/Tut1/callbacks-c.c into a text editor (for example, vi , or emacs).
  2. Save and close the file.

Compiling and Running

You are ready to compile the C code in order to implement the callbacks that you set up. To compile the code:

make -f makefile-c
If the compile fails, select the Makefile tab on the Code Generation Preferences dialog (from the Browser Options menu) and confirm that the CFLAGS field of the Makefile tab contains
-I/usr/include/Xm -D_NO_PROTO
main-c
  1. cd to the directory to which you wrote the output files.
  2. Type the following command at the prompt:
  3. Type the following command at the prompt:

Your interface should appear on the screen.

Testing the Interface

If you click MB1 on the PushButton labeled XTERM, an outline of an xterm should appear on your display. If you click on the PushButton labeled EXIT, your interface should disappear and the program should exit.

Note: On some systems, exit does not kill the parent process before all of its children have been killed. This means that you are not able to kill your interface before you exit out of all of the xterms that you created with the interface. To avoid this situation, kill all of the xterms before you select the EXIT button.

You have now completed Tutorial One.

 

Documentation: 

Tutorial Seven: Classes

 

Tutorial Seven: Classes

Using Builder Xcessory, you can group a set of widgets together into a new reusable component. This new component is called a class, and is added to the User Defined Classes group on the Palette.

Once created, a class can be instantiated in the same manner as any other Palette object. A class can be modified at any time and changes to a class will appear in all instances of that class.

One big advantage of classes is that in C, C++, ViewKit, Java, and UIL the generated code consists of only one block of code for a given class. This block of code is reused for the creation of the various instances of the class.

A Builder Xcessory class should not be confused with an X Toolkit Widget Class.

Note: This tutorial assumes that you have chosen C or C++ as your language.

Constructing the Interface

If you have questions about this procedure, review Creating and Resizing a Widget Instance .
If you have questions about this procedure, review Setting a Resource .
It should be about half the width of the Form.
It should be about half as wide as the Form. Set the Instance Name field in the Resource Editor to "question".
  1. Clear the Builder Xcessory display. If you have questions about this procedure, review Clearing an Interface .
  2. Create a Form widget, resized to approximately three inches high and four inches wide.
  3. Place a Label widget across the top of the Form. Set the Instance Name field in the Resource Editor to "title".
  4. Place a ScrolledList widget down the left side of the Form and under the Label.
  5. Add another Label on the right side of the Form under the first Label.
  6. Add a Frame under the Label, and resize it to be the same width as the Label.
  7. Add a Label inside the Frame. Set the Instance Name field in the Resource Editor to "answer".

The interface should now have the instance tree shown in the following figure:

Instance Tree

The interface itself should look something like the following figure:

Interface

Setting Resources

Widget 

Resource

Resource Value

title

bottomAttachment

Xm_ATTACH_NONE

title

leftAttachment

XmATTACH_FORM

title

leftOffset

0

title

rightAttachment

XmATTACH_FORM

title

rightOffset

0

title

topAttachment

XmATTACH_FORM

title

topOffset

0

scrolledWindow

bottomAttachment

XmATTACH_FORM

scrolledWindow

bottomOffset

15

scrolledWindow

leftAttachment

XmATTACH_FORM

scrolledWindow

leftOffset

15

scrolledWindow

rightWidget

question

scrolledWindow

rightAttachment

XmATTACH_WIDGET

scrolledWindow

rightOffset

15

scrolledWindow

topWidget

title

scrolledWindow

topAttachment

XmATTACH_WIDGET

scrolledWindow

topOffset

15

question

bottomAttachment

XmATTACH_NONE

question

rightAttachment

XmATTACH_FORM

question

rightOffset

15

question

leftAttachment

XmATTACH_NONE

question

topWidget

title

question

topAttachment

XmATTACH_WIDGET

question

topOffset

20

frame

bottomAttachment

XmATTACH_NONE

frame

leftWidget

scrolledWindow

frame

leftAttachment

XmATTACH_WIDGET

frame

leftOffset

0

frame

rightAttachment

XmATTACH_FORM

frame

rightOffset

15

frame

topWidget

question

frame

topAttachment

XmATTACH_WIDGET

frame

topOffset

30

  1. Confirm that the Resource Editor is displaying all of the resources of the currently selected widget by selecting All Resources from the Resource Editor View menu.
  2. Use the Form Editor and the Resource Editor to set the following constraint resource values. If you have questions about these procedures, refer to Setting Constraint Resources .

Your interface should now look something like the following figure:

Interface after Setting Constraint Resources

Creating a Class

You will now define this dialog as a class.

A popup dialog prompts you for the name of the class.
The tree beneath the top level widget is replaced by a single icon representing the new class, SelectDialog. Note that you can no longer edit the constituent widgets of the class in the interface itself.
  1. Select the top-most widget, the Form, and select Make Class from the Browser Edit menu.
  2. Enter "SelectDialog" in the dialog.

Editing a Class

The list of your top level widgets switches to a list of your classes. The class SelectDialog should be the only one in the list.
The Browser now displays the object instance hierarchy of your class, allowing you to set resources of the member widgets. Resources are set just as in Instances view.
A small eye icon appears next to Code. (After Code is selected, Expose is sensitized and can be selected on the Placement option menu. Widget instances that are members of a class are the only instances that can be exposed.)
When editing a class, you can force a resource to take the class value in all instances of the class or you can allow it to be overridden in a given class instance. To allow a class resource to be overridden in a class instance, you set it to be Exposed by clicking Expose on the resource setting options menu. Note that resources set to Style or None can not be Exposed.
items = "None", Code (Exposed)
singleSelectionCallback = Selector(), Code
selectionPolicy = XmSINGLE_SELECT, Code
If you plan on generating C, pass parameter class_in of parameter type SelectDialogDataPtr to Selector() .
  1. Switch to Classes view by clicking on the arrow button at the left of the Browser and selecting Classes.
  2. Select the Title widget and set the labelString resource to "Select Dialog".
  3. The resource setting of the labelString resource should be set to Code. Pull down the option menu and click on Expose.
  4. Select the Question widget, and set the labelString resource to "The item selected is..." and its resource setting to Code. Expose the resource.
  5. Select the List widget and set the following resources to these resource values (and resource settings):

Adding a Member

You can add data members to your class.

  1. Select the SelectDialog class in the Browser, and update the Resource Editor.
  2. Click on the (...) button next to the Protected Data field to bring up the Class Member Editor.
  3. Add a data member with Data Name selection and Data Type Compound String. Click Apply.

Adding a Method

You can also add a method to your class.

  1. Click on the (...) next to the Protected Methods field and toggle the Item Type option menu in the Class Member Editor.
  2. Add a method with a Method Name of get_selection and a Return Type of Compound String.
  3. Leave the Parameter Name and Parameter Type fields blank. Click Apply.

Creating a Class Instance

You have now finished designing the SelectDialog class.

The Browser now displays the object instance hierarchy of your interface, including all instances of your class. You can easily create another class instance.
You access the Storage Location dialog from the Resource Editor Component menu.
  1. Switch back to Instances view.
  2. Scroll the Palette until the SelectDialog class comes into view.
  3. Create an instance of SelectDialog by selecting it on the Palette and dragging it to your display.
  4. Set the Instance Name field on the Resource Editor to "selectItem" for the first class instance and "selectBuilder" for the second class instance.
  5. If you will be generating C, set the Storage Location for selectItem and selectBuilder to Global (Component:Storage Location). Accept the default Widget Name of each.

Editing a Class Instance

To edit an instance of your class:

All the exposed resources available in this class instance are displayed in the Resource Editor. You will find all the resources that you set as Exposed listed under Class Widget Resources, with a resource setting of Class. If you do not edit any of these fields, they will have the values you specified for the class. To override a resource, enter a new value.
list1.items = item1,item2,item3
question.labelString = You selected the following item:
Your selectItem instance has overridden the label and the list items but it has the same title that was specified in the class. Note that the resource setting for the overridden resources has changed to Code.
Your interface should now look something like the following figure:
  1. Update the Resource Editor for selectItem.
  2. Set the following values:

Edited Class Instance

question.labelString = The best builder tool is:
list.items = Builder Xcessory,
Acme Builder Tool,
Legos,
Fred
title.labelString = Select a Builder Tool
  1. Now override all the resources in the selectBuilder instance by entering the following resources:

Generating Code

You have now constructed an interface with two instances of your class. The next step is to write out the code for your interface. Save the UIL file and generate either C or C++ code for your interface. If you have questions about these procedures, review Generating Code .

When you generate code for an interface that contains classes, Builder Xcessory creates some additional files for your class. These files depend on the language you choose to generate.

C files

If you generate C files, Builder Xcessory generates two new files for each class in your interface. For this example, it generates SelectDialog.c and SelectDialog.h .

The SelectDialog.h file defines a structure that contains the widgets in your class as well as any data members or methods you defined. In SelectDialog.c the class widgets are created and their default resources are set.

C++ files

If you generate C++ code, Builder Xcessory generates files for each class in your interface.

For this example, it generates SelectDialog.C and SelectDialog.h .

The SelectDialog.C and SelectDialog.h files are similar to the SelectDialog.c and SelectDialog.h files generated for C code.

SelectDialog.h defines the class SelectDialog containing all the widget instances and data members or methods you defined.

In SelectDialog.C the class widgets and their default resources are set in the class constructor.

Editing the Callback Structures

C files

If you have generated C files, load the callbacks-c.c file into your editor. If you have questions about this procedure, refer to Setting Callback Resources .

#include "SelectDialog.h"
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
insert the lines:
XmListCallbackStruct *list_call =
(XmListCallbackStruct*) call_data;
SelectDialogDataPtr
select = (SelectDialogDataPtr) client_data;
XtVaSetValues(select->answer,
XmNlabelString, list_call->item, NULL);
  1. At the top of the file, add this line:
  2. Within the procedure Selector, after the line:
  3. Save and close the file.

C++ files

If you have generated C++ files, load the file SelectDialog.C into your editor. If you have questions about this procedure, refer to Setting Callback Resources .

#include <Xm/Xm.h>
XmListCallbackStruct *list_call =
(XmListCallbackSruct*)call_data;
XtVaSetValues(_answer,XmNlabelString, 
list_call->item, NULL);
  1. At the top of the file in the user code block <head>, add this line:
  2. Within the user code block, inside the method Selector, add the following lines:
  3. Save and close the file.

Compiling and Running

Compile and run your program. If you have questions about these procedures, review Compiling and Running .

You have now completed Tutorial Seven

 

Documentation Type: 

Tutorial Six: Compound Strings and Font Lists

 

Tutorial Six: Compound Strings and Font Lists

In this tutorial, you will experiment briefly with Builder Xcessory's major tools for implementing internationalization, the Compound String Editor and the Font List Editor. Review the discussion of these editors in the Builder Xcessory Reference Manual before proceeding with the tutorial.

Clearing the BX display

Clear the Builder Xcessory display by selecting New from the Browser File menu.

Compound Strings

Builder Xcessory supports compound strings and font lists to assist you in the development of internationalized applications. Specifically, it allows you to build compound strings that combine the characters of multiple character sets.

Creating and applying a font list

In this example you will create and apply members of a font list to the labelString resource of a Label widget.

If you have questions about this procedure, review Creating and Resizing a Widget Instance .
If you have questions about this procedure, review Updating the Resource Editor .
  1. Create a Label widget.
  2. Update the Resource Editor.
  3. Confirm that the Resource Editor is displaying all of the resources of the currently selected widget by selecting All Resources from the Resource Editor Resources menu.

Using Compound Strings

Bring up the Compound String Editor for the Label widget's labelString resource.

If you have questions about this procedure, review Using an Extended Editor .

Compound String Editor

The Compound String Editor contains the following components:

· A CombinationBox widget, displaying a Font Tag text field.

· A large arrow button pointing to the right. This indicates the direction in which entered text is read.

· The text field (currently containing the string "label"). In this field you can edit the string and apply different font tags to different parts of the string.

· A Show Output toggle. When the toggle is set, the compound string is previewed in the lower window. Any changes made in the editor are reflected in this window before the contents are applied to the currently selected widget resource using the OK button.

Experiment for a moment to demonstrate how these components work.

Show Output example

As an example of how Show Output works:

When it is set, the button appears pushed in.
Notice that the altered string is displayed in the Show Output window ( Show Output Window ), but not in the widget itself:
  1. Make sure the Show Output toggle is set.
  2. Put an insertion point at the end of the string "label", press return, and enter the string "wysiwyg".

Show Output Window

The widget label now reflects the full contents of the editor.
  1. Click the Apply button at the bottom of the Compound String Editor.
  2. As an example of how the direction indicator works, click the arrow to point right to left. On a line under the string "wysiwyg", type the string "backward" and click the Apply button.
  3. Note: This part of the string reads right to left (see Right to Left Reading String ).

Right to Left Reading String

  1. Click the direction button back to left-to-right before proceeding.

Font Tags

Any segment of the compound string that is not explicitly tagged takes the default font tag at run-time. The default font tag is assigned according to the following order of precedence:

  1. The first (top-most) untagged font in the Font List associated with the widget.
  2. The first tagged font in the Font List (if all fonts are tagged).

The first unnamed tag in the Font List is FONTLIST_DEFAULT_TAG_STRING.

  1. Click the arrow button to the right of the Font Tag label on the Compound String Editor.
  2. Note: There are currently no other font tags in the font list.
To create a new font tag, use the Font List Editor:

Font List Editor

The font definition of the currently selected member of the list (the default, untagged font) is copied to the new, unnamed, tag.
The tag is applied to the new member of the list.
This text is all tagged as new_tag. You can also tag text by highlighting it and then selecting a tag from the pop-down menu.
  1. Click New to create a new tag.
  2. Enter the name new_tag in the Font Tag text field and press return (or click the OK button to the right of the text field).
  3. Enter new_tag in the Font Tag text field and press return.
  4. On a new line below "backward", enter the string "And now for something completely different..." and click Apply.
  5. Select the three characters "abe" in the string "label", pop down the menu and select new_tag, and click Apply.

Editing font tags

You will now change the characteristics of new_tag by editing the tag using the Font List Editor.

Note that there is one entry in the list, with no associated tag.
Don't worry about aesthetic value here; use your imagination and create something completely different from the rather staid default font definition. For example, make the Size very large or very small.
This applies the full font list, including the newly created font, new_tag, as the resource value for the Label widget's fontList resource.
Note that the list appears in the text field to the right of the fontList resource on the Resource Editor, in the form:
<lots of font info>,<lots of font info>=new_tag.
  1. Display the Font List Editor for the fontList resource of the Label object (see Font List Editor ).
  2. On the Font List Editor, change the definition of new_tag by picking new settings on the Family and Size pop-up menus, and the Bold and Italic toggles.
  3. Click the Apply button on the bottom of the Font List Editor.
  4. Click the Dismiss button to remove the Font List Editor.

Applying font tags

Returning to the Compound String Editor, you'll notice that the font has not changed either in Show Output.

Click Apply on the Compound String Editor.

The new font is applied correctly in both the preview and the widget. A sample font change is shown in Compound String with Multiple Character Sets :

Compound String with Multiple Character Sets

That's all there is to creating compound strings that combine the characters of multiple character sets.

You have now completed Tutorial Six.

 

Documentation: 

Tutorial Three: Creating a Dialog

 

Tutorial Three: Creating a Dialog

In this tutorial, you will create an interface containing a BulletinBoard and two PushButtons. Clicking one PushButton will exit the application. Clicking the other will cause a dialog to appear. The dialog will consist of a BulletinBoard and a PushButton. Clicking this PushButton will dismiss the dialog.

Clear the Builder Xcessory display by selecting New from the Browser File menu.

Note: This tutorial assumes that you have chosen C as your language.

Creating Objects

Create a BulletinBoard and two PushButton children. If you are uncertain about how to do this, review See Creating and Resizing a Widget Instance and See Placing a Child Widget .

Creating a Dialog Shell

To create the dialog shell as a child of the bulletinBoard:

The dialog shell appears on your display. The Browser should now display dialogShell as the child of bulletinBoard and the parent of bulletinBoard1.
  1. Select BulletinBoard in the Containers group on the Palette.
  2. Position the upper-left corner of the BulletinBoard atop the existing bulletinBoard, and place it as a dialog by clicking MB3.

Completing the Collection

At this point you would add whatever widgets were to make up the dialog as descendents of bulletinBoard1. The dialog described in the remainder of this tutorial contains a single PushButton that dismisses the dialog. If you wish, you can experiment with Builder Xcessory and customize your own dialog for this example.

Adding a PushButton

Add a PushButton as the child of bulletinBoard1. This PushButton is created on the Browser object instance hierarchy as pushButton2.

The object instance hierarchy of your interface, displayed on the Browser, should now appear like the following figure:

Dialog Collection Instance Hierarchy

Editing Resources

Now you will use the Resource Editor or Builder Xcessory's extended editors to set widget resources. If you are uncertain about these procedures, review Using an Extended Editor and Setting Callback Resources .

labelString = DIALOG
activateCallback = DialogCallback()
labelString = EXIT
activateCallback = BxExitCB(0)
The latter is a predefined callback. If you have questions about using predefined callbacks, refer to Using Predefined Callbacks .
labelString = DISMISS
activateCallback = DismissCallback()
  1. Update the Resource Editor for pushButton.
  2. Confirm that the Resource Editor is displaying all of the resources of the currently selected widget by selecting All Resources from the Resource Editor View menu.
  3. Set the following resource values for pushButton:
  4. Set the following resource values for pushButton1:
  5. Set the following resource values for pushButton2:

Your interface should now appear like the following figure:

Top Level of Interface

Creating a Global Widget

You will now set bulletinBoard1 to have a Global scope, so that it can be referenced in the PushButton's DialogCallback.

The Storage Location dialog appears.
  1. Make bulletinBoard1 the currently selected object.
  2. Select Storage Location from the Resource Editor Component menu.
  3. Click on the Scope options menu, select Global.
  4. Confirm that Widget reflects the instance name bulletinBoard1.
  5. Click OK to dismiss the Storage Location dialog.

Generating Code

Save the interface code by writing a combination of C and UIL files. Then edit the file containing the callback structures to connect the functionality of the interface.

Save the UIL file and generate C code for your interface. If you have questions about these procedures, review Generating Code .

Confirming the Global Widget

Load <tutorial_path>/Tut3/creation-c.h into a text editor.

Observe that the following structure has been generated:

/*
* Global widget declarations.
* - EXTERNAL is set to extern if the
* defs file is not included from the
* main file.
*/
#ifdef DECLARE_BX_GLOBALS
#define EXTERNAL
#else
#define EXTERNAL extern
#endif
/*
* Start Global Widget Declarations.
*/
EXTERNAL Widget bulletinBoard1;
/*
* End Global Widget Declarations.
*/

Close the file.

Editing the Callback Structures

#include <Xm/Xm.h>
add the following:
#include "creation-c.h"
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
add the line:
XtManageChild(bulletinBoard1);
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
add the line:
XtUnmanageChild(bulletinBoard1);
The stubs in the callbacks-c.c , with your additions marked in bold, should now look like this:
The DialogCallback stub:
void
DialogCallback(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
XtManageChild(bulletinBoard1);
}
The DismissCallback stub:
void
DismissCallback(w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
XtUnmanageChild(bulletinBoard1);
}
  1. Load <tutorial_path>/Tut3/callbacks-c.c into a text editor.
  2. At the top of the file, after the line:
  3. Inside the procedure DialogCallback, after the line:
  4. Inside the procedure DismissCallback, after the line:
  5. Save and close the file.

Compiling and Running

Compile and run your program. If you have questions about these procedures, review Compiling and Running .

Testing the Interface

The application shell collection should appear on the screen.

  1. Pop up the dialog by clicking MB1 on the PushButton labeled "DIALOG". The dialog should look like the following figure:

Pop-up Dialog

  1. Remove the dialog by clicking "DISMISS".
  2. Exit the application by clicking "EXIT".

You have now completed Tutorial Three.

 

Documentation: 

Tutorial Two: Simple Objects

 

Tutorial Two: Simple Objects

In this tutorial, you will experiment with the creation of more complex interface objects. You will create a MenuBar with three CascadeButtons, each of which will be associated with a menu. Selecting a given item from one of these menus will execute a program. As part of this exercise, you will incorporate into your new collection the PushButtons that you built in Tutorial One.

If you have questions about clearing the interface, review Clearing an Interface .
If you have questions about these actions, review Creating and Resizing a Widget Instance .
  1. Clear Builder Xcessory.
  2. Select MainWindow from the Containers group on the Palette, resize the widget outline to about three inches square, and position it on your display.

Using Keep Parent

A convenient shortcut for creating a menu with several CascadeButtons is to use Keep Parent mode. Do the following:

If you have questions about these actions, review Placing a Child Widget .
Do not worry about the size of the MenuBar, it will be resized automatically by the MainWindow.
Notice that as soon as you select Keep Parent, all widgets on the Palette are grayed out except PulldownMenu and PopupMenu. This is because these collections are the only legal children of a MenuBar.
A number of things happen. Builder Xcessory does not merely create a menu. Rather, it creates a collection of three widgets: a CascadeButton, a menu, and a PushButton. This is the collection stored in the Palette under the name "PulldownMenu". Further, because Keep Parent is active, the top-most parent in this collection, cascadeButton, automatically becomes a child of the currently selected widget, menuBar. Note also that menuBar remains the currently selected widget.
If the MainWindow is not large enough, one or both of these collections will not be visible on your display, and you will need to resize both the MainWindow and the MenuBar. Your interface now appears likeMainWindow with CascadeButtons .
  1. Select MenuBar from the Menus group of the Palette and place it as a child of the MainWindow.
  2. Select Keep Parent on the Browser View menu.
  3. double-click MB1 on PulldownMenu in the Menus group on the Palette.
  4. Place another PulldownMenu collection as a child of menuBar.

MainWindow with CascadeButtons

  1. Unset Keep Parent on the View menu.

Setting CascadeButton Resources

Use the Resource Editor to change the following attributes of each of the CascadeButtons.

You can edit the Resource Editor text field directly, or use the Compound String Editor to make these changes.
Notice that, when set, the mnemonics appear underlined in the respective labels. Your interface should now appear as follows:
  1. Set the labelString resource to "Tools" for cascadeButton, and "Exit" for cascadeButton1.
  2. Set the mnemonic resource to "T" for the Tools CascadeButton, and "E" for the Exit CascadeButton.

Labeled CascadeButtons with Mnemonics

Creating Additional Widgets

You are now going to add two PushButtons to one of the PulldownMenus. By an amazing coincidence, they are the same as those you created in the first tutorial. If you still have the UIL file from Tutorial One, skip down to the section Reading Files .

If you do not have the UIL file from Tutorial One, do the following in order to add two PushButtons to your interface.

If you have questions about doing this, refer to Creating and Resizing a Widget Instance .
If you have questions about doing this, refer to Setting a Resource .
If you have questions about doing this, refer to Using Predefined Callbacks .
  1. Place two PushButtons as their own top level shells.
  2. Set the labelString resource of one PushButton to XTERM, and of the other to EXIT.
  3. Use the predefined callbacks to set the activateCallback resource of the XTERM PushButton to BxSystemCB("xterm&") and of the EXIT PushButton to BxExitCB(0).

Proceed to Deleting Widgets .

Reading Files

If you saved the UIL file from Tutorial One, read that file into your interface by doing the following:

The File Selection window appears.
You can do this either by editing the field itself, or by selecting a name from the Directories list, clicking the Filter button to display the appropriate subdirectory and parent, and repeating this process until the Filter field displays the full path.
The name is the default, <tutorial_path>/Tut1/uil.uil , unless you changed it during code generation.
The interface, a BulletinBoard containing two PushButtons, should appear on the display. Note that it is displayed on the Browser as the child of its own top-level application shell, the two top-level widgets and their descendents exist as separate collections.
  1. Select Read from the Browser File menu.
  2. Enter the absolute path <tutorial_path>/Tut1 into the Filter text field.
  3. Select the UIL file for the collection from the first tutorial by clicking on its name in the Files list.
  4. Click the OK button.

Deleting Widgets

Now you remove the menus' default PushButton children and replace them with copies of the PushButtons that you created in the first tutorial.

The PushButton is removed from your interface.
The addition to your interface is a BulletinBoard and two PushButtons.
The object instance hierarchy, as shown on your Browser display, should now appear as follows:
  1. Select the PushButton that is the child of the Tools PulldownMenu on your interface by clicking MB1 on its instance name, pushButton, in the Browser display.
  2. Select Delete on the Browser Edit menu.
  3. If you read in the UIL file from Tutorial One, drag each of the PushButtons outside of the BulletinBoard and place them as top-level objects.

Object Instance Hierarchy

Copying and Reparenting Widgets

You will now copy the XTERM PushButton to create a set of PushButtons that appear on the menu invoked by the Tools CascadeButton.

An icon appearing as a white square with a grey border is displayed as soon as you begin to move the cursor.
Because you used the Ctrl key during the previous operation, you copied the PushButton as a child of the menu, while preserving the original. Performing the operation without the Ctrl key would have moved the same widget instance from one place on the display to another.
  1. Press MB2 over the PushButton labeled XTERM on your interface.
  2. Holding down the mouse button, drag the icon over the widget instance pulldownMenu in the Browser display.
  3. Press the Ctrl key, and then release the mouse button.
  4. Repeat this procedure to create three more copies of the XTERM PushButton as children of pulldownMenu.

Setting PushButton Resources

You will now use the Resource Editor to change the PushButton resources so that selecting the PushButtons calls standard X Window System utility programs. Use the Resource Editor to change the following attributes of the PushButtons.

Use the XmString Editor to make these changes. If you have questions about this procedure, review Setting a Resource .
If you have questions about these procedures, review Setting Callback Resources .
  1. Set the labelString resource of three of the PushButtons to XBIFF, XLOAD and XCLOCK respectively.
  2. Set the Parameter Name for the activateCallback resource, AppCallback(), to "xbiff&" for the PushButton labeled XBIFF, "xload&" for that labeled XLOAD, and "xclock&" for that labeled XCLOCK.
  3. Remember to click the OK button to the right of the Parameter field before Applying each new value.
  4. Make sure that the activateCallback resource for the XTERM PushButton is set to AppCallback("xterm&").

Editing the Callback Structures

To edit the callback structures, do the following:

XmAnyCallbackStruct 
*acs=(XmAnyCallbackStruct*)call_data;
insert the line:
system((char *)client_data);
This command passes the input parameter, client_data , to the system call, system , which in turn passes its parameter to the operating system. This transaction is the same as typing the parameter on the command line, and results in the client being invoked when AppCallback is called.
  1. Click Edit to display the callback stub loaded into your text editor.
  2. Within the procedure AppCallback, after the line:
  3. Save and close the file.

Using Play Mode

You can test the look and feel of your interface in Play Mode. To test the cascade menu that you have just created, do the following:

  1. Set Play Mode on the Browser Project menu.
  2. Click on the Tools CascadeButton. Your MainWindow should now appear like Tools Menu :

Tools Menu

  • Set Build Mode from the Browser Project menu before continuing.
When you select an item from the menu, the Message Window notifies you which application would be called (in this case AppCallback). Builder Xcessory does not execute callbacks (other than predefined callbacks) in Play Mode.

Completing the Interface

Since the widget is copied with all of its resources, you do not have to set its callback routine. If you have questions about this procedure, review Copying and Reparenting Widgets .
In Play Mode, with the EXIT PushButton depressed, your interface should look something like the following figure:
  1. Delete the PushButton that is the child of the Exit PulldownMenu (pulldownMenu1) on your interface.
  2. Copy the EXIT PushButton from the first collection to be the child of the Exit PulldownMenu.

Exit Menu

Removing a TopLevelShell

Remove the read-in collection by the following method:

The object instance hierarchy of your interface, as displayed in the Browser, should now appear as in Object Instance Hierarchy .
  1. Select TopLevelShell1 on the Browser display.
  2. Select Delete from the Browser Edit menu.
  3. Delete the two stand-alone PushButtons.

Object Instance Hierarchy

Generating Code

When Builder Xcessory writes a Callbacks file to a directory containing another file with the same name, new callback stubs are appended to the old Callbacks file. Any callback structures in the original file are left untouched; you do not overwrite your old edited structures with blank stubs. In writing out the code for this interface, you could take advantage of this feature by building on the callbacks-c.c file from the first tutorial, which already contains the edited callback structures for the XTERM and EXIT PushButtons. You can accomplish this either by writing out the new Callbacks file into the directory that contains the old file, or by copying the old file into your present Output Files directory and then generating your output files. Of course, if you did not save the original file, or did not complete Tutorial One, you can write out a new Callbacks file and add all of the callback information.

For the purposes of this tutorial, you will write out the callbacks-c.c file into directory Tut2 .

You will probably want to change the destination directory to Tut2 . If you have questions about how to do this, review Changing the Destination Directory .

This writes the file uil.uil , which can be read back into Builder Xcessory to reconstruct the collection.
This writes out the C files, including the templates for the callback structures in the file callbacks-c.c .
  1. Select Save from the Browser File menu.
  2. Select Generate C from the Browser File menu.

Compiling and Running

Compile and run your program. If you have questions about these procedures, review Compiling and Running .

Testing the Interface

Your interface should appear on the screen.

The "Tools" menu appears. You can select any item on this menu by clicking on it.
You can loop through the menu using the arrow keys on the keyboard and select from the menu by pressing return when the option you want is highlighted.
The "Exit" menu appears.
The program exits.
  1. Click MB1 on the label "Tools".
  2. Test the mnemonics on the "Tools" menu. (For more information on how to do this, see Palette Mnemonics .)
  3. Scroll through the menu several times by repeatedly clicking either the up or down arrow key.
  4. Click on the label "Exit".
  5. Click on the EXIT button.

You have now completed Tutorial Two.

 

Documentation: 

Using the Tutorials

 

Using the Tutorials

Each tutorial demonstrates the use of Builder Xcessory in the construction of an interface. Tutorials do not share interfaces and are designed to stand alone, but we recommend that you do them in the order presented. The later tutorials tend to be more complex, and take for granted procedures described in detail in early tutorials. In general, if you are uncertain about the functionality of Builder Xcessory, review the Builder Xcessory User's Guide and the Builder Xcessory Reference Manual .

Setting Up Tutorial Directories

When Builder Xcessory writes a Callbacks file to a directory containing another Callbacks file with the same name, new callback stubs are simply appended to the old Callbacks file. Therefore, if you are starting a new interface, it is a good idea to do one of the following:

Starting a new interface

· Create a new directory and direct output files to that directory.

· Use the File Names tab of the Code Generation Preferences dialog (Browser:Options) to rename the Callbacks files to be generated for the new interface.

In each of the following tutorials, you will create an interface for which you will write output files. To prevent these files from overwriting one another, create the subdirectories Tut1 , Tut2 ,..., Tut9 .

Changing the Destination Directory

When you begin a new tutorial, use the following procedure:

  1. Select Code Generation Preferences from the Browser Options menu.
  2. On the File Names tab, enter the path for the appropriate directory in the Directory Path text field.
  3. For example, when you write out the files for Tutorial 1, change the path (which by default will be the directory from which you originally started Builder Xcessory) <tutorial_path>/Tut1 Click the OK button to the right of the text field.
  4. Click the Dismiss button to remove the dialog.

Notation of Wrapped Code

As a consequence of the long identifiers common in Motif, some identifiers are hyphenated in the code fragments presented below. In this and other cases, code that is intended to be entered as a single line in your program wraps around to a second line in the documentation.

Wrapped text is denoted by indentation of the second and subsequent lines. For example, the line:

XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;

should be entered on one line in your program.

 

Documentation: