CMSC 437/691C
Graphical User Interface Programming


TUE,THU 5:30-6:45 PM ACIV 150
Fall 1996


Project 4: Extending the Draw Program


Date Due Tuesday, November 19, 1996 before midnight.

Purpose

To gain experience using Motif menus, dialogs and scrolled windows, and designing and implementing a graphical modeling hierarchy.

Assignment

For this project, you will continue to refine the drawing editor application you developed in Project 3. In particular, you will extend the Motif-based portion of the interface, convert the single-level display list to a full graphical hierarchy, and add further direct manipulation capabilities to the graphical shapes. Here are the particular features you must add:

Menu Bar.
You should add a standard Motif-style menu bar to the application. The simplest way to do this is to make the top-level manager be a XmMainWindow widget and use the menu creation utilities described in the book. The toolbar and colorbar will remain, but the "Quit", "Clear" and "Delete" operations will be converted from PushButtons to menu items. In addition, several new operations will be added as menu items. The complete menu arrangement will be as follows:

FileEditArrangePen
ClearUndoGroup1 Pixel
SaveSelect AllUngroup2 Pixels
QuitDeselect AllMove To Front3 Pixels
DeleteMove To Back4 Pixels

The "Undo" edit command and "Pen" menu are required for graduate students only (see below).

Shape Manipulation.
In addition to being able to move individual shapes, you will add resizing capability to shapes that have been selected. Grabbing a control point of a selected shape with the left mouse button and dragging it with the mouse will cause the dimensions of the shape to be changed accordingly. You may either completely redraw the shapes after each mouse motion event, or simply display a rubber-band rectangle outline of the shape's bounding box while the control point is being dragged, in which case the shape will be redrawn with its new dimensions when the mouse button is released.

Grouping.
You will add a new type of node called a container node, analogous to a Manager widget, which will be used to convert your display list into a full graphics hierarchy. Initially, all created shapes are top-level nodes. Selecting more than one shape and issuing the "Group" command, however, will cause them to be collected under one container node, which is displayed by showing the control points of its collective bounding box. Moving this bounding box will cause all elements of the group to be moved. Resizing or changing attributes of groups, however, is not required. The grouping process can be repeated to any desired level of hierarchy. The "Ungroup" command reverses the grouping operation, breaking the currently selected groups into their components and making them into top-level nodes.

When a set of selected objects are grouped, the new group is placed on the top of the "stacking order", but the shapes retain their relative ordering previous to the group command. For example, if there are shapes 1-10 on the display list, and you group shapes 2, 4, and 7, then the group containing 2, 4, and 7 (in that order) will be placed on top of the display list. "Ungrouping" will place the members of the group in order into the display list where the group was.

Groups are truly hierarchical. If I have a group and a shape, and I group those together into a new group, ungrouping the new group will produce the old group and shape.

Layering Control.
Any selected shape or group can be moved to the top or bottom of the top-level display list by issuing the "Move to Front" or "Move to Back " menu commands. This operation is only defined for a single selection, not for multiple selections.

Selecting, Deleting.
The "Select All" and "Deselect All" menu items will cause the top-level display list to be traversed, selecting or deselecting each shape or group accordingly. The "Delete" menu item, as in the previous project, will cause the currently selected objects to be removed from the top-level display list.

Clear, Save, Quit.
The "Clear" menu item, as in the previous project, will simply remove all shapes/groups from the display list. The "Save" menu item will, for this project, simply print out a text representation of the current graphics hierarchy to the standard output. The format of the representation is not important, as long as it contains all the important information in the hierarchy. The "Quit" menu item should first pop up a Motif Question Dialog Box, asking the user if he really wants to quit, before actually exiting the program.

Graduate students must also implement the following:
Line Width Attribute.
A new attribute, line width, will be added which specifies the width in pixels of lines, rectangle and ellipse borders. This attribute will be specified from the "Pen" menu, which should contain buttons displaying representative lines of the given width rather than text. The current line width value should be indicated in the menu (e.g. by using toggle buttons). Just like the current line color attribute, this menu will not only set the current attribute value (to be used in subsequently created shapes) but also to change the line attribute of currently selected shapes. Changing any attributes (colors, fill status, line width) for a group will have no effect.

Undo
As with projects 2 and 3, users should be able to undo the last operation performed. For this project, "Undo" will be a menu option in the Edit menu. It is permitted for two consecutive undo commands to "undo the undo", but not required.

Hints

Making sure you have a good DynamicArray or LinkedList class will be a big help. Whatever its underlying implementation, it should support such operations as: add to bottom, add to top, remove, and delete, as well as ways of traversing it in both directions. Using a List of references or pointers to objects will make all your operations simpler.

The group, or container class should have a "draw" method defined on it and will maintain its own list of contained objects.

Resizing should be fairly straightforward if you implement control points as Rectangle objects. As a debugging tool, you might want to implement the "Save" operation first.