Linux
by Kamran Husain
IN THIS CHAPTER
- What Is the Interviews System?
- How to Get and Install Interviews
- Sample Applications
- idraw
Changes to Xdefaults
- ibuild
Code Generation
- Building an Application with ibuild
In this chapter, you will learn about the Interviews C++ class library development
system. You will learn about the tools available for Interviews and how to use them
to create front-end GUI applications.
Interviews offers a rich set of C++ functionality and tools for building applications.
This chapter can't possibly do it justice in the space provided. By reading to the
end of the chapter, though, you will get a feel for creating truly object-oriented
applications using Interviews.
To get the most out of this chapter, you need some knowledge of how to run the
C++ compiler and how to program in object-oriented languages. If you have not already
done so, you should install the X window package with at least Motif window manager
(mwm) or the OPEN LOOK manager (olwm).
The Interviews subsystem is a windowing system for X Window. Interviews is copyrighted
by The Board of Trustees of the Leland Stanford Junior University. Interviews was
developed by Mark Linton's group at Stanford.
What makes Interviews an interesting environment is that it provides an object-oriented
approach to building user interfaces. All components within Interviews, such as windows,
menus, scrollbars, and so on, are objects with inherited behavior. The name Interviews
is derived from the package presenting an interactive view of some data. For example,
a front end to a database provides an interactive view to the data in the database.
The Interviews kit is distributed in two packages: iv1 and iv2. The first package,
iv1, contains the binary and source files for the libraries. The second package includes
the man pages and a PostScript reference manual for the Interviews system.
The Interviews package is included on the CD that comes with this book.
-
TIP: I recommend that
you print the PostScript version of the Interviews manual if you plan on developing
any applications in Interviews. This manual is in the file /usr/doc/interviews/
refman.PS. You need a PostScript printer to print this document, or you can
view this manual via ghostscript.
The Interviews package comes with several applications found in the /usr/interviews/bin
directory. Applications to give you an idea of some of Interviews' potential are
shown in the dclock and idemo applications, shown in Figures 33.1
and 33.2.
FIGURE
33.1. The Interviews dclock
application.
FIGURE
33.2. A demo application with
Interviews.
The list of other ready-to-run applications under Interviews is shown in Listing
33.1.
We will cover some of these applications in a bit more detail in this chapter.
The rest you can try out on your own.
$ ls -al /usr/interviews/bin
total 1187
drwxr-xr-x 2 root root 1024 Nov 5 17:40 .
drwxr-xr-x 6 root root 1024 Nov 5 17:40 ..
-rwxr-xr-x 1 root root 9220 Apr 17 1994 alert
-rwxr-xr-x 1 root root 82 Apr 17 1994 cpu
-rwxr-xr-x 1 root root 17412 Apr 17 1994 dclock
-rwxr-xr-x 1 root root 259076 Apr 17 1994 doc
-rwxr-xr-x 1 root root 1616 Apr 17 1994 ibmkmf
-rwxr-xr-x 1 root root 689156 Apr 17 1994 ibuild
-rwxr-xr-x 1 root root 37892 Apr 17 1994 iclass
-rwxr-xr-x 1 root root 17412 Apr 17 1994 idemo
-rwxr-xr-x 1 root root 115716 Apr 17 1994 idraw
-rwxr-xr-x 1 root root 9220 Apr 17 1994 ifc
-rwxr-xr-x 1 root root 642 Apr 17 1994 ivmkmf
-rwxr-xr-x 1 root root 13316 Apr 17 1994 logo
-rwxr-xr-x 1 root root 17412 Apr 17 1994 mailbox
-rwxr-xr-x 1 root root 1736 Apr 17 1994 remind
-
TIP: You can always try
the applications in /usr/interviews/bin from an xterm by running
the command as a background process. For example, to run the ibuild application,
type the command ibuild &. If you do not run ibuild as a background
process, you can press Ctrl-z to put it in the background of a bash shell.
Let's start with an application in the Interviews package. Learning this application
will familiarize you with Interviews and working with its development tools. (See
Figure 33.3.)
The idraw application lets you draw rectangles, polygons, ellipses, and
other shapes interactively. Drawings are stored in files that can be printed on a
PostScript printer. You can open an existing drawing by typing a filename on the
command line when starting up idraw.
You must engage a tool before you can use it. You engage a tool by clicking on
its icon, or by typing the character that is below and to the right of its icon.
The icon of the drawing tool that's engaged appears in inverted colors. When it is
engaged, you use the tool by clicking the left mouse button in the drawing area.
The Select, Move, Scale, Stretch, Rotate, and Alter tools manipulate existing
graphics. Magnify makes a part of the view expand to fill the entire view.
FIGURE
33.3. The idraw application's
main screen.
Text, Line, Multiline, Open Spline, Ellipse, Rectangle, Polygon, and Closed Spline
create new graphics. Each tool works as follows:
- Select is used to select a graphic, unselecting all others.
- A graphic is selected if its handles are visible. Handles are small inverse-video
squares which either surround the graphic or demarcate its important points (such
as the endpoints of a line).
- If you hold down the Shift key and select an item, it selects the unselected
graphic (or unselects the selected graphic) you clicked on, but does not affect the
status of other selections.
- Clicking anywhere other than on a graphic unselects everything. You can also
drag a rubberband rectangle around a group of graphics to select all of them simultaneously.
The right mouse button invokes Select while the mouse is in the drawing area.
- Move lets you move graphics from one spot to another.
-
TIP: The middle mouse
button invokes Move while the mouse is in the drawing area.
- Scale is used to resize graphics about their centers.
- Stretch lets you stretch graphics vertically or horizontally, while tying down
the opposite edge.
- Rotate enables you to rotate graphics about their centers, according to the angle
between two radii: the one defined by the original clicking point and the one defined
by the current dragging point.
- Alter is used to alter a graphic's structure. See the rest of the descriptions
of tools to see how Alter affects each tool individually.
- Magnify is used to magnify a portion of the drawing specified by sweeping out
a rectangular area. The idraw application magnifies the area to occupy the
entire screen, if possible.
- Text inserts textual data. Create some text. Left-click to position the first
line of text, and then type as much text as you want. The input can be edited using
emacs-style keystrokes. You can leave text editing mode by typing ESC
or simply clicking somewhere else. The Alter tool lets you edit the text in an existing
text graphic.
- Line creates a line. The Shift key constrains the line to lie on either the vertical
or the horizontal axis. You may left-click with the Alter tool on either endpoint
of a line to move the endpoint to a new location.
- Multiline lets you create a set of connected lines. The Shift key constrains
each segment to lie on either the vertical or the horizontal axis. Each left-click
starts a new segment (adds a vertex). Each right-click removes the last vertex added.
The middle button finalizes the multiline. The Alter tool lets you move, add, and
remove vertices from an existing multiline.
- Open Spline creates an open B-spline. The Shift key constrains each control point
to lie on either the vertical or the horizontal axis with the preceding point. Each
left-click adds a control point. Each right-click removes the last control point
added. The middle button finalizes the spline. The Alter tool lets you move, add,
and remove control points from an existing open spline.
- Ellipse enables you to create an ellipse. The Shift key constrains the ellipse
to the shape of a circle. The Alter tool does not affect ellipses.
- Rectangle enables you to create a rectangle. The Shift key constrains the rectangle
to the shape of a square. The Alter tool lets you move the rectangle's corners independently
to form a four-sided polygon.
- Polygon enables you to create a polygon. The Shift key constrains each side to
lie on either the vertical or the horizontal axis. Each left-click starts a new segment
(adds a vertex). Each right-click removes the last vertex added. The middle button
finalizes the polygon.
- The Alter tool lets you move, add, and remove vertices from an existing polygon.
- Closed Spline enables you to create a closed B-spline in the same manner that
you create an open B-spline.
The pull-down menus File, Edit, Structure, Font, Brush, Pattern, FgColor, BgColor,
Align, and View, located above the drawing area, contain commands for editing the
drawing and controlling idraw's execution. The File menu contains the following
commands to operate on files:
New |
Destroys the current drawing and replaces it with an unnamed blank drawing. |
Revert |
Rereads the current drawing, destroying any unsaved changes. |
Open... |
Specifies an existing drawing. |
Save As |
Saves the current drawing in a file with a specific name. |
Save |
Saves the current drawing in the file from which it came. |
Print... |
Sends a PostScript version of the drawing to a printer or a file. |
Import Graphic... |
Can import images from files in the following formats: TIFF; PostScript generated
by pgmtops, ppmtops, and idraw; X bitmap format; and Unidraw
format. |
Quit |
Quits idraw. |
The Edit menu contains the following commands for editing graphics:
Undo |
Successive Undo commands undo previous editing operations. |
Redo |
Successive Redo commands redo subsequent editing operations up to the first operation
undone by Undo. Undone operations that have not been redone are lost as soon as a
new operation is performed. |
Cut, Copy, Paste |
Removes the selected graphics from the drawing and places them in a temporary storage
area. Copy keeps the original on the drawing area. Paste puts the contents of the
storage area, if any, into the location selected by the mouse. |
Duplicate |
Duplicates the selected graphics and adds the copies to the drawing. |
Delete |
Destroys all selected graphics. |
Select All |
Selects every graphic in the drawing. |
Flip Horizontal,
Flip Vertical |
Flips the selected graphics into their mirror images along the horizontal or vertical
axis. |
90 degrees Clockwise
and CounterCW |
Rotate the selected graphics 90 degrees clockwise or
counterclockwise. |
Precise Move...,
Precise Scale...,
Precise Rotate... |
These buttons let you move, scale, or rotate graphics byexact amounts that you type
in a dialog box. You can specify movements in pixels, points, centimeters, or inches.
Scalings are specified in terms of magnification factors in the horizontal and vertical
dimensions. Rotations are always in degrees. |
The Structure menu contains the following commands to modify the structure of the
drawing, which is the order in which graphics are drawn:
Group |
Collects the selected graphics in a newly created picture.
A picture is simply a graphic that contains other graphics. Group enables you to
build hierarchies of graphics. |
Ungroup |
Dissolves any selected pictures. |
Bring To Front |
Brings the selected graphics to the front of the drawing so that they are drawn on
top of (after) other graphics. |
Send To Back |
Sends the selected graphics to the back of the drawing so that they are drawn behind
(before) other graphics. |
The Font menu contains a set of fonts in which to display text. When you set the
current font from the menu, you also set the font of all selected graphics to that
font. A font indicator in the upper-right corner displays the current font.
The Brush menu contains a set of brushes with which to draw lines. When you set
the current brush from the menu, you also set the brush of all selected graphics
to that brush. The nonexistent brush draws invisible lines and non-outlined graphics.
The arrowhead brushes add arrowheads to one or both ends of lines, multilines,
and open splines. A brush indicator in the upper-left corner displays the current
brush.
The Pattern menu contains a set of patterns with which to fill graphics, but not
text. Text always appears solid, but you can use a different color than black to
get a halftoned shade. When you set the current pattern from the menu, you also set
the pattern of all the selected graphics to that pattern. The nonexistent pattern
draws unfilled graphics, while the other patterns draw graphics filled with a bitmap
or a halftoned shade.
The FgColor and BgColor menus contain a set of colors with which to draw graphics
and text. When you set the current foreground or background color from the FgColor
or BgColor menu, you also set the foreground or background color of all the selected
graphics. The ON bits in the bitmaps for dashed lines and fill patterns appear in
the foreground color; the OFF bits appear in the background color.
A black-and-white printer prints a halftoned shade of gray for any color other
than black or white. The brush, pattern, and font indicators all reflect the current
colors.
The Align menu contains commands to align graphics with other graphics.
The first graphic selected stays fixed, while the other graphics move in the order
that they were selected according to the type of alignment chosen. The last Align
command, Align to Grid, aligns a key point on each selected graphic to the nearest
point on idraw's grid.
The View menu contains the following commands:
New View |
Creates a duplicate idraw window containing a second view of the current
drawing. The second view may be panned, zoomed, and edited independently of the first.
Any number of additional views may be made in this manner. Changes made to a drawing
through one view appear synchronously in all other views of the same drawing. You
may also view another drawing in any idraw window via the Open command. |
Close View |
Closes the current idraw window. Closing the last idraw window
is equivalent to issuing a Quit command. |
Normal Size |
Sets the magnification to unity so the drawing appears at actual size. A What You
See Is What You Get (WYSIWYG) display. |
Reduce to Fit |
Reduces the magnification until the drawing fits entirely within the view. |
Center Page |
Modifies the view over the center of a 8.5- by 11-inch page as it's printed. Other
page sizes are not supported to date. |
Orientation |
Toggles the drawing's orientation. If the editor was showing a portrait view of the
drawing, it now shows a landscape view of the drawing, and vice versa. |
Grid on/off |
Toggles idraw's grid on or off. When the grid is on, idraw draws
a grid of equally spaced points behind the drawing. |
Grid Spacing |
Enables you to change the grid spacing by specifying one or two values in the units
desired (pixels, points, centimeters, or inches). If two values are given (separated
by a space), the first specifies the horizontal spacing, and the second specifies
the vertical spacing. One value specifies equal horizontal and vertical spacing. |
Gravity on/off Toggle |
Toggles gravity on or off. Gravity constrains tool operation to the grid, whether
or not the grid is visible. |
You can customize the number of changes that can be undone and the font, brush,
pattern, or color menus by setting resources in your Xdefaults database. Each string
of the form idraw.resource:definition sets a resource. For example, to customize
any of the paint menus, set a resource given by the concatenation of the menu's name
and the entry's number (such as idraw.pattern8) for each entry that you
want to override. All menus use the number 1 for the first entry.
You must set resources only for the entries that you want to override, not for
all of them. If you want to add entries to the menus, simply set resources for them.
However, don't skip any numbers after the end of the menu, because the menu ends
at the first undefined resource. To shorten a menu instead of extending it, specify
a blank string as the resource for the entry following the last item on the menu.
The idraw application understands the resources listed in Table 33.1. Table
33.1. The idraw resources.
history |
Sets the maximum number of changes that can be undone (20 by default). |
initialfont |
Specifies the font that is active on startup. Supply a number that identifies the
font by its position in the Font menu, starting from 1 for the first entry. |
font |
Defines a custom font to use for an entry in the Font menu. Give three strings, separated
by whitespace. The first string defines the font's name; the second string defines
the corresponding print font; and the third string defines the print size. For example,
idraw.font3:8x13bold Courier-Bold 13 defines the third font entry. |
initialbrush |
Specifies the brush that is active on startup. Give a number that identifies the
brush by its position in the Brush menu, starting from 1 for the first entry. Define
a custom brush to use for an entry in the Brush menu. The definition requires two
numbers: a 16-bit hexadecimal number to define the brush's line style (each 1 bit
draws a dash and each 0 bit produces a gap) and a decimal integer to define the brush's
width in pixels. For example, idraw.brush2:ffff 1 defines a single pixel-wide
solid line. If the definition specifies only the string none, it defines
the nonexistent brush. |
initialpattern |
Specifies the pattern that is active on startup. Give a number that identifies the
pattern by its position in the Pattern menu, starting from 1 for the first entry. |
pattern |
Defines a custom pattern to use for an entry in the Pattern menu. You can specify
the pattern from a 16x16 bitmap, an 8x8 bitmap, a 4x4 bitmap, a grayscale number,
or the string none. You specify the 16x16 bitmap with sixteen 16-bit hexadecimal
numbers, the 8x8 bitmap with eight 8-bit hexadecimal numbers, the 4x4 bitmap with
a single 16-bit hexadecimal number, and the grayscale number with a single floating-point
number. The floating-point number must contain a period to distinguish itself from
the single hexadecimal number, and it must lie between 0.0 and 1.0, with 0.0 corresponding
to a solid pattern and 1.0 to a clear pattern. On the printer, the bitmap patterns
appear as bitmaps, the grayscale patterns appear as halftoned shades, and the none
patterns never obscure any underlying graphics. For example, idraw.pattern8:8421
defines a diagonally hatched pattern. |
initialfgcolor |
Specify the foreground color that is active on startup. Give a number that identifies
the color by its position in the FgColor menu, starting from 1 for the first entry,
fgcolor. Define a custom color to use for an entry in the FgColor menu. Give a string
defining the name of the color, and (optionally) three decimal numbers between 0
and 65,535 following the name to define the red, green, and blue components of the
color's intensity. The intensities override the name; that is, idraw looks
up the name in a window system database of common colors only if you omit the intensities. |
initialbgcolor |
Specifies the background color that is active on startup. Give a number that identifies
the color by its position in the BgColor menu, starting from 1 for the first entry. |
bgcolor |
Defines a custom color to use for the entry in the BgColor menu. The same rules apply
to background colors as to foreground colors. |
The ibuild package is an editor that enables you to graphically create
a user interface for an Interviews application. The ibuild application can
save your work as an external file, or as actual C++ code that, when compiled, generates
the same user interface that you would create with ibuild. You restore a
previously saved interface by typing ibuild and the interface filename on
the command line. (See Figure 33.4.)
The ibuild application uses the TOOLDIR environment variable
for its tools and other parameters. If TOOLDIR is not defined, ibuild
looks for its parameters in the current working directory.
Let's examine the layout of the menus.
The first row of an ibuild editor displays information about its brush
(border width), foreground and background color, and so on in a fashion similar to
that in idraw. The next two rows show tools that initiate direct manipulation
and pull-down menus that contain commands. A panner on the top-right corner lets
you pan and zoom the workspace.
The middle portion of the editor shows the workspace for composing and assembling
user interface components.
The bottom of the editor contains rows of objects in the form of names and iconic
drawings that represent familiar Interviews abstractions. Clicking on one tool, dragging,
and releasing it in the workspace enables a user to place an instance of the corresponding
prototype at the desired location.
Direct manipulation tools lie horizontally along ibuild's second row.
You must engage a tool before you can use it. You engage a tool by clicking on its
icon, or by typing the character below and to the right of its icon. The icon of
the tool that's engaged appears in inverted colors. When it is engaged, you use the
tool by clicking the left mouse button in the workspace.
The Select, Move, Resize, Examine, Relate, and Edit tools manipulate text-based
user interface components. Magnify makes a part of the view expand to fill the entire
view. Narrow enables a user to navigate the structure of a composed interface in
the same editor.
The ibuild application provides the following tools:
- Select
- Move
- Resize
- Examine
- Info
- Relate
- Edit
- Magnify
- Narrow
- Create
- Tools
- Execute
- Quit
The Select tool is used for selecting an object and unselecting all others. An
object is selected if its handles are visible. Handles are small inverse-video squares
that surround the object. If you hold down the Shift key, Select extends the selection.
It selects the unselected component (or unselects the selected component) you clicked
on, but does not unselect other selections. Clicking anywhere other than on a component
unselects everything. You may also drag a rubberband rectangle around a group of
components to select all of them simultaneously.
-
TIP: The right mouse
button invokes the Select button while the mouse is in the workspace.
- The move button is used for moving objects from one spot to another.
-
TIP: The middle mouse
button invokes the Move button while the mouse is in the workspace.
The Resize tool can change the size of any selected objects. When user interface
components from the bottom panel are initially created in the workspace, or when
selected components are composed with composition interface objects in the Composition
pull-down menu, they are displayed with their natural sizes. Resize simulates the
resizing of the application window during running of the application by letting users
drag and sweep the selected user interface component.
The Examine tool is used to look at attributes associated with the selected user
interface components. User interface components in ibuild contain attributes
that assist users in designing the layout of the interface, or in customizing the
generated code. Typically, the pop-up menu of the Examine tool shows Info and Props
entries as options.
Selecting Info causes a component-specific dialog box to pop up. Some of the common
attributes shown in the dialog box include the following: Base Class Name, which
describes the actual class name in the Interviews library to which the selected component
corresponds; and Class Name, which describes the user-specified class name of the
component.
If the value of Class Name is the same as that of the Base Class Name, the library
class is used for instantiating the component during code generation, or a set of
subclass files are generated to assist the customization of the new class, as described
earlier. Member Name describes the member name of the selected component as a member
variable of the closest enclosing MonoScene object. If the member name is exported,
the MonoScene object can access and manipulate this specific member instance. Canvas
Dimensions shows how much workspace (corresponding to actual screen space) in pixels
is actually allocated to the selected component. Natural Size, Shrinkability, and
Stretchability describe how much workspace the selected component wants to have.
The dialog box associated with the Props entry shows the selected component's
instance name and user-defined properties. Property specification takes the form
attribute:value.
In order to assist users in locating certain elements with certain member names
or instance names, ibuild enables a user to probe these attributes by Shift-left-clicking
on these elements when they are composed.
The Info entry has a pull-right menu that has class name, member name pairs in
it; the pull-right menu associated with the Props entry has class name, instance
name pairs.
Examining a GraphicBlock component causes a third Graphics entry to display in
the pop-up menu. Selecting this option causes graphics in the GraphicBlock to be
transferred to idraw for further refinement.
Graphics can be transferred back to ibuild by simply saving and quitting
idraw. Attributes associated with graphics in ibuild that are not
known to idraw, such as member name, are not lost in this process. This
option is supported only for backward compatibility. A much better technique is to
use the Narrow tool to narrow into GraphicBlocks, which changes ibuild into
idraw in the same window.
-
NOTE: All machine-generated
names are guaranteed to be unique in one session of ibuild. This property
is lost with user-defined names, and when files generated by different sessions of
ibuild are compiled together.
The Relate tool provides a direct manipulation interface to semantically connect
compatible components. Typically, the end result of the Relate operation is the sharing
of attributes between the related components. For example, relating a scroller to
a file browser lets the scroller take the file browser's member name as its scrolling
target. Relating two push buttons causes the push buttons to mutually exclude each
other when receiving mouse clicks. In this case, the second (destination) push button
shares the ButtonState defined by the first (source) push button. Relate is also
very useful for semantically connecting Unidraw objects. For instance, an Editor
needs to be related to all enclosed Unidraw objects such as CommandControls, PanelControls,
and Viewers. In this case, the simplest way to establish the relations is to relate
the Editor with the object directly below it in the instance hierarchy, which causes
the relations to establish recursively.
The Edit tool manipulates text-based components. Engaging the Edit tool enables
users to perform editing on MenuItem, PushButton, RadioButton, CheckBox, Message,
stringEditor, PulldownMenu, PullrightMenu, CommandControl, HPanelControl, and VPanelControl
components.
The Magnify tool magnifies a portion of the interface specified by sweeping out
a rectangular area. The ibuild application magnifies the area to occupy
the entire screen, if possible.
The Narrow tool enables a user to navigate the structure of composed interfaces
in the same editor. Initially, ibuild starts at global scope. Engaging the
Narrow tool and selecting a component causes the hierarchy of the interface to be
displayed in a pop-up menu, with the highlighted entry showing the current scope.
Selecting a different entry causes the editor to switch to the scope of the selected
component. For instance, if a user chooses to narrow into an HBox, cutting or pasting
components in the workspace now affects only the HBox.
-
NOTE: Leaf-level components
don't define new scopes. Narrowing into graphics-related components such as GraphicBlocks,
CommandControls, PanelControls, and Viewers transforms ibuild into idraw
in the same window, in addition to switching the scope level. This feature is extremely
useful because specifying structured graphics objects, class names, and member names
can all be done within ibuild. Firing up idraw using the Examine
tool is still supported for backward compatibility purposes.
The Create Tool creates a prototypical tool of the current interface, and installs
it in the bottom tools palette. Users can choose between having the filename, a default
icon of the existing interface, or a customized bitmap as the new tool's icon. The
newly created tool can then be treated as a library tool for instantiation. This
allows domain-specific abstractions to be built and used across sessions of ibuild.
The Tools command enables a user to install tools to, or remove tools from, the
bottom tools panel. Users can choose to install (or remove) multiple tools from the
left (right) stringbrowser by selecting multiple entries and clicking the <<
Install (or Remove >>) button.
The Execute tool lets the user choose an executable from a file-chooser, and executes
the selected file without leaving ibuild.
The Quit command exits the current session of ibuild.
-
NOTE: The Edit menu for
ibuild contains commands that are very similar to those in idraw.
Refer to the idraw section for more details.
-
CAUTION: Changes made
with the Examine tool and Relate tool can be undone.
The Show Glue tool shows HGlue components with horizontal strips and VGlue components
with vertical strips. Showing Glue components with strips makes the structure associated
with the interface more apparent.
The Hidden Glue tool shows HGlue and VGlue components with their background color.
This is useful when the actual appearance of the interface is desired.
The Natural Size tool shows the selected interface components in their natural
form, similar to the way they are displayed initially when the generated interfaces
are executed.
The pull-down menus File, Edit Composition, Border, FgColor, BgColor, Align, and
View lie across the third row. They contain commands that are executed by pulling
down the menu and releasing the mouse button on the command, or by typing the character
associated with the command.
The File menu contains the following commands to operate on files:
- The New command destroys the current interface and replaces it with an unnamed
blank interface.
- The Revert command rereads the current interface, destroying any unsaved changes.
- The Open command specifies an existing interface file to edit through a FileChooser,
which lets you browse the file system easily.
- The Save As command saves the current interface in a file with a specific name.
- The Save command saves the current interface in the file from which it came.
The Generate button generates code for the interfaces in ibuild. A sequence
of dialog boxes pops up to let users check off files that they don't want to be overwritten.
The generated files include sets of subclass files and support files. Subclass files
have class name suffixes, and support files have filename postfixes. For instance,
the filename of a session of ibuild is dialogBox, and the top-level
MonoScene object that drives the interface is DialogBox.
Support files generated include the following:
- dialogBox-props
- dialogBoxmake
- dialogBox-imake
- dialogBox-main.c
- dialogBox-imake
- dialogBox-make
For each MonoScene component in ibuild, a set of subclass files is generated.
In this case, they include the following:
- DialogBox.c
- DialogBox.h
- DialogBox-core.c
- DialogBox-core.h
When you regenerate the code for an application, you are asked in a dialog box
whether you want to regenerate these files. As a general rule, all the default files
that ibuild recommends by checking in their dialog box should be overwritten.
The dialogBox-props file contains Interviews properties for customization.
Rewrite this file whenever you regenerate.
The dialogBox-main.c file contains a prototypical main routine to drive
the interface. Rewrite this file whenever you regenerate.
The DialogBox-core.c file encapsulates all information about the appearance
of the interface. The protected member variables are declared in this file.
The DialogBox-core.h file describes what objects are exported to the
subclass objects (such as DialogBox) for manipulation. This file is, and should be,
overwritten whenever you regenerate a new application using ibuild.
The DialogBox.h and DialogBox.c files enable users to implement
application-specific interfaces. When you are regenerating code from an ibuild
session, you are asked whether you want to overwrite these files. If you already
have application-dependent code in these files, you don't want to overwrite these
files. By default, ibuild doesn't overwrite these files.
-
NOTE: These two files
are under the user's control; the core files (DialogBox-core.[ch]) are under
ibuild's control.
The Composition menu contains commands to modify the structure of the interface.
See Table 33.2 for a list of these commands.
Table 33.2. Composition commands.
Command |
Action |
Dissolve |
Dissolves the selected components by deleting the top-level parents and exposing
the children of the selected components. Leaf-level components cannot be dissolved.
Compose the selected components with the corresponding composition object. The order
of selection decides the order in which they are composed. |
Hbox |
Tiles the selected components left to right in abutting fashion. |
Vbox |
Tiles the selected components top to bottom in abutting fashion. |
Deck |
Stacks the selected components on top of each other, with the last selected component
on the top. |
Frame |
Puts a frame around each of the selected components. |
ShadowFrame |
Puts a shadow frame around each of the selected components. |
ViewPort |
Puts a viewport around each of the selected components. |
MenuBar |
Tiles the selected components row by row as in an HBox (horizontal box). It also
implements the sweeping effect when MenuItems, pull-down menus, or pull-right menus
are the selected components. |
Shaper |
Redefines the resizing behavior of the selected components. Shaper is an ibuild-generated
class, which is useful for overriding the default resizing behavior of library components. |
The Reorder command reorders the components inside a composition according to
the current selection order. For instance, narrowing into an HBox, reselecting its
components, and executing Narrow defines ordering of the components in the HBox corresponding
to the new selection order.
Similarly, the Raise command brings the selected components to the front of the
interface so that they are drawn on top of (after) the other components in the interface.
For example, if a selected component is raised in a Deck, it appears on top of all
the components.
The Lower command sends the selected components to the back of the interface so
that they are drawn behind (before) the other components in the interface.
The Font menu contains a set of fonts with which to print text-based components.
The default value is the current font from the menu. You also set all the selected
components' fonts to that font. A font indicator in the upper-right corner displays
the current font.
The Border menu contains a set of brushes that are used to set border widths of
Border and Frame components. A border indicator in the upper-left corner displays
the current border.
The FgColor and BgColor menus contain a set of colors with which to draw components
and text. When you set the current foreground or background color from the FgColor
or BgColor menu, you also set all the selected components' foreground or background
colors.
The Align menu contains commands to set the alignment of the message on Message-based
components. Examples of these components include pull-down and pull-right menus,
MenuItem components, and Message components. The effects of alignment are more apparent
when the selected components are resized.
Subclasses enable you to introduce user-defined objects for customizing your interfaces.
These are abstraction mechanisms that break down complicated user interfaces into
more manageable and reusable subcomponents, which are more amenable to user customization.
Without subclass objects, the generated code consists of static functions that assemble
the library user interface elements into complete interfaces.
The subclasses that you can work with are as listed here :
- MonoScene Subclass
- Dialog Subclass
- Editor Subclass
Member names associated with the components are therefore useless.
With subclass objects, children of a subclass instance become the instance's interior
definition. If the interior components are exported, they become member variables
of the subclass instance.
Selecting MonoScene Subclass causes each selected component to be enclosed in
a MonoScene subclass object.
Selecting Dialog Subclass is similar to selecting MonoScene Subclass, except that
it provides features of the Dialog class in the library as well.
Editor Subclass is useful when the end application is a domain-specific editor.
Objects kept by an editor, such as the KeyMap, Selection, Component, and ControlState,
can all be subclassed to define domain-specific behavior.
Conceptually, components created in the workspace are instances of the actual
Interviews and Unidraw counterparts. All separate components (uncomposed and composed
components without common parents) generate separate windows after code generation.
For example, if the user-specified filename associated with an ibuild session
is hello, the files hello-imake, hello-make, hello-props,
and hello-main.c are generated.
- hello-imake and hello-make are an imakefile and a
makefile generated by ibuild using ibmkmf, respectively.
- hello-props contains attribute:value pairs required by Interviews to
associate properties to user-interface objects on a per instance basis.
- hello-main.c contains a generated main() routine to instantiate
the interfaces. If no MonoScene objects exist in ibuild, static functions
are generated in hello-main.c to assemble the interface components. MonoScene
(or MonoScene subclass) objects are user-defined abstractions to decompose complex
user interfaces into simpler, higher-level elements, which are described later.
All user interface components can be subclassed by simply renaming their Class
Name attribute to be different from the Base Class Name, using the Examine tool and
selecting the Info entry.
A set of four files is generated for each subclassed component in ibuild.
If the Class Name of a subclassed component is Displayer, and the Base Class
Name is stringEditor, the following files are created: Displayer.h,
Displayer.c, Displayer-core.h, and Displayer-core.c as
the output of the Generate command.
For the previous set of files, Displayercore is a subclass of stringEditor,
and Displayer is a subclass of Displayercore. The -core.*
postfixed files are core files that are under ibuild's control, and you
should not modify them. These core files contain enhanced widget definitions to accommodate
library deficiencies and provide a more convenient user model.
Displayer.h and Displayer.c are subclass files that are provided
for customization, which typically involves redefinition of some virtual functions
defined by the base class.
The ibuild application also allows the creation of new user interface
abstractions by providing MonoScene subclass, Dialog subclass, and Editor subclass
composition mechanisms. Typically, the topmost composition of a completed user interface
component is a MonoScene subclass object. All enclosed components of a subclass object
can be thought of as its members. For instance, if a Dialog subclass instance called
Informer is used to wrap (abstract) the previous interface, Informer.h,
Informer.c, Informer-core.h, and Informer-core.c are generated.
In this case, Informercore is a subclass of Dialog, and Informer
is a subclass of Informercore. Like Displayer, Informer-core.h
and Informer-core.c are under ibuild's control; Informer.h
and Informer.c are for user customization. In addition to providing enhanced
widget definitions, Informer-core.c also contains definitions of its appearance
by instantiating its member components. Informer-core.h provides an interface
to Informer.h where the exported members can be selected by using the Examine
tool, as explained later.
You must set resources only for the entries that you want to override, not for
all of them. If you want to add entries to the menus, simply set resources for them.
However, don't skip any numbers after the end of the menu, because the menu ends
at the first undefined resource. To shorten a menu instead of extending it, specify
a blank string as the resource for the entry following the last item in the menu.
The ibuild application understands the resources listed in Table 33.3,
in addition to those specified in idraw.
Table 33.3. Additional resources for ibuild.
Resource |
Action |
initialborder |
Specifies the border that is active on startup. Give a number that identifies the
border by its position in the Border menu starting from 1 for the first entry. Border
specification is similar to brush specification in idraw, except only solid
brushes should be used because they are used to set border widths of Border and Frame
components. |
border i |
Defines a custom border to use for the ith entry in the Border menu. Unlike normal
brush specification, the first 16-bit hexadecimal number should always be 0xffff
to indicate solid brush. The second hexadecimal number should give the desired border
width in pixels. Border specification affects only certain interface objects, as
described earlier |
.
Let's start with a simple application, shown in Figure 33.5. You will build an
interface with three check buttons, two push buttons, and a label. The label was
created with the Message tool.
FIGURE
33.5. The ibuild sample application.
Collect the check buttons by selecting them and grouping them with the Composition/VBox
selection. For the push buttons, use the HBox selection to group them horizontally.
All components of the application were glued together, using the VBOX item, to
create one big application. Because this is one screen, attach the Monoscreen composition
property to all objects in this application in order to allow all portions of the
application screen to be filled with blanks, which are not explicitly covered by
an object.
Now, save the application with the File/Save As button. See Figure 33.6 for this
dialog box. After saving this application, use the File/Generate option to generate
all the source, makefiles, and property files for this application. Now you can build
the application as shown in Figure 33.7.
FIGURE
33.6. Saving the sample application.
FIGURE
33.7. Generating files for the sample
application.
The following files are created in your current working directory after you are done:
iview/sample1
iview/sample1-imake
iview/sample1-main.c
iview/sample1-main.o
iview/sample1-make
iview/sample1-props
-
NOTE: If you do not have
the TOOLDIR variable defined, you also see a lot of files with the extension
Tool. Do not delete them unless you point TOOLDIR to the /usr/Interviews
Tools directory. The Tools files provide some interesting insights
into how the interface tools work for Interviews.
The version of ibuild on this distribution creates a makefile that fails
around line 182, when you try to create the application with a make command.
The error is that two makefile variables, SRCS and OBJS, create
assignments that do not have a trailing \ for each source file to create.
Edit the makefile manually to add these trailing backslashes, or concatenate all
the names into one line.
So, the lines
SRCS =
_MonoScene_5.$(CCSUFFIX)
_MonoScene_5-core.$(CCSUFFIX)
sample1-main.$(CCSUFFIX)
OBJS =
_MonoScene_5.o
_MonoScene_5-core.o
sample1-main.o
become the following:
SRCS = _MonoScene_5.$(CCSUFFIX) \
_MonoScene_5-core.$(CCSUFFIX) \
sample1-main.$(CCSUFFIX)
OBJS = _MonoScene_5.o \
_MonoScene_5-core.o \
sample1-main.o
Figure 33.8 shows the makefile for this application generated by the build.
FIGURE
33.8. A sample makefile for this application.
-
NOTE: Do not forget to
edit the makefile to create the correct arguments for the SRCS and OBJS
macros.
Now, you can create the application sample1-exe with the following command:
$ make -f sample1-make sample1
This make command spews a lot of messages from the GNU g++ compiler.
You should not see any error messages if you have edited your sample1-make
file as described earlier. After you have created the application, you can execute
this application with this command:
$ sample1
The result of this application is shown in Figure 33.5.
-
CAUTION: If you do assign
the Monoscreen composition to the final VBox or HBox of this application, your application
will not fill in any blank areas on the main screen. The result is a semitransparent
window of whatever happens to be on the screen at the time and the rest of your application's
objects.
-
CAUTION: Do not forget
to group all of your objects together, or each object will have its own independent
window.
The last order of business for your sample application is to add code to take
actions when a button is pressed. This step enables you to attach your own code to
your newly created application. A GUI by itself really does not serve any purpose,
does it? The code that takes action is called an Interactor.
Add another button to the application you just created, and attach an Interactor
to it. Click with the left button on this button, and hold it down. You see two menu
items pop up on the mouse cursor. While holding the left button down, move the cursor
to the right of this menu to get another list of items, including one titled PushButton.
Move the cursor to this item and go left. You are presented with a dialog box (shown
in Figure 33.9) showing all the attributes of this push button.
FIGURE
33.9. The PushButton attributes.
Name this push button by typing mybuttonhere in the Member Name box, and
check the Export button.
Next, specify the ButtonState instance to use by typing enterBS
in the ButtonState dialog. Now click on the ButtonState button to create
this instance. See Figure 33.10 for this dialog box.
FIGURE
33.10. Creating the ButtonState
instance.
The finished application is shown in Figure 33.11.
FIGURE
33.11. The finished application.
Make sure that the ButtonState is exported, and make entered the name of
the function that is called when this button is pressed. Click OK to accept this.
Now, set the setting value of this push button to 1. Click OK to accept it.
Press the left mouse button on the string utility, and then press the left mouse
button again on the Info button to get the info for stringEditor. As you
did with the push button, create an exported member function called stringEditor.
Click OK to accept and dismiss this dialog.
Use the Relate tool to connect the push button to the stringEditor.
Click on the push button, and hold the left mouse button down to select the PushButton
item from the pop-up menu that appears. Let go of the mouse button. A line is drawn
from this button to your cursor.
Now, move the cursor to the stringEditor, and press the left mouse button
again. This brings up another pop-up menu from which you select stringEditor
as your target.
The stringEditor is now the target, and the push button is the source.
To see whether they are related, use the Examine tool to ensure that the ButtonState
name of stringEditor is now enterBS.
-
NOTE: The order in which
you select the relationship is important. The target (stringEditor) receives
the ButtonState from the source (pushButton).
The final step is to create the classes that wrap the core around another class.
Remember that we created a MonoScreen class as the topmost class for this application.
Using the Examine tool, get the info on the Mono_* class for this application.
When you get the dialog box for this application, change the Class Name to something
else, like Sample1. Click OK to save.
Now, generate the code for this application. You see the following four files
listed:
iview/Sample1-core.c
iview/Sample1-core.h
iview/Sample1.c
iview/Sample1.h
Do not edit the *-core files. Edit the Sample1.c and Sample1.h
files to create your own functions. The Sample1.h file looks like the one
shown in Listing 33.2. The Sample1.c file is shown in Listing 33.3.
#ifndef Sample1_h
#define Sample1_h
#include "Sample1-core.h"
class Sample1 : public Sample1_core {
public:
Sample1(const char*);
virtual void entered();
};
#endif