GGCaret.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by Bier on August 9, 1985 2:51:35 pm PDT
Contents: Facilities for moving the caret and storing information about the neighborhood it inhabits (such as what trajectory it is sitting on).
DIRECTORY
GGInterfaceTypes,
GGModelTypes;
GGCaret: CEDAR DEFINITIONS =
BEGIN
Caret: TYPE = GGInterfaceTypes.Caret;
GargoyleData: TYPE = GGInterfaceTypes.GargoyleData;
Joint: TYPE = GGModelTypes.Joint;
Point: TYPE = GGModelTypes.Point;
Segment: TYPE = GGModelTypes.Segment;
Sequence: TYPE = GGModelTypes.Sequence;
Traj: TYPE = GGModelTypes.Traj;
The story of the Caret.
There are two carets in Gargoyle (so far): THE caret, and the anchor. Someday there will also be a copy caret.
If the caret exists, it is drawn whenever the scene is painted. Some operations put the caret on the overlay plane so that it can move (See GGMouseEventImpl.DuringSelectPoint for example). Update causes the caret to exist. Kill makes it cease to exist. Exists checks. Update also tells the caret where its new position is. GetPoint retrieves the current position.
TellOnOverlay tells the caret it is on (or off) the overlay. This does not actually put the caret on the overlay. GGRefresh.MoveToOverlay[caret] does that. Only GGRefresh should call TellOnOverlay.
The caret moves for several reasons. The $SelectPoint operations move the caret, using gravity to help it point to joints, segments, and alignment lines. The $Drag operations allow the caret to pick up some object (which jumps to the caret at the beginning) and then allow the caret to be attracted by gravity as usual. During all of this, the caret remembers the object it has picked up (called the Chair) and the object it is currently being attracted to (called the Attractor). SitOnJoint, SitOnSegment, and DoNotSit tell the caret about the chair (or lack of one). Update tells the caret about the attractor.
At the end of a dragging operation, the caret knows if two trajectories have just become touching. Hence, it was natural to put MakeChairTouchAttractor, and MakeChairTouchTrajJoint in this module. These procedures call GGTouch to create the actual touching relationships.
This caret exists. IF traj # NIL, then the caret is sitting on a trajectory. If the caret is sitting on a trajectory and onJoint then joint is the number of the joint on which the caret is sitting. Otherwise, segNum is the number of the segment on which the caret is sitting.
GetPoint: PROC [caret: Caret] RETURNS [point: Point];
Kill: PROC [caret: Caret];
Exists: PROC [caret: Caret] RETURNS [BOOL];
This caret no longer exists. It should disappear from the screen.
For use by GGRefreshImpl.
TellOnOverlay: PROC [caret: Caret, onOverlay: BOOL];
IsOnOverlay: PROC [caret: Caret] RETURNS [BOOL];
The Chair.
SitOnJoint: PROC [caret: Caret, chair: Traj, jointNum: NAT];
SitOnSegment: PROC [caret: Caret, chair: Traj, segNum: NAT];
DoNotSit: PROC [caret: Caret];
GetChair: PROC [caret: Caret] RETURNS [chair: Traj, isJoint: BOOL, joint: Joint, jointNum: NAT, seg: Segment];
The Attractor.
Update: PROC [gargoyleData: GargoyleData, point: Point, attractor: Traj, onJoint: BOOLTRUE, attractorJointNum: NAT ← 999, attractorSegNum: NAT ← 999];
GetAttractor: PROC [caret: Caret] RETURNS [attractor: Traj, isJoint: BOOL, joint: Joint, jointNum: NAT, seg: Segment];
Touching.
MakeChairTouchAttractor: PROC [caret: Caret, gargoyleData: GargoyleData];
MakeChairTouchTrajJoint: PROC [caret: Caret, gargoyleData: GargoyleData, traj: Traj, jointNum: NAT];
Used for placing the anchor, for instance.
Copy: PROC [to, from: Caret];
These procedures will be replaced by adding a field to GargoyleData.
GetSequence: PROC [caret: Caret] RETURNS [seq: Sequence];
seq represents the segment which is currently being added (e.g. GGMouseEvent.EndAdd).
SetSequence: PROC [caret: Caret, seq: Sequence];
Used for dropping the anchor.
END.