Scheme>SchemeViewing.Mesa
Last Edited by: Spreitzer, February 12, 1984 10:14 pm
DIRECTORY Basics, BiScrollers, Graphics, InputFocus, IO, OrderedSymbolTableRef, Rope, SchemeRep, SchemeEditing, TIPUser, ViewerClasses, ViewerOps, ViewRec;
SchemeViewing: CEDAR PROGRAM
IMPORTS BiScrollers, Graphics, InputFocus, IO, OrderedSymbolTableRef, Rope, SchemeEditing, TIPUser, ViewerOps, ViewRec
EXPORTS SchemeEditing =
BEGIN OPEN SchemeRep, SchemeEditing;
editorClasses: PUBLIC ARRAY SubjectClass OF BiScrollers.BiScrollerClass ← [
BiScrollers.NewBiScrollerClass[
flavor: $SchemeIconEditor,
extrema: PicExtrema,
notify: NotifyScheme,
paint: PaintScheme,
destroy: DestroyEditor,
tipTable: TIPUser.InstantiateNewTIPTable["SchemeIcon.TIP"]],
BiScrollers.NewBiScrollerClass[
flavor: $SchemeExpansionEditor,
extrema: PicExtrema,
notify: NotifyScheme,
paint: PaintScheme,
destroy: DestroyEditor,
tipTable: TIPUser.InstantiateNewTIPTable["SchemeExpansion.TIP"]]
];
PicExtrema: BiScrollers.ExtremaProc --PROC [clientData: REF ANY, direction: Vec] RETURNS [min, max: Geom2D.Vec]-- =
{editor: Editor ← NARROW[clientData];
smallestX:Coord ← PikCoord[editor.subjectPic.coordsByValue[X].LookupSmallest[]];
smallestY:Coord ← PikCoord[editor.subjectPic.coordsByValue[Y].LookupSmallest[]];
largestX: Coord ← PikCoord[editor.subjectPic.coordsByValue[X].LookupLargest[]];
largestY: Coord ← PikCoord[editor.subjectPic.coordsByValue[Y].LookupLargest[]];
min ← [
IF smallestX # NIL THEN smallestX.z ELSE -10,
IF smallestY # NIL THEN smallestY.z ELSE -10];
max ← [
IF largestX # NIL THEN largestX.z ELSE 10,
IF largestY # NIL THEN largestY.z ELSE 10];
};
PikCoord: PROC [any: REF ANY] RETURNS [coord: Coord] = {
coord ← IF any # NIL THEN WITH any SELECT FROM
c: Coord => c,
cl: LORA => NARROW[cl.first],
ENDCASE => ERROR
ELSE NIL};
PaintScheme: ViewerClasses.PaintProc --PROC [self: Viewer, context: Graphics.Context, whatChanged: REF ANY, clear: BOOL]-- =
BEGIN
editor: Editor ← NARROW[BiScrollers.QuaBiScroller[self].ClientDataOf[]];
[] ← Graphics.SetPaintMode[context, invert];
IF whatChanged = NIL THEN {
DrawPic[editor.subjectPic, context, [0, 0]];
SetBack[editor.primary]; DrawBack[editor.primary, context];
SetBack[editor.secondary]; DrawBack[editor.secondary, context]}
ELSE WITH whatChanged SELECT FROM
la: LORA => UpdateWhatever[la, context];
coord: Coord => UpdateCoord[coord, context];
pb: PointBack => IF pb.x # pb.sx OR pb.y # pb.sy THEN {DrawBack[pb, context]; SetBack[pb]; DrawBack[pb, context]};
line: Line => {SetLine[line]; DrawLine[line, context]};
text: Text => {SetText[text]; DrawText[text, context]};
pi: PictureInstance => {SetInstance[pi]; DrawPic[pi.of, context, pi.s]};
ENDCASE => ERROR;
END;
SetInstance: PROC [pi: PictureInstance] =
{pi.s[X] ← pi.org.c[X].z; pi.s[Y] ← pi.org.c[Y].z};
DrawPic: PROC [pic: PictureDef, context: Graphics.Context, at: VertexReals] =
BEGIN
DrawObject: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] =
{stop ← FALSE;
WITH any SELECT FROM
line: Line => {SetLine[line]; DrawLine[line, context]};
text: Text => {SetText[text]; DrawText[text, context]};
pi: PictureInstance => {IF pi.in # pic THEN ERROR;
SetInstance[pi]; DrawPic[pi.of, context, pi.s]};
ENDCASE => ERROR};
org: Graphics.Mark ← Graphics.Save[context];
Graphics.Translate[self: context, tx: at[X], ty: at[Y]];
pic.objects.EnumerateIncreasing[DrawObject];
Graphics.Restore[context, org];
END;
UpdateWhatever: PROC [l: LORA, context: Graphics.Context] =
BEGIN
WITH l.first SELECT FROM
a: ATOM => SELECT a FROM
$Labels => FOR ll: LORA ← l.rest, ll.rest WHILE ll # NIL DO
text: Text ← NARROW[ll.first];
IF text.sxy#[text.org.c[X].z, text.org.c[Y].z] OR NOT text.sr.Equal[text.rope]
THEN {DrawText[text, context]; SetText[text]; DrawText[text, context]};
ENDLOOP;
ENDCASE => ERROR;
ENDCASE => ERROR;
END;
UpdateCoord: PROC [coord: Coord, context: Graphics.Context] =
BEGIN
UpdatePIC: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] =
{c2: Coord ← NARROW[any]; stop ← FALSE;
IF c2.axis = coord.axis THEN UpdateCoord[c2, context]};
coord.z ← coord.dz + Org[coord];
IF coord.z = coord.sz THEN RETURN;
coord.sz ← coord.z;
FOR dl: LORA ← coord.dependents, dl.rest WHILE dl # NIL DO
WITH dl.first SELECT FROM
c2: Coord => UpdateCoord[c2, context];
pt: Point => FOR l: LORA ← pt.dependents, l.rest WHILE l # NIL DO
WITH l.first SELECT FROM
line: Line => IF line.sa # [line.a.c[X].z, line.a.c[Y].z] OR line.sb # [line.b.c[X].z, line.b.c[Y].z]
THEN {DrawLine[line, context]; SetLine[line]; DrawLine[line, context]};
text: Text => IF text.sxy # [text.org.c[X].z, text.org.c[Y].z]
THEN {DrawText[text, context]; SetText[text]; DrawText[text, context]};
pi: PictureInstance => IF pi.s # [pi.org.c[X].z, pi.org.c[Y].z] THEN {
DrawPic[pi.of, context, pi.s];
SetInstance[pi];
DrawPic[pi.of, context, pi.s];
pi.coords.EnumerateIncreasing[UpdatePIC]};
ENDCASE => ERROR;
ENDLOOP;
ENDCASE => ERROR;
ENDLOOP;
END;
Org: PROC [coord: Coord] RETURNS [z: REAL] =
{z ← IF coord.parent = NIL THEN 0 ELSE
WITH coord.parent SELECT FROM
c2: Coord => c2.z,
pi: PictureInstance => pi.org.c[coord.axis].z,
ENDCASE => ERROR};
SetLine: PROC [line: Line] = {
line.sa ← [line.a.c[X].z, line.a.c[Y].z];
line.sb ← [line.b.c[X].z, line.b.c[Y].z]};
DrawLine: PROC [line: Line, context: Graphics.Context] =
BEGIN
Graphics.SetCP[context, line.sa[X], line.sa[Y]];
Graphics.DrawTo[context, line.sb[X], line.sb[Y]];
END;
SetText: PROC [text: Text] =
{text.sxy ← [text.org.c[X].z, text.org.c[Y].z]; text.sr ← text.rope};
DrawText: PROC [text: Text, context: Graphics.Context] =
BEGIN
Graphics.SetCP[context, text.sxy[X], text.sxy[Y]];
Graphics.DrawRope[context, text.sr];
END;
SetBack: PROC [back: PointBack] = {back.sx ← back.x; back.sy ← back.y};
DrawBack: PROC [back: PointBack, context: Graphics.Context] =
BEGIN
org: Graphics.Mark ← Graphics.Save[context];
Graphics.Translate[self: context, tx: back.sx, ty: back.sy];
IF back.primary
THEN Graphics.DrawStroke[self: context, path: primaryPath]
ELSE Graphics.DrawBox[context, [-1.5, -1.5, 1.5, 1.5]];
Graphics.Restore[context, org];
END;
gray: CARDINAL = 257*18*5;
primaryPath: Graphics.Path ← Graphics.NewPath[];
NotifyScheme: ViewerClasses.NotifyProc --PROC [self: Viewer, input: LIST OF REF ANY]-- =
BEGIN
editor: Editor ← NARROW[BiScrollers.QuaBiScroller[self].ClientDataOf[]];
WHILE input # NIL DO
WITH input.first SELECT FROM
a: ATOM => SELECT a FROM
$StartSelect => input ← StartSelect[editor, FALSE, input];
$TrackSelect => input ← TrackSelect[editor, FALSE, input];
$FinalSelect => input ← FinalSelect[editor, FALSE, input];
$StartDraw => input ← StartSelect[editor, TRUE, input];
$TrackDraw => input ← TrackSelect[editor, TRUE, input];
$FinalDraw => input ← FinalSelect[editor, TRUE, input];
$Move => input ← Move[editor, input];
$EndMove => {EndMove[editor]; input ← input.rest};
$SetGoal => {editor.strandGoal ← editor.primary.point; input ← input.rest};
$FinishWire => {NewStrand[editor, TRUE]; input ← input.rest};
$BreakWire => input ← BreakWire[editor, input];
$JoinWire => input ← JoinWire[editor, input];
$DownShift => {editor.oldHor ← FALSE; input ← input.rest};
$DownCtrl => {editor.oldHor ← TRUE; input ← input.rest};
ENDCASE => ERROR;
ENDCASE => ERROR;
ENDLOOP;
END;
SetBackToPoint: PUBLIC PROC [editor: Editor, pb: PointBack, p: Point] =
BEGIN
pb.point ← p;
pb.x ← p.c[X].z;
pb.y ← p.c[Y].z;
NotifyBack[pb, editor];
END;
NotifyBack: PROC [pb: PointBack, editor: Editor] =
{ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: pb]};
EndMove: PROC [editor: Editor] =
BEGIN
IF editor.moveSubject[X] # NIL THEN {RestoreCoords[editor.subjectPic, editor.moveSubject[X]]; editor.moveSubject[X] ← NIL};
IF editor.moveSubject[Y] # NIL THEN {RestoreCoords[editor.subjectPic, editor.moveSubject[Y]]; editor.moveSubject[Y] ← NIL};
END;
Move: PROC [editor: Editor, input: LORA] RETURNS [output: LORA] =
BEGIN
rawCoords: BiScrollers.ClientCoords = NARROW[input.rest.first];
moveX: BOOLEAN = DecodeBool[$NoShift, $Shift, input.rest.rest.first];
moveY: BOOLEAN = DecodeBool[$NoCtrl, $Ctrl, input.rest.rest.rest.first];
output ← input.rest.rest.rest.rest;
editor.session.mostRecentEditor ← editor;
IF editor.moveSubject # [editor.primary.cx, editor.primary.cy] THEN {
EndMove[editor];
editor.moveSubject ← [editor.primary.cx, editor.primary.cy];
UntableCoords[editor.subjectPic, editor.moveSubject[X]];
UntableCoords[editor.subjectPic, editor.moveSubject[Y]];
};
IF moveX THEN SetZ[editor, X, rawCoords.x];
IF moveY THEN SetZ[editor, Y, rawCoords.y];
END;
SetZ: PROC [editor: Editor, axis: Axis, z: REAL] =
BEGIN
c: Coord ← editor.moveSubject[axis];
IF c.parent # NIL AND ISTYPE[c.parent, PictureInstance] THEN {Complain[editor, IO.PutFR[" can't move in %g axis", IO.rope[axisNames[axis]]]]; RETURN};
c.z ← z; c.dz ← z - Org[c];
NotifyCoord[c, editor];
END;
NotifyCoord: PUBLIC PROC [coord: Coord, editor: Editor] =
BEGIN
ViewerOps.PaintViewer[viewer: editor.v, hint: client, clearClient: FALSE, whatChanged: coord];
END;
UntableCoords: PROC [pic: PictureDef, root: Coord] =
BEGIN
UntablePIC: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] =
{c2: Coord ← NARROW[any]; stop ← FALSE;
IF c2.axis = root.axis THEN UntableCoords[pic, c2]};
UntableCoord[pic.coordsByValue[root.axis], root];
FOR l: LORA ← root.dependents, l.rest WHILE l # NIL DO
WITH l.first SELECT FROM
c: Coord => UntableCoords[pic, c];
p: Point => FOR dl: LORA ← p.dependents, dl.rest WHILE dl # NIL DO
WITH dl.first SELECT FROM
pi: PictureInstance => pi.coords.EnumerateIncreasing[UntablePIC];
x: Line => NULL;
x: Text => NULL;
ENDCASE => ERROR;
ENDLOOP;
ENDCASE => ERROR;
ENDLOOP;
END;
UntableCoord: PROC [table: Table, coord: Coord] =
BEGIN
found: REF ANY ← table.Lookup[coord];
IF found = coord
THEN {IF table.Delete[coord] # coord THEN ERROR}
ELSE {cl: LORANARROW[found];
cl2: LORA ← Filter[cl, coord];
IF cl2.rest = NIL THEN
{IF table.Delete[coord] # cl THEN ERROR; table.Insert[cl2.first]}
ELSE IF cl2 # cl THEN
{IF table.Delete[coord] # cl THEN ERROR; table.Insert[cl2]}
};
END;
Filter: PUBLIC PROC [list: LORA, elt: REF ANY] RETURNS [filtered: LORA] =
BEGIN
IF list.first = elt THEN RETURN [list.rest];
filtered ← list;
FOR list ← list, list.rest WHILE list.rest # NIL DO
IF list.rest.first = elt THEN {list.rest ← list.rest.rest; RETURN};
ENDLOOP;
ERROR;
END;
EntableCoord: PUBLIC PROC [table: Table, coord: Coord] =
BEGIN
old: REF ANY;
old ← table.Lookup[coord];
IF old # NIL THEN WITH old SELECT FROM
c: Coord => {IF table.Delete[coord] # c THEN ERROR; table.Insert[LIST[c, coord]]};
l: LORA => l.rest ← CONS[coord, l.rest];
ENDCASE => ERROR
ELSE table.Insert[coord];
END;
RestoreCoords: PROC [pic: PictureDef, root: Coord] =
BEGIN
EntablePIC: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] =
{c2: Coord ← NARROW[any]; stop ← FALSE;
IF c2.axis = root.axis THEN RestoreCoords[pic, c2]};
EntableCoord[pic.coordsByValue[root.axis], root];
FOR l: LORA ← root.dependents, l.rest WHILE l # NIL DO
WITH l.first SELECT FROM
c: Coord => RestoreCoords[pic, c];
p: Point => FOR dl: LORA ← p.dependents, dl.rest WHILE dl # NIL DO
WITH dl.first SELECT FROM
pi: PictureInstance => pi.coords.EnumerateIncreasing[EntablePIC];
x: Line => NULL;
x: Text => NULL;
ENDCASE => ERROR;
ENDLOOP;
ENDCASE => ERROR;
ENDLOOP;
END;
StartSelect: PROC [editor: Editor, drawing: BOOLEAN, input: LORA] RETURNS [output: LORA] =
BEGIN
editor.session.ctlRV.DisplayMessage[ViewRec.clearMessagePlace];
PushSelection[editor];
output ← TrackSelect[editor, drawing, input]
END;
PushSelection: PROC [editor: Editor] =
BEGIN
editor.secondary.x ← editor.primary.x;
editor.secondary.y ← editor.primary.y;
editor.secondary.cx ← editor.primary.cx;
editor.secondary.cy ← editor.primary.cy;
editor.secondary.point ← editor.primary.point;
NotifyBack[editor.secondary, editor];
END;
TrackSelect: PROC [editor: Editor, drawing: BOOLEAN, input: LORA] RETURNS [output: LORA] =
BEGIN
rawCoords: BiScrollers.ClientCoords = NARROW[input.rest.first];
snapX: BOOLEAN = DecodeBool[$NoShift, $Shift, input.rest.rest.first];
snapY: BOOLEAN = DecodeBool[$NoCtrl, $Ctrl, input.rest.rest.rest.first];
ctl: CtlPanel ← editor.session.ctlPanel;
output ← input.rest.rest.rest.rest;
editor.session.mostRecentEditor ← editor;
IF drawing AND editor.subjectClass = expansion AND ctl.expansionAction = strand AND ctl.action = create THEN --strange snapping
SnapWire[editor, snapX, snapY, rawCoords]
ELSE IF (editor.subjectClass = expansion AND NOT drawing) OR ctl.action = delete THEN --snap to point
SnapToPoint[editor, rawCoords, editor.primary]
ELSE BEGIN
IF snapX
THEN [editor.primary.x, editor.primary.cx] ← SnapToCoord[rawCoords.x, editor.subjectPic.coordsByValue[X]]
ELSE {editor.primary.x ← rawCoords.x; editor.primary.cx ← NIL};
IF snapY
THEN [editor.primary.y, editor.primary.cy] ← SnapToCoord[rawCoords.y, editor.subjectPic.coordsByValue[Y]]
ELSE {editor.primary.y ← rawCoords.y; editor.primary.cy ← NIL};
END;
NotifyBack[editor.primary, editor];
END;
SnapWire: PROC [editor: Editor, snapX, snapY: BOOLEAN, rawCoords: BiScrollers.ClientCoords] =
BEGIN
IF editor.secondary.cx = NIL OR editor.secondary.cy = NIL THEN {Complain[editor, " no secondary coordinates!"]; RETURN};
IF snapX AND snapY THEN {
IF editor.strandGoal = NIL THEN SnapToPoint[editor, rawCoords, editor.primary]
ELSE IF editor.oldHor THEN {
editor.primary.x ← (editor.primary.cx ← editor.secondary.cx).z;
editor.primary.y ← (editor.primary.cy ← editor.strandGoal.c[Y]).z}
ELSE {
editor.primary.x ← (editor.primary.cx ← editor.strandGoal.c[X]).z;
editor.primary.y ← (editor.primary.cy ← editor.secondary.cy).z}}
ELSE IF snapX THEN {
editor.primary.x ← (editor.primary.cx ← editor.secondary.cx).z;
editor.primary.y ← rawCoords.y; editor.primary.cy ← NIL}
ELSE IF snapY THEN {
editor.primary.x ← rawCoords.x; editor.primary.cx ← NIL;
editor.primary.y ← (editor.primary.cy ← editor.secondary.cy).z}
ELSE {
editor.primary.x ← rawCoords.x; editor.primary.cx ← NIL;
editor.primary.y ← rawCoords.y; editor.primary.cy ← NIL};
END;
SnapToPoint: PROC [editor: Editor, rawCoords: BiScrollers.ClientCoords, back: PointBack] =
BEGIN
Nearest: PROC [raw: REF ANY, r: REF REAL] RETURNS [p: Point, d: REAL] =
BEGIN
Account: PROC [deps: LORA] =
BEGIN
FOR deps ← deps, deps.rest WHILE deps # NIL DO
WITH deps.first SELECT FROM
point: Point => {dx, dy, d2: REAL;
dx ← point.c[X].z - rawCoords.x;
dy ← point.c[Y].z - rawCoords.y;
d2 ← dx*dx + dy*dy;
IF p = NIL OR d2 < d THEN {p ← point; d ← d2}};
c: Coord => NULL;
ENDCASE => ERROR;
ENDLOOP;
END;
p ← NIL;
d ← 0;
WITH raw SELECT FROM
c: Coord => {IF r # NIL THEN r^ ← c.z; Account[c.dependents]};
la: LORA => {
c: Coord;
FOR l: LORA ← la, l.rest WHILE l # NIL DO
c ← NARROW[l.first];
Account[c.dependents];
ENDLOOP;
IF r # NIL THEN r^ ← c.z};
ENDCASE => ERROR;
END;
rawHi, rawLo: REF ANY;
ans: Point ← NIL;
rr^ ← rl^ ← rawCoords.x;
IF (rawHi ← editor.subjectPic.coordsByValue[X].Lookup[rr]) # NIL
THEN [ans,] ← Nearest[rawHi, NIL];
WHILE ans = NIL DO
ansLo, ansHi: Point ← NIL;
dl, dr: REAL;
rawLo ← editor.subjectPic.coordsByValue[X].LookupNextSmaller[rl];
rawHi ← editor.subjectPic.coordsByValue[X].LookupNextLarger[rr];
IF rawLo = NIL AND rawHi = NIL THEN {Complain[editor, " no points!"]; RETURN};
IF rawLo # NIL THEN [ansLo, dl] ← Nearest[rawLo, rl];
IF rawHi # NIL THEN [ansHi, dr] ← Nearest[rawHi, rr];
IF ansLo # NIL AND ansHi = NIL THEN ans ← ansLo ELSE
IF ansLo = NIL AND ansHi # NIL THEN ans ← ansHi ELSE
IF ansLo # NIL AND ansHi # NIL THEN ans ← IF dl < dr THEN ansLo ELSE ansHi;
ENDLOOP;
back.x ← (back.cx ← ans.c[X]).z;
back.y ← (back.cy ← ans.c[Y]).z;
END;
DecodeBool: PROC [false, true: ATOM, any: REF ANY] RETURNS [BOOL] = {
IF any = false THEN RETURN [FALSE];
IF any = true THEN RETURN [TRUE];
ERROR};
rl: REF REALNEW [REAL ← 86];
rr: REF REALNEW [REAL ← 47];
SnapToCoord: PROC [raw: REAL, table: Table] RETURNS [nearest: REAL, coord: Coord] =
BEGIN
l, m, h: REF ANY;
low, high: Coord;
rr^ ← raw;
[l, m, h] ← table.Lookup3[rr];
IF m # NIL THEN {coord ← PikCoord[m]; RETURN [coord.z, coord]} ELSE
IF l = NIL AND h = NIL THEN RETURN [0, NIL];
low ← PikCoord[l];
high ← PikCoord[h];
IF low = NIL THEN coord ← high ELSE
IF high = NIL THEN coord ← low ELSE
IF raw-low.z < high.z-raw THEN coord ← low
ELSE coord ← high;
nearest ← coord.z;
END;
FinalSelect: PROC [editor: Editor, drawing: BOOLEAN, input: LORA] RETURNS [output: LORA] =
BEGIN
output ← TrackSelect[editor, drawing, input];
IF editor.primary.cx = NIL THEN editor.primary.cx ← NewCoord[X, editor.primary.x, editor.subjectPic];
IF editor.primary.cy = NIL THEN editor.primary.cy ← NewCoord[Y, editor.primary.y, editor.subjectPic];
editor.primary.point ← MakePoint[editor.subjectPic, [editor.primary.cx, editor.primary.cy]];
IF drawing THEN Draw[editor];
InputFocus.SetInputFocus[self: editor.v];
END;
Draw: PROC [editor: Editor] =
BEGIN
SELECT editor.session.ctlPanel.action FROM
create => SELECT editor.subjectClass FROM
icon => SELECT editor.session.ctlPanel.iconAction FROM
line => [] ← NewLine[editor.subjectPic, editor.secondary.point, editor.primary.point];
text => NewText[editor.subjectPic, editor.primary.point, editor.session.ctlPanel.name];
instance => NewInstance[editor.subjectPic, editor.primary.point, editor.session.ctlPanel.cellType, editor.session.ctlPanel.icon];
ENDCASE => ERROR;
expansion => SELECT editor.session.ctlPanel.expansionAction FROM
component => NewComponent[editor];
port => NewPort[editor];
strand => NewStrand[editor, FALSE];
ENDCASE => ERROR;
ENDCASE => ERROR;
delete => SELECT editor.subjectClass FROM
icon => SELECT editor.session.ctlPanel.iconAction FROM
line => [] ← DeleteLine[editor.subjectPic, editor.secondary.point, editor.primary.point];
text => DeleteText[editor.subjectPic, editor.primary.point];
instance => DeleteInstance[editor.subjectPic, editor.primary.point, NIL];
ENDCASE => ERROR;
expansion => SELECT editor.session.ctlPanel.expansionAction FROM
component => DeleteComponent[editor];
port => DeletePort[editor];
strand => DeleteStrand[editor];
ENDCASE => ERROR;
ENDCASE => ERROR;
ENDCASE => ERROR;
IF editor.subjectClass = expansion THEN CheckObjects[editor.subjectPic];
IF editor.primary.point # NIL AND editor.primary.point.deleted THEN editor.primary.point ← NIL;
IF editor.secondary.point # NIL AND editor.secondary.point.deleted THEN editor.secondary.point ← NIL;
END;
CheckObjects: PROC [pic: PictureDef] =
{Check: PROC [any: REF ANY] RETURNS [stop: BOOLEAN] =
{stop ← FALSE;
WITH any SELECT FROM
l: Line => IF NOT Member[l, l.net.stuff] THEN ERROR;
t: Text => NULL;
pi: PictureInstance => NULL;
ENDCASE => ERROR};
pic.objects.EnumerateIncreasing[Check]};
Member: PROC [elt: REF ANY, list: LORA] RETURNS [found: BOOLEAN] =
{found ← FALSE;
FOR list ← list, list.rest WHILE list # NIL DO
IF list.first = elt THEN RETURN [TRUE];
ENDLOOP;
found ← FALSE};
Start: PROC =
BEGIN
Graphics.MoveTo[primaryPath, -5, 5, TRUE];
Graphics.LineTo[primaryPath, 5, -5];
Graphics.MoveTo[primaryPath, -5, -5, FALSE];
Graphics.LineTo[primaryPath, 5, 5];
END;
Start[];
END.