<> 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]>> <> 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]}; <> <<, , , >> <> LineReadProc: ReadProc = BEGIN <> 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 <> 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 <> 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.