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:
LORA ←
NARROW[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 REAL ← NEW [REAL ← 86];
rr: REF REAL ← NEW [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.