home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 10 / Fresh_Fish_10_2352.bin / new / dev / obero / oberon / projectoberonsrc / graphicframes.mod (.txt) < prev    next >
Oberon Text  |  1994-10-17  |  18KB  |  485 lines

  1. Syntax10.Scn.Fnt
  2. MODULE GraphicFrames; (*NW 18.4.88 / 30.6.93*)
  3.     IMPORT Display, Viewers, Input, Fonts, Texts, Graphics, Oberon, MenuViewers;
  4.     CONST (*update message ids*)
  5.         restore = 0;
  6.         drawobj = 1; drawobjs = 2; drawobjd = 3;
  7.         drawnorm = 4; drawsel = 5; drawdel = 6;
  8.         markW = 5;
  9.     TYPE
  10.         Frame* = POINTER TO FrameDesc;
  11.         Location* = POINTER TO LocDesc;
  12.         LocDesc* = RECORD
  13.                 x*, y*: INTEGER;
  14.                 next*: Location
  15.             END ;
  16.         FrameDesc* = RECORD (Display.FrameDesc)
  17.                 graph*: Graphics.Graph;
  18.                 Xg*, Yg*: INTEGER;  (*pos rel to graph origin*)
  19.                 X1*, Y1*: INTEGER;  (*right and upper margins*)
  20.                 x*, y*, col*: INTEGER;  (*x = X + Xg, y = Y + Yg*)
  21.                 marked*, ticked*: BOOLEAN;
  22.                 mark*: LocDesc
  23.             END ;
  24.         DrawMsg* = RECORD (Graphics.Msg)
  25.                 f*: Frame;
  26.                 x*, y*, col*, mode*: INTEGER
  27.             END ;
  28.         CtrlMsg* = RECORD (Graphics.Msg)
  29.                 f*: Frame;
  30.                 res*: INTEGER
  31.             END ;
  32.         UpdateMsg = RECORD (Display.FrameMsg)
  33.                 id: INTEGER;
  34.                 graph: Graphics.Graph;
  35.                 obj: Graphics.Object
  36.             END ;
  37.         SelQuery = RECORD (Display.FrameMsg)
  38.                 f: Frame; time: LONGINT
  39.             END ;
  40.         FocusQuery = RECORD (Display.FrameMsg)
  41.                 f: Frame
  42.             END ;
  43.         PosQuery = RECORD (Display.FrameMsg)
  44.                 f: Frame; x, y: INTEGER
  45.             END ;
  46.         DispMsg = RECORD (Display.FrameMsg)
  47.                 x1, y1, w: INTEGER;
  48.                 pat: Display.Pattern;
  49.                 graph: Graphics.Graph
  50.             END ;
  51.     VAR Crosshair*: Oberon.Marker;
  52.         newcap: Graphics.Caption;
  53.         DW, DH, CL: INTEGER;
  54.         W: Texts.Writer;
  55.     (*Exported procedures:
  56.         Restore, Focus, Selected, This, Draw, DrawNorm, Erase,
  57.         DrawObj, EraseObj, Change, Defocus, Deselect, Macro, New*)
  58.     PROCEDURE Restore*(F: Frame);
  59.         VAR x, x0, y: INTEGER; M: DrawMsg;
  60.     BEGIN F.X1 := F.X + F.W; F.Y1 := F.Y + F.H;
  61.         F.x := F.X + F.Xg; F.y := F.Y1 + F.Yg; F.marked := FALSE; F.mark.next := NIL;
  62.         Oberon.RemoveMarks(F.X, F.Y, F.W, F.H); Display.ReplConst(F.col, F.X, F.Y, F.W, F.H, 0);
  63.         IF F.ticked THEN
  64.             y := F.Yg MOD 16 + F.Y1 - 16; x0 := F.Xg MOD 16 + F.X;
  65.             WHILE y >= F.Y DO
  66.                 x := x0;
  67.                 WHILE x < F.X1 DO Display.Dot(Display.white, x, y, 0); INC(x, 16) END ;
  68.                 DEC(y, 16)
  69.             END
  70.         END ;
  71.         M.f := F; M.x := F.x; M.y := F.y; M.col := 0; M.mode := 0; Graphics.Draw(F.graph, M)
  72.     END Restore;
  73.     PROCEDURE Focus*(): Frame;
  74.         VAR FQ: FocusQuery;
  75.     BEGIN FQ.f := NIL; Viewers.Broadcast(FQ); RETURN FQ.f
  76.     END Focus;
  77.     PROCEDURE Selected*(): Frame;
  78.         VAR SQ: SelQuery;
  79.     BEGIN SQ.f := NIL; SQ.time := 0; Viewers.Broadcast(SQ); RETURN SQ.f
  80.     END Selected;
  81.     PROCEDURE This*(x, y: INTEGER): Frame;
  82.         VAR PQ: PosQuery;
  83.     BEGIN PQ.f := NIL; PQ.x := x; PQ.y := y; Viewers.Broadcast(PQ); RETURN PQ.f
  84.     END This;
  85.     PROCEDURE Draw*(F: Frame);
  86.         VAR UM: UpdateMsg;
  87.     BEGIN UM.id := drawsel; UM.graph := F.graph; Viewers.Broadcast(UM)
  88.     END Draw;
  89.     PROCEDURE DrawNorm(F: Frame);
  90.         VAR UM: UpdateMsg;
  91.     BEGIN UM.id := drawnorm; UM.graph := F.graph; Viewers.Broadcast(UM)
  92.     END DrawNorm;
  93.     PROCEDURE Erase*(F: Frame);
  94.         VAR UM: UpdateMsg;
  95.     BEGIN UM.id := drawdel; UM.graph := F.graph; Viewers.Broadcast(UM)
  96.     END Erase;
  97.     PROCEDURE DrawObj*(F: Frame; obj: Graphics.Object);
  98.         VAR UM: UpdateMsg;
  99.     BEGIN UM.id := drawobj; UM.graph := F.graph; UM.obj := obj; Viewers.Broadcast(UM)
  100.     END DrawObj;
  101.     PROCEDURE EraseObj*(F: Frame; obj: Graphics.Object);
  102.         VAR UM: UpdateMsg;
  103.     BEGIN UM.id := drawobjd; UM.graph := F.graph; UM.obj := obj; Viewers.Broadcast(UM)
  104.     END EraseObj;
  105.     PROCEDURE Change*(F: Frame; VAR msg: Graphics.Msg);
  106.     BEGIN
  107.         IF F # NIL THEN Erase(F); Graphics.Handle(F.graph, msg); Draw(F) END
  108.     END Change;
  109.     PROCEDURE FlipMark(x, y: INTEGER);
  110.     BEGIN
  111.         Display.ReplConst(Display.white, x-7, y, 15, 1, 2);
  112.         Display.ReplConst(Display.white, x, y-7, 1, 15, 2)
  113.     END FlipMark;
  114.     PROCEDURE Defocus*(F: Frame);
  115.         VAR m: Location;
  116.     BEGIN newcap := NIL;
  117.         IF F.marked THEN
  118.             FlipMark(F.mark.x, F.mark.y); m := F.mark.next;
  119.             WHILE m # NIL DO FlipMark(m.x, m.y); m := m.next END ;
  120.             F.marked := FALSE; F.mark.next := NIL
  121.         END
  122.     END Defocus;
  123.     PROCEDURE Deselect*(F: Frame);
  124.         VAR UM: UpdateMsg;
  125.     BEGIN
  126.         IF F # NIL THEN
  127.             UM.id := drawnorm; UM.graph := F.graph; Viewers.Broadcast(UM);
  128.             Graphics.Deselect(F.graph)
  129.         END
  130.     END Deselect;
  131.     PROCEDURE Macro*(VAR Lname, Mname: ARRAY OF CHAR);
  132.         VAR x, y: INTEGER;
  133.             F: Frame;
  134.             mac: Graphics.Macro; mh: Graphics.MacHead;
  135.             L: Graphics.Library;
  136.     BEGIN F := Focus();
  137.         IF F # NIL THEN
  138.             x := F.mark.x - F.x; y := F.mark.y - F.y;
  139.             L := Graphics.ThisLib(Lname, FALSE);
  140.             IF L # NIL THEN
  141.                 mh := Graphics.ThisMac(L, Mname);
  142.                 IF mh # NIL THEN
  143.                     Deselect(F); Defocus(F);
  144.                     NEW(mac); mac.x := x; mac.y := y; mac.w := mh.w; mac.h := mh.h;
  145.                     mac.mac := mh; mac.do := Graphics.MacMethod; mac.col := Oberon.CurCol;
  146.                     Graphics.Add(F.graph, mac); DrawObj(F, mac)
  147.                 END
  148.             END
  149.         END
  150.     END Macro;
  151.     PROCEDURE CaptionCopy(F: Frame;
  152.             x1, y1: INTEGER; T: Texts.Text; beg, end: LONGINT): Graphics.Caption;
  153.         VAR ch: CHAR;
  154.             dx, w, x2, y2, w1, h1: INTEGER;
  155.             cap: Graphics.Caption;
  156.             pat: Display.Pattern;
  157.             R: Texts.Reader;
  158.     BEGIN Texts.Write(W, 0DX);
  159.         NEW(cap); cap.len := SHORT(end - beg);
  160.         cap.pos := SHORT(Graphics.T.len)+1; cap.do := Graphics.CapMethod;
  161.         Texts.OpenReader(R, T, beg); Texts.Read(R, ch); W.fnt := R.fnt; W.col := R.col; w := 0;
  162.         cap.x := x1 - F.x; cap.y := y1 - F.y + R.fnt.minY;
  163.         WHILE beg < end DO
  164.             Display.GetChar(R.fnt.raster, ch, dx, x2, y2, w1, h1, pat);
  165.             INC(w, dx); INC(beg); Texts.Write(W, ch); Texts.Read(R, ch)
  166.         END ;
  167.         cap.w := w; cap.h := W.fnt.height; cap.col := W.col;
  168.         Texts.Append(Graphics.T, W.buf); Graphics.Add(F.graph, cap); RETURN cap
  169.     END CaptionCopy;
  170.     PROCEDURE SendCaption(cap: Graphics.Caption);
  171.         VAR M: Oberon.CopyOverMsg;
  172.     BEGIN
  173.         M. text := Graphics.T; M.beg := cap.pos; M.end := M.beg + cap.len; Viewers.Broadcast(M)
  174.     END SendCaption;
  175.     PROCEDURE Edit(F: Frame; x0, y0: INTEGER; k0: SET);
  176.         VAR obj: Graphics.Object;
  177.             x1, y1, w, h, t: INTEGER;
  178.             beg, end, time: LONGINT;
  179.             k1, k2: SET;
  180.             mark, newmark: Location;
  181.             T: Texts.Text;
  182.             Fd: Frame;
  183.             G: Graphics.Graph;
  184.             CM: CtrlMsg;
  185.         PROCEDURE NewLine(x, y, w, h: INTEGER);
  186.             VAR line: Graphics.Line;
  187.         BEGIN NEW(line); line.col := Oberon.CurCol; line.x := x - F.x; line.y := y - F.y;
  188.             line.w := w; line.h := h; line.do := Graphics.LineMethod; Graphics.Add(G, line)
  189.         END NewLine;
  190.     BEGIN k1 := k0; G := F.graph;
  191.         IF k0 = {1} THEN
  192.             obj := Graphics.ThisObj(G, x0 - F.x, y0 - F.y);
  193.             IF (obj # NIL) & ~obj.selected THEN
  194.                 CM.f := F; CM.res := 0; obj.do.handle(obj, CM);
  195.                 IF CM.res # 0 THEN (*done*) k0 := {} END
  196.             END
  197.         END ;
  198.         REPEAT Input.Mouse(k2, x1, y1); k1 := k1 + k2;
  199.             DEC(x1, (x1-F.x) MOD 4); DEC(y1, (y1-F.y) MOD 4);
  200.             Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x1, y1)
  201.         UNTIL  k2 = {};
  202.         Oberon.FadeCursor(Oberon.Mouse);
  203.         IF k0 = {2} THEN (*left key*)
  204.             w := ABS(x1-x0); h := ABS(y1-y0);
  205.             IF k1 = {2} THEN
  206.                 IF (w < 7) & (h < 7) THEN (*set mark*)
  207.                     IF (x1 - markW >= F.X) & (x1 + markW < F.X1) &
  208.                         (y1 - markW >= F.Y) & (y1 + markW < F.Y1) THEN
  209.                         Defocus(F); Oberon.PassFocus(Viewers.This(F.X, F.Y));
  210.                         F.mark.x := x1; F.mark.y := y1; F.marked := TRUE; FlipMark(x1, y1)
  211.                     END
  212.                 ELSE (*draw line*) Deselect(F);
  213.                     IF w < h THEN
  214.                         IF y1 < y0 THEN y0 := y1 END ;
  215.                         NewLine(x0, y0, Graphics.width, h)
  216.                     ELSE
  217.                         IF x1 < x0 THEN x0 := x1 END ;
  218.                         NewLine(x0, y0, w, Graphics.width)
  219.                     END ;
  220.                     Draw(F)
  221.                 END
  222.             ELSIF k1 = {2, 1} THEN (*copy selection to caret mark*)
  223.                 Deselect(F); Oberon.GetSelection(T, beg, end, time);
  224.                 IF time >= 0 THEN DrawObj(F, CaptionCopy(F, x1, y1, T, beg, end)) END
  225.             ELSIF k1 = {2, 0} THEN
  226.                 IF F.marked THEN (*set secondary mark*)
  227.                         NEW(newmark); newmark.x := x1; newmark.y := y1; newmark.next := NIL;
  228.                     FlipMark(x1, y1); mark := F.mark.next;
  229.                     IF mark = NIL THEN F.mark.next := newmark ELSE
  230.                         WHILE mark.next # NIL DO mark := mark.next END ;
  231.                         mark.next := newmark
  232.                     END
  233.                 END
  234.             END
  235.         ELSIF k0 = {1} THEN (*middle key*)
  236.             IF k1 = {1} THEN (*move*)
  237.                 IF (x0 # x1) OR (y0 # y1) THEN
  238.                     Fd := This(x1, y1); Erase(F);
  239.                     IF Fd = F THEN Graphics.Move(G, x1-x0, y1-y0)
  240.                     ELSIF (Fd # NIL) & (Fd.graph = G) THEN
  241.                         Graphics.Move(G, (x1-Fd.x-x0+F.x) DIV 4 * 4, (y1-Fd.y-y0+F.y) DIV 4 * 4)
  242.                     END ;
  243.                     Draw(F)
  244.                 END
  245.             ELS