The Builder Xcessory User's Guide is copyrighted by Integrated Computer Solutions, Inc., with all rights reserved. No part of this book may be reproduced, transcribed, stored in a retrieval system, or transmitted in any form or by any means electronic, mechanical, photocopying, recording, or otherwise, without the prior written consent of Integrated Computer Solutions, Inc.
201 Broadway, Cambridge, MA 02139
E-mail: info@ics.com
WWW: http://www.ics.com
Builder Xcessory, BX, BX/Ada, Builder Xcessory PRO, BX PRO, BX/Win Software Development Kit, BX/Win SDK, Database Xcessory, DX, DatabasePak, DBPak, EnhancementPak, EPak, ViewKit ObjectPak, VKit, and ICS Motif are trademarks of Integrated Computer Solutions, Inc.
All other trademarks are property of their respective owners.
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.
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 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.
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.
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:
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.
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:
Expressions are evaluated from left to right. Standard order of precedence is enforced for binary operator expressions.
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:
When the callback is called, the resources of the designated object are set to the specified values by using the function XtSetValues.
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.
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.
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:
If you are generating UIL, you can specify the widget ID with the widget name using MrmFetchWidget.
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.
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.
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:
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.
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.
A creation callback might look like the following:
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.
You can access widget IDs by using the structure that Builder Xcessory generates for each class when you are working in C.
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.
If you are generating UIL, you can obtain the widget ID by calling MrmFetchWidget on the widget name.
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.
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.
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.
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:
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.
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 ).
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.
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 .
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.
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 .
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
).
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().
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 .
When you add an event method to an object within a class, Builder Xcessory adds your routine as a public method.
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.
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.
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.
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.
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:
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.
5. Click on Apply to register the timer procedure.
All current timer procedures are displayed in the window above these fields.
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.
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.
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.
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:
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.
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.
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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
After installing Builder Xcessory on your system, enter the following command at the command line:
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:
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).
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.
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.
In your first Builder Xcessory session, the following Language Dialog window also appears in the foreground:
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.
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: When you select UIL as your default language, Builder Xcessory generates UIL to implement the interface and C code to implement the application.
Once you select a language at the beginning of your session, Builder Xcessory's three main windows are displayed:
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.
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.
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:
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.
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
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
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
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
· Build the application for which you are creating an interface
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
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:
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
Provides access to the online, hypertext help system, as well as version and copyright information.
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:
The Toolbar, optionally shown with the Browser View menu, allows you to place frequently used menu items within easy reach.
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.
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.
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.
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.
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.
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
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 .
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.
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.
· 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.
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.
To deselect one object within a group of selected objects, hold down Ctrl and click on that object. The other selected objects remain selected.
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:
· ViewKit ObjectPak Vk 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 .
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 .
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 .
The Palette can be viewed in outline or tabbed form (Figures Builder Xcessory Palette (Outline View) and Builder Xcessory Palette (Tabbed View) ):
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
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.
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.
To create a new top-level group, select New Group from the Palette Edit menu.
To create a new group subordinate to an existing group, select New Group from the Palette MB3 Quick Access menu.
Allows you to control the Palette's appearance by performing the following operations:
· Show the Palette in full or reduced (tabbed) view
· Display the Palette icons with only pixmaps, only labels, or both
Allows you to manipulate the Palette by performing the following operations:
· Merge a catalog with the current catalog
· Save the current Palette catalog
Allows you to rearrange the Palette by performing the following operations:
· Move objects from one group to another
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)
· Modify the properties of an object icon
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 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.
1. With MB1, click on the desired object.
2. Position the upper left-hand corner of the object where you want to place it, and click again with MB1.
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 ).
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.
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 ).
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.
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).
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
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.
· 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.
The Toolbar, optionally shown with the Resource Editor View menu, allows you to place frequently used menu items within easy reach.
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.
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.
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 .
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 .
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:
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 ).
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.
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.
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.
When building a user interface with Builder Xcessory, you spend much of your time using the Resource Editor to customize your UI objects.
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.
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.
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.
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.
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.
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:
For this example, you can work with UIL, C, C++, or ViewKit as your project language.
2. Select either UIL, C, C++, or ViewKit as your language from the Choose a Language dialog of the Browser Options menu.
To create widgets, use the following procedure:
1. Create a MainWindow about three inches wide and two inches high.
2. Create a MenuBar and place it as a child of the MainWindow, using one of the following methods:
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.
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):
2. Create a DrawingArea and place it as a child of the BulletinBoard.
Your Interface in Progress shows the result of the preceding steps:
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.
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:
Now that we have created the basic widgets, we'll begin customizing the widgets and designing the layout.
First, we'll set a number of resources on the Scale widgets:
1. Select all of the scales, using one of the following methods:
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):
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).
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.
3. Use the Alignment Editor to align and distribute the widgets.
Your Interface in Progress shows the result of the preceding steps:
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++.
You can make the necessary object IDs accessible using one of the following methods:
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.
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.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.
2. Add the code for the setColorCallback procedure using one of the following methods:
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.
The function setColorCallback performs the following operations:
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:
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.
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:
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.
2. Set the following resources on the CascadeButton (VkSubMenu):
3. Set the following resources on the PushButton (VkMenuAction) menu item:
4. Create a Help menu and apply the following resources to the Cascade:
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:
Do not add the callback or change the instance name in ViewKit; change only the labelString.
1. Create a BulletinBoard as a child of a DialogShell, in turn a child of your MainWindow.
2. Set the following resource on the BulletinBoard:
3. Create a Label as a child of the BulletinBoard (genericDialog) and set the following resources:
4. Create a PushButton as a child of the BulletinBoard and set the following resources:
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:
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:
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) .
We've now reached a point where we would like to test our application and its interface.
1. Save the interface.(Browser:File).
2. Enter Play Mode (Browser:Project) and test your interface.
3. When you are finished testing, re-enter Build Mode (Browser:Project).
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.
You can add or delete resources from a style at any time. This affects all objects using the style.
4. Apply the style to your entire interface, preserving the background value of the DrawingArea widget.
5. Create a second style as a child of BaseStyle1 (the style we've created above).
6. Add the following resource:value pairs to the style:
7. Apply (force) this style to your DialogShell and its children.
8. Edit the first style you created (BaseStyle1), changing the value of the following resource:
For more information about styles, including the creation of system styles, refer to Styles .
You can generate source code and run your application at any point in the development process.
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).
2. Generate source code (Browser:File:Generate).
3. Build and run your application.
You can now run your color selector. This concludes our Motif example.
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.
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.
1. Create your main window about three inches wide and two inches high.
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.)
1. Create a MenuBar and place it as a child of the main window, using one of the following methods:
2. Create a Label and place it as a child of the main window.
3. Create a Scrollbar and place it as a child of the main window.
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.
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):
2. Create a Canvas and place it as a child of the main window.
Your Interface in Progress shows the result of the preceding steps:
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.
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:
Now that we have created the basic objects, we'll begin customizing them and designing the layout.
We'll begin this stage by setting a number of resources.
1. Select all of the Scrollbars using one of the following methods:
2. Update the Resource Editor using one of the following methods:
3. Set the following resources (check that All Resources is selected from the Resource Editor View menu):
4. Set the following resources on all the Labels:
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 .
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):
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.
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:
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.
2. Add the code for the setColor method using one of the following methods:
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.
Insert the following code into the setColor method User Code Block in the AwtFrame.java file.
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.
2. Set the following resources on the Menu:
3. Set the following resources on the Menu Item:
4. Create an Exit method for the Exit Menu Item:
5. Create a Dialogs menu and apply the following resources to the Menu:
1. Create a Dialog as a child of your main window.
2. Set the following resource on the Dialog:
3. Create the Dialog contents.
5. Add two Labels to the Dialog. (Java does not directly support multiline labels.) Set the following resources:
6. Create a Panel as a child of the Dialog.
7. Create a PushButton as a child of the Panel and set the following resources:
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:
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).
2. Enter Play Mode (Browser:Project:Play Mode) and test your interface.
3. When you are finished testing, re-enter Build Mode (Browser:Project).
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.
You can add or delete resources from a style at any time. This affects all objects using the style.
4. Apply the style to your entire interface, preserving the background value of the Canvas widget.
5. Create a second style as a child of BaseStyle1 (the style we've created above).
6. Add the following resource:value pairs to the style:
7. Apply (force) this style to your DialogShell and its children.
8. Edit the first style you created (BaseStyle1), changing the value of the following resource:
For more information about styles, including the creation of system styles, refer to Styles .
You can generate source code and run your application at any point in the development process.
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).
2. Generate source code (Browser:File:Generate).
3. Build and run your application.
You can now run your color selector. This concludes our Java example.
Feel free to continue to explore Builder Xcessory' capabilities. Some ideas for additional work include:
· Experiment with the GridBag layout.
Selecting and Deselecting Objects
Example: A Simple Color Selector
Adding Action to Your Interface
Creating a Uniform Look and Feel for Your Application
Adding Action to your Interface
Creating a Uniform Look and Feel for Your Application
Creating a Class with Builder Xcessory
Adding Methods and Data Members
Exposing Callbacks and Event Methods
Aligning and Distributing Objects
Placing Objects without Setting width and height
Initializing Resources at Run Time
Callbacks with XtSetValues Calls
Managing and Unmanaging Objects
Callback Procedures and Event Methods
Using Callbacks in C++ Classes
Using Event Methods in Java Classes
Using Timers, Event Handlers, and Translations
Integrating Builder Xcessory with Your Environment
Using Builder Xcessory with Your Tools
Designing Your Application in an Integrated Environment
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
Placing Resource Values in Resource or UIL Files
Creating Multifont and Multidirectional Strings
Designing Your Own Message Catalog
Porting GIL Interfaces to Motif
Strategies for Importing Your GIL Documents
Setting Up Tutorial Directories
Changing the Destination Directory
Tutorial Three: Creating a Dialog
Tutorial Four: Using Resource Styles
Tutorial Five: Advanced Techniques
Tutorial Six: Compound Strings and Font Lists
Tutorial Eight: Creating Classes and Subclasses
Tutorial Nine: Creating a Java Applet or Application
In building and testing an interface with Builder Xcessory, use the following procedure:
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.
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.
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.
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.
First, create the objects by following these steps:
2. Place a label and a text field within the form as shown in the following figure:
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:
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:
The collection is now collapsed into a class instance on the Browser as shown in the following figure:
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:
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.
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.
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 .
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 .
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.
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.
To add a member to a class, follow these steps:
1. Switch the Browser to Classes view.
3. Update the Resource Editor.
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.
Class Member Editor illustrates the Class Member Editor for a class 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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 ):
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.)
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.
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 .)
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.
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.
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:
Once you make a component object of a class a receptor, you can add children to any of that class's 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.
Continuing the LabelField example, assume you want to include a toggle button to the subclass ToggleField.
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.
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.
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.
You can also share a library of classes among a group of users.
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.
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).
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).
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.
· 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.
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 ).
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 ).
The two sections are scrollable text regions. The contents of the text regions are included verbatim into the base and derived class .h
files. 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 ):
The following sections describe the files generated by Builder Xcessory for each language.
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.
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.
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.
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.
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.
Builder Xcessory allows you to create Java applications or Java applets. Java applications have the following attributes:
· Contain a single main()
method
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
System.exit()
cannot be used.
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.
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.
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.
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.
The following table provides an overview of the environment services available from Builder Xcessory and the conditions under which they are available:
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.
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.
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.
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.
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.
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.
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 ).
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 ).
5. Change any incorrect parameters.
6. To execute a build of your application, select Make Application from the Browser Project menu.
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.
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.
3. Verify the parameters on the Makefile Customization dialog.
4. Select Make Application from the Browser Project menu.
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.
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 ):
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 ):
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.
While your application is building, messages are displayed in the Browser message area.
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.
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.
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.
When the build is complete, Builder Xcessory loads the executable file into your environment's debugger, which is displayed on your screen.
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:
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.
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.
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.
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.
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 .
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.
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 .)
Use the following notation to enter a new source code control command:
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.
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:
In Builder Xcessory you would enter:
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.
This section describes first how to check a file out of source code control, then how to check it back in.
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:
2. Set or remove any check out options you want.
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.
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 .
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.
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.
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.
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.
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 .
You can also specify a memory error-checking tool to use with your code.
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 ):
3. On the Test Tools tab of the Tools Customization dialog, select Purify Command, MemAdvisor Command, or Other Command.
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.
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 emacsclient
tool to work, you must add the following Emacs Lisp command to your .emacs
file (the file that emacs
runs at startup):
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.
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:
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.
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).
Any language-specific information required by the application must be kept separate from the application source code. Typically, this information includes:
· 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.
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.
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.
A character set is the set of all the characters required to represent the words in the language.
A code set is the set of binary values required to represent the character set of a language.
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:
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.
When internationalizing an application, there are three broad types of problem:
Note: A Japanese version is available. Contact your ICS Sales Representative.
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.
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.
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:
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.
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):
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.
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):
At start-up, the application finds the correct UID file based on how your UIDPATH is set. See the description of MrmOpenHierarchy
in the
OSF Motif 1.2 Programmer's Reference for further details.
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.
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:
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.
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.
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.
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().
formats time and dates according to locale; both
strftime()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.
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 indicates that the resource is hard-coded with calls to XtSetValues, and is the default.
· App indicates that the resource is placed in an app-defaults file, which can be edited to produce localized versions of the application.
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).
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:
2. Scroll the dialog to find the Compound String and Font types, and set the App toggle for each (see Default Resource Type Settings).
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++.
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
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.
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.
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.
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.
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.
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.
The input method, with the locale set and the correct X11R5 calls in your application, communicates with your application automatically.
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.
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.
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.
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.
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.
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 .
You create the different font sets and tag them, so that they can be used in defining multifont strings.
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.
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.
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.
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.
Your application handles static and dynamic output differently in C/C++.
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:
Value of the filename parameter, or the application's class name if filename is NULL |
||
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.
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.
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.
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)
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.
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.
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.
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
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.
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.
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:
2. Select Align from the Browser Edit menu or MB3.
3. Select the desired alignment from the resulting menu.
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:
The following sections describe other techniques for layouts.
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.
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.
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.
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.
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 .
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
A side's offset is the distance maintained between that side and its attachment.
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.
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.
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.
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.
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.
Combines child objects with optional labels in separate columns, and allows you to specify their relative position.
Similar to RowColumn, IconBox adds the concept of an absolute cell position.
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.
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.
A special purpose manager, Plotter manages any number of the various Plot types (Pie Plot, Bar Plot, etc.) included in EnhancementPak.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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)
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:
Children have the following constraints:
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:
Children have the following constraints:
The Card layout causes the container to place its children atop one another, providing show
, first
, last
, next
, and previous
methods 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:
Children have the following constraints:
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:
Children have the following constraints:
Hint: To change the order in which the children are laid out, use the Raise/Lower operations (Browser:Edit or MB3 Quick Access menu).
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 gridx
values 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 fill
resource. 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.
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:
Children have the following constraints:
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.
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.
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.
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:
Entries capitalized in Builder Xcessory are capitalized in the index:
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:
:
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:
· Text preceded by a % denotes text to enter on the command line:
· Book titles, chapter names, and section names appear in italic:
· The main windows of Builder Xcessory are capitalized as follows:
Guide Interface Language (GIL) is the save format used by the Sun Microsystems product Devguide.
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.
Builder Xcessory's Import GIL option (Browser:File) reads GIL version 3 (GIL-3) files exclusively.
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.
Select GIL Options from the Browser Options menu to display the GIL Options dialog:
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.
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.
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.
In Devguide, you can use Groups to group objects together. Builder Xcessory imports Groups as Motif bulletin boards.
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.
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.
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.
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
· XView and PostScript drawing models for canvases
You should also be aware of the conversion conventions described in the following sections.
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.
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.
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.
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.
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.
Adding a PulldownMenu
Adding PushButtons
File Menu
Renaming PushButtons
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:
To label the menu items, follow these steps:
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.
()
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.
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
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:
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.
Children Added to the Subclass FilePlus
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.
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.
Defining a Virtual Method
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:
file.uil
in the File Name input field.To save the subclass (FilePlus):
fileplus.uil
in the File Name input field in the File Selection dialog.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 ).
Project, Private, and Public Classes
Using a Class in Your Application
Now you are ready to create your application.
Partially-built Application
Adding the Subclass FilePlus
Generating Code
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.
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 .
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.
defs.h
file:Setting the Resources
Setting the createCallback resource
Using the Callback Editor
Setting the activateCallback resource
Setting resources for pushButton
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 .
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".
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.
Testing Look and Feel
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
<tutorial_path>/Tut5/callbacks-c.c
into a text editor. 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>
callbacks-c.c
file.XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
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;
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);
XmAnyCallbackStruct
*acs=(XmAnyCallbackStruct*)call_data;
exit(0);
Reviewing the Edited Stubs
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;
}
AddWord stub
void
Dismiss stub
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));
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.
You have now completed Tutorial Five.
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.
Tut4
.Creating the Interface
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
Style Hierarchy
Using the Style Editor
You use the Style Editor to assign resource values to a given style.
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.
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
Setting Other Styles
Selecting Multiple Resources
Completing the Hierarchy
Edited Style Hierarchy
Applying Styles to Widgets
Now you will apply your styles to the objects in your interface.
Selecting objects
Applying styles to objects
Applying styles to an instance tree
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.
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
Create container window
Working with Dialogs
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
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
Creating the ItemFont style
To create the ItemFont style:
Apply styles to classes
To apply styles to classes:
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:
Code
All code should go into the User Code Blocks:
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:
or
Since the Java code generator automatically creates a Makefile, you can also use the following command to compile your code:
Running the application
To run the application, on the command line type either:
or
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:
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:
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.
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:
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:
Resized BulletinBoard
Placing a Child Widget
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:
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":
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:
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.
AppCallback
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.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:
BxExitCB(0)
should now be displayed for activateCallback in the Resource 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 .
uil
. uil
(the default interface name; see Starting Builder Xcessory ), which can be read back into Builder Xcessory to reconstruct the collection.callbacks-c.c
file each time.Reviewing the Callback Structures
To review the callback structures, do the following:
callbacks-c.c
file should contain the following procedures (not necessarily in this order):<tutorial_path>/Tut1/callbacks-c.c
into a text editor (for example, vi , or emacs).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:
-I/usr/include/Xm -D_NO_PROTO
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.
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
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
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.
Editing a Class
class_in
of parameter type SelectDialogDataPtr
to Selector()
.Adding a Member
You can add data members to your class.
Adding a Method
You can also add a method to your class.
Creating a Class Instance
You have now finished designing the SelectDialog class.
Editing a Class Instance
To edit an instance of your class:
list1.items = item1,item2,item3
question.labelString = You selected the following item:
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
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 .
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);
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
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.
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:
Show Output Window
Right to Left Reading String
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:
The first unnamed tag in the Font List is FONTLIST_DEFAULT_TAG_STRING.
Font List Editor
Editing font tags
You will now change the characteristics of new_tag by editing the tag using the Font List Editor.
<lots of font info>,<lots of font info>=new_tag.
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.
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:
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)
labelString = DISMISS
activateCallback = DismissCallback()
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.
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:
Close the file.
Editing the Callback Structures
callbacks-c.c
, with your additions marked in bold, should now look like this:<tutorial_path>/Tut3/callbacks-c.c
into a text editor.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.
Pop-up Dialog
You have now completed Tutorial Three.
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.
Using Keep Parent
A convenient shortcut for creating a menu with several CascadeButtons is to use Keep Parent mode. Do the following:
MainWindow with CascadeButtons
Setting CascadeButton Resources
Use the Resource Editor to change the following attributes of each of the CascadeButtons.
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.
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:
<tutorial_path>/Tut1/uil.uil
, unless you changed it during code generation.<tutorial_path>/Tut1
into the Filter text field.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.
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.
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.
Editing the Callback Structures
To edit the callback structures, do the following:
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.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:
Tools Menu
Completing the Interface
Exit Menu
Removing a TopLevelShell
Remove the read-in collection by the following method:
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 .
uil.uil
, which can be read back into Builder Xcessory to reconstruct the collection. callbacks-c.c
.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.
You have now completed Tutorial Two.
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:
<tutorial_path>/Tut1
Click the OK button to the right of the text field.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:
should be entered on one line in your program.