GEditLineImpl.mesa; Edited by McGregor on December 10, 1982 1:55 pm
DIRECTORY
GEditClasses,
GEditIO,
GEditViewer,
Graphics USING [DrawTo, SetCP];
GEditLineImpl: PROGRAM
IMPORTS GEditIO, GEditViewer, Graphics =
BEGIN OPEN GEditViewer, GEditClasses;
Line: TYPE = REF LineRec ;
LineRec: TYPE = RECORD [
x1, x2: INTEGER ← 0,
y1, y2: INTEGER ← 0
] ;
LineNewProc: NewProc = BEGIN
[self: Object, x, y: INTEGER]
line: Line;
self.info ← NEW[LineRec];
line ← NARROW[self.info];
line.x1 ← x; line.y1 ← y;
line.x2 ← x+60; line.y2 ← y+1;
END ;
LineDeleteProc: DeleteProc = BEGIN
[self: Object]
This doesn't do anything for now...
END ;
LineMoveProc: MoveProc = BEGIN
[self: Object, parent: ViewerClasses.Viewer, controlPoint: ControlPoint, grain: SelectionGrain, dx, dy: INTEGER]
lineInfo: Line ~ NARROW[self.info];
BEGIN OPEN lineInfo;
IF grain=point THEN SELECT controlPoint FROM
0 => {x1 ← x1+dx; y1 ← y1+dy};
1 => {x2 ← x2+dx; y2 ← y2+dy};
ENDCASE
ELSE BEGIN
x1 ← x1+dx;
x2 ← x2+dx;
y1 ← y1+dy;
y2 ← y2+dy;
END;
END;
END ;
LineSelectHighlightProc: SelectHighlightProc = BEGIN
[self: Object, context: Graphics.Context, controlPoint: ControlPoint, grain: SelectionGrain]
lineInfo: Line ~ NARROW[self.info];
DrawControlPoint[context, lineInfo.x1, lineInfo.y1,
IF grain=object OR controlPoint#0 THEN object ELSE point];
DrawControlPoint[context, lineInfo.x2, lineInfo.y2,
IF grain=object OR controlPoint#1 THEN object ELSE point];
END ;
LinePaintProc: PaintProc = BEGIN
[self: Object, context: Graphics.Context]
lineInfo: Line ~ NARROW[self.info];
Graphics.SetCP[context, lineInfo.x1, lineInfo.y1];
Graphics.DrawTo[context, lineInfo.x2, lineInfo.y2];
END;
LineResolveProc: 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;
lineInfo: Line ~ NARROW[self.info];
d0: INTEGER ~ Distance[lineInfo.x1, lineInfo.y1];
d1: INTEGER ~ Distance[lineInfo.x2, lineInfo.y2];
IF d0>d1 THEN RETURN[d1, 1, lineInfo.x2, lineInfo.y2] ELSE RETURN[d0, 0, lineInfo.x1, lineInfo.y1];
END ;
LineNextProc: NextProc = {RETURN[(current+1) MOD 2]};
Line rope format is:
<x1>, <x2>, <y1>, <y2>
all integers
LineReadProc: ReadProc = BEGIN
PROC [n: RefOtherNode, specs: Rope.ROPE]
OPEN GEditIO;
line: Line ~ NEW[LineRec];
offset: INT ← 0;
[line.x1, offset] ← GetInteger[specs, offset];
[line.x2, offset] ← GetInteger[specs, offset];
[line.y1, offset] ← GetInteger[specs, offset];
[line.y2, offset] ← GetInteger[specs, offset];
n.info ← line;
END ;
LineWriteProc: WriteProc = BEGIN
PROC [n: RefOtherNode] RETURNS [specs: Rope.ROPE]
OPEN GEditIO;
line: Line ~ NARROW[n.info];
specs ← PutInteger[NIL, line.x1];
specs ← PutInteger[specs, line.x2];
specs ← PutInteger[specs, line.y1];
specs ← PutInteger[specs, line.y2];
END ;
LineCopyProc: CopyProc = BEGIN
PROC [old: RefOtherNode] RETURNS [newinfo: REF ANY]
OPEN GEditIO;
line: Line ~ NARROW[old.info];
newinfo ← NEW[LineRec ← line^];
END ;
LineClassRec: ClassRec ← [
newProc: LineNewProc,
deleteProc: LineDeleteProc,
moveProc: LineMoveProc,
selectProc: LineSelectHighlightProc,
paintProc: LinePaintProc,
resolveProc: LineResolveProc,
nextProc: LineNextProc,
readProc: LineReadProc,
writeProc: LineWriteProc,
copyProc: LineCopyProc
];
[] ← RegisterClass[$Line, LineClassRec];
END.