<> <> <> <<>> <> DIRECTORY PEConstraints, PEDisplay USING [DrawVertex, DrawSegment], PERefresh USING [DisableSegmentRefresh, EnableSegmentRefresh], PETrajectoryOps USING [FollowingVertex, PrecedingVertex], PETypes, ViewerClasses USING [Viewer]; PEConstraintsImpl: CEDAR PROGRAM IMPORTS PEDisplay, PERefresh, PETrajectoryOps EXPORTS PEConstraints = BEGIN OPEN PEConstraints, PEDisplay, PERefresh, PETrajectoryOps, PETypes; Constrain: PUBLIC PROCEDURE [pathViewer: ViewerClasses.Viewer, vertex: VertexNode, segment: SegmentNode, newPosition: Point] = { <> followingVertex, precedingVertex: VertexNode; followingSegment, precedingSegment: SegmentNode; [followingVertex, followingSegment] _ FollowingVertex[vertex, segment]; [precedingVertex, precedingSegment] _ PrecedingVertex[vertex, segment]; UnconstrainedUpdate[pathViewer, vertex, segment, newPosition]; }; UnconstrainedUpdate: PROCEDURE [pathViewer: ViewerClasses.Viewer, vertex: VertexNode, segment: SegmentNode, newPosition: Point] = { <> DrawVertexAndSegments[pathViewer: pathViewer, vertex: vertex, segment: segment, undo: TRUE]; vertex.first.point _ newPosition; DrawVertexAndSegments[pathViewer: pathViewer, vertex: vertex, segment: segment]; }; DrawVertexAndSegments: PRIVATE PROCEDURE [pathViewer: ViewerClasses.Viewer, vertex: VertexNode, segment: SegmentNode, undo: BOOLEAN _ FALSE] = { <> IF undo THEN { DisableSegmentRefresh[segment.first]; IF vertex.rest = NIL AND segment.rest # NIL THEN DisableSegmentRefresh[segment.rest.first]; } ELSE { EnableSegmentRefresh[segment.first]; IF vertex.rest = NIL AND segment.rest # NIL THEN EnableSegmentRefresh[segment.rest.first]; }; DrawVertex[pathViewer: pathViewer, vertex: vertex.first, undo: undo]; DrawSegment[pathViewer: pathViewer, segment: segment.first, undo: undo]; IF vertex.rest = NIL AND segment.rest # NIL THEN DrawSegment[pathViewer: pathViewer, segment: segment.rest.first, undo: undo]; }; END.