GEditTextImpl.mesa; Edited by McGregor on December 10, 1982 2:05 pm
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]
nop since handled by Viewers
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]};
Text rope format is:
<wx>, <wy>, <ww>, <wh>, <border>, <contents>
wx, wy, ww, wh integers
border is {T, F}
contents is PutGet.ToRope of the text viewer contents
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
PROC [n: RefOtherNode, specs: Rope.ROPE]
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
PROC [n: RefOtherNode] RETURNS [specs: Rope.ROPE]
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
PROC [old: RefOtherNode] RETURNS [newinfo: REF ANY]
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.