Syntax10.Scn.Fnt (* Semesterarbeit Wintersemester 91/92 von Samuel Urech Erweiterung des Graphikeditors Kepler um Texte Programmiersprache: Oberon-2 auf Ceres-1 Autor: Samuel Urech, Tannenrauchstrasse 35/107, 8038 Z Tel. 01 481 92 92 Stud.Nr. 87-906-434 Datum: 20.11.91 Stand: 12.2.92 adapted to V4: J. Templ, 27.09.93 MODULE Kepler7; IMPORT Display, Oberon, Fonts, Files, TextFrames, Texts, MenuViewers, KeplerPorts, KeplerGraphs, KeplerFrames, Kepler2; CONST MM = 1; CR = 0DX; menu = "System.Close System.Copy System.Grow Edit.Search Edit.Replace Kepler7.Update "; TYPE Text* = POINTER TO TextDesc; TextDesc* = RECORD (KeplerFrames.ButtonDesc) text* : Texts.Text END; Frame* = POINTER TO FrameDesc; FrameDesc* = RECORD (TextFrames.FrameDesc) keplerText* : Text; graph* : KeplerGraphs.Graph END; (* ---------------------------------------- Hilfsprozeduren ------------------------------------- *) PROCEDURE CopyText( srcText : Texts.Text; VAR dstText : Texts.Text ); (* srcText wird auf dstText kopiert, der alte Inhalt von dstText wird gel scht. *) VAR b : Texts.Buffer; BEGIN NEW( dstText ); Texts.Open( dstText, "" ); dstText.notify := srcText.notify; NEW( b ); Texts.OpenBuf( b ); Texts.Save( srcText, 0, srcText.len, b ); Texts.Append( dstText, b ) END CopyText; (* ----------------------------------- Text-Methoden ------------------------------------- *) PROCEDURE (t : Text) HandleMouse* (f: KeplerFrames.Frame; x, y: INTEGER; keys: SET); VAR X, Y: INTEGER; keySum: SET; newText: Texts.Text; tf: Frame; v: MenuViewers.Viewer; BEGIN IF keys = {MM} THEN keySum := keys; REPEAT f.TrackMouse(x, y, keys); KeplerFrames.GetMouse(f, x, y, keys); keySum := keySum + keys; UNTIL keys = {}; IF keySum = {MM} THEN CopyText(t.text, newText); NEW(tf); TextFrames.Open( tf, newText, 0); tf.keplerText := t; tf.graph := f.G; Oberon.AllocateUserViewer(Oberon.Mouse.X, X, Y); v := MenuViewers.New(TextFrames.NewMenu("KeplerText", menu), tf, TextFrames.menuH, X, Y); END END END HandleMouse; PROCEDURE ( t : Text ) Draw*( f : KeplerPorts.Port ); VAR r : Texts.Reader; ch : CHAR; line : ARRAY 256 OF CHAR; i, xBase, xOff, y, lineHeight, oldNegOff, negOff : INTEGER; lineBeg : LONGINT; curFont : Fonts.Font; curCol, curVoff : SHORTINT; BEGIN lineBeg := 0; Texts.OpenReader( r, t.text, lineBeg ); Texts.Read( r, ch ); xBase := t.p[ 0 ].x; xOff := 0; y := t.p[ 0 ].y; oldNegOff := 0; negOff := 0; WHILE ~ r.eot DO lineHeight := 4 * r.fnt.maxY + r.voff; WHILE ( ~ r.eot ) & ( ch # CR ) DO IF 4 * r.fnt.maxY + r.voff > lineHeight THEN lineHeight := 4 * r.fnt.maxY + r.voff; END; IF r.voff + 4 * r.fnt.minY < negOff THEN negOff := r.voff + 4 * r.fnt.minY; END; Texts.Read( r, ch ); END; xOff := 0; Texts.OpenReader( r, t.text, lineBeg ); Texts.Read( r, ch ); IF ( ch = CR ) & ( f IS KeplerPorts.BalloonPort ) THEN line[ 0 ] := "l"; line[ 1 ] := 0X; f.DrawString( xBase, y - lineHeight + oldNegOff, line, r.fnt, r.col, Display.replace ); END; WHILE ( ~ r.eot ) & ( ch # CR ) DO i := 0; curFont := r.fnt; curCol := r.col; curVoff := r.voff; WHILE ( ~ r.eot ) & ( ch # CR ) & ( curFont = r.fnt ) & ( curCol = r.col ) & ( curVoff = r.voff ) & ( i < 255 ) DO line[ i ] := ch; INC( i ); Texts.Read( r, ch ); END; line[ i ] := 0X; f.DrawString( xBase + xOff, y + curVoff - lineHeight + oldNegOff, line, curFont, curCol, Display.replace ); INC( xOff, KeplerPorts.StringWidth( line, curFont ) ); END; DEC( y, lineHeight - oldNegOff ); oldNegOff := negOff; negOff := 0; lineBeg := Texts.Pos( r ); Texts.Read( r, ch ); END END Draw; PROCEDURE ( t : Text ) Read*( VAR r : Files.Rider ); BEGIN NEW( t.text ); Texts.Load( r, t.text); t.text.notify := TextFrames.NotifyDisplay; t.Read^( r ); END Read; PROCEDURE ( t : Text ) Write*( VAR r : Files.Rider ); BEGIN Texts.Store( r, t.text); t.Write^( r ); END Write; (* ------------------------------------------- Text-Commands ---------------------------------- *) PROCEDURE Update*; (* Schreibt den Text aus dem Viewer, von dem aus der Befehl aufgerufen wurde, an seine Ursprungsposition zur ck. *) VAR f : Frame; balloon1, balloon2 : KeplerPorts.BalloonPort; textCorner : Kepler2.Offset; dx, dy : INTEGER; T: Texts.Text; R: Texts.Reader; ch: CHAR; BEGIN IF Oberon.Par.vwr.dsc.next IS Frame THEN f := Oberon.Par.vwr.dsc.next( Frame ); NEW( balloon1 ); KeplerPorts.InitBalloon( balloon1 ); f.keplerText.Draw( balloon1 ); CopyText( f.text, f.keplerText.text ); NEW( balloon2 ); KeplerPorts.InitBalloon( balloon2 ); f.keplerText.Draw( balloon2 ); textCorner := f.keplerText.p[ 1 ]( Kepler2.Offset ); IF ( balloon2.W <= 0 ) OR ( balloon2.H <= 0 ) THEN dx := 100 - textCorner.dx; dy := (-100) - textCorner.dy; textCorner.dx := 100; textCorner.dy := -100; ELSE dx := balloon2.W - textCorner.dx; dy := -balloon2.H - textCorner.dy; textCorner.dx := balloon2.W; textCorner.dy := -balloon2.H; END; (* IF *) f.graph.Move( textCorner, dx, dy ); textCorner.Calc; f.keplerText.Draw( balloon1 ); textCorner.Draw( balloon1 ); f.graph.notify( KeplerGraphs.restore, f.graph, f.keplerText, balloon1 ); T := Oberon.Par.vwr.dsc(TextFrames.Frame).text; Texts.OpenReader(R, T, T.len - 1); Texts.Read(R, ch); IF ch = "!" THEN Texts.Delete(T, T.len - 1, T.len) END END END Update; PROCEDURE NewText*; VAR t: Text; corner: Kepler2.Offset; sel: Texts.Text; beg, end, time: LONGINT; b: Texts.Buffer; balloon: KeplerPorts.BalloonPort; W: Texts.Writer; BEGIN IF KeplerFrames.nofpts >= 1 THEN NEW(t); NEW(corner); NEW(corner.c); t.text := TextFrames.Text(""); t.nofpts := 2; t.cmd := ""; t.par := ""; KeplerFrames.ConsumePoint(t.p[0]); corner.c.nofpts := 1; corner.c.p[0] := t.p[0]; INC(t.p[0].refcnt ); t.p[1] := corner; corner.refcnt := 1; Oberon.GetSelection(sel, beg, end, time); IF (time < 0) OR (beg = end) THEN Texts.OpenWriter(W); Texts.WriteString(W, "no selection"); Texts.Append(t.text, W.buf) ELSE NEW(b); Texts.OpenBuf(b); Texts.Save(sel, beg, end, b); Texts.Append(t.text, b); END ; NEW(balloon); KeplerPorts.InitBalloon(balloon); t.Draw(balloon); corner.dx := balloon.W; corner.dy := -balloon.H; corner.Calc; KeplerFrames.Focus.Append(corner); KeplerFrames.Focus.Append(t) END END NewText; END Kepler7.