CDWireAndSelectCommands.mesa (part of Chipndale)
by Christian Jacobi June 29, 1983 4:44 pm
last edited Christian Jacobi February 3, 1984 7:19 pm
DIRECTORY
CD,
CDApplications,
CDCommands,
CDCommandOps,
CDOps,
CDOrient,
CDRects,
CDSequencer,
TerminalIO,
CDInline;
CDWireAndSelectCommands:
CEDAR
PROGRAM
IMPORTS CDApplications, CDCommandOps, CDCommands, CDOps, CDSequencer, TerminalIO, CDRects, CDInline =
BEGIN
AddARect:
PROC[design:
CD.Design, r:
CD.DesignRect, l:
CD.Level] =
BEGIN
ob: CD.ObPtr;
sz: CD.DesignPosition ← CDInline.SizeOfRect[r];
orient: CD.Orientation ← CDOrient.original;
IF sz.y<sz.x
THEN {
w: CD.DesignNumber ← sz.x;
sz.x ← sz.y;
sz.y ← w;
orient ← CDOrient.rotate90
};
IF sz.x<=0 THEN {TerminalIO.WriteRope["Empty object not included\n"]; RETURN};
ob ← CDRects.CreateRect[sz, l];
CDOps.AddAnObject[
design: design,
ob: ob,
location: CDInline.BaseOfRect[r],
orientation: orient]
END;
SelectExclusive:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Select pointed"];
CDCommands.DeselectAll[comm.design];
CDCommands.Select[comm.design, comm.pos];
TerminalIO.WriteLn[];
END;
ReSelect:
PROC [design:
CD.Design, pos:
CD.DesignPosition, verbose:
BOOL←
TRUE]
RETURNS [done:
BOOL←TRUE] =
BEGIN
Deselect:
PROC[a:
CD.ApplicationPtr] =
INLINE BEGIN
IF a.selected
THEN {
a.selected ← FALSE;
CDOps.DelayedRedraw[design, CDApplications.ARectO[a], TRUE]
}
END;
DeselectList:
PROC[list:
CD.ApplicationList] =
BEGIN
FOR w:
CD.ApplicationList ← list, w.rest
WHILE w#
NIL
DO
Deselect[w.first]
ENDLOOP
END;
ap: CD.ApplicationPtr ← NIL; --any application where pos points to
FOR w:
CD.ApplicationList ← CDOps.AppList[design], w.rest
WHILE w#
NIL
DO
IF CDApplications.PointToO[pos, w.first]
AND CDApplications.PointToI[pos, w.first]
THEN {
--hit
IF w.first.selected
THEN {
DeselectList[w.rest];
CDOps.ReOrderApplication[design, w.first];
IF verbose THEN CDCommandOps.WriteInfo[w.first];
RETURN
}
ELSE IF ap=NIL THEN ap ← w.first
}
ELSE Deselect[w.first]
ENDLOOP;
--if a selected ap is pointed we already did return
IF ap#
NIL
THEN {
ap.selected ← TRUE;
CDOps.ReOrderApplication[design, ap];
CDOps.DelayedRedraw[design, CDApplications.ARectO[ap], FALSE];
IF verbose THEN CDCommandOps.WriteInfo[ap]
}
ELSE {
done ← FALSE;
IF verbose THEN TerminalIO.WriteRope[" (no object)"];
}
END;
RectDist:
PROC[pos:
CD.DesignPosition, r:
CD.Rect]
RETURNS [
CD.DesignNumber] =
--Distance between a point and a rectangle
BEGIN
RETURN [
MAX[
(IF pos.x<r.x1 THEN (r.x1-pos.x) ELSE IF pos.x>r.x2 THEN (pos.x-r.x2) ELSE 0),
(IF pos.y<r.y1 THEN (r.y1-pos.y) ELSE IF pos.y>r.y2 THEN (pos.y-r.y2) ELSE 0)
]]
END;
CloseReSelect:
PROC [design:
CD.Design, pos:
CD.DesignPosition, verbose:
BOOL←
TRUE, dist:
CD.DesignNumber] =
BEGIN
IF ~ReSelect[design, pos, verbose]
THEN {
ap: CD.ApplicationPtr ← NIL;
FOR w:
CD.ApplicationList ← CDOps.AppList[design], w.rest
WHILE w#
NIL
DO
d: CD.DesignNumber = RectDist[pos, CDApplications.ARectI[w.first]];
IF d<dist THEN {ap ← w.first; dist ← d}
ENDLOOP;
IF ap#
NIL
THEN {
ap.selected ← TRUE;
CDOps.DelayedRedraw[design, CDApplications.ARectO[ap], FALSE];
IF verbose
THEN {
TerminalIO.WriteRope["found close object"];
CDCommandOps.WriteInfo[ap]
}
}
}
END;
ReSelectExclusive:
PROC [comm: CDSequencer.Command] =
--select pointed application exclusive;
--(but dont select an other application if the pointed one is already the right one)
BEGIN
TerminalIO.WriteRope["(Re)Select pointed"];
[] ← ReSelect[comm.design, comm.pos];
TerminalIO.WriteLn[];
END;
CloseReSelectCommand:
PROC [comm: CDSequencer.Command] =
--select pointed application exclusive;
--(but dont select an other application if the pointed one is already the right one)
--if there is none, select closest
BEGIN
TerminalIO.WriteRope["Select (most close)"];
[] ← CloseReSelect[comm.design, comm.pos, TRUE, 50];
TerminalIO.WriteLn[];
END;
AddRect:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Add rect\n"];
AddARect[comm.design, CDInline.ToRect[comm.sPos, comm.pos], comm.l];
END;
AddWire:
PROC [comm: CDSequencer.Command] =
--uses pos, sPos, n (for width), b (for firstHorizontal), l (for level)
BEGIN
InternalAddWire[comm: comm, firstOnly: FALSE]
END;
ContinueWire:
PROC [comm: CDSequencer.Command] =
BEGIN
InternalAddWire[comm: comm, firstOnly: TRUE]
END;
InternalAddWire:
PROC [comm: CDSequencer.Command, firstOnly:
BOOL←
FALSE] =
--this procedure knows EXACTLY the algorithm used for showing
--temporary wires in the cursor part
BEGIN
start: CD.DesignPosition ← comm.sPos;
stop: CD.DesignPosition ← comm.pos;
wireWidth: CD.DesignNumber ← comm.n;
IF wireWidth=0 THEN {AddRect[comm]; RETURN};
TerminalIO.WriteRope["Add wire\n"];
IF
--firstHorizontal-- comm.b
THEN {
IF stop.x<=start.x
AND stop.x>=start.x-wireWidth
AND (stop.y<start.y OR stop.y>start.y+wireWidth) THEN { --crazy vertical wire
IF
ABS[start.y-stop.y]<
CD.lambda
THEN
{TerminalIO.WriteRope[" Empty Wire not added\n"]; RETURN};
stop.x ← start.x+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l];
RETURN
};
--not only crazy vertical
IF stop.y>=start.y
AND stop.y<=start.y+wireWidth
THEN
{
--horizontal wire
stop.y ← start.y+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l]
}
ELSE {
--L shaped (firsthorizontal)
IF start.x<=stop.x THEN {stop.x ← stop.x+wireWidth}
ELSE {t: CD.Number=stop.x; stop.x ← start.x; start.x ← t};
stop.y ← start.y+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l];
IF firstOnly THEN RETURN;
start.x ← comm.pos.x; stop.y ← comm.pos.y; stop.x ← start.x+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l];
}
}
ELSE {
-- NOT firstHorizontalVC --
IF stop.y<=start.y
AND stop.y>=start.y-wireWidth
AND (stop.x<start.x OR stop.x>start.x+wireWidth) THEN { --crazy horizontal wire
IF
ABS[stop.x-start.x]<
CD.lambda
THEN
{TerminalIO.WriteRope[" Empty Wire not added\n"]; RETURN};
stop.y ← start.y+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l];
RETURN
};
-- not only crazy horizontal
IF stop.x>=start.x
AND stop.x<=start.x+wireWidth
THEN
{
--vertical wire
stop.x ← start.x+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l]
}
ELSE {
--L shaped (firstVertical)
IF start.y<=stop.y THEN {stop.y ← stop.y+wireWidth}
ELSE {t: CD.Number = stop.y; stop.y ← start.y; start.y ← t};
stop.x ← start.x+wireWidth;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l];
IF firstOnly THEN RETURN;
start.y ← comm.pos.y; stop.y ← start.y+wireWidth; stop.x ← comm.pos.x;
AddARect[comm.design, CDInline.ToRect[start, stop], comm.l];
}
}
END;
DeselectPointed:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Remove selection\n"];
CDCommands.DeSelect[comm.design, comm.pos]
END;
DeSelectLast:
PROC [design:
CD.Design, pos:
CD.DesignPosition, usePos:
BOOL←
TRUE]
RETURNS [done:
BOOL←
FALSE] =
BEGIN
sel: CD.ApplicationPtr ← NIL;
FOR w:
CD.ApplicationList ← CDOps.AppList[design], w.rest
WHILE w#
NIL
DO
IF w.first.selected
THEN {
IF ~usePos OR CDApplications.PointToI[pos, w.first] THEN sel ← w.first;
};
ENDLOOP;
IF sel#
NIL
THEN {
sel.selected ← FALSE;
done ← TRUE;
CDOps.DelayedRedraw[design, CDApplications.ARectO[sel]];
}
END;
DeselectLastSelected:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Remove selection\n"];
[] ← DeSelectLast[comm.design, comm.pos, TRUE]
END;
AddSelection:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Add selection "];
CDCommands.Select[comm.design, comm.pos];
TerminalIO.WriteLn[];
END;
DeselectAll:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Deselect all\n"];
CDCommands.DeselectAll[comm.design]
END;
DeleteSelected:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Delete selected\n"];
CDCommands.DeleteSelected[comm.design]
END;
DeletePointed:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Delete pointed\n"];
CDCommands.DeletePointed[comm.design, comm.pos]
END;
Undelete:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Undelete\n"];
CDCommands.Undelete[comm.design]
END;
SelectAll:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Select all\n"];
CDCommands.SelectAll[comm.design]
END;
AreaAddSelect:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Inclusive select area\n"];
CDCommands.AreaSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos]]
END;
AAddSelect:
PROC [comm: CDSequencer.Command] =
--Auto select area or pointed
BEGIN
IF comm.pos=comm.sPos
THEN {
TerminalIO.WriteRope["select inclusive "];
CDCommands.Select[comm.design, comm.pos];
TerminalIO.WriteLn[];
}
ELSE {
TerminalIO.WriteRope["select inclusive\n"];
CDCommands.AreaSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos]]
}
END;
AreaAddSelectTouching:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["select inclusive touching\n"];
CDCommands.AreaSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos], TRUE]
END;
AreaOnlySelect:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Exclusive select area\n"];
CDCommands.DeselectAll[comm.design];
CDCommands.AreaSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos]]
END;
ADeSelect:
PROC [comm: CDSequencer.Command] =
--Auto deselect area or pointed
BEGIN
TerminalIO.WriteRope["deselect\n"];
IF comm.pos=comm.sPos THEN CDCommands.DeSelect[comm.design, comm.pos]
ELSE CDCommands.AreaDeSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos]]
END;
AreaDeSelect:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Deselect area\n"];
CDCommands.AreaDeSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos]]
END;
AreaDeSelectTouching:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Deselect touching\n"];
CDCommands.AreaDeSelect[comm.design, CDInline.ToRect[comm.pos, comm.sPos], TRUE]
END;
AbortCommand:
PROC [comm: CDSequencer.Command] =
BEGIN
TerminalIO.WriteRope["Try to abort current command\n"];
CDSequencer.AbortTheCommand[comm.design]
END;
Impl:
PROC [] =
BEGIN
CDSequencer.ImplementCommand[$AbortCommand, AbortCommand,, dontQueue];
CDSequencer.ImplementCommand[$DrawRect, AddRect];
CDSequencer.ImplementCommand[$DrawWire, AddWire];
CDSequencer.ImplementCommand[$ContinueWire, ContinueWire];
CDSequencer.ImplementCommand[$DeleteS, DeleteSelected];
CDSequencer.ImplementCommand[$DeleteP, DeletePointed];
CDSequencer.ImplementCommand[$Undel, Undelete];
CDSequencer.ImplementCommand[$OnlySelectP, SelectExclusive,, doQueue];
CDSequencer.ImplementCommand[$ReSelectOnlyP, ReSelectExclusive,, doQueue];
CDSequencer.ImplementCommand[$CloseReSelectOnlyP, CloseReSelectCommand,, doQueue];
CDSequencer.ImplementCommand[$AddSelectP, AddSelection,, doQueue];
CDSequencer.ImplementCommand[$DeSelectLP, DeselectLastSelected,, doQueue];
CDSequencer.ImplementCommand[$DeSelectFP, DeselectPointed,, doQueue];
--oldy--CDSequencer.ImplementCommand[$DeSelectP, DeselectPointed,, doQueue];
CDSequencer.ImplementCommand[$DeSelectS, DeselectAll,, doQueue];
CDSequencer.ImplementCommand[$SelectAll, SelectAll,, doQueue];
CDSequencer.ImplementCommand[$AreaOnlySelect, AreaOnlySelect,, doQueue];
CDSequencer.ImplementCommand[$AreaAddSelect, AreaAddSelect,, doQueue];
CDSequencer.ImplementCommand[$AreaAddSelectTouching, AreaAddSelectTouching,, doQueue];
CDSequencer.ImplementCommand[$AAddSelect, AAddSelect,, doQueue];
CDSequencer.ImplementCommand[$AreaDeSelect, AreaDeSelect,, doQueue];
CDSequencer.ImplementCommand[$AreaDeSelectTouching, AreaDeSelectTouching,, doQueue];
CDSequencer.ImplementCommand[$ADeSelect, ADeSelect,, doQueue];
END;
Impl[];
END.