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 >
Oberon Text  |  2012-04-20  |  9KB  |  216 lines

  1. Syntax10.Scn.Fnt
  2. Syntax10b.Scn.Fnt
  3. Syntax10i.Scn.Fnt
  4. Syntax12.Scn.Fnt
  5. MODULE GraphicElems;    (** CAS **)  (*mod NW 19.3.91/ HM 27.9.93*)
  6.     IMPORT
  7.         Input, Display, Files, Oberon, Viewers, MenuViewers, Texts, TextFrames, Graphics, GraphicFrames, TextPrinter;
  8.     CONST
  9.         Menu = "System.Close  System.Copy  System.Grow  Draw.Delete  GraphicElems.Update ";
  10.         mm = TextFrames.mm; Scale = mm DIV 10;
  11.         unit = TextFrames.Unit; Unit = TextPrinter.Unit;
  12.         MinW = 3*mm; MinH = MinW; GripW = 15*Scale DIV unit; GripH = GripW;
  13.         rightKey = 0; middleKey = 1; leftKey = 2;
  14.     TYPE
  15.         Elem* = POINTER TO ElemDesc;
  16.         ElemDesc* = RECORD(Texts.ElemDesc)
  17.             SW*, SH*, PW*, PH*: LONGINT;    (**screen, printer box**)
  18.             graph*: Graphics.Graph;
  19.             Xg*, Yg*: INTEGER;
  20.             empty*: BOOLEAN
  21.         END;
  22.         Frame = POINTER TO FrameDesc;
  23.         FrameDesc = RECORD (GraphicFrames.FrameDesc)
  24.             elem: Elem
  25.         END;
  26.     VAR x0, x1, y0, y1: INTEGER;
  27.         W: Texts.Writer;
  28.     PROCEDURE MarkMenu (F: Frame);
  29.         VAR R: Texts.Reader; V: Viewers.Viewer; T: Texts.Text; ch: CHAR;
  30.     BEGIN V := Viewers.This(F.X, F.Y);
  31.         IF V IS MenuViewers.Viewer THEN
  32.             T := V.dsc(TextFrames.Frame).text;
  33.             IF T.len > 0 THEN Texts.OpenReader(R, T, T.len - 1); Texts.Read(R, ch) ELSE ch := 0X END;
  34.             IF ch # "!" THEN Texts.Write(W, "!"); Texts.Append(T, W.buf) END
  35.         END
  36.     END MarkMenu;
  37.     PROCEDURE Changed (E: Elem);
  38.         VAR T: Texts.Text; pos: LONGINT;
  39.     BEGIN
  40.         T := Texts.ElemBase(E); pos := Texts.ElemPos(E); T.notify(T, Texts.replace, pos-1, pos)
  41.     END Changed;
  42.     PROCEDURE FlipGrip (x0, y0, w, h: INTEGER);
  43.     BEGIN Display.ReplConst(Display.white, x0 + w - GripW, y0, GripW, GripH, Display.invert)
  44.     END FlipGrip;
  45.     (* operations on elements *)
  46.     PROCEDURE SetSize* (E: Elem; w, h: LONGINT);
  47.     BEGIN
  48.         IF w < MinW THEN w := MinW END;
  49.         IF h < MinH THEN h := MinH END;
  50.         E.W := w; E.H := h; E.SW := w; E.SH := h;
  51.         E.PW := 4 * (w DIV unit) * Unit; E.PH := 4 * (h DIV unit) * Unit
  52.     END SetSize;
  53.     PROCEDURE box(obj: Graphics.Object; VAR done: BOOLEAN);
  54.     BEGIN
  55.         IF obj.x < x0 THEN x0 := obj.x END ;
  56.         IF x1 < obj.x + obj.w THEN x1 := obj.x + obj.w END ;
  57.         IF obj.y < y0 THEN y0 := obj.y END ;
  58.         IF y1 < obj.y + obj.h THEN y1 := obj.y + obj.h END
  59.     END box;
  60.     PROCEDURE Open* (E: Elem; G: Graphics.Graph; Xg, Yg: INTEGER; adjust: BOOLEAN);
  61.     BEGIN E.graph := G;
  62.         x0 := MAX(INTEGER); x1 := MIN(INTEGER); y0 := MAX(INTEGER); y1 := MIN(INTEGER);
  63.         Graphics.Enumerate(G, box);
  64.         IF x0 = MAX(INTEGER) THEN E.empty := TRUE; E.Xg := 0; E.Yg := 0; SetSize(E, 0, 0)
  65.         ELSE E.empty := FALSE;
  66.             IF adjust THEN E.Xg := -x0; E.Yg := -y1; SetSize(E, LONG(x1-x0) * unit, LONG(y1-y0) * unit)
  67.             ELSE E.Xg := Xg; E.Yg := Yg; SetSize(E, E.W, E.H)
  68.             END
  69.         END
  70.     END Open;
  71.     PROCEDURE CopyGraph (G: Graphics.Graph): Graphics.Graph;
  72.         VAR g: Graphics.Graph;
  73.     BEGIN 
  74.         Graphics.SelectArea(G, MIN(INTEGER), MIN(INTEGER), MAX(INTEGER), MAX(INTEGER));
  75.         NEW(g); Graphics.Copy(G, g, 0, 0); Graphics.Deselect(g);
  76.         RETURN g
  77.     END CopyGraph;
  78.     PROCEDURE Copy* (SE, DE: Elem);
  79.     BEGIN SE.W := SE.SW; SE.H := SE.SH;
  80.         Texts.CopyElem(SE, DE); Open(DE, CopyGraph(SE.graph), SE.Xg, SE.Yg, FALSE)
  81.     END Copy;
  82.     PROCEDURE HandleFrame (f: Display.Frame; VAR msg: Display.FrameMsg);
  83.         VAR F: Frame; F1: Frame;
  84.     BEGIN
  85.         F := f(Frame);
  86.         (*IF msg IS GraphicFrames.UpdateMsg THEN    use when UpdateMsg gets exported*)
  87.         IF msg IS Oberon.InputMsg THEN GraphicFrames.Handle(F, msg);
  88.             WITH msg: Oberon.InputMsg DO
  89.                 IF (msg.id = Oberon.consume) OR (msg.id = Oberon.track) & (msg.keys # {}) THEN
  90.                     MarkMenu(F)
  91.                 END
  92.             END
  93.         ELSIF msg IS Oberon.CopyMsg THEN
  94.             NEW(F1); GraphicFrames.Open(F1, F.graph, F.Xg, F.Yg, F.col, F.ticked);
  95.             F1.handle := F.handle; F1.elem := F.elem;
  96.             msg(Oberon.CopyMsg).F := F1
  97.         ELSE GraphicFrames.Handle(F, msg)
  98.         END
  99.     END HandleFrame;
  100.     PROCEDURE OpenViewer* (E: Elem);
  101.         VAR v: Viewers.Viewer; f: Frame; x, y: INTEGER;
  102.     BEGIN NEW(f); GraphicFrames.Open(f, CopyGraph(E.graph), 0, 0, Display.black, TRUE); 
  103.         f.elem := E; f.handle := HandleFrame;
  104.         Oberon.AllocateUserViewer(Oberon.Mouse.X, x, y);
  105.         v := MenuViewers.New(TextFrames.NewMenu("GraphicElems.Graph", Menu), f, TextFrames.menuH, x, y)
  106.     END OpenViewer;
  107.     PROCEDURE Track (E: Elem; keys: SET; x, y, x0, y0: INTEGER);
  108.         VAR keysum: SET; x1, y1, w, h: INTEGER; hit: BOOLEAN;
  109.     BEGIN
  110.         IF middleKey IN keys THEN x1 := x - x0; y1 := y - y0; keysum := keys;
  111.             w := SHORT(E.W DIV unit); h := SHORT(E.H DIV unit);
  112.             hit := ~E.empty & (x1 >= w-GripW) & (0 <= y1) & (y1 < GripH);
  113.             IF hit THEN FlipGrip(x0, y0, w, h) END;
  114.             REPEAT Input.Mouse(keys, x, y); Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x, y);
  115.                 keysum := keysum + keys
  116.             UNTIL keys = {};
  117.             IF hit THEN FlipGrip(x0, y0, w, h) END;
  118.             IF keysum = {middleKey} THEN
  119.                 IF hit THEN INC(w, (x - x0) - x1); DEC(h, (y - y0) - y1);
  120.                     SetSize(E, LONG(w) * unit, LONG(h) * unit); Changed(E)
  121.                 ELSE OpenViewer(E)
  122.                 END
  123.             END
  124.         END
  125.     END Track;
  126.     (* handle elements *)
  127.     PROCEDURE Handle* (e: Texts.Elem; VAR msg: Texts.ElemMsg);
  128.         VAR E, E1: Elem; x, y, w, h: INTEGER; f: GraphicFrames.Frame; g: Graphics.Graph; version: CHAR;
  129.     BEGIN E := e(Elem);
  130.         IF msg IS TextFrames.DisplayMsg THEN
  131.             WITH msg: TextFrames.DisplayMsg DO
  132.                 IF msg.prepare THEN E.W := E.SW; E.H := E.SH
  133.                 ELSE
  134.                     x := msg.X0; y := msg.Y0; w := SHORT(E.W DIV unit); h := SHORT(E.H DIV unit);
  135.                     IF E.empty THEN
  136.                         Display.ReplPattern(Display.white, Display.grey1, x, y, w, h, Display.replace)
  137.                     ELSE NEW(f); GraphicFrames.Open(f, E.graph, E.Xg, E.Yg, Display.black, FALSE);
  138.                         f.X := x; f.Y := y; f.W := w; f.H := h;
  139.                         GraphicFrames.Restore(f); FlipGrip(x, y, w, h);
  140.                         msg.elemFrame := f
  141.                     END
  142.                 END
  143.             END
  144.         ELSIF msg IS TextPrinter.PrintMsg THEN
  145.             WITH msg: TextPrinter.PrintMsg DO
  146.                 IF msg.prepare THEN E.W := E.PW; E.H := E.PH
  147.                 ELSE
  148.                     Graphics.Print(E.graph, E.Xg*4 + msg.X0, E.Yg*4 + msg.Y0 + SHORT(E.PH DIV Unit));
  149.                     E.W := E.SW; E.H := E.SH
  150.                 END
  151.             END
  152.         ELSIF msg IS Texts.IdentifyMsg THEN
  153.             WITH msg: Texts.IdentifyMsg DO msg.mod := "GraphicElems"; msg.proc := "Alloc" END
  154.         ELSIF msg IS Texts.FileMsg THEN
  155.             WITH msg: Texts.FileMsg DO
  156.                 IF msg.id = Texts.load THEN
  157.                     Files.Read(msg.r, version); NEW(g); Graphics.Load(g, msg.r);
  158.                     IF version = 1X THEN Open(E, g, 0, 0, TRUE)
  159.                     ELSE Files.ReadInt(msg.r, E.Xg); Files.ReadInt(msg.r, E.Yg); Open(E, g, E.Xg, E.Yg, FALSE)
  160.                     END
  161.                 ELSIF msg.id = Texts.store THEN
  162.                     E.W := E.SW; E.H := E.SH;
  163.                     Files.Write(msg.r, 2X); Graphics.Store(E.graph, msg.r);
  164.                     Files.WriteInt(msg.r, E.Xg); Files.WriteInt(msg.r, E.Yg)
  165.                 END
  166.             END
  167.         ELSIF msg IS Texts.CopyMsg THEN NEW(E1); Copy(E, E1); msg(Texts.CopyMsg).e := E1
  168.         ELSIF msg IS TextFrames.TrackMsg THEN
  169.             WITH msg: TextFrames.TrackMsg DO Track(E, msg.keys, msg.X, msg.Y, msg.X0, msg.Y0) END
  170.         ELSIF msg IS TextFrames.FocusMsg THEN
  171.             WITH msg: TextFrames.FocusMsg DO
  172.                 f := msg.elemFrame(GraphicFrames.Frame);
  173.                 f.ticked := msg.focus; GraphicFrames.Restore(f);
  174.                 IF ~msg.focus THEN FlipGrip(f.X, f.Y, f.W, f.H) END
  175.             END
  176.         END
  177.     END Handle;
  178.     PROCEDURE Alloc*;
  179.         VAR e: Elem;
  180.     BEGIN NEW(e); e.handle := Handle; Texts.new := e
  181.     END Alloc;
  182.     (* commands *)
  183.     PROCEDURE Insert*;    (** ["^" | "*" | name] **)
  184.         VAR S: Texts.Scanner; text: Texts.Text;
  185.             beg, end, time: LONGINT;
  186.             V: Viewers.Viewer;
  187.             G, g: Graphics.Graph;
  188.             e: Elem;
  189.             msg: TextFrames.InsertElemMsg;
  190.     BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
  191.         IF (S.class = Texts.Char) & (S.c = "^") THEN
  192.             Oberon.GetSelection(text, beg, end, time);
  193.             IF time >= 0 THEN Texts.OpenScanner(S, text, beg); Texts.Scan(S) END
  194.         END;
  195.         NEW(g);
  196.         IF (S.class = Texts.Char) & (S.c = "*") THEN
  197.             V := Oberon.MarkedViewer();
  198.             IF (V.dsc # NIL) & (V.dsc.next # NIL) & (V.dsc.next IS GraphicFrames.Frame) THEN
  199.                 G := V.dsc.next(GraphicFrames.Frame).graph;
  200.                 IF G.sel = NIL THEN g := CopyGraph(G) ELSE Graphics.Copy(G, g, 0, 0) END
  201.             END
  202.         ELSIF S.class = Texts.Name THEN Graphics.Open(g, S.s)
  203.         END;
  204.         NEW(e); e.handle := Handle; Open(e, g, 0, 0, TRUE);
  205.         msg.e := e; Oberon.FocusViewer.handle(Oberon.FocusViewer, msg)
  206.     END Insert;
  207.     PROCEDURE Update*;
  208.         VAR V: Viewers.Viewer; F: Frame; R: Texts.Reader; T: Texts.Text; ch: CHAR;
  209.     BEGIN V := Oberon.Par.vwr; F := V.dsc.next(Frame); T := V.dsc(TextFrames.Frame).text;
  210.         GraphicFrames.Deselect(F); Open(F.elem, CopyGraph(F.graph), 0, 0, TRUE); Changed(F.elem);
  211.         Texts.OpenReader(R, T, T.len - 1); Texts.Read(R, ch);
  212.         IF ch = "!" THEN Texts.Delete(T, T.len - 1, T.len) END
  213.     END Update;
  214. BEGIN Texts.OpenWriter(W)
  215. END GraphicElems.
  216.