<> DIRECTORY GEditClasses, GEditIO, GEditViewer, Rope USING [ROPE], ViewerClasses USING [Viewer], ViewerOps USING [CreateViewer, DestroyViewer, MoveViewer], ViewerTools USING [GetTiogaContents, MakeNewTextViewer, SetTiogaContents, TiogaContentsRec]; GEditTextImpl: PROGRAM IMPORTS GEditIO, GEditViewer, ViewerOps, ViewerTools EXPORTS GEditIO = BEGIN OPEN GEditViewer, GEditClasses; Text: TYPE = REF TextRec ; TextRec: TYPE = RECORD [ viewer: ViewerClasses.Viewer ] ; TextNewProc: NewProc = BEGIN <<[self: Object, x, y: INTEGER, parent: ViewerClasses.Viewer]>> initialData: Rope.ROPE ~ "Text"; viewer: ViewerClasses.Viewer ~ ViewerOps.CreateViewer[$Text, [parent: parent, wx: x, wy: y, wh: 15, ww: 80, scrollable: FALSE, data: initialData]]; textData: Text; textData _ self.info _ NEW[TextRec]; textData.viewer _ viewer; END ; TextDeleteProc: DeleteProc = BEGIN <<[self: Object]>> textData: Text _ NARROW[self.info]; ViewerOps.DestroyViewer[textData.viewer, FALSE]; END ; TextMoveProc: MoveProc = BEGIN <<[self: Object, parent: ViewerClasses.Viewer, controlPoint: ControlPoint, grain: SelectionGrain, dx, dy: INTEGER]>> text: Text ~ NARROW[self.info]; textViewer: ViewerClasses.Viewer ~ text.viewer; BEGIN OPEN textViewer; IF grain=point THEN SELECT controlPoint FROM 0 => BEGIN ViewerOps.MoveViewer[textViewer, wx+dx, wy+dy, ww-dx, wh-dy, FALSE]; END; 1 => BEGIN ViewerOps.MoveViewer[textViewer, wx+dx, wy, ww-dx, wh+dy, FALSE]; END; 2 => BEGIN ViewerOps.MoveViewer[textViewer, wx, wy+dy, ww+dx, wh-dy, FALSE]; END; 3 => BEGIN ViewerOps.MoveViewer[textViewer, wx, wy, ww+dx, wh+dy, FALSE]; END; ENDCASE ELSE ViewerOps.MoveViewer[textViewer, wx+dx, wy+dy, ww, wh, FALSE]; END; END ; TextSelectHighlightProc: SelectHighlightProc = BEGIN <<[self: Object, context: Graphics.Context, controlPoint: ControlPoint, grain: SelectionGrain]>> text: Text ~ NARROW[self.info]; textViewer: ViewerClasses.Viewer ~ text.viewer; DrawControlPoint[context, textViewer.wx, textViewer.wy, IF grain=object OR controlPoint#0 THEN object ELSE point]; DrawControlPoint[context, textViewer.wx, textViewer.wy+textViewer.wh, IF grain=object OR controlPoint#1 THEN object ELSE point]; DrawControlPoint[context, textViewer.wx+textViewer.ww, textViewer.wy, IF grain=object OR controlPoint#2 THEN object ELSE point]; DrawControlPoint[context, textViewer.wx+textViewer.ww, textViewer.wy+textViewer.wh, IF grain=object OR controlPoint#3 THEN object ELSE point]; END ; TextPaintProc: PaintProc = BEGIN <<[self: Object, context: Graphics.Context]>> <> END; TextResolveProc: 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; text: Text ~ NARROW[self.info]; viewer: ViewerClasses.Viewer ~ text.viewer; d0: INTEGER ~ Distance[viewer.wx, viewer.wy]; d1: INTEGER ~ Distance[viewer.wx, viewer.wy+viewer.wh]; d2: INTEGER ~ Distance[viewer.wx+viewer.ww, viewer.wy]; d3: INTEGER ~ Distance[viewer.wx+viewer.ww, viewer.wy+viewer.wh]; affinity _ MIN[MIN[d0, d1], MIN[d2, d3]]; IF d0=affinity THEN RETURN[affinity, 0, viewer.wx, viewer.wy] ELSE IF d1=affinity THEN RETURN[affinity, 1, viewer.wx, viewer.wy+viewer.wh] ELSE IF d2=affinity THEN RETURN[affinity, 2, viewer.wx+viewer.ww, viewer.wy] ELSE RETURN[affinity, 3, viewer.wx+viewer.ww, viewer.wy+viewer.wh]; END ; TextInputProc: InputProc = BEGIN SELECT input FROM $Edge => BEGIN text: Text ~ NARROW[self.info]; viewer: ViewerClasses.Viewer ~ text.viewer; viewer.border _ NOT viewer.border; ViewerOps.MoveViewer[viewer, viewer.wx, viewer.wy, viewer.ww, viewer.wh]; END; ENDCASE; RETURN[FALSE, FALSE]; END; TextNextProc: NextProc = {RETURN[(current+(IF backwards THEN 3 ELSE 1)) MOD 4]}; <> <<, , , , , >> <> <> <> MyParent: PUBLIC SIGNAL RETURNS [viewer: ViewerClasses.Viewer] = CODE; -- used to find out what parent viewer in which to construct an embedded text viewer. Caught by GEditInitProc. TextReadProc: ReadProc = BEGIN <> OPEN GEditIO; text: Text ~ NEW[TextRec]; parent: ViewerClasses.Viewer _ SIGNAL MyParent; wx, wy, ww, wh: INTEGER; border: BOOL; contents: Rope.ROPE; offset: INT _ 0; [wx, offset] _ GetInteger[specs, offset]; [wy, offset] _ GetInteger[specs, offset]; [ww, offset] _ GetInteger[specs, offset]; [wh, offset] _ GetInteger[specs, offset]; [border, offset] _ GetBoolean[specs, offset]; [contents, offset] _ GetRope[specs, offset]; text.viewer _ ViewerTools.MakeNewTextViewer[[wx: wx, wy: wy, ww: ww, wh: wh, border: border, parent: parent, scrollable: FALSE], FALSE]; ViewerTools.SetTiogaContents[text.viewer, NEW[ViewerTools.TiogaContentsRec _ [contents, NIL]]]; n.info _ text; END ; TextWriteProc: WriteProc = BEGIN <> OPEN GEditIO; text: Text ~ NARROW[n.info]; viewer: ViewerClasses.Viewer ~ text.viewer; specs _ PutInteger[NIL, viewer.wx]; specs _ PutInteger[specs, viewer.wy]; specs _ PutInteger[specs, viewer.ww]; specs _ PutInteger[specs, viewer.wh]; specs _ PutBoolean[specs, viewer.border]; specs _ GEditIO.PutTiogaContents[specs, ViewerTools.GetTiogaContents[viewer]]; END ; TextCopyProc: CopyProc = BEGIN <> OPEN GEditIO; text: Text ~ NARROW[old.info]; oldViewer: ViewerClasses.Viewer ~ text.viewer; newViewer: ViewerClasses.Viewer ~ ViewerTools.MakeNewTextViewer[[wx: oldViewer.wx, wy: oldViewer.wy, ww: oldViewer.ww, wh: oldViewer.wh, border: oldViewer.border, parent: oldViewer.parent, scrollable: oldViewer.scrollable], FALSE]; newinfo _ NEW[TextRec _ [newViewer]]; ViewerTools.SetTiogaContents[newViewer, ViewerTools.GetTiogaContents[oldViewer]]; END ; TextClassRec: ClassRec _ [ newProc: TextNewProc, deleteProc: TextDeleteProc, moveProc: TextMoveProc, selectProc: TextSelectHighlightProc, paintProc: TextPaintProc, resolveProc: TextResolveProc, nextProc: TextNextProc, inputProc: TextInputProc, readProc: TextReadProc, writeProc: TextWriteProc, copyProc: TextCopyProc ]; [] _ RegisterClass[$Text, TextClassRec]; END.