home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
jËzyki_programowania
/
oberon
/
system
/
graphicelems.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
2012-04-20
|
9KB
|
216 lines
Syntax10.Scn.Fnt
Syntax10b.Scn.Fnt
Syntax10i.Scn.Fnt
Syntax12.Scn.Fnt
MODULE GraphicElems; (** CAS **) (*mod NW 19.3.91/ HM 27.9.93*)
IMPORT
Input, Display, Files, Oberon, Viewers, MenuViewers, Texts, TextFrames, Graphics, GraphicFrames, TextPrinter;
CONST
Menu = "System.Close System.Copy System.Grow Draw.Delete GraphicElems.Update ";
mm = TextFrames.mm; Scale = mm DIV 10;
unit = TextFrames.Unit; Unit = TextPrinter.Unit;
MinW = 3*mm; MinH = MinW; GripW = 15*Scale DIV unit; GripH = GripW;
rightKey = 0; middleKey = 1; leftKey = 2;
TYPE
Elem* = POINTER TO ElemDesc;
ElemDesc* = RECORD(Texts.ElemDesc)
SW*, SH*, PW*, PH*: LONGINT; (**screen, printer box**)
graph*: Graphics.Graph;
Xg*, Yg*: INTEGER;
empty*: BOOLEAN
END;
Frame = POINTER TO FrameDesc;
FrameDesc = RECORD (GraphicFrames.FrameDesc)
elem: Elem
END;
VAR x0, x1, y0, y1: INTEGER;
W: Texts.Writer;
PROCEDURE MarkMenu (F: Frame);
VAR R: Texts.Reader; V: Viewers.Viewer; T: Texts.Text; ch: CHAR;
BEGIN V := Viewers.This(F.X, F.Y);
IF V IS MenuViewers.Viewer THEN
T := V.dsc(TextFrames.Frame).text;
IF T.len > 0 THEN Texts.OpenReader(R, T, T.len - 1); Texts.Read(R, ch) ELSE ch := 0X END;
IF ch # "!" THEN Texts.Write(W, "!"); Texts.Append(T, W.buf) END
END
END MarkMenu;
PROCEDURE Changed (E: Elem);
VAR T: Texts.Text; pos: LONGINT;
BEGIN
T := Texts.ElemBase(E); pos := Texts.ElemPos(E); T.notify(T, Texts.replace, pos-1, pos)
END Changed;
PROCEDURE FlipGrip (x0, y0, w, h: INTEGER);
BEGIN Display.ReplConst(Display.white, x0 + w - GripW, y0, GripW, GripH, Display.invert)
END FlipGrip;
(* operations on elements *)
PROCEDURE SetSize* (E: Elem; w, h: LONGINT);
BEGIN
IF w < MinW THEN w := MinW END;
IF h < MinH THEN h := MinH END;
E.W := w; E.H := h; E.SW := w; E.SH := h;
E.PW := 4 * (w DIV unit) * Unit; E.PH := 4 * (h DIV unit) * Unit
END SetSize;
PROCEDURE box(obj: Graphics.Object; VAR done: BOOLEAN);
BEGIN
IF obj.x < x0 THEN x0 := obj.x END ;
IF x1 < obj.x + obj.w THEN x1 := obj.x + obj.w END ;
IF obj.y < y0 THEN y0 := obj.y END ;
IF y1 < obj.y + obj.h THEN y1 := obj.y + obj.h END
END box;
PROCEDURE Open* (E: Elem; G: Graphics.Graph; Xg, Yg: INTEGER; adjust: BOOLEAN);
BEGIN E.graph := G;
x0 := MAX(INTEGER); x1 := MIN(INTEGER); y0 := MAX(INTEGER); y1 := MIN(INTEGER);
Graphics.Enumerate(G, box);
IF x0 = MAX(INTEGER) THEN E.empty := TRUE; E.Xg := 0; E.Yg := 0; SetSize(E, 0, 0)
ELSE E.empty := FALSE;
IF adjust THEN E.Xg := -x0; E.Yg := -y1; SetSize(E, LONG(x1-x0) * unit, LONG(y1-y0) * unit)
ELSE E.Xg := Xg; E.Yg := Yg; SetSize(E, E.W, E.H)
END
END
END Open;
PROCEDURE CopyGraph (G: Graphics.Graph): Graphics.Graph;
VAR g: Graphics.Graph;
BEGIN
Graphics.SelectArea(G, MIN(INTEGER), MIN(INTEGER), MAX(INTEGER), MAX(INTEGER));
NEW(g); Graphics.Copy(G, g, 0, 0); Graphics.Deselect(g);
RETURN g
END CopyGraph;
PROCEDURE Copy* (SE, DE: Elem);
BEGIN SE.W := SE.SW; SE.H := SE.SH;
Texts.CopyElem(SE, DE); Open(DE, CopyGraph(SE.graph), SE.Xg, SE.Yg, FALSE)
END Copy;
PROCEDURE HandleFrame (f: Display.Frame; VAR msg: Display.FrameMsg);
VAR F: Frame; F1: Frame;
BEGIN
F := f(Frame);
(*IF msg IS GraphicFrames.UpdateMsg THEN use when UpdateMsg gets exported*)
IF msg IS Oberon.InputMsg THEN GraphicFrames.Handle(F, msg);
WITH msg: Oberon.InputMsg DO
IF (msg.id = Oberon.consume) OR (msg.id = Oberon.track) & (msg.keys # {}) THEN
MarkMenu(F)
END
END
ELSIF msg IS Oberon.CopyMsg THEN
NEW(F1); GraphicFrames.Open(F1, F.graph, F.Xg, F.Yg, F.col, F.ticked);
F1.handle := F.handle; F1.elem := F.elem;
msg(Oberon.CopyMsg).F := F1
ELSE GraphicFrames.Handle(F, msg)
END
END HandleFrame;
PROCEDURE OpenViewer* (E: Elem);
VAR v: Viewers.Viewer; f: Frame; x, y: INTEGER;
BEGIN NEW(f); GraphicFrames.Open(f, CopyGraph(E.graph), 0, 0, Display.black, TRUE);
f.elem := E; f.handle := HandleFrame;
Oberon.AllocateUserViewer(Oberon.Mouse.X, x, y);
v := MenuViewers.New(TextFrames.NewMenu("GraphicElems.Graph", Menu), f, TextFrames.menuH, x, y)
END OpenViewer;
PROCEDURE Track (E: Elem; keys: SET; x, y, x0, y0: INTEGER);
VAR keysum: SET; x1, y1, w, h: INTEGER; hit: BOOLEAN;
BEGIN
IF middleKey IN keys THEN x1 := x - x0; y1 := y - y0; keysum := keys;
w := SHORT(E.W DIV unit); h := SHORT(E.H DIV unit);
hit := ~E.empty & (x1 >= w-GripW) & (0 <= y1) & (y1 < GripH);
IF hit THEN FlipGrip(x0, y0, w, h) END;
REPEAT Input.Mouse(keys, x, y); Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y);
keysum := keysum + keys
UNTIL keys = {};
IF hit THEN FlipGrip(x0, y0, w, h) END;
IF keysum = {middleKey} THEN
IF hit THEN INC(w, (x - x0) - x1); DEC(h, (y - y0) - y1);
SetSize(E, LONG(w) * unit, LONG(h) * unit); Changed(E)
ELSE OpenViewer(E)
END
END
END
END Track;
(* handle elements *)
PROCEDURE Handle* (e: Texts.Elem; VAR msg: Texts.ElemMsg);
VAR E, E1: Elem; x, y, w, h: INTEGER; f: GraphicFrames.Frame; g: Graphics.Graph; version: CHAR;
BEGIN E := e(Elem);
IF msg IS TextFrames.DisplayMsg THEN
WITH msg: TextFrames.DisplayMsg DO
IF msg.prepare THEN E.W := E.SW; E.H := E.SH
ELSE
x := msg.X0; y := msg.Y0; w := SHORT(E.W DIV unit); h := SHORT(E.H DIV unit);
IF E.empty THEN
Display.ReplPattern(Display.white, Display.grey1, x, y, w, h, Display.replace)
ELSE NEW(f); GraphicFrames.Open(f, E.graph, E.Xg, E.Yg, Display.black, FALSE);
f.X := x; f.Y := y; f.W := w; f.H := h;
GraphicFrames.Restore(f); FlipGrip(x, y, w, h);
msg.elemFrame := f
END
END
END
ELSIF msg IS TextPrinter.PrintMsg THEN
WITH msg: TextPrinter.PrintMsg DO
IF msg.prepare THEN E.W := E.PW; E.H := E.PH
ELSE
Graphics.Print(E.graph, E.Xg*4 + msg.X0, E.Yg*4 + msg.Y0 + SHORT(E.PH DIV Unit));
E.W := E.SW; E.H := E.SH
END
END
ELSIF msg IS Texts.IdentifyMsg THEN
WITH msg: Texts.IdentifyMsg DO msg.mod := "GraphicElems"; msg.proc := "Alloc" END
ELSIF msg IS Texts.FileMsg THEN
WITH msg: Texts.FileMsg DO
IF msg.id = Texts.load THEN
Files.Read(msg.r, version); NEW(g); Graphics.Load(g, msg.r);
IF version = 1X THEN Open(E, g, 0, 0, TRUE)
ELSE Files.ReadInt(msg.r, E.Xg); Files.ReadInt(msg.r, E.Yg); Open(E, g, E.Xg, E.Yg, FALSE)
END
ELSIF msg.id = Texts.store THEN
E.W := E.SW; E.H := E.SH;
Files.Write(msg.r, 2X); Graphics.Store(E.graph, msg.r);
Files.WriteInt(msg.r, E.Xg); Files.WriteInt(msg.r, E.Yg)
END
END
ELSIF msg IS Texts.CopyMsg THEN NEW(E1); Copy(E, E1); msg(Texts.CopyMsg).e := E1
ELSIF msg IS TextFrames.TrackMsg THEN
WITH msg: TextFrames.TrackMsg DO Track(E, msg.keys, msg.X, msg.Y, msg.X0, msg.Y0) END
ELSIF msg IS TextFrames.FocusMsg THEN
WITH msg: TextFrames.FocusMsg DO
f := msg.elemFrame(GraphicFrames.Frame);
f.ticked := msg.focus; GraphicFrames.Restore(f);
IF ~msg.focus THEN FlipGrip(f.X, f.Y, f.W, f.H) END
END
END
END Handle;
PROCEDURE Alloc*;
VAR e: Elem;
BEGIN NEW(e); e.handle := Handle; Texts.new := e
END Alloc;
(* commands *)
PROCEDURE Insert*; (** ["^" | "*" | name] **)
VAR S: Texts.Scanner; text: Texts.Text;
beg, end, time: LONGINT;
V: Viewers.Viewer;
G, g: Graphics.Graph;
e: Elem;
msg: TextFrames.InsertElemMsg;
BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
IF (S.class = Texts.Char) & (S.c = "^") THEN
Oberon.GetSelection(text, beg, end, time);
IF time >= 0 THEN Texts.OpenScanner(S, text, beg); Texts.Scan(S) END
END;
NEW(g);
IF (S.class = Texts.Char) & (S.c = "*") THEN
V := Oberon.MarkedViewer();
IF (V.dsc # NIL) & (V.dsc.next # NIL) & (V.dsc.next IS GraphicFrames.Frame) THEN
G := V.dsc.next(GraphicFrames.Frame).graph;
IF G.sel = NIL THEN g := CopyGraph(G) ELSE Graphics.Copy(G, g, 0, 0) END
END
ELSIF S.class = Texts.Name THEN Graphics.Open(g, S.s)
END;
NEW(e); e.handle := Handle; Open(e, g, 0, 0, TRUE);
msg.e := e; Oberon.FocusViewer.handle(Oberon.FocusViewer, msg)
END Insert;
PROCEDURE Update*;
VAR V: Viewers.Viewer; F: Frame; R: Texts.Reader; T: Texts.Text; ch: CHAR;
BEGIN V := Oberon.Par.vwr; F := V.dsc.next(Frame); T := V.dsc(TextFrames.Frame).text;
GraphicFrames.Deselect(F); Open(F.elem, CopyGraph(F.graph), 0, 0, TRUE); Changed(F.elem);
Texts.OpenReader(R, T, T.len - 1); Texts.Read(R, ch);
IF ch = "!" THEN Texts.Delete(T, T.len - 1, T.len) END
END Update;
BEGIN Texts.OpenWriter(W)
END GraphicElems.