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:
File | Edit | Arrange | Pen |
Clear | Undo | Group | 1 Pixel |
Save | Select All | Ungroup | 2 Pixels |
Quit | Deselect All | Move To Front | 3 Pixels |
| Delete | Move To Back | 4 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.