home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari FTP
/
ATARI_FTP_0693.zip
/
ATARI_FTP_0693
/
Tex
/
td187src.lzh
/
MTPOPUPS.I
< prev
next >
Wrap
Text File
|
1991-06-08
|
17KB
|
549 lines
(*#######################################################################
M A G I C P O P U P S
#######################################################################
V1.01 19.11.90 Peter Hellinger Popups können jetzt analog zu
den MagicDials verschoben werden
V1.00 21.10.90 Peter Hellinger
V0.01 02.09.90 Peter Hellinger
#######################################################################*)
IMPLEMENTATION MODULE mtPopups;
(*------------------------------*)
(* COMPILERSWITCHES *)
(*------------------------------*)
(* TDI-Version: DEAKTIVIERT *)
(*------------------------------*)
(* V- Overflow-Checks *)
(* R- Range-Checks *)
(* S- Stack-Check *)
(* N- NIL-Checks *)
(* T- TDI-Compiler vor 3.01 *)
(* Q+ Branch statt Jumps *)
(* *)
(*------------------------------*)
(* MM2-Version: AKTIVIERT *)
(*------------------------------*)
(*$R- Range-Checks *)
(*$S- Stack-Check *)
(* *)
(*------------------------------*)
FROM SYSTEM IMPORT ADDRESS, ADR;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
FROM MagicSys IMPORT Nil, Null, Bit0, Bit1, Bit2, Bit3, Bit4, Bit5, Bit6, Bit7,
Bit8, Bit9, Bit10, Bit11, Bit12, Bit13, Bit14, Bit15,
LOC, Byte, ByteSet, sWORD, sINTEGER, sCARDINAL, sBITSET,
lWORD, lINTEGER, lCARDINAL, lBITSET,
CastToChar, CastToByte, CastToByteset, CastToInt,
CastToCard, CastToBitset, CastToWord, CastToLInt,
CastToLCard, CastToLBitset, CastToLWord, CastToAddr;
FROM MagicAES IMPORT GBOX, GTEXT, GBOXTEXT, GIBOX, GSTRING, GTITLE,
Exit, DISABLED, OBJECT, ObjcDraw, ObjcFind, TEDINFO,
BEGMCTRL, ENDMCTRL, WindUpdate, WFFULLXYWH, WindGet,
FormButton, GrafHandle, MUKEYBD, MUBUTTON, MUM1,
MUM2, MUMESAG, MUTIMER, EvntMulti, AESIntIn, AESIntOut,
AESCall;
FROM mtAppl IMPORT VDIHandle, MouseOn, MouseOff, MouseArrow, MouseHand;
FROM mtArea IMPORT AREA, NewAREA, DisposeAREA, FreeArea, SaveArea,
CopyArea, RestoreArea, MOVEUP, MOVEDOWN, MOVELEFT,
MOVERIGHT, MoveArea;
FROM MagicStrings IMPORT Assign, Append, Length;
IMPORT MagicAES, MagicVDI;
TYPE tRect = RECORD
x: sINTEGER;
y: sINTEGER;
w: sINTEGER;
h: sINTEGER;
END;
TYPE obTree = POINTER TO ARRAY [0..1000] OF MagicAES.OBJECT;
tString = ARRAY [0..40] OF CHAR;
tTedPtr = POINTER TO TEDINFO;
VAR Main: ARRAY [0..51] OF OBJECT;
MainTitle: TEDINFO;
Sub: ARRAY [0..51] OF OBJECT;
SubTitle: TEDINFO;
mainArea: AREA;
subArea: AREA;
frontArea: AREA;
SubBegin: sINTEGER;
b: sBITSET;
bool, rekExit: BOOLEAN;
screen: tRect;
chW, chH: sINTEGER;
bW, bH: sINTEGER;
mW, mH: sINTEGER;
PROCEDURE scanType (t: obTree; entry, flag: sINTEGER): sINTEGER;
(* Scannt nach einem bestimmten Typflag *)
VAR o, r: INTEGER;
BEGIN
o:= entry;
WHILE (o >= entry) DO
WITH t^[o] DO
IF flag = obType THEN rekExit:= TRUE; RETURN o; END;
IF (obHead > -1) THEN
r:= scanType (t, obHead, flag);
IF rekExit THEN RETURN r; END;
END;
o:= obNext;
END;
END;
RETURN 0;
END scanType;
PROCEDURE SameLength (menu: obTree; num, max: sINTEGER);
VAR i: sINTEGER;
BEGIN
FOR i:= 0 TO num - 1 DO menu^[i].obWidth:= max; END;
END SameLength;
PROCEDURE PosMenu (menu: obTree; ob, maxW, maxH: sINTEGER);
VAR x, y: sINTEGER;
b: sBITSET;
BEGIN
WITH menu^[0] DO
IF ob > 0 THEN
x:= Main[0].obX + Main[ob].obX + (Main[ob].obWidth DIV 2);
y:= Main[0].obY + Main[ob].obY - (chW DIV 2);
ELSE
MagicAES.GrafMkstate (x, y, b, b);
END;
obX:= x; obY:= y; obWidth:= maxW; obHeight:= maxH;
IF (obX + obWidth) > mW THEN obX:= mW - obWidth - 1; END;
IF (obY + obHeight) > mH THEN obY:= mH - obHeight - 1; END;
IF obX < screen.x THEN obX:= screen.x + 1; END;
IF obY < screen.y THEN obY:= screen.y + 1; END;
END;
END PosMenu;
PROCEDURE calcArea (tree: obTree; VAR frame: sINTEGER; VAR r: tRect);
(* berechnet das umgebende Rechteck des Basis-Objekts *)
VAR x: sINTEGER;
BEGIN
frame:= ORD(tree^[0].Box.frame) + 1;
IF (frame > 127) THEN frame:= 257 - frame; END;
r.x:= tree^[0].obX - frame;
r.y:= tree^[0].obY - frame;
r.w:= tree^[0].obWidth + (frame * 2);
r.h:= tree^[0].obHeight + (frame * 2);
END calcArea;
PROCEDURE DoEvent (VAR x, y: sINTEGER;
VAR button: sBITSET;
VAR scan: sINTEGER): sBITSET;
VAR event: sBITSET;
i: sINTEGER;
split: RECORD
CASE: BOOLEAN OF
TRUE: wert: sINTEGER;|
FALSE: hi: CHAR;
lo: CHAR;|
END;
END;
BEGIN
(* Array's laden *)
event:= {MUKEYBD, MUTIMER, MUBUTTON};
AESIntIn[ 0]:= CastToInt (event);
AESIntIn[ 1]:= 257;
AESIntIn[ 2]:= 3;
AESIntIn[ 3]:= 0;
AESIntIn[14]:= 0;
AESIntIn[15]:= 0;
i:= AESCall(25, 16, 7, 1, 0);
event:= CastToBitset (i);
x:= AESIntOut[1];
y:= AESIntOut[2];
button:= CastToBitset (AESIntOut[3]);
(* kbshift:= CastToBitset (AESIntOut[4]); *)
split.wert:= AESIntOut[5];
scan:= CastToInt (split.hi);
(* ascii:= split.lo; *)
RETURN event;
END DoEvent;
PROCEDURE ScreenDim (VAR cw, ch, bw, bh, mw, mh: sINTEGER);
VAR i: sINTEGER;
BEGIN
MagicAES.GrafHandle (i, cw, ch, bw, bh);
MagicAES.WindGet (0, 7, screen);
mw:= screen.x + screen.w - 1;
mh:= screen.y + screen.h - 1;
END ScreenDim;
PROCEDURE Entprelle;
VAR x, y: sINTEGER;
button: sBITSET;
BEGIN
REPEAT
MagicAES.GrafMkstate (x, y, button, b);
UNTIL button = {};
END Entprelle;
PROCEDURE DoMenu (t: obTree; area: AREA): sINTEGER;
CONST Links = Bit0;
Rechts = Bit1;
VAR x, y, ox, oy, i, f, j, o, d, xx, yy: sINTEGER;
ob, oldob, taste, scan, clicks: sINTEGER;
button, kbshift, event: sBITSET;
ascii: CHAR;
fr: tRect;
PROCEDURE DrawBar (o: sINTEGER);
VAR r: tRect;
BEGIN
IF o > 0 THEN
r.x:= t^[0].obX + t^[o].obX;
r.y:= t^[0].obY + t^[o].obY;
r.w:= r.x + t^[o].obWidth - 1;
r.h:= r.y + t^[o].obHeight - 1;
MagicVDI.Bar (VDIHandle, r);
END;
END DrawBar;
BEGIN
i:= MagicVDI.SetWritemode (VDIHandle, MagicVDI.XOR);
i:= MagicVDI.SetFillcolor (VDIHandle, 1);
bool:= MagicVDI.SetFillperimeter (VDIHandle, FALSE);
oldob:= -1; ob:= -1; ox:= -1; oy:= -1;
WindUpdate (BEGMCTRL);
LOOP
event:= DoEvent (x, y, button, scan);
(* Objekt finden *)
IF (x # ox) OR (y # oy) THEN
ob:= MagicAES.ObjcFind (t, 0, 999, x, y);
ox:= x;
oy:= y;
END;
IF (MUKEYBD IN event) THEN
CASE scan OF
114,
28: (* Objekt selektiert *)
MouseOff; DrawBar (oldob); MouseOn; EXIT;|
72: o:= ob;
IF o > 2 THEN
DEC (o);
IF (DISABLED IN t^[o].obState) THEN DEC (o); END;
IF o >= 2 THEN ob:= o; END;
ELSE
ob:= t^[0].obTail;
END;
|
80: o:= ob;
IF (o < t^[0].obTail) AND (o > 1) THEN
INC (o);
IF (DISABLED IN t^[o].obState) THEN INC (o); END;
IF o <= t^[0].obTail THEN ob:= o; END;
ELSE
ob:= 2;
END;
|
97: MouseOff; DrawBar (oldob); MouseOn; ob:= -1; EXIT;
|
ELSE ;
END;
END;
(* Rechte Maustaste? *)
IF (MUBUTTON IN event) AND (Rechts IN button) THEN
Entprelle; MouseOff; DrawBar (oldob); MouseOn; ob:= -1; EXIT;
END;
(* Objekt gültig? *)
IF (ob > 1) AND NOT (DISABLED IN t^[ob].obState) THEN
(* Objekt selektiert? *)
IF ob # oldob THEN
MouseOff;
DrawBar (oldob);
DrawBar (ob);
oldob:= ob;
MouseOn;
END;
(* Linke Maustaste? *)
IF (MUBUTTON IN event) AND (Links IN button) THEN
Entprelle; MouseOff; DrawBar (oldob); MouseOn; EXIT;
END;
ELSIF (ob = 1) THEN
IF (MUBUTTON IN event) AND (Links IN button) THEN
MouseHand;
LOOP
MagicAES.GrafMkstate (x, y, button, b);
IF NOT (Links IN button) THEN EXIT; END;
IF (x # ox) OR (y # oy) THEN
calcArea (t, f, fr);
bool:= SaveArea (frontArea, fr);
(* Vertikale Bewegung *)
d:= oy - y;
IF (d > 0) THEN (* Menü nach oben bewegt *)
MoveArea (area, d, MOVEUP, xx, yy);
t^[0].obY:= yy + f;
ELSIF (d < 0) THEN (* Menü nach unten bewegt *)
MoveArea (area, ABS(d), MOVEDOWN, xx, yy);
t^[0].obY:= yy + f;
END;
calcArea (t, f, fr);
CopyArea (frontArea, fr.x, fr.y);
(* Horizontale Bewegung *)
d:= ox - x;;
IF (d > 0) THEN (* Menü nach links bewegt *)
MoveArea (area, d, MOVELEFT, xx, yy);
t^[0].obX:= xx + f;
ELSIF (d < 0) THEN (* Dialog nach rechts bewegt *)
MoveArea (area, ABS(d), MOVERIGHT, xx, yy);
t^[0].obX:= xx + f;
END;
calcArea (t, f, fr);
CopyArea (frontArea, fr.x, fr.y);
ox:= x; oy:= y;
END;
END; (* LOOP *)
calcArea (t, f, fr);
CopyArea (frontArea, fr.x, fr.y);
MouseArrow;
FreeArea (frontArea);
END;
END;
END; (* LOOP *)
i:= MagicVDI.SetWritemode (VDIHandle, MagicVDI.REPLACE);
WindUpdate (ENDMCTRL);
RETURN ob;
END DoMenu;
PROCEDURE MakeMenu (tree, menu: obTree; title: ADDRESS;
subnum, type: sINTEGER): sINTEGER;
VAR maxW, maxH, num, i, j, ob, len, offset: sINTEGER;
ted: tTedPtr;
BEGIN
ted:= title; len:= ted^.teTxtlen;
j:= 0; num:= 0; maxW:= (len + 4) * chW; maxH:= chH + 1;
(*-- Basisobjekt --*)
menu^[num].obNext:= -1;
menu^[num].obHead:= 1;
menu^[num].obTail:= 0;
menu^[num].obType:= GBOX;
menu^[num].obFlags:= {};
menu^[num].obState:= {};
menu^[num].Box.char:= 0C;
menu^[num].Box.frame:= 377C;
menu^[num].Box.flags:= {Bit15, Bit11};
menu^[num].obX:= 0;
menu^[num].obY:= 0;
menu^[num].obWidth:= 0;
menu^[num].obHeight:= 0;
INC (num);
(*-- Titelzeile --*)
menu^[num].obNext:= -1;
menu^[num].obHead:= -1;
menu^[num].obTail:= -1;
menu^[num].obType:= GBOXTEXT;
menu^[num].obFlags:= {};
menu^[num].obState:= {};
menu^[num].TedPtr:= title;
menu^[num].obX:= 0;
menu^[num].obY:= 0;
menu^[num].obWidth:= 0;
menu^[num].obHeight:= chH;
MagicAES.ObjcAdd (menu, 0, num);
INC (num);
(*-- Suchposition im Baum festlegen --*)
IF subnum > 0 THEN
ob:= SubBegin + 1;
FOR j:= 1 TO (subnum - 3) DO ob:= tree^[ob].obNext; END;
IF ob < SubBegin THEN RETURN -1; END;
offset:= ob - 1;
j:= tree^[ob].obHead;
ELSE
ob:= 2; offset:= 1; j:= 0;
END;
(*-- Objekte addieren --*)
LOOP
i:= scanType (tree, j, type);
IF tree^[i].obWidth > maxW THEN maxW:= tree^[i].obWidth; END;
menu^[num].obNext:= -1;
menu^[num].obHead:= -1;
menu^[num].obTail:= -1;
menu^[num].obType:= tree^[i].obType;
menu^[num].obFlags:= tree^[i].obFlags;
menu^[num].obState:= tree^[i].obState;
menu^[num].StringPtr:= tree^[i].StringPtr;
menu^[num].obX:= 0;
menu^[num].obY:= maxH;
menu^[num].obWidth:= tree^[i].obWidth;
menu^[num].obHeight:= chH;
MagicAES.ObjcAdd (menu, 0, num);
INC (num);
INC (maxH, chH); j:= i + 1;
IF i = tree^[ob].obTail THEN EXIT; END;
END;
SameLength (menu, num, maxW);
PosMenu (menu, subnum, maxW, maxH);
(*-- Offset für weitere Suche merken --*)
IF subnum = 0 THEN SubBegin:= j; END;
RETURN offset;
END MakeMenu;
PROCEDURE PopupMenu (menu: ADDRESS; title: ARRAY OF CHAR): sINTEGER;
VAR i, j, m, s, ret, len, ob, oldob, off1, off2: sINTEGER;
r: tRect;
bool: BOOLEAN;
t: obTree;
BEGIN
IF menu = NIL THEN RETURN -1; END;
ScreenDim (chW, chH, bW, bH, mW, mH);
ret:= -1; t:= menu; len:= Length (title); j:= 0;
MainTitle.tePtext:= ADR (title);
MainTitle.tePtmplt:= ADR (title);
MainTitle.tePvalid:= ADR (title);
MainTitle.teFont:= 3;
MainTitle.teResvd1:= 0;
MainTitle.teJust:= 2;
MainTitle.teColor:= 011A1H;
MainTitle.teResvd2:= 0;
MainTitle.teThickness:= -1;
MainTitle.teTxtlen:= len;
MainTitle.teTmplen:= len;
off1:= MakeMenu (t, ADR(Main), ADR(MainTitle), 0, GTITLE);
calcArea (ADR(Main), j, r);
bool:= SaveArea (mainArea, r);
ObjcDraw (ADR(Main), 0, 51, screen);
MouseOn;
LOOP
m:= DoMenu (ADR(Main), mainArea) + off1;
IF m < 1 THEN ret:= -1; EXIT; END;
IF Exit IN t^[m].obFlags THEN ret:= m; EXIT; END;
IF m > 2 THEN
len:= Length (Main[m - off1].StringPtr^);
SubTitle.tePtext:= ADDRESS (Main[m - off1].StringPtr);
SubTitle.tePtmplt:= ADDRESS (Main[m - off1].StringPtr);
SubTitle.tePvalid:= ADDRESS (Main[m - off1].StringPtr);
SubTitle.teFont:= 3;
SubTitle.teResvd1:= 0;
SubTitle.teJust:= 2;
SubTitle.teColor:= 011A1H;
SubTitle.teResvd2:= 0;
SubTitle.teThickness:= -1;
SubTitle.teTxtlen:= len;
SubTitle.teTmplen:= len;
off2:= MakeMenu (t, ADR(Sub), ADR(SubTitle), m, GSTRING);
calcArea (ADR(Sub), j, r);
bool:= SaveArea (subArea, r);
ObjcDraw (ADR(Sub), 0, 51, screen);
s:= DoMenu (ADR(Sub), subArea);
RestoreArea (subArea);
IF s > 0 THEN ret:= s + off2; EXIT; END;
END; (* IF m > 2 *)
END; (* LOOP *)
RestoreArea (mainArea);
FreeArea (subArea);
FreeArea (mainArea);
RETURN ret;
END PopupMenu;
PROCEDURE StringPopup (VAR string: ARRAY OF CHAR; title: ARRAY OF CHAR): sINTEGER;
VAR i, j, m, s, l1, l2, maxW, maxH, num: sINTEGER;
mr, sr: tRect;
bool: BOOLEAN;
StrArray: ARRAY [0..49] OF tString;
t: obTree;
BEGIN
ScreenDim (chW, chH, bW, bH, mW, mH);
l1:= Length (string); l2:= Length (title);
i:= 0; j:= 0; num:= 0;
(*-- Basisobjekt --*)
Main[num].obNext:= -1;
Main[num].obHead:= 1;
Main[num].obTail:= 0;
Main[num].obType:= GBOX;
Main[num].obFlags:= {};
Main[num].obState:= {};
Main[num].Box.char:= 0C;
Main[num].Box.frame:= 377C;
Main[num].Box.flags:= {Bit15, Bit11};
Main[num].obX:= 0;
Main[num].obY:= 0;
Main[num].obWidth:= 0;
Main[num].obHeight:= 0;
INC (num);
(*-- Titelzeile --*)
Main[num].obNext:= -1;
Main[num].obHead:= -1;
Main[num].obTail:= -1;
Main[num].obType:= GBOXTEXT;
Main[num].obFlags:= {};
Main[num].obState:= {};
Main[num].TedPtr:= ADR(MainTitle);
Main[num].obX:= 0;
Main[num].obY:= 0;
Main[num].obWidth:= 0;
Main[num].obHeight:= chH;
MagicAES.ObjcAdd (ADR(Main), 0, num);
INC (num);
MainTitle.tePtext:= ADR (title);
MainTitle.tePtmplt:= ADR (title);
MainTitle.tePvalid:= ADR (title);
MainTitle.teFont:= 3;
MainTitle.teResvd1:= 0;
MainTitle.teJust:= 2;
MainTitle.teColor:= 011A1H;
MainTitle.teResvd2:= 0;
MainTitle.teThickness:= -1;
MainTitle.teTxtlen:= l2;
MainTitle.teTmplen:= l2;
i:= 0; j:= 0; maxW:= (l2 + 2)* chW; maxH:= chH + 1;
LOOP
s:= 0;
WHILE (i < l1) AND (string[i] # '|') AND (s < 40) DO
StrArray[j, s]:= string[i]; INC (i); INC (s);
END;
StrArray[j, s]:= 0C;
Main[num].obNext:= -1;
Main[num].obHead:= -1;
Main[num].obTail:= -1;
Main[num].obType:= GSTRING;
Main[num].obFlags:= {};
Main[num].obState:= {};
Main[num].StringPtr:= ADR(StrArray[j]);
Main[num].obX:= 0;
Main[num].obY:= maxH;
Main[num].obWidth:= (s + 2) * chW;
IF Main[num].obWidth > maxW THEN maxW:= Main[num].obWidth; END;
Main[num].obHeight:= chH;
MagicAES.ObjcAdd (ADR(Main), 0, num);
INC (num); INC (j); INC (maxH, chH);
IF string[i] = 0C THEN EXIT; ELSE INC (i); END;
END;
SameLength (ADR(Main), num, maxW);
PosMenu (ADR(Main), 0, maxW, maxH);
calcArea (ADR(Main), j, mr);
bool:= SaveArea (mainArea, mr);
MouseOn;
ObjcDraw (ADR(Main), 0, 51, screen);
m:= DoMenu (ADR(Main), mainArea);
RestoreArea (mainArea);
FreeArea (mainArea);
IF m > 0 THEN RETURN m - 1; ELSE RETURN -1; END;
END StringPopup;
BEGIN
bool:= NewAREA (mainArea);
bool:= NewAREA (subArea);
bool:= NewAREA (frontArea);
END mtPopups.