Reference

gilt(1)

graphical user interface builder for the Amulet toolkit

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).