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 >
Wrap
Oberon Text
|
1994-10-17
|
18KB
|
485 lines
Syntax10.Scn.Fnt
MODULE GraphicFrames; (*NW 18.4.88 / 30.6.93*)
IMPORT Display, Viewers, Input, Fonts, Texts, Graphics, Oberon, MenuViewers;
CONST (*update message ids*)
restore = 0;
drawobj = 1; drawobjs = 2; drawobjd = 3;
drawnorm = 4; drawsel = 5; drawdel = 6;
markW = 5;
TYPE
Frame* = POINTER TO FrameDesc;
Location* = POINTER TO LocDesc;
LocDesc* = RECORD
x*, y*: INTEGER;
next*: Location
END ;
FrameDesc* = RECORD (Display.FrameDesc)
graph*: Graphics.Graph;
Xg*, Yg*: INTEGER; (*pos rel to graph origin*)
X1*, Y1*: INTEGER; (*right and upper margins*)
x*, y*, col*: INTEGER; (*x = X + Xg, y = Y + Yg*)
marked*, ticked*: BOOLEAN;
mark*: LocDesc
END ;
DrawMsg* = RECORD (Graphics.Msg)
f*: Frame;
x*, y*, col*, mode*: INTEGER
END ;
CtrlMsg* = RECORD (Graphics.Msg)
f*: Frame;
res*: INTEGER
END ;
UpdateMsg = RECORD (Display.FrameMsg)
id: INTEGER;
graph: Graphics.Graph;
obj: Graphics.Object
END ;
SelQuery = RECORD (Display.FrameMsg)
f: Frame; time: LONGINT
END ;
FocusQuery = RECORD (Display.FrameMsg)
f: Frame
END ;
PosQuery = RECORD (Display.FrameMsg)
f: Frame; x, y: INTEGER
END ;
DispMsg = RECORD (Display.FrameMsg)
x1, y1, w: INTEGER;
pat: Display.Pattern;
graph: Graphics.Graph
END ;
VAR Crosshair*: Oberon.Marker;
newcap: Graphics.Caption;
DW, DH, CL: INTEGER;
W: Texts.Writer;
(*Exported procedures:
Restore, Focus, Selected, This, Draw, DrawNorm, Erase,
DrawObj, EraseObj, Change, Defocus, Deselect, Macro, New*)
PROCEDURE Restore*(F: Frame);
VAR x, x0, y: INTEGER; M: DrawMsg;
BEGIN F.X1 := F.X + F.W; F.Y1 := F.Y + F.H;
F.x := F.X + F.Xg; F.y := F.Y1 + F.Yg; F.marked := FALSE; F.mark.next := NIL;
Oberon.RemoveMarks(F.X, F.Y, F.W, F.H); Display.ReplConst(F.col, F.X, F.Y, F.W, F.H, 0);
IF F.ticked THEN
y := F.Yg MOD 16 + F.Y1 - 16; x0 := F.Xg MOD 16 + F.X;
WHILE y >= F.Y DO
x := x0;
WHILE x < F.X1 DO Display.Dot(Display.white, x, y, 0); INC(x, 16) END ;
DEC(y, 16)
END
END ;
M.f := F; M.x := F.x; M.y := F.y; M.col := 0; M.mode := 0; Graphics.Draw(F.graph, M)
END Restore;
PROCEDURE Focus*(): Frame;
VAR FQ: FocusQuery;
BEGIN FQ.f := NIL; Viewers.Broadcast(FQ); RETURN FQ.f
END Focus;
PROCEDURE Selected*(): Frame;
VAR SQ: SelQuery;
BEGIN SQ.f := NIL; SQ.time := 0; Viewers.Broadcast(SQ); RETURN SQ.f
END Selected;
PROCEDURE This*(x, y: INTEGER): Frame;
VAR PQ: PosQuery;
BEGIN PQ.f := NIL; PQ.x := x; PQ.y := y; Viewers.Broadcast(PQ); RETURN PQ.f
END This;
PROCEDURE Draw*(F: Frame);
VAR UM: UpdateMsg;
BEGIN UM.id := drawsel; UM.graph := F.graph; Viewers.Broadcast(UM)
END Draw;
PROCEDURE DrawNorm(F: Frame);
VAR UM: UpdateMsg;
BEGIN UM.id := drawnorm; UM.graph := F.graph; Viewers.Broadcast(UM)
END DrawNorm;
PROCEDURE Erase*(F: Frame);
VAR UM: UpdateMsg;
BEGIN UM.id := drawdel; UM.graph := F.graph; Viewers.Broadcast(UM)
END Erase;
PROCEDURE DrawObj*(F: Frame; obj: Graphics.Object);
VAR UM: UpdateMsg;
BEGIN UM.id := drawobj; UM.graph := F.graph; UM.obj := obj; Viewers.Broadcast(UM)
END DrawObj;
PROCEDURE EraseObj*(F: Frame; obj: Graphics.Object);
VAR UM: UpdateMsg;
BEGIN UM.id := drawobjd; UM.graph := F.graph; UM.obj := obj; Viewers.Broadcast(UM)
END EraseObj;
PROCEDURE Change*(F: Frame; VAR msg: Graphics.Msg);
BEGIN
IF F # NIL THEN Erase(F); Graphics.Handle(F.graph, msg); Draw(F) END
END Change;
PROCEDURE FlipMark(x, y: INTEGER);
BEGIN
Display.ReplConst(Display.white, x-7, y, 15, 1, 2);
Display.ReplConst(Display.white, x, y-7, 1, 15, 2)
END FlipMark;
PROCEDURE Defocus*(F: Frame);
VAR m: Location;
BEGIN newcap := NIL;
IF F.marked THEN
FlipMark(F.mark.x, F.mark.y); m := F.mark.next;
WHILE m # NIL DO FlipMark(m.x, m.y); m := m.next END ;
F.marked := FALSE; F.mark.next := NIL
END
END Defocus;
PROCEDURE Deselect*(F: Frame);
VAR UM: UpdateMsg;
BEGIN
IF F # NIL THEN
UM.id := drawnorm; UM.graph := F.graph; Viewers.Broadcast(UM);
Graphics.Deselect(F.graph)
END
END Deselect;
PROCEDURE Macro*(VAR Lname, Mname: ARRAY OF CHAR);
VAR x, y: INTEGER;
F: Frame;
mac: Graphics.Macro; mh: Graphics.MacHead;
L: Graphics.Library;
BEGIN F := Focus();
IF F # NIL THEN
x := F.mark.x - F.x; y := F.mark.y - F.y;
L := Graphics.ThisLib(Lname, FALSE);
IF L # NIL THEN
mh := Graphics.ThisMac(L, Mname);
IF mh # NIL THEN
Deselect(F); Defocus(F);
NEW(mac); mac.x := x; mac.y := y; mac.w := mh.w; mac.h := mh.h;
mac.mac := mh; mac.do := Graphics.MacMethod; mac.col := Oberon.CurCol;
Graphics.Add(F.graph, mac); DrawObj(F, mac)
END
END
END
END Macro;
PROCEDURE CaptionCopy(F: Frame;
x1, y1: INTEGER; T: Texts.Text; beg, end: LONGINT): Graphics.Caption;
VAR ch: CHAR;
dx, w, x2, y2, w1, h1: INTEGER;
cap: Graphics.Caption;
pat: Display.Pattern;
R: Texts.Reader;
BEGIN Texts.Write(W, 0DX);
NEW(cap); cap.len := SHORT(end - beg);
cap.pos := SHORT(Graphics.T.len)+1; cap.do := Graphics.CapMethod;
Texts.OpenReader(R, T, beg); Texts.Read(R, ch); W.fnt := R.fnt; W.col := R.col; w := 0;
cap.x := x1 - F.x; cap.y := y1 - F.y + R.fnt.minY;
WHILE beg < end DO
Display.GetChar(R.fnt.raster, ch, dx, x2, y2, w1, h1, pat);
INC(w, dx); INC(beg); Texts.Write(W, ch); Texts.Read(R, ch)
END ;
cap.w := w; cap.h := W.fnt.height; cap.col := W.col;
Texts.Append(Graphics.T, W.buf); Graphics.Add(F.graph, cap); RETURN cap
END CaptionCopy;
PROCEDURE SendCaption(cap: Graphics.Caption);
VAR M: Oberon.CopyOverMsg;
BEGIN
M. text := Graphics.T; M.beg := cap.pos; M.end := M.beg + cap.len; Viewers.Broadcast(M)
END SendCaption;
PROCEDURE Edit(F: Frame; x0, y0: INTEGER; k0: SET);
VAR obj: Graphics.Object;
x1, y1, w, h, t: INTEGER;
beg, end, time: LONGINT;
k1, k2: SET;
mark, newmark: Location;
T: Texts.Text;
Fd: Frame;
G: Graphics.Graph;
CM: CtrlMsg;
PROCEDURE NewLine(x, y, w, h: INTEGER);
VAR line: Graphics.Line;
BEGIN NEW(line); line.col := Oberon.CurCol; line.x := x - F.x; line.y := y - F.y;
line.w := w; line.h := h; line.do := Graphics.LineMethod; Graphics.Add(G, line)
END NewLine;
BEGIN k1 := k0; G := F.graph;
IF k0 = {1} THEN
obj := Graphics.ThisObj(G, x0 - F.x, y0 - F.y);
IF (obj # NIL) & ~obj.selected THEN
CM.f := F; CM.res := 0; obj.do.handle(obj, CM);
IF CM.res # 0 THEN (*done*) k0 := {} END
END
END ;
REPEAT Input.Mouse(k2, x1, y1); k1 := k1 + k2;
DEC(x1, (x1-F.x) MOD 4); DEC(y1, (y1-F.y) MOD 4);
Oberon.DrawCursor(Oberon.Mouse, Oberon.Arrow, x1, y1)
UNTIL k2 = {};
Oberon.FadeCursor(Oberon.Mouse);
IF k0 = {2} THEN (*left key*)
w := ABS(x1-x0); h := ABS(y1-y0);
IF k1 = {2} THEN
IF (w < 7) & (h < 7) THEN (*set mark*)
IF (x1 - markW >= F.X) & (x1 + markW < F.X1) &
(y1 - markW >= F.Y) & (y1 + markW < F.Y1) THEN
Defocus(F); Oberon.PassFocus(Viewers.This(F.X, F.Y));
F.mark.x := x1; F.mark.y := y1; F.marked := TRUE; FlipMark(x1, y1)
END
ELSE (*draw line*) Deselect(F);
IF w < h THEN
IF y1 < y0 THEN y0 := y1 END ;
NewLine(x0, y0, Graphics.width, h)
ELSE
IF x1 < x0 THEN x0 := x1 END ;
NewLine(x0, y0, w, Graphics.width)
END ;
Draw(F)
END
ELSIF k1 = {2, 1} THEN (*copy selection to caret mark*)
Deselect(F); Oberon.GetSelection(T, beg, end, time);
IF time >= 0 THEN DrawObj(F, CaptionCopy(F, x1, y1, T, beg, end)) END
ELSIF k1 = {2, 0} THEN
IF F.marked THEN (*set secondary mark*)
NEW(newmark); newmark.x := x1; newmark.y := y1; newmark.next := NIL;
FlipMark(x1, y1); mark := F.mark.next;
IF mark = NIL THEN F.mark.next := newmark ELSE
WHILE mark.next # NIL DO mark := mark.next END ;
mark.next := newmark
END
END
END
ELSIF k0 = {1} THEN (*middle key*)
IF k1 = {1} THEN (*move*)
IF (x0 # x1) OR (y0 # y1) THEN
Fd := This(x1, y1); Erase(F);
IF Fd = F THEN Graphics.Move(G, x1-x0, y1-y0)
ELSIF (Fd # NIL) & (Fd.graph = G) THEN
Graphics.Move(G, (x1-Fd.x-x0+F.x) DIV 4 * 4, (y1-Fd.y-y0+F.y) DIV 4 * 4)
END ;
Draw(F)
END
ELS