Each item on a slate has a shape. Shapes provide more sophisticated control over the coordinates of an item than just its raw coordinates. Simple items have a shape that cannot be changed; complex items have a shape that is determined by the class defining that item. Predefined shapes mimic the primitive canvas item types: point, rectangle, oval, line, and polygon.
An item with a given shape has a set of attributes called features. Features are inspired by Gleicher's work on constraint-based graphics [3]. A feature is typically a point location on the item. An item can be queried to find the value of a feature, and the feature can be moved to change the shape of the item. For rectangular items, the default features are its center, the four corners, and the four edges; for lines, the features are the vertices of the line.
For example, to find the coordinates of the north-west corner of a rectangular item, we could execute:
set northwest [$slate feature $frame nw]
To reshape the item by moving the north-west corner left and down ten pixels, we could execute:
$slate reshape $frame -10 10 nw
All features can be read, but not all can be set; center, for example, can be read but not set. Any feature that can be set can also be grappled - that is, have a grab handle attached to it. For example, executing the code:
$slate grapple $citem
will add grab handles to the four corners and edges of the given item. The effect of executing this code is shown on the right of figure 4 - this item can be resized by dragging any of the grab handles.
The Shape classes are implemented as collections of class procedures - each class handles feature queries and reshaping of all items with that shape. Complex items can choose their own set of features by overriding their shape-related methods. For example, the Terminal item in figure 5 has features called ``origin'' and ``terminal,'' which are its base and connection point respectively.