GEditRectangleImpl.mesa; Edited by McGregor on December 10, 1982 2:29 pm
DIRECTORY
GEditClasses,
GEditIO,
GEditViewer,
Graphics USING [black, Color, DrawBox, SetColor, white];
GEditRectangleImpl: PROGRAM
IMPORTS GEditIO, GEditViewer, Graphics =
BEGIN OPEN GEditViewer, GEditClasses;
Rectangle: TYPE = REF RectangleRec ;
RectangleRec: TYPE = RECORD [
x1, x2: INTEGER ← 0,
y1, y2: INTEGER ← 0,
color: Graphics.Color ← Graphics.black -- ideally this would come from the style
] ;
RectangleNewProc: NewProc = BEGIN
[self: Object, x, y: INTEGER]
rectangle: Rectangle;
self.info ← NEW[RectangleRec];
rectangle ← NARROW[self.info];
rectangle.x1 ← x; rectangle.y1 ← y;
rectangle.x2 ← x+20; rectangle.y2 ← y+40;
rectangle.color ← Graphics.black;
END ;
RectangleDeleteProc: DeleteProc = BEGIN
[self: Object]
This doesn't do anything for now...
END ;
RectangleMoveProc: MoveProc = BEGIN
[self: Object, parent: ViewerClasses.Viewer, controlPoint: ControlPoint, grain: SelectionGrain, dx, dy: INTEGER]
recInfo: Rectangle ~ NARROW[self.info];
BEGIN OPEN recInfo;
IF grain=point THEN SELECT controlPoint FROM
0 => {x1 ← x1+dx; y1 ← y1+dy};
1 => {x1 ← x1+dx; y2 ← y2+dy};
2 => {x2 ← x2+dx; y1 ← y1+dy};
3 => {x2 ← x2+dx; y2 ← y2+dy};
ENDCASE
ELSE BEGIN
x1 ← x1+dx;
x2 ← x2+dx;
y1 ← y1+dy;
y2 ← y2+dy;
END;
END;
END ;
RectangleSelectHighlightProc: SelectHighlightProc = BEGIN
[self: Object, context: Graphics.Context, controlPoint: ControlPoint, grain: SelectionGrain]
recInfo: Rectangle ~ NARROW[self.info];
DrawControlPoint[context, recInfo.x1, recInfo.y1,
IF grain=object OR controlPoint#0 THEN object ELSE point];
DrawControlPoint[context, recInfo.x1, recInfo.y2,
IF grain=object OR controlPoint#1 THEN object ELSE point];
DrawControlPoint[context, recInfo.x2, recInfo.y1,
IF grain=object OR controlPoint#2 THEN object ELSE point];
DrawControlPoint[context, recInfo.x2, recInfo.y2,
IF grain=object OR controlPoint#3 THEN object ELSE point];
END ;
RectanglePaintProc: PaintProc = BEGIN
[self: Object, context: Graphics.Context]
recInfo: Rectangle ~ NARROW[self.info];
Graphics.SetColor[context, recInfo.color];
Graphics.DrawBox[context, [recInfo.x1, recInfo.y1, recInfo.x2, recInfo.y2]];
END;
RectangleResolveProc: ResolveProc = BEGIN
[self: Object, x, y: INTEGER] RETURNS [affinity: INTEGER, controlPoint: ControlPoint, tx, ty: INTEGER]
Distance: PROC [objX, objY: INTEGER] RETURNS [INTEGER] = INLINE BEGIN
squareRootOfLastIntegerOverTwo: INTEGER ~ 128;
dx: INTEGER ~ x-objX;
dy: INTEGER ~ y-objY;
IF ABS[dx] >= squareRootOfLastIntegerOverTwo OR ABS[dy] >= squareRootOfLastIntegerOverTwo THEN RETURN [LAST[INTEGER]];
RETURN[(dx*dx) + (dy*dy)];
END;
recInfo: Rectangle ~ NARROW[self.info];
d0: INTEGER ~ Distance[recInfo.x1, recInfo.y1];
d1: INTEGER ~ Distance[recInfo.x1, recInfo.y2];
d2: INTEGER ~ Distance[recInfo.x2, recInfo.y1];
d3: INTEGER ~ Distance[recInfo.x2, recInfo.y2];
affinity ← MIN[MIN[d0, d1], MIN[d2, d3]];
IF d0=affinity THEN RETURN[affinity, 0, recInfo.x1, recInfo.y1]
ELSE IF d1=affinity THEN RETURN[affinity, 1, recInfo.x1, recInfo.y2]
ELSE IF d2=affinity THEN RETURN[affinity, 2, recInfo.x2, recInfo.y1]
ELSE RETURN[affinity, 3, recInfo.x2, recInfo.y2];
END ;
RectangleInputProc: InputProc = BEGIN
rec: Rectangle ~ NARROW[self.info];
SELECT input FROM
$Black  => rec.color ← Graphics.black;
$Grey  => rec.color ← [rgb, 245B, 245B, 245B]; -- grey hack
$White  => rec.color ← Graphics.white;
ENDCASE;
RETURN[FALSE, TRUE];
END;
RectangleNextProc: NextProc = {RETURN[(current+(IF backwards THEN 3 ELSE 1)) MOD 4]};
Rectangle rope format is:
<x1>, <x2>, <y1>, <y2>, <color>
all integers except color is a loopholed INT
RectangleReadProc: ReadProc = BEGIN
PROC [n: RefOtherNode, specs: Rope.ROPE]
OPEN GEditIO;
rec: Rectangle ~ NEW[RectangleRec];
offset: INT ← 0;
temp: INT;
[rec.x1, offset] ← GetInteger[specs, offset];
[rec.x2, offset] ← GetInteger[specs, offset];
[rec.y1, offset] ← GetInteger[specs, offset];
[rec.y2, offset] ← GetInteger[specs, offset];
[temp, offset] ← GetInt[specs, offset];
rec.color ← LOOPHOLE[temp];
n.info ← rec;
END ;
RectangleWriteProc: WriteProc = BEGIN
PROC [n: RefOtherNode] RETURNS [specs: Rope.ROPE]
OPEN GEditIO;
rec: Rectangle ~ NARROW[n.info];
specs ← PutInteger[NIL, rec.x1];
specs ← PutInteger[specs, rec.x2];
specs ← PutInteger[specs, rec.y1];
specs ← PutInteger[specs, rec.y2];
specs ← PutInt[specs, LOOPHOLE[rec.color]];
END ;
RectangleCopyProc: CopyProc = BEGIN
PROC [old: RefOtherNode] RETURNS [newinfo: REF ANY]
OPEN GEditIO;
rec: Rectangle ~ NARROW[old.info];
newinfo ← NEW[RectangleRec ← rec^];
END ;
RectangleClassRec: ClassRec ← [
newProc: RectangleNewProc,
deleteProc: RectangleDeleteProc,
moveProc: RectangleMoveProc,
selectProc: RectangleSelectHighlightProc,
paintProc: RectanglePaintProc,
resolveProc: RectangleResolveProc,
inputProc: RectangleInputProc,
nextProc: RectangleNextProc,
readProc: RectangleReadProc,
writeProc: RectangleWriteProc,
copyProc: RectangleCopyProc
];
[] ← RegisterClass[$Rectangle, RectangleClassRec];
END.