home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 10
/
Fresh_Fish_10_2352.bin
/
new
/
dev
/
obero
/
oberon
/
projectoberonsrc
/
graphics.mod
(
.txt
)
< prev
next >
Wrap
Oberon Text
|
1994-10-17
|
21KB
|
569 lines
Syntax10.Scn.Fnt
MODULE Graphics; (*NW 21.12.89 / 3.2.92*)
IMPORT Files, Modules, Display, Fonts, Printer, Texts, Oberon;
CONST NameLen* = 16; GraphFileId = 0F9X; LibFileId = 0FDX;
TYPE
Graph* = POINTER TO GraphDesc;
Object* = POINTER TO ObjectDesc;
Method* = POINTER TO MethodDesc;
Line* = POINTER TO LineDesc;
Caption* = POINTER TO CaptionDesc;
Macro* = POINTER TO MacroDesc;
ObjectDesc* = RECORD
x*, y*, w*, h*, col*: INTEGER;
selected*, marked*: BOOLEAN;
do*: Method;
next, dmy: Object
END ;
Msg* = RECORD END ;
WidMsg* = RECORD (Msg) w*: INTEGER END ;
ColorMsg* = RECORD (Msg) col*: INTEGER END ;
FontMsg* = RECORD (Msg) fnt*: Fonts.Font END ;
Name* = ARRAY NameLen OF CHAR;
GraphDesc* = RECORD
time*: LONGINT;
sel*, first: Object
END ;
MacHead* = POINTER TO MacHeadDesc;
MacExt* = POINTER TO MacExtDesc;
Library* = POINTER TO LibraryDesc;
MacHeadDesc* = RECORD
name*: Name;
w*, h*: INTEGER;
ext*: MacExt;
lib*: Library;
first: Object;
next: MacHead
END ;
LibraryDesc* = RECORD
name*: Name;
first: MacHead;
next: Library
END ;
MacExtDesc* = RECORD END ;
Context* = RECORD
nofonts, noflibs, nofclasses: INTEGER;
font: ARRAY 10 OF Fonts.Font;
lib: ARRAY 4 OF Library;
class: ARRAY 10 OF Modules.Command
END;
MethodDesc* = RECORD
module*, allocator*: Name;
new*: Modules.Command;
copy*: PROCEDURE (from, to: Object);
draw*, handle*: PROCEDURE (obj: Object; VAR msg: Msg);
selectable*: PROCEDURE (obj: Object; x, y: INTEGER): BOOLEAN;
read*: PROCEDURE (obj: Object; VAR R: Files.Rider; VAR C: Context);
write*: PROCEDURE (obj: Object; cno: SHORTINT; VAR R: Files.Rider; VAR C: Context);
print*: PROCEDURE (obj: Object; x, y: INTEGER)
END ;
LineDesc* = RECORD (ObjectDesc)
END ;
CaptionDesc* = RECORD (ObjectDesc)
pos*, len*: INTEGER
END ;
MacroDesc* = RECORD (ObjectDesc)
mac*: MacHead
END ;
VAR new*: Object;
width*, res*: INTEGER;
T*: Texts.Text; (*captions*)
LineMethod*, CapMethod*, MacMethod* : Method;
FirstLib: Library;
W, TW: Texts.Writer;
PROCEDURE Add*(G: Graph; obj: Object);
BEGIN obj.marked := FALSE; obj.selected := TRUE; obj.next := G.first;
G.first := obj; G.sel := obj; G.time := Oberon.Time()
END Add;
PROCEDURE Draw*(G: Graph; VAR M: Msg);
VAR obj: Object;
BEGIN obj := G.first;
WHILE obj # NIL DO obj.do.draw(obj, M); obj := obj.next END
END Draw;
PROCEDURE ThisObj*(G: Graph; x, y: INTEGER): Object;
VAR obj: Object;
BEGIN obj := G.first;
WHILE (obj # NIL) & ~obj.do.selectable(obj, x ,y) DO obj := obj.next END ;
RETURN obj
END ThisObj;
PROCEDURE SelectObj*(G: Graph; obj: Object);
BEGIN
IF obj # NIL THEN obj.selected := TRUE; G.sel := obj; G.time := Oberon.Time() END
END SelectObj;
PROCEDURE SelectArea*(G: Graph; x0, y0, x1, y1: INTEGER);
VAR obj: Object; t: INTEGER;
BEGIN obj := G.first;
IF x1 < x0 THEN t := x0; x0 := x1; x1 := t END ;
IF y1 < y0 THEN t := y0; y0 := y1; y1 := t END ;
WHILE obj # NIL DO
IF (x0 <= obj.x) & (obj.x + obj.w <= x1) & (y0 <= obj.y) & (obj.y + obj.h <= y1) THEN
obj.selected := TRUE; G.sel := obj
END ;
obj := obj.next
END ;
IF G.sel # NIL THEN G.time := Oberon.Time() END
END SelectArea;
PROCEDURE Enumerate*(G: Graph; handle: PROCEDURE (obj: Object; VAR done: BOOLEAN));
VAR obj: Object; done: BOOLEAN;
BEGIN done := FALSE; obj := G.first;
WHILE (obj # NIL) & ~done DO handle(obj, done); obj := obj.next END
END Enumerate;
(*----------------procedures operating on selection -------------------*)
PROCEDURE Deselect*(G: Graph);
VAR obj: Object;
BEGIN obj := G.first; G.sel := NIL; G.time := 0;
WHILE obj # NIL DO obj.selected := FALSE; obj := obj.next END
END Deselect;
PROCEDURE DrawSel*(G: Graph; VAR M: Msg);
VAR obj: Object;
BEGIN obj := G.first;
WHILE obj # NIL DO
IF obj.selected THEN obj.do.draw(obj, M) END ;
obj := obj.next
END
END DrawSel;
PROCEDURE Handle*(G: Graph; VAR M: Msg);
VAR obj: Object;
BEGIN obj := G.first;
WHILE obj # NIL DO
IF obj.selected THEN obj.do.handle(obj, M) END ;
obj := obj.next
END
END Handle;
PROCEDURE Move*(G: Graph; dx, dy: INTEGER);
VAR obj, ob0: Object; x0, x1, y0, y1: INTEGER;
BEGIN obj := G.first;
WHILE obj # NIL DO
IF obj.selected & ~(obj IS Caption) THEN
x0 := obj.x; x1 := obj.w + x0; y0 := obj.y; y1 := obj.h + y0;
IF dx = 0 THEN (*vertical move*)
ob0 := G.first;
WHILE ob0 # NIL DO
IF ~ob0.selected & (ob0 IS Line) & (x0 <= ob0.x) & (ob0.x <= x1) & (ob0.w < ob0.h) THEN
IF (y0 <= ob0.y) & (ob0.y <= y1) THEN
INC(ob0.y, dy); DEC(ob0.h, dy); ob0.marked := TRUE
ELSIF (y0 <= ob0.y + ob0.h) & (ob0.y + ob0.h <= y1) THEN
INC(ob0.h, dy); ob0.marked := TRUE
END
END ;
ob0 := ob0.next
END
ELSIF dy = 0 THEN (*horizontal move*)
ob0 := G.first;
WHILE ob0 # NIL DO
IF ~ob0.selected & (ob0 IS Line) & (y0 <= ob0.y) & (ob0.y <= y1) & (ob0.h < ob0.w) THEN
IF (x0 <= ob0.x) & (ob0.x <= x1) THEN
INC(ob0.x, dx); DEC(ob0.w, dx); ob0.marked := TRUE
ELSIF (x0 <= ob0.x + ob0.w) & (ob0.x + ob0.w <= x1) THEN
INC(ob0.w, dx); ob0.marked := TRUE
END
END ;
ob0 := ob0.next
END
END
END ;
obj := obj.next
END ;
obj := G.first; (*now move*)
WHILE obj # NIL DO
IF obj.selected THEN INC(obj.x, dx); INC(obj.y, dy) END ;
obj.marked := FALSE; obj := obj.next
END
END Move;
PROCEDURE Copy*(Gs, Gd: Graph; dx, dy: INTEGER);
VAR obj: Object;
BEGIN obj := Gs.first;
WHILE obj # NIL DO
IF obj.selected THEN
obj.do.new; obj.do.copy(obj, new); INC(new.x, dx); INC(new.y, dy);
obj.selected := FALSE; Add(Gd, new)
END ;
obj := obj.next
END ;
new := NIL
END Copy;
PROCEDURE Delete*(G: Graph);
VAR obj, pred: Object;
BEGIN G.sel := NIL; obj := G.first;
WHILE (obj # NIL) & obj.selected DO obj := obj.next END ;
G.first := obj;
IF obj # NIL THEN
pred := obj; obj := obj.next;
WHILE obj # NIL DO
IF obj.selected THEN pred.next := obj.next ELSE pred := obj END ;
obj := obj.next
END
END
END Delete;
(* ---------------------- Storing ----------------------- *)
PROCEDURE WMsg(s0, s1: ARRAY OF CHAR);
BEGIN Texts.WriteString(W, s0); Texts.WriteString(W, s1);
Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
END WMsg;
PROCEDURE InitContext(VAR C: Context);
BEGIN C.nofonts := 0; C.noflibs := 0; C.nofclasses := 4;
C.class[1] := LineMethod.new; C.class[2] := CapMethod.new; C.class[3] := MacMethod.new
END InitContext;
PROCEDURE FontNo*(VAR W: Files.Rider; VAR C: Context; fnt: Fonts.Font): SHORTINT;
VAR fno: SHORTINT;
BEGIN fno := 0;
WHILE (fno < C.nofonts) & (C.font[fno] # fnt) DO INC(fno) END ;
IF fno = C.nofonts THEN
Files.Write(W, 0); Files.Write(W, 0); Files.Write(W, fno);
Files.WriteString(W, fnt.name); C.font[fno] := fnt; INC(C.nofonts)
END ;
RETURN fno
END FontNo;
PROCEDURE StoreElems(VAR W: Files.Rider; VAR C: Context; obj: Object);
VAR cno: INTEGER;
BEGIN
WHILE obj # NIL DO
cno := 1;
WHILE (cno < C.nofclasses) & (obj.do.new # C.class[cno]) DO INC(cno) END ;
IF cno = C.nofclasses THEN
Files.Write(W, 0); Files.Write(W, 2); Files.Write(W, SHORT(cno));
Files.WriteString(W, obj.do.module); Files.WriteString(W, obj.do.allocator);
C.class[cno] := obj.do.new; INC(C.nofclasses)
END ;
obj.do.write(obj, SHORT(cno), W, C); obj := obj.next
END ;
Files.Write(W, -1)
END StoreElems;
PROCEDURE Store*(G: Graph; VAR W: Files.Rider);
VAR C: Context;
BEGIN InitContext(C); StoreElems(W, C, G.first)
END Store;
PROCEDURE WriteObj*(VAR W: Files.Rider; cno: SHORTINT; obj: Object);
BEGIN Files.Write(W, cno); Files.WriteInt(W, obj.x); Files.WriteInt(W, obj.y);
Files.WriteInt(W, obj.w); Files.WriteInt(W, obj.h); Files.WriteInt(W, obj.col)
END WriteObj;
PROCEDURE WriteFile*(G: Graph; name: ARRAY OF CHAR);
VAR F: Files.File; W: Files.Rider; C: Context;
BEGIN F := Files.New(name); Files.Set(W, F, 0); Files.Write(W, GraphFileId);
InitContext(C); StoreElems(W, C, G.first); Files.Register(