GGDescribeImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by Bier on January 26, 1987 3:38:48 pm PST
Contents: Printing out descriptions of gargoyle objects onto text streams, for debugging and feedback.
Pier, November 20, 1986 10:54:51 am PST
DIRECTORY
Atom, GGDescribe, GGInterfaceTypes, GGModelTypes, GGSegmentTypes, GGTouch, GGTraj, IO, Rope;
GGDescribeImpl: CEDAR PROGRAM
IMPORTS Atom, GGTouch, GGTraj, IO, Rope
EXPORTS GGDescribe = BEGIN
AlignmentPoint: TYPE = GGInterfaceTypes.AlignmentPoint;
EntityGenerator: TYPE = GGModelTypes.EntityGenerator;
FeatureData: TYPE = GGInterfaceTypes.FeatureData;
GargoyleData: TYPE = GGInterfaceTypes.GargoyleData;
Outline: TYPE = GGModelTypes.Outline;
OutlineDescriptor: TYPE = GGModelTypes.OutlineDescriptor;
Segment: TYPE = GGSegmentTypes.Segment;
Sequence: TYPE = GGModelTypes.Sequence;
SequenceGenerator: TYPE = GGModelTypes.SequenceGenerator;
Slice: TYPE = GGModelTypes.Slice;
SliceDescriptor: TYPE = GGModelTypes.SliceDescriptor;
SliceParts: TYPE = GGModelTypes.SliceParts;
TouchGroup: TYPE = GGSegmentTypes.TouchGroup;
TouchItem: TYPE = GGSegmentTypes.TouchItem;
TouchItemGenerator: TYPE = GGTouch.TouchItemGenerator;
Traj: TYPE = GGModelTypes.Traj;
TrajGenerator: TYPE = GGModelTypes.TrajGenerator;
NotYetImplemented: PUBLIC SIGNAL = CODE;
terseSlice: BOOLFALSE;
DescribeFeature: PUBLIC PROC [feature: FeatureData, gargoyleData: GargoyleData] RETURNS [rope: Rope.ROPE] = {
IF feature = NIL THEN RETURN["nothing"]
ELSE {
SELECT feature.resultType FROM
outline => {
outline: Outline ← NARROW[feature.shape, OutlineDescriptor].slice;
tParts: SliceParts ← outline.class.newParts[outline, feature.hitPart, gargoyleData.drag.selectState];
rope ← outline.class.describe[outline, tParts];
};
slice => IF terseSlice THEN rope ← Rope.Concat[Atom.GetPName[NARROW[feature.shape, SliceDescriptor].slice.class.type], " slice"]
ELSE { -- do this because feature doesn't carry hitParts for slices, so we ask the slice to tell us its hitParts and then describe itself using those parts
tSlice: Slice ← NARROW[feature.shape, SliceDescriptor].slice;
tParts: SliceParts ← tSlice.class.newParts[tSlice, feature.hitPart, gargoyleData.drag.selectState];
rope ← tSlice.class.describe[tSlice, tParts];
};
distanceLine => rope ← "distance line";
slopeLine => rope ← "slope line";
angleLine => rope ← "angle line";
symmetryLine => rope ← "symmetry line";
radiiCircle => rope ← "compass circle";
intersectionPoint => {
firstObj, secondObj: Rope.ROPE;
alignPoint: AlignmentPoint ← NARROW[feature.shape];
line1: FeatureData ← alignPoint.curve1;
line2: FeatureData ← alignPoint.curve2;
tangent: BOOL ← alignPoint.tangent;
IF line1 = NIL AND line2 = NIL THEN {
rope ← IO.PutFR["the anchor"];
}
ELSE {
firstObj ← IF line1 # NIL THEN DescribeSourceFeature[line1, gargoyleData]
ELSE "unknown";
secondObj ← IF line2 # NIL THEN DescribeSourceFeature[line2, gargoyleData]
ELSE "unknown";
IF tangent THEN rope ← IO.PutFR["a %g/%g tangency point", [rope[firstObj]], [rope[secondObj]] ]
ELSE rope ← IO.PutFR["a %g/%g intersection point", [rope[firstObj]], [rope[secondObj]] ];
};
};
midpoint => {
seqPart: GGInterfaceTypes.SequencePart ← NARROW[feature.hitPart];
segNum: NAT ← seqPart.segNum;
rope ← IO.PutFR["midpoint of segment %g", [integer[segNum]]];
};
anchor => {
rope ← IO.PutFR["anchor"];
};
ENDCASE => ERROR;
};
};
DescribeSourceFeature: PUBLIC PROC [feature: FeatureData, gargoyleData: GargoyleData] RETURNS [rope: Rope.ROPE] = {
IF feature = NIL THEN RETURN["nothing"]
ELSE {
SELECT feature.type FROM
outline => rope ← "outline";
slice => rope ← Rope.Concat[Atom.GetPName[NARROW[feature.shape, SliceDescriptor].slice.class.type], " slice"];
distanceLine => rope ← "distance line";
slopeLine => rope ← "slope line";
angleLine => rope ← "angle line";
symmetryLine => rope ← "symmetry line";
radiiCircle => rope ← "compass circle";
intersectionPoint => {
firstObj, secondObj: Rope.ROPE;
firstObj ← IF NARROW[feature.shape, AlignmentPoint].curve1 # NIL THEN DescribeSourceFeature[NARROW[feature.shape, AlignmentPoint].curve1, gargoyleData]
ELSE "unknown";
secondObj ← IF NARROW[feature.shape, AlignmentPoint].curve2 # NIL THEN DescribeSourceFeature[NARROW[feature.shape, AlignmentPoint].curve2, gargoyleData]
ELSE "unknown";
rope ← IO.PutFR["a %g/%g intersection point", [rope[firstObj]], [rope[secondObj]] ];
};
midpoint => rope ← IO.PutFR["midpoint of segment ???"];
ENDCASE => ERROR;
};
};
DescribeTraj: PUBLIC PROC [traj: Traj] RETURNS [text: Rope.ROPE] = {
text ←
SELECT traj.role FROM
open => IO.PutFR["a %g-segment open trajectory", [integer[traj.segCount]]],
fence => IO.PutFR["a %g-segment fence", [integer[traj.segCount]]],
hole => IO.PutFR["a %g-segment hole", [integer[traj.segCount]]],
ENDCASE => "";
};
DescribeJoint: PUBLIC PROC [traj: Traj, jointNum: NAT] RETURNS [text: Rope.ROPE] = {
end: BOOL;
end ← GGTraj.IsEndJoint[traj, jointNum];
IF end THEN text ← IO.PutFR["end joint %g on ", [integer[jointNum]] ]
ELSE text ← IO.PutFR["joint %g on ", [integer[jointNum]] ];
text ← Rope.Concat[text, DescribeSegment[traj, IF GGTraj.HiJoint[traj]=jointNum AND traj.role=open THEN jointNum-1 ELSE jointNum]];
Describes one of the possible two segments this joint is on
};
DescribeControlPoint: PUBLIC PROC [traj: Traj, segNum: NAT, cpNum: NAT] RETURNS [text: Rope.ROPE] = {
text ← Rope.Cat[IO.PutFR["control point %g on ", [integer[cpNum]]], DescribeSegment[traj, segNum] ];
};
DescribeSegment: PUBLIC PROC [traj: Traj, segNum: NAT] RETURNS [text: Rope.ROPE] = {
IF segNum=LAST[NAT] THEN text ← Rope.Cat["a segment on ", DescribeTraj[traj]] ELSE {
seg: Segment ← GGTraj.FetchSegment[traj, segNum];
text ← Rope.Cat[seg.class.describe[seg, TRUE, TRUE, TRUE, NIL], IO.PutFR[" segment %g on ", [integer[segNum]]], DescribeTraj[traj]];
text ← Rope.Cat[Atom.GetPName[seg.class.type], IO.PutFR[" segment %g on ", [integer[segNum]]], DescribeTraj[traj]];
};
};
DescribeSequence: PUBLIC PROC [seq: Sequence] RETURNS [text: Rope.ROPE] = {
text ← Rope.Cat[IO.PutFR["One or more parts of "], DescribeTraj[seq.traj]];
};
DescribeItem: PROC [f: IO.STREAM, item: TouchItem] = {
SELECT item.touchingPartType FROM
joint => f.PutF["Item: joint on %g", [rope[DescribeTraj[NARROW[item.traj]]]]];
segment => f.PutF["Item: segment on %g", [rope[DescribeTraj[NARROW[item.traj]]]]];
ENDCASE => ERROR;
};
DescribeTouchGroup: PUBLIC PROC [group: TouchGroup] RETURNS [text: Rope.ROPE] = {
f: IO.STREAM;
touchGen: TouchItemGenerator;
f ← IO.ROS[];
f.PutF["TouchGroup: (%1.2f, %1.2f)\n", [real[group.point.x]], [real[group.point.y]]];
touchGen ← GGTouch.AllTouchItems[group];
FOR item: TouchItem ← GGTouch.NextTouchItem[touchGen], GGTouch.NextTouchItem[touchGen] UNTIL item = NIL DO
f.PutChar[IO.TAB];
DescribeItem[f, item];
f.PutChar[IO.CR];
ENDLOOP;
text ← IO.RopeFromROS[f];
};
END.