NAME
gilt - graphical user interface builder for the Amulet toolkit
SYNOPSIS
gilt
DESCRIPTION
gilt is an interface builder for the Amulet graphical user interface toolkit. gilt allows dialog boxes and other windows to be created interactively using the mouse. Widgets, such as scroll bars, buttons, and text input fields can be placed with the mouse, and properties set. Then, gilt will generate C++ code to generate the same window at run time. gilt stands for Graphical Interface Layout Tool.
The general way to use gilt is to select a widget or drawing primitive in the palette, then drag or click in the window where that widget is to appear. When the palette is in "select" mode (with the arrow selected), then clicking on objects with the left button selects them, pressing and dragging moves them, dragging on the handles grows them, and double clicking sets their properties. Dragging in the background where there are no objects will select all the objects in the region. Multiple objects can be moved at the same time. Some objects, such as the various button panels, cannot be resized. All of the objects have a default size, so if you click on the desired object in the palette, and then click in the main window without moving, then an object of the default size will be created.
As always in OpenAmulet, when creating, moving or growing (or typing text into a text field), you can abort the operation by typing ^G (control-g). Of course, (almost) all operations are undoable using the Undo item in the Edit menu.
What can be created
The main palette contains all of the objects that currently can be created using OpenAmulet. They are (from top to bottom, left to right):
- The selection arrow
-
In this mode, objects are selected, editing, moved and grown. New objects are not created.
- Run
-
In Run mode, you can operate the widgets like the end-user would. This doesn't really affect anything, so it isn't very useful, but it was easy to provide.
- Rectangle
-
Drag out a rectangle.
- Line
-
Drag out a line.
- Arc
-
Drag out an ellipse or circle (to get a circle, it is useful to turn on gridding in the Arrange menu, see below).
- An arbitrary Polygon
-
Click for each point. To finish, click at the original point for a closed polygon, or double click for the last point. Or you can click back on the Selection Arrow in the palette to stop creating the polygon.
- A Text string
-
Double click on the string after you create it to change the label, which is the string displayed.
- A Bordered rectangle
-
This is an instance of the Am_Border_Rectangle, and is often useful for arranging different groups of widgets.
- A single Button
-
Note that if you are going to create a bunch of buttons, it is usually more convenient to use the buttons panel.
- Multiple Buttons in a panel
- An OK-Cancel button pair
-
If you are creating a dialog box, it is a good idea to have one of these in it. These come with the appropriate methods built-in.
- An Option button
-
This displays as a single button, but when you press on it, you get a pop-up menu of choices.
- Checkboxes
-
These let a user select one or more of a set of options.
- Radio buttons
-
These let a user select exactly one of a set of options.
- A text input field
- A number input text field
- A Scrolling group
-
This is an area in which a program can add objects. (There is currently no way in gilt to add objects to the scrolling group interactively).
There are many other widgets in the OpenAmulet widget library that are not yet supported in gilt (see the Widgets chapter in the OA Reference Manual).
Style and Font Properties
All objects are always created with the default properties defined by the prototypes. (Unlike most graphics editors, choices in the color palettes do not affect the next object drawn --- you have to draw the object first, select it and then change its properties.) If an object is selected, then you can set its color and font using the palettes on the left of the gilt window. The middle palette is for the fill color of the object. The top-left item in the menu looks white but is actually unfilled (Am_No_Style).
If no object is selected, then clicking on a color in the color palette will set the background for the window.
The group of lines is used to set the line-style. Note that you have to click pretty much exactly on top of the line. The Line style does not affect most of the widgets, but it is used for changing the color of the lines, the outlines for rectangles, circles and polygons, and the color of the text in a regular Text object. The top-left entry in the line palette is invisible and means no-line, which is sometimes useful for rectangles and circles.
The bottom palette is for changing the font used for strings. Currently, only the default (Fixed) font is supported. The rows are for the Small, Medium and Large sizes, and the columns are for Bold, Italic and Underline.
Other Object Properties
Each kind of object also has additional properties that can be set. These are available by selecting an object then selecting ``Properties...'' from the edit menu. A faster way to get to the properties window for an object is to double-click on it, or to click on it with the middle mouse button. For these, the object does not even have to be selected.
If you Cancel any of these dialog boxes, the changes are not made, and after you hit OK, you can later Undo the changes using the regular Undo in the Edit menu.
All objects have a Name property which, if supplied, is the name of the slot the object is put in.
The Label property is used to change the string displayed for text objects, and also the label for buttons and text and number input fields.
All of the panel widgets (like button panels, radio buttons, checkboxes, etc.) have a large set of properties. The name of the widget is at the top, and then the list of current labels of all the values. Selecting a name will let it be deleted (``Delete Item'') or its string edited (typing RETURN or hitting ``Update Item'' confirms the change), and a new item can be added by typing the new label and hitting ``New Item''. Note that this interface only supports putting text items into the labels. You might instead want to use the built-in command objects. Also, you might want to use a graphical object or a group as a label. Whereas these are easy to do by writing code in OpenAmulet, gilt does not provide an interface to this yet. The OK-Cancel buttons will not allow you to change their labels or add new ones.
Also for panels, you can control various properties of the layout of the buttons. If ``Vertical Layout'' is selected, then the buttons will be up-and-down, and if it is not selected, then the buttons will be across (horizontal). (This button selects whether the Am_LAYOUT field of the widget will contain Am_Vertical_Layout or Am_Horizontal_Layout). The ``Box on Left'' button is used for radio buttons and check boxes and tells which side of the label the box is on. If ``Fixed Width'' is selected, then all the buttons are the same width, otherwise not (this might be important if they are not vertical). The Horizontal and Vertical Spacing between Items can be adjusted either bigger or smaller to control how far apart the items in the panel are. If you want multiple rows and columns, you can specify the Maximum Number of Items in a Row or Column.
For a Number Input widget, you can specify whether the values that can be specified should be restricted to a range of values, and if so, what the minimum and maximum values are.
The Border rectangle under the Motif look-and-feel can look ``Selected'' (pushed in). In the Windows and Macintosh Look-And-Feel, this button has no effect on the appearance of the widget.
For scroll groups, you can specify the size of the scrollable region (``Inner Width and Height''), whether the Vertical and Horizontal scroll bars are displayed at all or not, and which side of the group the scroll bars are on.
Commands in the Menus
The accelerators for each of these are displayed in the menus. Most of these use the built-in command objects without change .
- File menu
-
(Unfortunately, OpenAmulet does not yet have a load-save dialog box with a scrolling list of files, so all of these just use a text field to type in the file name.)
- Open...
-
This opens a file that was stored in gilt's internal format (using Save). Note: Cannot open a C++ file (generated by ``Generate C++''). extbf{BUG}: Open destroys everything currently in the window without asking for confirmation and this is not undoable.
- Save As...
-
This saves the contents of the current window in gilt's internal format. Be sure to save the design both in gilt's format so it can be read back in, and to Generate C++ from the design so it can be used by other programs. (Save uses OpenAmulet's built in Load and Save mechanism.)
- Save
-
Saves to the stored filename if specified in a previous Save As... or Open, or else prompts for a name to save to.
- Generate C++ ...
-
Generates a C++ file for the window.
- Quit
-
Exits the application. BUG: Does not check to see if anything needs to be saved before quitting.
- Edit
- Undo
-
Undoes the last operation. This uses the Am_Multiple_Undo_Object so multiple operations can be undone.
- Redo
-
If the last operation was Undo, then this undoes the undo (thereby redoing the operation).
- Cut
-
If some graphical objects are selected, this removes them from the window and puts them into the invisible clipboard so they can be pasted. BUG: Does not use the ``real'' clipboard so objects cannot be cut and pasted to other applications.
- Copy
-
If some graphical objects are selected, this copies them into the invisible clipboard so they can be pasted. BUG: Does not use the ``real'' clipboard so objects cannot be cut and pasted to other applications.
- Paste
-
Takes the objects in the invisible clipboard that were previously cut or copied and puts a copy onto the screen. Note that the position will be directly over the old objects. BUG: Does not use the ``real'' clipboard so objects cannot be cut and pasted to other applications
- Clear
-
Deletes the selected objects without putting them in the clipboard.
- Clear All
-
Deletes all the objects.
- Duplicate
-
Makes new objects just like the selected objects and put them in the window 10 pixels from the original objects.
- Select All
-
Selects all the objects.
- Properties...
-
Pops up the dialog box to edit the properties of the object. An accelerator for this is to double click on the objects.
- Arrange
- To Top
-
Make the selected object not be covered by any other objects
- To Bottom
-
Make the selected objects be covered by all other objects.
- Group
-
Collect all the selected objects into a group. Groups can have names, and will be saved to the file using the name as the slot name the group is in.
- UnGroup
-
Make the selected groups no longer be a group.
- Turn Grid On/Turn Grid Off
-
Enable or disable gridding, which is very useful for getting objects aligned nicely. This button uses Am_Cycle_Value_Command and is a toggle.
- Motif Look, Windows Look, Macintosh Look
-
Choose which look the widgets are shown in. Note: Does not affect what is stored to the file: the widgets will still come up with the look of whatever platform they are on.
- Nudge Left, Right, Down, Up
-
Move the selected objects one pixel in the specified direction. BUG: Not undoable.
- Align Lefts, Rights, Tops, Bottoms
-
Align all the selected objects so they have the same left/right/top/bottom. Uses the selected object furthest in the specified direction (e.g., the left-most) to align to. BUG: Not undoable.
- Same Widths, Heights
-
Make all the selected objects have the same width/height as the biggest of the selected objects. BUG: Not undoable.
- About
-
Displays dialog boxes about OpenAmulet and about gilt. Click anywhere in the About OpenAmulet dialog box for it to go away.
Using the Objects with an Application
gilt generates fairly simple C++ code for the specified objects. The file creates a group or window with a name specified by the programmer in the Generate C++ dialog box (see next section). This main group or window will have all of the drawn objects as parts. If the part was given a name using the ``Name for item'' field of the property sheet for the object, then that name is used for the part. For example, suppose that a text field was added to the window, and the ``Name for Item'' for the text input widget is ``foo''. Then, the window will have a slot named foo that will contain the text input widget.
gilt is set up to allow the generated dialog boxes to be used by accessing and setting the values of the widgets in them. The generated C++ file is {it not} intended to be the main program. You should have a different file with main() in it, and link the generated file to it. gilt will generate a header file to be used to connect them.
The typical way to use a gilt-generated dialog box called ``MyDB'' with a widget named ``FOO'' is:
Include mydb.h in your source file:
#include "mydb.h"
Initialize MyDB at the top of main:
MyDB_Initialize();
When you want to pop up MyDB, first set the default value of the widget using
MyDB.Get_Object(FOO).Set(Am_VALUE, defaultvalue);
Pop up the window, and if OK, then get the value out of the dialog box:
Am_Value ok;
Am_Pop_Up_Window_And_Wait(MyDB, ok, true);
if (ok.Valid()) {
Am_Value new_val = MyDB.Get_Object(FOO).Get(Am_VALUE);
// now do something with the value
// next set slots of the command to make this command undoable
} else {
Am_Abort_Widget(MyDB.GET_Object(FOO)); //keep out of undo history
}
gilt is not set up to specify call-backs (or Am_DO_METHODs) with widgets. If you want a widget to have a custom command or a Am_DO_METHOD, you will have to edit the generated C++ code. For example, if gilt generated the following code, you could hand-edit the code to add the my_do_method line shown in bold:
.Add_Part(GOFORITBUTTON, Am_Button.Create()
.Set(Am_LEFT, 94)
.Set(Am_TOP, 69)
.Set(Am_WIDTH, 66)
.Set(Am_HEIGHT, 40)
.Set(Am_FILL_STYLE, Am_Amulet_Purple)
.Get_Object(Am_COMMAND)
.Set(Am_LABEL, ``Go For It'')
.Set(Am_DO_METHOD, my_do_method) //added by hand-editing
.Get_Owner()
)
The ``Generate C++'' dialog box
The defaults for the name fields are generated from the name of the file last saved or opened. If all the fields are blank (due to not having saved to a file, or because the ``Clear All'' button at the bottom is hit), then filling in the ``Name of Main Object'' field will fill in default values for the other fields.
There are lots of options when saving the C++ file. The main window or object must be given a name. This will be used as the name of a global C++ variable that holds the prototype for the object. The initialization procedure will be called that name with ``_Initialize'' appended.
The filename for the C++ file is specified next. If you don't specify an extension, then gilt will append ``.cc'' (on all platforms --- so if you are on a PC and want a ``.cpp'' extension, just specify the full filename including an extension).
Normally, you will also want a header file that can be #included into your application. You might not want a header file if you have exactly one file in your application and you include the generated C++ file directly in your C++ file.
gilt can either generate the dialog box as a window or you can create a group instead. If you make a group, then you can put instances of it inside a different group or window. If you create a window, you can pop it up with Am_Pop_Up_Window_And_Wait or just by making it Am_VISIBLE on the screen. The window's title can be specified, and whether it should be fixed size or not.
Next, you can specify the size that the window or group should be. The default is to use the formulas Am_Width_Of_Parts and Am_Height_Of_Parts so the window be just as big as the contents. The other alternative is to explicitly set the size. The default values for the Width and Height are the current size of the gilt window, so it is a good idea to resize the gilt window so it shows the window the size you want to see it at run-time before issuing the Generate C++ command.
The Clear All button clears all the values in the Generate C++ dialog box, in case the default values generated by the system are not useful. OK generates the file, and Cancel gets rid of the dialog box without doing anything.
Slot and Object Names
The names given to objects are used as slot names for the object as part of the main group or window. Therefore, the names should be valid as part names. gilt helps with this by substituting underscores ``_'' for any character found in the name that isn't legal as a C++ variable name.
In the header file, gilt generates a define for the slot name, and in the C++ file, gilt generates a Am_Register_Slot_Name call for the slot name.
Creating the Dialog Box or Group
Don't forget to call the Initialize procedure before trying to access the object. This sets the global variable with a prototype of the dialog box or group. If you only need one, then you can use this directly. If you may need more than one, then the global variable can be used as a prototype from which copies or instances can be made.
Setting and Accessing the Values of Widgets
All of the widgets that have names can be easily accessed by getting them out of the top-level object's named slots. Since all widget's values are available in the Am_VALUE slot of the widget, it is easy to set and access the values. For example, the following is the code used for a dialog box called Name_And_Label_Window which has two text input widgets in slots NAME_OBJ and LABEL_OBJ. The customize_text method below is the Am_DO_METHOD of a command, and it sets up the command so it is undoable.
Am_Define_Method(Am_Customize_Object_Method, void, customize_text,
(Am_Object cmd, Am_Object owner)) {
Am_String ls = owner.Get(Am_TEXT);
Am_String vs = owner.Get(Lw_NAME);
Name_And_Label_Window.Get_Object(NAME_OBJ).Set(Am_VALUE, vs);
Name_And_Label_Window.Get_Object(LABEL_OBJ).Set(Am_VALUE, ls);
Am_Value ok;
Am_Pop_Up_Window_And_Wait(Name_And_Label_Window, ok, true);
if (ok.Valid()) {
Am_String new_vs = Name_And_Label_Window.Get_Object(NAME_OBJ)
.Get(Am_VALUE);
fix_lw_name(new_vs);
owner.Set(Lw_NAME, new_vs);
Am_String new_ls=Name_And_Label_Window.Get_Object(LABEL_OBJ)
.Get(Am_VALUE);
owner.Set(Am_TEXT, new_ls);
cmd.Set(Am_OBJECT_MODIFIED, owner);
cmd.Set(Am_SLOTS_TO_SAVE, Am_Value_List().Add(Lw_NAME).Add(Am_TEXT),
Am_OK_IF_NOT_THERE);
cmd.Set(Am_OLD_VALUE, Am_Value_List().Add(vs).Add(ls));
cmd.Set(Am_VALUE, Am_Value_List().Add(new_vs).Add(new_ls));
} else {
Am_Abort_Widget(cmd); //keep out of undo history
}
}
Other properties of the widgets, such as their color, labels or whether they are visible or not, could also be set by the program, if desired.
Editing the Generated C++ and Header Files
Since gilt cannot read the Generated C++ code back in, it is important that you not hand-edit the C++ file or header file, or these changes will be lost if you need to regenerate the dialog box. The intention is that you will Save the objects as a gilt file (using Save or Save As) and then Generate the C++ file. If any changes are needed, then load in the gilt file and edit it interactive using gilt and Generate the C++ file again. The interface to the generated objects is designed so that you can do it all from your main program, and not have to edit the generated file at all.
The generated C++ file and header file are just plain text and are quite readable, so you can edit them if you really want to, but remember that all hand-edits will have to be done again if you generate the C++ file again.
SEE ALSO
gilt is documented fully in section 8 of the OpenAmulet Reference Manual.
AUTHOR
gilt was originally written as AmEdit by S.Nebel (Linkworks Ltd Wellington,NZ) 1997.
Modified and updated by Brad A. Myers of the Amulet project at CMU.
This manual page was written by James R. Van Zandt <[email protected]>, for the Debian GNU/Linux system (but may be used by others).