home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_GEN
/
GUITLS38.ZIP
/
GUITOOLS.MOD
< prev
next >
Wrap
Text File
|
1994-02-16
|
80KB
|
2,179 lines
(**********************************************************************
:Program. GUITools.mod
:Contents. Functions for creating and using GUIs
:Author. Carsten Ziegeler
:Address. Augustin-Wibbelt-Str.7, 33106 Paderborn, Germany
:Phone. 05254/67439
:Copyright. Freeware, refer to GUITools-Documentation
:Language. Modula-2
:Translator. M2Amiga V4.1
:Remark. OS 2.0 required
:Remark. see GUITools-Documentation for detailled information
:History. v38.0 Carsten Ziegeler 16-Feb-94
***********************************************************************)
(* ------------------------------------------------------------------------
Entwicklung:
25.03.1993 : Erste Definitionsversuche
10.04.1993 : VollfunktionsfΣhige Version mit allen n÷tigen Prozeduren
22.05.1993 : Kleinere MΣngel behoben, Konstanten fⁿr OpenIntScreen
Version 37.0
29.08.1993 : Kleinere Erweiterungen, Version 37.3 (First Release)
26.09.1993 : Keys-Support, alle Gadgets erhalten im userData-Feld
eine GUIGadgetInfo-Struktur, die z.T. PUBLIC ist.
Unterstⁿtzt alle Gadget-Kinds bis auf generic und palette
bis OS 2.04 (V37.175)
12.11.1993 : Intern wird nun jeder GUIInfoPtr mit zugeh÷rigem Window
gemerkt und bei CloseIntWindow ggf freigegeben !
18.11.1993 : OpenIntScreenTags, OpenIntWindowTags fⁿr mehr FlexibilitΣt
DrawBox, kleinere Verbesserungen beim Key-Handling
28.11.1993 : Beginn der Implementation von Resizable-Gadgets
01.12.1993 : Neue Font-Behandlung fⁿr Menⁿs ! Ende der Resizeable-Gads
04.12.1993 : CreateGUIInfoTags
05.12.1993 : Hook-Funktion fⁿr Key-Equivalente
17.12.1993 : CreateSpecialGadget / Refresh-Funktionen / Drawinfo
20.12.1993 : Verbesserung einer Funktionen / neues Memory-Management
22.12.1993 : Fehlerbehebung bei menuPick, menuHelp
02.01.1994 : Unterstⁿtzt nun alle Gadgets, weitere Fehler behoben
03.01.1994 : ShowRequester
06.01.1994 : Volle Requester-Unterstⁿtzung, RemoveGadgets/RemoveMenu
verbessert und erweitert
11.01.1994 : Fehler in RedrawGadgets behoben, nun volle SpecialGadgets-
Unterstⁿtzung mit Refresh
12.01.1994 : Erste Optimierungen + Laufzeitverbesserungen
23.01.1994 : ErklΣrungen in den Definitionsmodule ins Englische ⁿbersetzt
28.01.1994 : Fehler in RemoveGadgets behoben (CreateContext fehlte )
29.01.1994 : RememberTags filtert nun doppelte TagItems korrekt aus. Das-
selbe tun nun auch OpenIntWindowTags/OpenIntScreenTags.
31.01.1994 : Fehler bei Speicheranforderung behoben. DrawInfo war nicht
LONG ALIGNED !
06.02.1994 : Overflow-Problem bei DrawGadget behoben
08.02.1994 : Speicherfehler bei RemoveMenu/SetGUI behoben
RefreshWindowFrame ⁿber Tags eingefⁿhrt
09.02.1994 : Alle Tests erfolgreich durchgefⁿhrt. Shared-Library-Problem
bei OpenIntWindow behoben
16.02.1994 : Original DrawInfo-Struktur - keine Kopie mehr
Version 38.0 (Second Release)
(* --------------- Speicheranforderung von GUIInfo ----------------------- *)
In Wirklichkeit wird bedeutend mehr als nur die GUIInfo-Struktur angefordert.
"Dahinter" stehen noch folgende Strukturen (V38.0)
GUIWindowInfo dadurch kann ⁿber eine die globale Variable
allWindowsWithGUI eine Verkettung aller GUIInfo-Strukts
erreicht werden, so da▀ eine freigabe bei CloseIntWindow
leicht m÷glich ist
Des weiteren folgen nun die "variablen" EintrΣge. Fⁿr jedes Gadget werden
4 Bytes fⁿr den GadgetPtr reserviert, so da▀ alle Gadgets dann in einem
Array von GadgetPtr erreicht werden k÷nnen.
Fⁿr jeden Menu-Eintrag wird eine NewMenu-Struktur reserviert.
maxGads * 4 Array von GadgetPtr
maxMenus* SIZE(NewMenu) Array von NewMenu-Strukturen
REALGUILENGTH gibt die wirkliche LΣnge an, die reserviert wird, aber OHNE
die variablen EintrΣge !
GUIWININFO gibt den Offset der GUIWindowInfo-Struktur an
GUIEND gibt den Offset fⁿr die variablen EintrΣge an
(* ----------------- Bedeutung der Status-Flags -------------------------- *)
Die Flags belegen 16 Bit in sind in gui^.status abgelegt.
gadgetsSet Sind Gadgets im Window gesetzt
menuSet Menⁿ angehΣngt
rememberGadTags Alle Tags der Gadgets merken, fⁿr RedrawGadgets
redrawGads Informiert SetGUI, RedrawGadgets(.., FALSE)
Da nun SetGUI die deaktivierten Gadgets deaktivieren mu▀
und das erste EntryGadget ggf zur Eingabe freigibt
spezialGadsNoText GUITools-Gadgets nur neu zeichnen, nicht aber den Text
z.B fⁿr progressIndicator wenn sich nur Indicator Σndert
restoreProcessWindow bei Aufruf von FreeGUIInfo wird der windowPtr-Eintrag
der Process-Struktur restauriert
setProcessWindow Setzt bei CreateGUIInfoTags den windowPtr-Eintrag auf
das window
refreshWF Soll auch RefreshWindowFrame bei EndRefresh benutzt werden
(* ---------------------- interne Darstellung von GUIGadgetInfo (V38.0) -- *)
ScanGadget :
v3 enthΣlt immer noch die Gadget-Nummer
mxKind : v0 : gtmxActive
v1 : Anzahl an Auswahlm÷glichkeiten
cycleKind : v0 : gtcyActive
v1 : Anzahl an Auswahlm÷glichkeiten
checkboxKind : v0B : enthΣlt Status
sliderKind : v0S : gtslLevel
v1S : gtslMax
v2S : gtslMin
scrollerKind : v0S : gtscTop
v1S : gtscVisible
v2S : gtscTotal
listviewKind : v0 : gtlvSelected
v1 : Anzahl der EintrΣge (65535 bei 0 EintrΣgen)
paletteKind : v0 : gtpaColor
v1 : 2^gtpaDepth
v2 : gtpaColorOffset
progressIndicatorKind : v0 : piMax
v1 : piCurr
bevelboxKind : v0B : recessed
(* -------------------- Arbeitsweise von RememberTags ------------------ *)
INTERNE PROZEDUR, um die angegebenen Tags eines Gadgets zu merken, diese
werden in der im userData-Feld abgelegten Info-Struktur unter tags gemerkt,
nbrTags enthΣlt die Anzahl.
Die Tags, die Werte beinhalten, die ScanGadget sich merkt, werden ausge-
filtert. Es kann sein, da▀ schon eine Tag-Liste gemerkt wurde, dann wird
eine neue aus beiden erzeugt und die erste entfernt.
ZusΣtzlich wird ein weiteres Tag mit dem Wert tagMore angehΣngt !
impTags zeigt immer auf diesen tagMore-Tag bzw NIL
Des weiteren werden doppelte TagItems ausgefiltert.
(* ---------------- Making a shared library with M2LMC -------------------- *)
(M2LMC ⌐ C.Ziegeler is freeware. It helps converting "standard"-modules into
shared-libraries ! )
Please, do all this only with a copy of the needed files !!
Before you can convert GUITools with M2LMC you have to delete the following
procedures in the GUITools.def and GUITools.mod - File:
- ShowRequesterP
- SimpleReqP
After the conversion into a shared library with M2LMC you have to do some
changes/replacements in the file GUIToolsLib.mod before compiling !
- ConvKMsgToGMsg : Change all calls of GadWithKey into GadWithKeyE (2 x)
- OpenIntWindow: Replace old procedure with this one:
(*$ EntryExitCode:=FALSE *)
CONST wst = LONGCARD(waScreenTitle);
BEGIN
ASSEMBLE(MOVE.L A2, -(A7) MOVE.L #0, -(A7)
MOVE.L #tagEnd, -(A7) MOVE.L A0, -(A7)
MOVE.L #wst, -(A7) MOVE.L A7, A2
BSR.S OpenIntWindowTags
ADD.L #16, A7 MOVE.L (A7)+, A2
RTS END);
- OpenIntScreen: Replace old procedure with this one:
(*$ EntryExitCode:=FALSE *)
BEGIN
ASSEMBLE(MOVE.L A2, -(A7) MOVE.L #0, A2
BSR.S OpenIntScreenTags
MOVE.L (A7)+, A2 RTS END);
- SimpleReq: Replace old procedure with this one
(*$ EntryExitCode:=FALSE *)
BEGIN
ASSEMBLE(MOVE.L A0, A1 MOVE.L A2, -(A7) MOVE.L #0, A0 MOVE.L #0, A2
BSR.S ShowRequester MOVE.L (A7)+, A2 RTS END);
--------------------------------------------------------------------------- *)
IMPLEMENTATION MODULE GUITools;
(*$ NilChk:=FALSE EntryClear:=FALSE StackChk:=FALSE RangeChk:=FALSE
OverflowChk:=FALSE CaseChk:=FALSE ReturnChk:=FALSE LargeVars:=FALSE
*)
FROM SYSTEM IMPORT ADDRESS, ADR, CAST, LONGSET, TAG, WORD;
FROM DiskFontL IMPORT OpenDiskFont;
FROM ExecD IMPORT ListPtr, MemReqSet, MemReqs, MsgPort, NodePtr, Task;
FROM ExecL IMPORT AllocMem, FindTask, Forbid, FreeMem, Permit, WaitPort;
FROM GadToolsD IMPORT NewGadgetFlagSet, NewGadgetFlags, listviewKind,
mxKind, genericKind, numKinds, integerKind, cycleKind,
stringKind, sliderKind, scrollerKind, NewMenu, nmEnd,
checkboxKind, GtTags, checkboxWidth, checkboxHeight,
mxWidth, mxHeight, buttonKind, paletteKind;
FROM GraphicsD IMPORT TextAttrPtr, TextFontPtr, TextAttr, FontFlagSet,
FontStyleSet, FontFlags, jam1;
FROM GraphicsL IMPORT OpenFont, CloseFont, SetAPen, RectFill;
FROM IntuiMacros IMPORT MenuNum, ItemNum, SubNum, MenuItemUserData;
FROM IntuitionD IMPORT DrawInfoPtr, DrawInfo, Gadget, GadgetPtr, DrawPens,
ScreenPtr, WindowPtr, IDCMPFlagSet, IDCMPFlags,
WindowFlagSet, EasyStruct, EasyStructPtr,
IntuiTextPtr, MenuItemPtr, IntuiMessagePtr,
StringInfoPtr, GaTags, WaTags, publicScreen,
SaTags, IntuiText, GadgetFlags, menuNull, noItem;
FROM String IMPORT Copy, Occurs, noOccur;
FROM UtilityD IMPORT Tag, TagItem, TagItemPtr, tagMore, tagEnd,
tagFilterNOT, tagIgnore;
FROM UtilityL IMPORT FindTagItem, NextTagItem, ToUpper, CloneTagItems,
FreeTagItems, FilterTagItems;
IMPORT G : GadToolsL, I : IntuitionL;
TYPE
GUIWindowInfoPtr = POINTER TO GUIWindowInfo;
GUIWindowInfo = RECORD
next : GUIWindowInfoPtr;
prev : GUIWindowInfoPtr;
window : WindowPtr;
gui : GUIInfoPtr;
END;
ProcessPtr = POINTER TO Process; (* erspart Import von DosD ! *)
Process = RECORD
t : Task; m : MsgPort; p : WORD; unwichtig : ARRAY[0..13] OF LONGCARD;
windowPtr : WindowPtr;
END;
TAGARRAY = ARRAY[0..16] OF Tag;
CONST NOTREMEMBERTAGS = TAGARRAY{Tag(gtmxActive), Tag(gtcbChecked),
Tag(gtcyActive), Tag(gtslMin), Tag(gtslMax),
Tag(gtslLevel), Tag(gtscTop), Tag(gtscVisible), Tag(gtscTotal),
Tag(gtlvSelected), Tag(gtpaColorOffset), Tag(gtpaColor),
Tag(sgbbRecessed), Tag(sgpiCurrentValue), Tag(sgpiMaxValue),
Tag(gaDisabled), tagEnd};
REALGUISIZE = SIZE(GUIInfo) + SIZE(GUIWindowInfo);
GUIWININFO = SIZE(GUIInfo);
GUIEND = GUIWININFO + SIZE(GUIWindowInfo);
noKeyEqu = -1;
gadgetsSet = 0; menuSet = 1; rememberGadTags = 2; redrawGads = 3;
spezialGadsNoText = 4; restoreProcessWindow = 5; setProcessWindow = 6;
refreshWF = 7;
SPEZIALGADSIZE = SIZE(Gadget) + SIZE(IntuiText);
lvNotSel = 65535;
VAR allWindowsWithGUI : GUIWindowInfoPtr;
PROCEDURE SetGUIError(gui : GUIInfoPtr; error : INTEGER);
BEGIN
IF gui^.firstError = guiSet THEN gui^.firstError := error END;
END SetGUIError;
PROCEDURE CreateGUIInfo(window : WindowPtr;
maxGads, maxMenus : INTEGER) : GUIInfoPtr;
VAR gui : GUIInfoPtr;
BEGIN
gui := CreateGUIInfoTags(window, maxGads, maxMenus, NIL);
IF gui # NIL THEN
gui^.menuFont := ADR(gui^.font);
END;
RETURN gui;
END CreateGUIInfo;
PROCEDURE CreateGUIInfoTags(window : WindowPtr;
maxGads : INTEGER;
maxMenus : INTEGER;
tags : TagItemPtr) : GUIInfoPtr;
VAR gui : GUIInfoPtr;
next : TagItemPtr;
info : DrawInfoPtr;
winInf : GUIWindowInfoPtr;
length : LONGINT;
error : LONGINT;
i : INTEGER;
BEGIN
gui := NIL;
error := cgiNoError;
IF window # NIL THEN
length := REALGUISIZE;;
INC(length, maxGads * 4);
INC(length, maxMenus * SIZE(NewMenu));
gui := AllocMem(length, MemReqSet{memClear, public});
IF gui # NIL THEN
gui^.window := window;
WITH gui^ DO
firstError := guiSet;
gui^.screen := window^.wScreen;
FOR i := 0 TO 25 DO
keys[i] := noKeyEqu;
END;
prcwin := CAST(ProcessPtr, FindTask(NIL))^.windowPtr;
gadgets := ADDRESS(gui);
INC(gadgets, GUIEND);
newMenus := ADDRESS(gui);
INC(newMenus, GUIEND);
INC(newMenus, maxGads*4);
menuFont := screen^.font;
port := window^.userPort;
maxgads := maxGads;
maxmenus := maxMenus;
END;
WITH gui^.font DO
name := window^.rPort^.font^.message.node.name;
ySize := window^.rPort^.font^.ySize;
style := window^.rPort^.font^.style;
flags := window^.rPort^.font^.flags;
END;
gui^.visual := G.GetVisualInfoA(window^.wScreen, NIL);
IF gui^.visual # NIL THEN
gui^.drawinfo := I.GetScreenDrawInfo(window^.wScreen);
IF gui^.drawinfo # NIL THEN
IF (maxGads > 0) THEN
gui^.gad := G.CreateContext(gui^.gadlist);
WITH gui^.newgad DO
textAttr := ADR(gui^.font);
visualInfo := gui^.visual;
END;
IF gui^.gadlist = NIL THEN
error := cgiCreateContext;
I.FreeScreenDrawInfo(gui^.screen, gui^.drawinfo);
G.FreeVisualInfo(gui^.visual);
FreeMem(gui, length);
gui := NIL;
END;
END;
IF maxMenus > 0 THEN
gui^.newMenus^[0].type := nmEnd;
END;
ELSE
error := cgiNoDrawInfo;
G.FreeVisualInfo(gui^.visual);
FreeMem(gui, length);
gui := NIL;
END;
ELSE
error := cgiNoVisualInfo;
FreeMem(gui, length);
gui := NIL;
END;
ELSE
error := cgiNoMemory;
END;
ELSE
error := cgiNoWindow;
END;
IF gui # NIL THEN
winInf := ADDRESS(gui);
INC(winInf, GUIWININFO);
Forbid;
IF allWindowsWithGUI = NIL THEN
allWindowsWithGUI := winInf;
ELSE
winInf^.next := allWindowsWithGUI;
allWindowsWithGUI^.prev := winInf;
allWindowsWithGUI := winInf;
END;
winInf^.window := window;
winInf^.gui := gui;
Permit;
END;
IF tags # NIL THEN
next := NextTagItem(tags);
WHILE next # NIL DO
IF gui # NIL THEN
IF next^.tag = Tag(guiResizableGads) THEN
IF next^.data # 0 THEN
INCL(gui^.status, rememberGadTags);
INCL(gui^.status, refreshWF);
ELSE
EXCL(gui^.status, rememberGadTags);
EXCL(gui^.status, refreshWF);
END;
ELSIF next^.tag = Tag(guiFlags) THEN
gui^.flags := CAST(GUIInfoFlagSet, next^.data);
ELSIF next^.tag = Tag(guiGadFont) THEN
gui^.newgad.textAttr := TextAttrPtr(next^.data);
ELSIF next^.tag = Tag(guiMenuFont) THEN
gui^.menuFont := TextAttrPtr(next^.data);
ELSIF next^.tag = Tag(guiVanKeyFct) THEN
gui^.vanKeyHook := CAST(VanKeyFct, next^.data);
ELSIF next^.tag = Tag(guiSetProcessWindow) THEN
IF next^.data # 0 THEN
INCL(gui^.status, setProcessWindow);
ELSE
EXCL(gui^.status, setProcessWindow);
END;
ELSIF next^.tag = Tag(guiRestoreProcessWindow) THEN
IF next^.data # 0 THEN
INCL(gui^.status, restoreProcessWindow);
ELSE
EXCL(gui^.status, restoreProcessWindow);
END;
ELSIF next^.tag = Tag(guiRefreshWindowFrame) THEN
IF next^.data # 0 THEN
INCL(gui^.status, refreshWF);
ELSE
EXCL(gui^.status, refreshWF);
END;
END;
END;
IF next^.tag = Tag(guiCreateError) THEN
IF next^.data # 0 THEN
CAST(LINTPTR, next^.data)^ := error;
END;
END;
next := NextTagItem(tags);
END;
END;
IF (gui # NIL) AND (setProcessWindow IN gui^.status) THEN
CAST(ProcessPtr, FindTask(NIL))^.windowPtr := window;
END;
RETURN gui;
END CreateGUIInfoTags;
PROCEDURE FreeGUIInfo(gui : GUIInfoPtr);
VAR winInf : GUIWindowInfoPtr;
BEGIN
IF gui # NIL THEN
winInf := ADDRESS(gui);
INC(winInf, GUIWININFO);
Forbid;
IF winInf^.prev = NIL THEN
allWindowsWithGUI := winInf^.next;
ELSE
winInf^.prev^.next := winInf^.next;
END;
IF winInf^.next # NIL THEN
winInf^.next^.prev := winInf^.prev;
END;
Permit;
RemoveGadgets(gui, TRUE);
RemoveMenu(gui, TRUE);
WITH gui^ DO
IF gadlist # NIL THEN G.FreeGadgets(gadlist) END;
IF restoreProcessWindow IN status THEN
CAST(ProcessPtr, FindTask(NIL))^.windowPtr := prcwin;
END;
IF visual # NIL THEN G.FreeVisualInfo(visual) END;
IF drawinfo # NIL THEN I.FreeScreenDrawInfo(screen, drawinfo) END;
FreeMem(gui, REALGUISIZE + maxgads*4 + maxmenus*SIZE(NewMenu));
END;
END;
END FreeGUIInfo;
(* INTERNE PROZEDUR, um Gadget-Text zu berechnen darzustellen *)
PROCEDURE CalcText(gui : GUIInfoPtr; Gadget : GadgetPtr);
VAR text : IntuiTextPtr;
flags : NewGadgetFlagSet;
length: LONGINT;
ysize : INTEGER;
BEGIN
text := Gadget^.gadgetText;
IF text^.iText # NIL THEN
flags := CAST(NewGadgetFlagSet, Gadget^.specialInfo);
WITH text^ DO
frontPen := gui^.drawinfo^.pens^[textPen];
backPen := gui^.drawinfo^.pens^[backGroundPen];
drawMode := jam1;
leftEdge := Gadget^.leftEdge;
topEdge := Gadget^.topEdge;
length := I.IntuiTextLength(text);
ysize := text^.iTextFont^.ySize;
IF placetextLeft IN flags THEN
DEC(leftEdge, length+2);
INC(topEdge, (Gadget^.height - ysize) DIV 2);
ELSIF placetextRight IN flags THEN
INC(leftEdge, Gadget^.width+2);
INC(topEdge, (Gadget^.height - ysize) DIV 2);
ELSIF placetextAbove IN flags THEN
INC(leftEdge, (Gadget^.width - length) DIV 2);
DEC(topEdge, 2+ysize);
ELSIF placetextBelow IN flags THEN
INC(leftEdge, (Gadget^.width - length) DIV 2);
INC(topEdge, Gadget^.height+2);
ELSIF placetextIn IN flags THEN
INC(leftEdge, (Gadget^.width - length) DIV 2);
INC(topEdge, (Gadget^.height - ysize) DIV 2);
END;
IF ngHighlabel IN flags THEN
frontPen := gui^.drawinfo^.pens^[highLightTextPen];
END;
END;
END;
END CalcText;
(* INTERNE PROZEDUR, um die spezial-gadget-kinds zu zeichen *)
PROCEDURE DrawGadget(gui : GUIInfoPtr;
Gadget: GadgetPtr;
ginfo : GUIGadgetInfoPtr);
VAR oldAPen : INTEGER;
cut : LONGINT;
BEGIN
IF ginfo^.kind = progressIndicatorKind THEN
DrawBox(gui, Gadget^.leftEdge, Gadget^.topEdge,
Gadget^.width, Gadget^.height, TRUE);
oldAPen := gui^.window^.rPort^.fgPen;
WITH Gadget^ DO
IF ginfo^.v1 > 0 THEN
cut := LONGINT(width-3) * LONGINT(ginfo^.v1S) DIV LONGINT(ginfo^.v0S);
SetAPen(gui^.window^.rPort, gui^.drawinfo^.pens^[fillPen]);
RectFill(gui^.window^.rPort, leftEdge + 2, topEdge + 1,
leftEdge + cut, topEdge + height - 2);
END;
IF ginfo^.v1S < ginfo^.v0S THEN
SetAPen(gui^.window^.rPort, gui^.drawinfo^.pens^[backGroundPen]);
cut := LONGINT(width-3) * LONGINT(ginfo^.v1S) DIV LONGINT(ginfo^.v0S);
RectFill(gui^.window^.rPort, leftEdge + cut + 1,
topEdge + 1, leftEdge + width - 3, topEdge + height - 2);
END;
END;
SetAPen(gui^.window^.rPort, oldAPen);
ELSIF ginfo^.kind = bevelboxKind THEN
DrawBox(gui, Gadget^.leftEdge, Gadget^.topEdge,
Gadget^.width, Gadget^.height, ginfo^.v0B);
END;
IF (~(spezialGadsNoText IN gui^.status)) AND
(Gadget^.gadgetText^.iText # NIL) THEN
I.PrintIText(gui^.window^.rPort, Gadget^.gadgetText, 0, 0);
END;
END DrawGadget;
PROCEDURE SetGUI(gui : GUIInfoPtr) : INTEGER;
VAR Gadget : GadgetPtr;
buffer : ARRAY[0..1] OF TagItem;
i : INTEGER;
BEGIN
WITH gui^ DO
IF (firstError = guiSet) AND (~(gadgetsSet IN status)) AND
(gadlist # NIL) AND (gad # NIL) THEN
IF I.AddGList(window, gadlist, -1, -1, NIL) = 0 THEN END;
I.RefreshGList(gadlist, window, NIL, -1);
G.GTRefreshWindow(window, NIL);
IF (activateFirstEGad IN flags) AND (firstEGad # NIL) THEN
IF I.ActivateGadget(firstEGad, window, NIL) THEN END;
END;
INCL(status, gadgetsSet);
Gadget := spezialGad;
WHILE Gadget # NIL DO
DrawGadget(gui, Gadget, Gadget^.userData);
Gadget := Gadget^.nextGadget;
END;
IF redrawGads IN status THEN
FOR i := 0 TO actgad-1 DO
IF ~(CAST(GUIGadgetInfoPtr,
gadgets^[i]^.userData)^.gadActive) THEN
GadgetStatus(gui, i, FALSE);
END;
END;
EXCL(status, redrawGads);
END;
ELSE
SetGUIError(gui, gadgetError);
END;
END;
IF (gui^.firstError = guiSet) AND (~(menuSet IN gui^.status)) AND
(gui^.actmenu > 0) THEN
gui^.menus := G.CreateMenusA(ADDRESS(gui^.newMenus), NIL);
IF gui^.menus # NIL THEN
IF G.LayoutMenusA(gui^.menus, gui^.visual, TAG(buffer,
gtmnTextAttr, gui^.menuFont, tagEnd)) THEN
IF I.SetMenuStrip(gui^.window, gui^.menus) THEN
INCL(gui^.status, menuSet);
ELSE
SetGUIError(gui, menuSetError);
G.FreeMenus(gui^.menus);
gui^.menus := NIL;
END;
ELSE
SetGUIError(gui, menuLayoutError);
G.FreeMenus(gui^.menus);
gui^.menus := NIL;
END;
ELSE
SetGUIError(gui, menuError);
END;
END;
RETURN gui^.firstError;
END SetGUI;
(* INTERNE PROCEDURE, um Gadget-spezifische Parameter festzustellen *)
PROCEDURE ScanGadget(ginfo : GUIGadgetInfoPtr; tags:TagItemPtr;
create : BOOLEAN);
VAR tag : TagItemPtr;
list : ListPtr;
node : NodePtr;
i : CARDINAL;
PROCEDURE LoadVX(sTag : Tag; adr : CARDPTR; default : CARDINAL);
BEGIN
tag := FindTagItem(sTag, tags);
IF tag # NIL THEN
adr^ := CARDINAL(tag^.data);
ELSIF create THEN
adr^ := default;
END;
END LoadVX;
PROCEDURE LoadLabelsV1(sTag : Tag);
VAR labPtr : POINTER TO ADDRESS;
BEGIN
tag := FindTagItem(sTag, tags);
IF tag # NIL THEN
ginfo^.v1 := 0;
labPtr := ADDRESS(tag^.data);
WHILE labPtr^ # NIL DO
INC(ginfo^.v1);
INC(labPtr, 4);
END;
END;
END LoadLabelsV1;
PROCEDURE LoadV0B(sTag : Tag);
BEGIN
tag := FindTagItem(sTag, tags);
IF tag # NIL THEN
ginfo^.v0B := tag^.data # 0;
ELSIF create THEN
ginfo^.v0B := FALSE;
END;
END LoadV0B;
PROCEDURE LoadVXS(sTag : Tag; adr : INTPTR; default : INTEGER);
BEGIN
tag := FindTagItem(sTag, tags);
IF tag # NIL THEN
adr^ := INTEGER(tag^.data);
ELSIF create THEN
adr^ := default;
END;
END LoadVXS;
BEGIN
CASE ginfo^.kind OF
mxKind : LoadVX(Tag(gtmxActive), ADR(ginfo^.v0), 0);
LoadLabelsV1(Tag(gtmxLabels));
| cycleKind : LoadVX(Tag(gtcyActive), ADR(ginfo^.v0), 0);
LoadLabelsV1(Tag(gtcyLabels));
| checkboxKind : LoadV0B(Tag(gtcbChecked));
| sliderKind : LoadVXS(Tag(gtslMin), ADR(ginfo^.v2S), 0);
LoadVXS(Tag(gtslMax), ADR(ginfo^.v1S), 15);
LoadVXS(Tag(gtslLevel), ADR(ginfo^.v0S), 0);
| scrollerKind : LoadVXS(Tag(gtscTop), ADR(ginfo^.v0S), 0);
LoadVXS(Tag(gtscVisible), ADR(ginfo^.v1S), 2);
LoadVXS(Tag(gtscTotal), ADR(ginfo^.v2S), 0);
| listviewKind : LoadVX(Tag(gtlvSelected), ADR(ginfo^.v0), lvNotSel);
tag := FindTagItem(Tag(gtlvLabels), tags);
IF tag # NIL THEN
IF tag^.lidata = -1 THEN
ginfo^.v0 := lvNotSel;
ginfo^.v1 := lvNotSel;
ELSE
list := ADDRESS(tag^.data);
IF list^.head^.succ = NIL THEN (* Liste leer*)
ginfo^.v0 := lvNotSel;
ginfo^.v1 := lvNotSel;
ELSE
ginfo^.v1 := 0;
node := list^.head;
WHILE node^.succ # NIL DO
INC(ginfo^.v1);
node := node^.succ;
END;
END;
END;
ELSIF create THEN
ginfo^.v0 := lvNotSel;
ginfo^.v1 := lvNotSel;
END;
| paletteKind : LoadVX(Tag(gtpaColor), ADR(ginfo^.v0), 1);
tag := FindTagItem(Tag(gtpaDepth), tags);
IF tag # NIL THEN
ginfo^.v1 := 1;
FOR i := 1 TO CARDINAL(tag^.data) DO
ginfo^.v1 := ginfo^.v1 * 2;
END;
ELSIF create THEN
ginfo^.v1 := 2;
END;
LoadVX(Tag(gtpaColorOffset), ADR(ginfo^.v2), 0);
ELSE
IF ginfo^.kind = progressIndicatorKind THEN
LoadVX(Tag(sgpiMaxValue), ADR(ginfo^.v0), 100);
LoadVX(Tag(sgpiCurrentValue), ADR(ginfo^.v1), 0);
ELSIF ginfo^.kind = bevelboxKind THEN
LoadV0B(Tag(sgbbRecessed));
END;
END;
tag := FindTagItem(Tag(gaDisabled), tags);
IF tag # NIL THEN
ginfo^.gadActive := tag^.data = 0;
ELSIF create THEN
ginfo^.gadActive := TRUE;
END;
END ScanGadget;
PROCEDURE RememberTags(ginfo : GUIGadgetInfoPtr; tags : TagItemPtr);
VAR nbr : LONGCARD;
newchain: TagItemPtr;
oldTags : TagItemPtr;
newTags : TagItemPtr;
next : TagItemPtr;
i : CARDINAL;
BEGIN
IF tags # NIL THEN
newchain := CloneTagItems(tags);
IF newchain # NIL THEN
nbr := FilterTagItems(newchain, ADR(NOTREMEMBERTAGS), tagFilterNOT);
IF nbr > 0 THEN (* gibt es ⁿberhaupt welche ? *)
IF ginfo^.nbrTags = 0 THEN (* ein Platz fⁿr tagMore *)
INC(nbr);
ELSE (* Doppelte Tags suchen ! *)
next := ginfo^.tags;
FOR i := 1 TO ginfo^.nbrTags-1 DO
newTags := FindTagItem(next^.tag, newchain);
IF newTags # NIL THEN
DEC(nbr);
next^.data := newTags^.data;
newTags^.tag := tagIgnore;
END;
END;
END;
IF nbr > 0 THEN
newTags := AllocMem(SIZE(TagItem) * (nbr + ginfo^.nbrTags),
MemReqSet{memClear});
ELSE
newTags := NIL;
END;
IF newTags # NIL THEN
ginfo^.impTags := NIL;
oldTags := ginfo^.tags;
next := oldTags;
ginfo^.tags := newTags;
IF ginfo^.nbrTags > 0 THEN
FOR i := 1 TO ginfo^.nbrTags-1 DO (* alte Tags kopieren *)
newTags^ := next^; (* bis auf tagMore *)
INC(newTags, SIZE(TagItem));
INC(next, SIZE(TagItem));
END;
FreeMem(oldTags, SIZE(TagItem) * ginfo^.nbrTags);
END;
INC(ginfo^.nbrTags, nbr);
oldTags := newchain;
next := NextTagItem(oldTags);
WHILE next # NIL DO
newTags^ := next^;
INC(newTags, SIZE(TagItem));
next := NextTagItem(oldTags);
END;
ginfo^.impTags := newTags;
END;
END;
END;
FreeTagItems(newchain);
END;
END RememberTags;
PROCEDURE CreateGadget(gui : GUIInfoPtr;
left, top, width, height : INTEGER;
kind : LONGCARD;
tags : TagItemPtr);
TYPE CHARARR4 = ARRAY[0..3] OF CHAR;
VAR pointer : LONGCARD;
tag : TagItemPtr;
newtags : TagItemPtr;
ginfo : GUIGadgetInfoPtr;
buffer : ARRAY[0..5] OF LONGCARD;
keyPos : INTEGER;
key : ARRAY[0..1] OF CHAR;
BEGIN
WITH gui^ DO
gadget := NIL;
IF (kind >= numKinds) AND (G.gadtoolsBase^.version <= 39) THEN
SetGUIError(gui, noGadToolsGadKind);
gad := NIL;
RETURN;
END;
IF (actgad < maxgads) AND (~(gadgetsSet IN status)) THEN
IF gad # NIL THEN (* ggf Standardgr÷▀en eintragen *)
IF addStdUnderscore IN flags THEN (* gtUnderscore-Tag *)
newtags := TAG(buffer, gtUnderscore, '_',
tagMore, tags, NIL);
IF tags = NIL THEN buffer[2] := tagEnd END;
ELSE
newtags := tags;
END;
IF kind = checkboxKind THEN
IF width = 0 THEN width := checkboxWidth END;
IF height = 0 THEN height := checkboxHeight END;
ELSIF kind = mxKind THEN
IF width = 0 THEN width := mxWidth END;
IF height = 0 THEN height := mxHeight END;
ELSIF (kind = stringKind) OR (kind = integerKind) THEN
IF height = 0 THEN height := newgad.textAttr^.ySize + 4 END;
END;
IF addBorderDims IN flags THEN
INC(left, window^.borderLeft);
INC(top, window^.borderTop);
END;
newgad.leftEdge := left;
newgad.topEdge := top;
newgad.width := width;
newgad.height := height;
tag := NIL; (* TAG-Liste ggf korrigieren fⁿr Notify *)
IF (kind = stringKind) AND (stringNotify IN flags) THEN
tag := FindTagItem(Tag(gtstString), newtags);
IF tag # NIL THEN pointer := tag^.data END;
(* Bei Strings nur suchen, nicht Σndern *)
ELSIF (kind = integerKind) AND (integerNotify IN flags) THEN
tag := FindTagItem(Tag(gtinNumber), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.data := LONGCARD(LINTPTR(tag^.data)^);
END;
ELSIF (kind = checkboxKind) AND (checkboxNotify IN flags) THEN
tag := FindTagItem(Tag(gtcbChecked), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.data := LONGCARD(BOOLPTR(tag^.data)^);
END;
ELSIF (kind = mxKind) AND (mxNotify IN flags) THEN
tag := FindTagItem(Tag(gtmxActive), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.data := LONGCARD(CARDPTR(tag^.data)^);
END;
ELSIF (kind = cycleKind) AND (cycleNotify IN flags) THEN
tag := FindTagItem(Tag(gtcyActive), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.data := LONGCARD(CARDPTR(tag^.data)^);
END;
ELSIF (kind = sliderKind) AND (sliderNotify IN flags) THEN
tag := FindTagItem(Tag(gtslLevel), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.lidata := LONGINT(INTPTR(tag^.data)^);
END;
ELSIF (kind = scrollerKind) AND (scrollerNotify IN flags) THEN
tag := FindTagItem(Tag(gtscTop), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.lidata := LONGINT(INTPTR(tag^.data)^);
END;
ELSIF (kind = listviewKind) AND (listviewNotify IN flags) THEN
tag := FindTagItem(Tag(gtlvSelected), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.data := LONGCARD(CARDPTR(tag^.data)^);
END;
ELSIF (kind = paletteKind) AND (paletteNotify IN flags) THEN
tag := FindTagItem(Tag(gtpaColor), newtags);
IF tag # NIL THEN
pointer := tag^.data;
tag^.data := LONGCARD(CARDPTR(tag^.data)^);
END;
END;
gad := G.CreateGadgetA(kind, gad^, newgad, newtags);
IF gad # NIL THEN (* GUIGadgetInfo in userData eintragen !*)
ginfo := AllocMem(SIZE(GUIGadgetInfo), MemReqSet{memClear});
IF ginfo # NIL THEN
(* Zeiger auf erstes Gadget merken *)
IF firstGad = NIL THEN
firstGad := ginfo;
ELSE (* alle weiteren mitteinander verketten *)
CAST(GUIGadgetInfoPtr,
gadgets^[actgad-1]^.userData)^.nextGadInfo := ginfo;
END;
ginfo^.userData := newgad.userData;
ginfo^.kind := kind;
ginfo^.v3 := actgad;
gad^.userData := ginfo;
ScanGadget(ginfo, newtags, TRUE);(* Spezifische Params ermitteln*)
IF rememberGadTags IN status THEN
RememberTags(ginfo, newtags); (* Tags merken ! *)
END;
IF tag # NIL THEN (* Alte TAG-List wieder herstellen *)
tag^.data := pointer;
ginfo^.buffer := ADDRESS(tag^.data); (* und Notify an*)
ginfo^.onlyIntern := internMsgHandling IN flags;
(* Intern macht nur Sinn, wenn die entsprechenden Notifys an
sind ! Bei buttonKind also nicht) *)
ELSE
ginfo^.onlyIntern := FALSE;
END;
ginfo^.lvClearTime := lvKeyClearTime IN flags;
(* Gad-Desc merken *)
ginfo^.gadDesc := newgad;
(* ggf EntryGadgets +verbinden+ *)
IF ((kind = integerKind) OR (kind = stringKind))
AND (linkEntryGads IN flags) THEN
IF firstEGad = NIL THEN firstEGad := gad END;
IF lastEGad # NIL THEN
CAST(GUIGadgetInfoPtr, lastEGad^.userData)^.nextEGad := gad;
CAST(GUIGadgetInfoPtr,
lastEGad^.userData)^.nextEGadNbr := actgad;
END;
lastEGad := gad;
IF cycleEntryGads IN flags THEN
ginfo^.nextEGad := firstEGad;
ginfo^.nextEGadNbr := CAST(GUIGadgetInfoPtr,
firstEGad^.userData)^.v3;
END;
END;
(* ggf Key-Equivalent eintragen *)
IF vanillaKeysNotify IN flags THEN
tag := FindTagItem(Tag(gtUnderscore), newtags);
IF tag # NIL THEN
key[0] := CAST(CHARARR4, tag^.data)[3];
key[1] := 0C;
IF newgad.gadgetText # NIL THEN
keyPos := Occurs(STRPTR(newgad.gadgetText)^, 0, key, TRUE);
ELSE
keyPos := noOccur;
END;
IF keyPos # noOccur THEN
INC(keyPos);
key[0] := ToUpper(STRPTR(newgad.gadgetText)^[keyPos]);
IF (key[0] >= 'A') AND (key[0] <= 'Z') THEN
IF keys[ORD(key[0]) - ORD('A')] = noKeyEqu THEN
keys[ORD(key[0]) - ORD('A')] := actgad;
ELSE
SetGUIError(gui, gadKeyDefTwice);
gad := NIL;
END;
ELSIF ~(allowAllVanillaKeys IN flags) THEN
SetGUIError(gui, gadKeyNotAllowed);
gad := NIL;
END;
ELSE
SetGUIError(gui, gadKeyNotFound);
gad := NIL;
END;
END;
END;
gadgets^[actgad] := gad; (* nΣchstes Gad vorbereiten *)
gadget := gad;
INC(actgad);
INC(newgad.gadgetID);
newgad.gadgetText := NIL;
ELSE
SetGUIError(gui, memError);
gad := NIL;
END; (* IF ginfo # NIL *)
END;
END;
ELSE
SetGUIError(gui, tooManyGadsError);
gad := NIL;
END;
END; (* WITH gui^ *)
END CreateGadget;
PROCEDURE CreateGadgetText(gui : GUIInfoPtr;
left, top, width, height : INTEGER;
kind : LONGCARD;
text : ADDRESS;
tags : TagItemPtr);
BEGIN
gui^.newgad.gadgetText := text;
CreateGadget(gui, left, top, width, height, kind, tags);
END CreateGadgetText;
PROCEDURE CreateGadgetFull(gui : GUIInfoPtr;
left, top, width, height : INTEGER;
kind : LONGCARD;
text : ADDRESS;
place: NewGadgetFlagSet;
tags : TagItemPtr);
BEGIN
WITH gui^.newgad DO
gadgetText := text;
flags := place;
END;
CreateGadget(gui, left, top, width, height, kind, tags);
END CreateGadgetFull;
PROCEDURE MakeMenuEntry(gui : GUIInfoPtr; type : SHORTCARD;
text, key : ADDRESS);
BEGIN
WITH gui^ DO
IF (actmenu < (maxmenus-1)) AND (~(menuSet IN status)) THEN
newMenus^[actmenu].type := type;
newMenus^[actmenu].label := text;
newMenus^[actmenu].commKey := key;
menuAdr := ADR(newMenus^[actmenu]);
INC(actmenu);
newMenus^[actmenu].type := nmEnd;
ELSE
menuAdr := NIL;
SetGUIError(gui, tooManyMenusError);
END;
END;
END MakeMenuEntry;
PROCEDURE GadWithKey(gui : GUIInfoPtr; nbr : INTEGER; shift : BOOLEAN);
VAR ginfo : GUIGadgetInfoPtr;
pointer: ADDRESS;
buffer : ARRAY[0..2] OF TagItem;
BEGIN
WITH gui^ DO
gadget := gadgets^[nbr];
gadID := gadget^.gadgetID;
ginfo := gadget^.userData;
IF gadgDisabled IN gadget^.flags THEN
msgClass := IDCMPFlagSet{};
cardCode := 0;
ginfo := NIL; (* Damit nicht in CASE-Zweig gelangt wird *)
END;
IF ginfo # NIL THEN
gadNbr := ginfo^.v3;
CASE ginfo^.kind OF
buttonKind : msgClass := IDCMPFlagSet{gadgetUp};
cardCode := 0;
| stringKind : IF I.ActivateGadget(gadget, window, NIL) THEN END;
cardCode := 0;
msgClass := IDCMPFlagSet{gadgetDown};
| integerKind: IF I.ActivateGadget(gadget, window, NIL) THEN END;
cardCode := 0;
msgClass := IDCMPFlagSet{gadgetDown};
| checkboxKind:msgClass := IDCMPFlagSet{gadgetUp};
IF ginfo^.buffer # NIL THEN
ginfo^.bool^ := ~(ginfo^.bool^);
END;
ginfo^.v0B := ~ginfo^.v0B;
pointer := TAG(buffer, gtcbChecked, ginfo^.v0B, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
charCode := 0C;
boolCode := ginfo^.v0B;
| mxKind : msgClass := IDCMPFlagSet{gadgetDown};
IF shift THEN
IF ginfo^.v0 = 0 THEN
ginfo^.v0 := ginfo^.v1-1;
ELSE
DEC(ginfo^.v0);
END;
ELSE
IF ginfo^.v0 = ginfo^.v1-1 THEN
ginfo^.v0 := 0;
ELSE
INC(ginfo^.v0);
END;
END;
IF ginfo^.card # NIL THEN
ginfo^.card^ := ginfo^.v0;
END;
cardCode := ginfo^.v0;
pointer := TAG(buffer, gtmxActive, ginfo^.v0, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
| cycleKind : msgClass := IDCMPFlagSet{gadgetUp};
IF shift THEN
IF ginfo^.v0 = 0 THEN
ginfo^.v0 := ginfo^.v1-1;
ELSE
DEC(ginfo^.v0);
END;
ELSE
IF ginfo^.v0 = ginfo^.v1-1 THEN
ginfo^.v0 := 0;
ELSE
INC(ginfo^.v0);
END;
END;
IF ginfo^.card # NIL THEN
ginfo^.card^ := ginfo^.v0;
END;
cardCode := ginfo^.v0;
pointer := TAG(buffer, gtcyActive, ginfo^.v0, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
| sliderKind : msgClass := IDCMPFlagSet{gadgetUp};
IF shift THEN
IF ginfo^.v0S > ginfo^.v2S THEN
DEC(ginfo^.v0S);
END;
ELSIF ginfo^.v0S < ginfo^.v1S THEN
INC(ginfo^.v0S);
END;
IF ginfo^.int # NIL THEN
ginfo^.int^ := ginfo^.v0S;
END;
intCode := ginfo^.v0S;
pointer := TAG(buffer, gtslLevel, ginfo^.v0S, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
| paletteKind :msgClass := IDCMPFlagSet{gadgetUp};
IF shift THEN
IF ginfo^.v0 > ginfo^.v2 THEN
DEC(ginfo^.v0);
END;
ELSIF ginfo^.v0 < ginfo^.v1-1 THEN
INC(ginfo^.v0);
END;
IF ginfo^.card # NIL THEN
ginfo^.card^ := ginfo^.v0;
END;
cardCode := ginfo^.v0;
pointer := TAG(buffer, gtpaColor, ginfo^.v0, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
| scrollerKind:msgClass := IDCMPFlagSet{gadgetUp};
IF shift THEN
IF ginfo^.v0S > 0 THEN
DEC(ginfo^.v0S);
END;
ELSIF ginfo^.v0S < ginfo^.v2S THEN
INC(ginfo^.v0S);
END;
IF ginfo^.int # NIL THEN
ginfo^.int^ := ginfo^.v0S;
END;
intCode := ginfo^.v0S;
pointer := TAG(buffer, gtscTop, ginfo^.v0S, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
| listviewKind:msgClass := IDCMPFlagSet{gadgetUp};
IF ginfo^.v1 # lvNotSel THEN
IF shift THEN
IF ginfo^.v0 = lvNotSel THEN
ginfo^.v0 := ginfo^.v1-1;
ELSIF ginfo^.v0 > 0 THEN
DEC(ginfo^.v0);
END;
ELSE
IF ginfo^.v0 = lvNotSel THEN
ginfo^.v0 := 0;
ELSIF ginfo^.v0 < ginfo^.v1-1 THEN
INC(ginfo^.v0);
END;
END;
IF ginfo^.card # NIL THEN
ginfo^.card^ := ginfo^.v0;
END;
cardCode := ginfo^.v0;
pointer := TAG(buffer,
gtlvSelected, ginfo^.v0,
gtlvTop, ginfo^.v0, tagEnd);
G.GTSetGadgetAttrsA(gadget, window, NIL, pointer);
ELSE
msgClass := IDCMPFlagSet{};
cardCode := lvNotSel;
END;
IF ginfo^.lvClearTime THEN
im.seconds := 0;
im.micros := 0;
END;
ELSE
END;
IF ginfo^.onlyIntern THEN msgClass := IDCMPFlagSet{} END;
(* CreateGadget sorgt dafⁿr, da▀ nur bei den Gadgets das Flag
gesetzt ist, bei denen es auch sinnvoll ist ! *)
END;
END;
END GadWithKey;
PROCEDURE ConvKMsgToGMsg(gui : GUIInfoPtr);
VAR nbr : INTEGER;
shift: INTEGER;
key : CHAR;
BEGIN
WITH gui^ DO
IF vanillaKey IN msgClass THEN
key := CHAR(im.code);
nbr := ORD(ToUpper(key)) - ORD('A');
IF (ToUpper(key) >= 'A') AND (ToUpper(key) <= 'Z') AND
(keys[nbr] # noKeyEqu) THEN
nbr := keys[nbr];
GadWithKey(gui, nbr, key = ToUpper(key));
ELSIF (callVanillaKeyFct IN flags) AND (vanKeyHook # NIL) AND
(vanKeyHook(key, ADR(nbr), ADR(shift))) THEN
GadWithKey(gui, nbr, shift # 0);
END;
END;
END;
END ConvKMsgToGMsg;
PROCEDURE HandleIntMsg(gui : GUIInfoPtr);
VAR ginfo : GUIGadgetInfoPtr;
fkt : MenuFct;
done : BOOLEAN;
BEGIN
done := FALSE;
WITH gui^ DO
msgClass := im.class;
cardCode := im.code;
IF (gadgetUp IN msgClass) OR (gadgetDown IN msgClass) OR
(mouseMove IN msgClass) THEN
gadget := ADDRESS(im.iAddress);
gadID := gadget^.gadgetID;
ginfo := gadget^.userData; (* MU▀ # NIL sein ! *)
gadNbr := ginfo^.v3;
END;
IF gadgetUp IN msgClass THEN
CASE ginfo^.kind OF
| integerKind : IF (ginfo^.lint # NIL) AND (autoUpdateEGads IN flags) THEN
ginfo^.lint^ := StringInfoPtr(gadget^.specialInfo)^.longInt;
done := TRUE;
END;
| stringKind : IF (ginfo^.string # NIL) AND (autoUpdateEGads IN flags) THEN
Copy(ginfo^.string^,
STRPTR(StringInfoPtr(gadget^.specialInfo)^.buffer)^);
done := TRUE;
END;
| checkboxKind: ginfo^.v0B := ~ginfo^.v0B;
IF ginfo^.bool # NIL THEN
ginfo^.bool^ := ~(ginfo^.bool^);
done := TRUE;
END;
charCode := 0C;
boolCode := ginfo^.v0B;
| sliderKind,
scrollerKind : ginfo^.v0S := CAST(INTEGER, im.code);
IF ginfo^.int # NIL THEN
ginfo^.int^ := CAST(INTEGER, im.code);
done := TRUE;
END;
| cycleKind,
listviewKind,
paletteKind : ginfo^.v0 := im.code;
IF ginfo^.card # NIL THEN
ginfo^.card^ := im.code;
done := TRUE;
END;
ELSE
END;
(* NΣchstes EntryGadget aktivieren *)
IF ((ginfo^.kind = integerKind) OR (ginfo^.kind = stringKind))
AND (ginfo^.nextEGad # NIL) THEN
IF im.code = 0 THEN (* Nicht mit TAB etc verlassen, dann ...*)
REPEAT
IF ~(gadgDisabled IN ginfo^.nextEGad^.flags) THEN
IF ginfo^.nextEGad # gadget THEN(* Gibt es vielleich nur eins?*)
IF I.ActivateGadget(ginfo^.nextEGad, window, NIL) THEN END;
END;
ginfo := NIL;
ELSE
ginfo := ginfo^.nextEGad^.userData;
END;
UNTIL ginfo = NIL;
ginfo := gadget^.userData; (* ginfo wiederherstellen*)
END;
END;
ELSIF gadgetDown IN msgClass THEN
CASE ginfo^.kind OF
| mxKind : ginfo^.v0 := im.code;
IF ginfo^.card # NIL THEN
ginfo^.card^ := im.code;
done := TRUE;
END;
| sliderKind,
scrollerKind : ginfo^.v0S := CAST(INTEGER, im.code);
IF ginfo^.int # NIL THEN
ginfo^.int^ := CAST(INTEGER, im.code);
done := TRUE;
END;
ELSE
END;
ELSIF menuPick IN msgClass THEN
IF im.code # menuNull THEN
menuNum := MenuNum(im.code);
itemNum := ItemNum(im.code);
subNum := SubNum(im.code);
itemAdr := I.ItemAddress(menus, im.code);
IF callMenuData IN flags THEN
IF (itemAdr # NIL) AND (MenuItemUserData(itemAdr) # NIL) THEN
fkt := CAST(MenuFct, MenuItemUserData(itemAdr));
IF fkt() THEN msgClass := IDCMPFlagSet{} END;
END;
END;
ELSE
msgClass := IDCMPFlagSet{};
END;
ELSIF menuHelp IN msgClass THEN
menuNum := MenuNum(im.code);
itemNum := ItemNum(im.code);
subNum := SubNum(im.code);
IF itemNum # noItem THEN
itemAdr := I.ItemAddress(menus, im.code);
ELSE
itemAdr := NIL;
END;
ELSIF mouseMove IN msgClass THEN
CASE ginfo^.kind OF
| sliderKind,
scrollerKind : ginfo^.v0S := CAST(INTEGER, im.code);
IF ginfo^.int # NIL THEN
ginfo^.int^ := CAST(INTEGER, im.code);
done := TRUE;
END;
ELSE
END;
ELSIF (vanillaKey IN msgClass) AND (convertKeys IN flags) THEN
ConvKMsgToGMsg(gui);
ELSIF (refreshWindow IN msgClass) AND (doRefresh IN flags) THEN
BeginRefresh(gui);
EndRefresh(gui, TRUE);
msgClass := IDCMPFlagSet{};
END;
IF done AND ginfo^.onlyIntern THEN msgClass := IDCMPFlagSet{} END;
END;
END HandleIntMsg;
PROCEDURE WaitIntMsg(gui : GUIInfoPtr);
BEGIN
REPEAT
IF ~((menuPick IN gui^.im.class) AND (gui^.im.code # menuNull)) THEN
WaitPort(gui^.port);
END;
UNTIL GetIntMsg(gui);
END WaitIntMsg;
PROCEDURE GetIntMsg(gui : GUIInfoPtr) : BOOLEAN;
VAR intmsg : IntuiMessagePtr;
BEGIN
IF (menuPick IN gui^.im.class) AND (gui^.im.code # menuNull) THEN
gui^.im.code := I.ItemAddress(gui^.menus, gui^.im.code)^.nextSelect;
ELSE
gui^.im.code := menuNull;
END;
IF gui^.im.code = menuNull THEN
intmsg := G.GTGetIMsg(gui^.port);
IF intmsg = NIL THEN RETURN FALSE END;
gui^.im := intmsg^;
G.GTReplyIMsg(intmsg);
END;
IF ~(noHandleIntMsgCall IN gui^.flags) THEN HandleIntMsg(gui) END;
IF gui^.msgClass = IDCMPFlagSet{} THEN RETURN FALSE END;
RETURN TRUE;
END GetIntMsg;
PROCEDURE EmptyIntMsgPort(gui : GUIInfoPtr);
VAR intmsg : IntuiMessagePtr;
BEGIN
Forbid; (* Keine neuen Nachrichten bitte ! *)
REPEAT
intmsg := G.GTGetIMsg(gui^.port);
IF intmsg # NIL THEN G.GTReplyIMsg(intmsg) END;
UNTIL intmsg = NIL;
Permit;
END EmptyIntMsgPort;
PROCEDURE GadgetStatus(gui : GUIInfoPtr; nbr : INTEGER; status : BOOLEAN);
VAR Gadget : GadgetPtr;
buffer : ARRAY[0..1] OF TagItem;
BEGIN
Gadget := gui^.gadgets^[nbr];
IF CAST(GUIGadgetInfoPtr, Gadget^.userData)^.kind = genericKind THEN
IF status THEN
I.OnGadget(Gadget, gui^.window, NIL);
ELSE
I.OffGadget(Gadget,gui^.window, NIL);
END;
ELSIF CAST(GUIGadgetInfoPtr, Gadget^.userData)^.kind <= guiToolsKinds THEN
G.GTSetGadgetAttrsA(Gadget, gui^.window, NIL,
TAG(buffer, gaDisabled, ~status, tagEnd));
END;
CAST(GUIGadgetInfoPtr, Gadget^.userData)^.gadActive := status;
END GadgetStatus;
PROCEDURE ModifyGadget(gui : GUIInfoPtr; nbr : INTEGER; tags : TagItemPtr);
VAR Gadget : GadgetPtr;
ginfo : GUIGadgetInfoPtr;
BEGIN
WITH gui^ DO
Gadget := gadgets^[nbr];
ginfo := Gadget^.userData;
ScanGadget(ginfo, tags, FALSE); (* Spezifische Werte updaten *)
IF rememberGadTags IN status THEN
RememberTags(ginfo, tags); (* Tags merken *)
END;
IF ginfo^.kind > guiToolsKinds THEN
INCL(status, spezialGadsNoText);
DrawGadget(gui, Gadget, ginfo);
EXCL(status, spezialGadsNoText);
ELSE
G.GTSetGadgetAttrsA(Gadget, window, NIL, tags);
END;
END;
END ModifyGadget;
PROCEDURE UpdateEGad(gui : GUIInfoPtr; nbr : INTEGER);
VAR gadg : GadgetPtr;
ginfo : GUIGadgetInfoPtr;
BEGIN
WITH gui^ DO
gadg := gadgets^[nbr];
ginfo := gadg^.userData;
IF ginfo^.buffer # NIL THEN
IF ginfo^.kind = integerKind THEN
ginfo^.lint^ := StringInfoPtr(gadg^.specialInfo)^.longInt;
ELSIF ginfo^.kind = stringKind THEN
Copy(ginfo^.string^,
STRPTR(StringInfoPtr(gadg^.specialInfo)^.buffer)^);
END;
END;
END;
END UpdateEGad;
PROCEDURE UpdateEntryGadgets(gui : GUIInfoPtr);
VAR i : INTEGER;
BEGIN
FOR i := 0 TO gui^.actgad-1 DO
UpdateEGad(gui, i);
END;
END UpdateEntryGadgets;
PROCEDURE VarToGad(gui : GUIInfoPtr; nbr : INTEGER);
VAR ginfo : GUIGadgetInfoPtr;
tagbuf : ARRAY[0..2] OF TagItem;
BEGIN
ginfo := gui^.gadgets^[nbr]^.userData;
IF ginfo^.buffer # NIL THEN
CASE ginfo^.kind OF
stringKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtstString, ginfo^.string, tagEnd));
| integerKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtinNumber, ginfo^.lint^, tagEnd));
| checkboxKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtcbChecked, ginfo^.bool^,tagEnd));
| cycleKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtcyActive, ginfo^.card^, tagEnd));
| mxKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtmxActive, ginfo^.card^, tagEnd));
| sliderKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtslLevel, ginfo^.int^, tagEnd));
| scrollerKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtscTop, ginfo^.int^, tagEnd));
| listviewKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtlvSelected, ginfo^.card^, tagEnd));
| paletteKind : ModifyGadget(gui, nbr, TAG(tagbuf,
gtpaColor, ginfo^.card^, tagEnd));
ELSE
END;
END;
END VarToGad;
PROCEDURE AllVarsToGad(gui : GUIInfoPtr);
VAR i : INTEGER;
BEGIN
FOR i := 0 TO gui^.actgad-1 DO
VarToGad(gui, i);
END;
END AllVarsToGad;
PROCEDURE TopazAttr():TextAttrPtr;
BEGIN
RETURN ADR(TextAttr{name: ADR('topaz.font'), ySize: 8});
END TopazAttr;
PROCEDURE GetOwnFont(name : ADDRESS; size : CARDINAL;
font : TextAttrPtr) : TextFontPtr;
VAR NewFont : TextFontPtr;
OwnAttr : TextAttr;
BEGIN
IF font = NIL THEN font := ADR(OwnAttr) END;
font^.name := name;
WITH font^ DO
ySize := size;
style := FontStyleSet{};
flags := FontFlagSet{romFont};
END;
NewFont := OpenFont(font);
IF NewFont = NIL THEN
font^.flags := FontFlagSet{diskFont};
NewFont := OpenDiskFont(font);
END;
RETURN NewFont;
END GetOwnFont;
PROCEDURE RemOwnFont(font : TextFontPtr);
BEGIN
IF font # NIL THEN CloseFont(font) END;
END RemOwnFont;
PROCEDURE DoubleTags(tag1, tag2 : TagItemPtr);
VAR tag : TagItemPtr;
next: TagItemPtr;
BEGIN
next := NextTagItem(tag1);
WHILE next # NIL DO
tag := FindTagItem(next^.tag, tag2);
IF tag # NIL THEN
next^.tag := tagIgnore;
END;
next := NextTagItem(tag1);
END;
END DoubleTags;
PROCEDURE OpenIntWindowTags(left, top, width, height : INTEGER;
name: ADDRESS; idcmpFlags: IDCMPFlagSet;
windowFlags : WindowFlagSet;
screen : ScreenPtr;
tags : TagItemPtr):WindowPtr;
VAR buffer : ARRAY[0..11] OF TagItem;
pubscr : ScreenPtr;
window : WindowPtr;
BEGIN
window := NIL;
IF screen = NIL THEN
pubscr := I.LockPubScreen(NIL);
screen := pubscr;
ELSE
pubscr := NIL;
END;
IF width = asScreen THEN width := screen^.width-left END;
IF height = asScreen THEN height := screen^.height-top END;
IF (pubscr # NIL) OR (publicScreen IN screen^.flags) THEN
IF TAG(buffer, waTitle, name,
waLeft, left,
waTop, top,
waWidth, width,
waHeight, height,
waIDCMP, idcmpFlags,
waFlags, windowFlags,
waPubScreen, screen,
waPubScreenFallBack, TRUE,
tagMore, tags, tagEnd) # NIL THEN
buffer[9].tag := tagEnd;
IF tags # NIL THEN
DoubleTags(ADR(buffer), tags);
buffer[9].tag := tagMore;
END;
END;
ELSE
IF TAG(buffer, waTitle, name,
waLeft, left,
waTop, top,
waWidth, width,
waHeight, height,
waIDCMP, idcmpFlags,
waFlags, windowFlags,
waCustomScreen, screen,
tagMore, tags, tagEnd) # NIL THEN
buffer[8].tag := tagEnd;
IF tags # NIL THEN
DoubleTags(ADR(buffer), tags);
buffer[8].tag := tagMore;
END;
END;
END;
window := I.OpenWindowTagList(NIL, ADR(buffer));
IF pubscr # NIL THEN I.UnlockPubScreen(NIL, pubscr) END;
RETURN window;
END OpenIntWindowTags;
PROCEDURE OpenIntWindow(left, top, width, height : INTEGER;
name: ADDRESS;
idcmpFlags: IDCMPFlagSet;
windowFlags : WindowFlagSet;
screen : ScreenPtr):WindowPtr;
VAR tags : ARRAY[0..1] OF TagItem;
BEGIN
RETURN OpenIntWindowTags(left, top, width, height, name,
idcmpFlags, windowFlags, screen,
TAG(tags, waScreenTitle, name, tagEnd));
END OpenIntWindow;
PROCEDURE CloseIntWindow(window : WindowPtr);
VAR intmsg : IntuiMessagePtr;
list : GUIWindowInfoPtr;
next : GUIWindowInfoPtr;
BEGIN
IF window # NIL THEN
IF window^.userPort # NIL THEN
Forbid; (* Keine neuen Nachrichten bitte ! *)
REPEAT
intmsg := G.GTGetIMsg(window^.userPort);
IF intmsg # NIL THEN G.GTReplyIMsg(intmsg) END;
UNTIL intmsg = NIL;
I.ModifyIDCMP(window, IDCMPFlagSet{});
Permit;
END;
(* GUI noch vorhanden ? , sollte auch mehrere GUIs pro Window handeln*)
Forbid;
list := allWindowsWithGUI;
WHILE list # NIL DO
IF list^.window = window THEN
next := list^.next;
FreeGUIInfo(list^.gui); (* list ist jetzt ungⁿltig ! *)
list := next;
ELSE
list := list^.next;
END;
END;
Permit;
I.CloseWindow(window);
END;
END CloseIntWindow;
PROCEDURE OpenIntScreenTags(id:LONGCARD; depth:INTEGER;
name : ADDRESS;
font : TextAttrPtr;
tags : TagItemPtr) : ScreenPtr;
VAR tagBuffer : ARRAY[0..7] OF TagItem;
BEGIN
IF TAG(tagBuffer, saPens, ADR(CARDINAL{0FFFFH}),
saDepth, depth,
saDisplayID, id,
saTitle, name,
saFont, font,
tagMore, tags, tagEnd) # NIL THEN
tagBuffer[5]. tag := tagEnd;
IF tags # NIL THEN
DoubleTags(ADR(tagBuffer), tags);
tagBuffer[5].tag := tagMore;
END;
RETURN I.OpenScreenTagList(NIL, ADR(tagBuffer));
ELSE
RETURN NIL;
END;
END OpenIntScreenTags;
PROCEDURE OpenIntScreen(id:LONGCARD; depth:INTEGER;
name : ADDRESS; font : TextAttrPtr) : ScreenPtr;
BEGIN
RETURN OpenIntScreenTags(id, depth, name, font, NIL);
END OpenIntScreen;
PROCEDURE CloseIntScreen(screen : ScreenPtr);
BEGIN
IF screen # NIL THEN
Forbid;
WHILE screen^.firstWindow # NIL DO
CloseIntWindow(screen^.firstWindow);
END;
I.CloseScreen(screen);
Permit;
END;
END CloseIntScreen;
PROCEDURE DrawBox(gui : GUIInfoPtr; left, top, width, height : INTEGER;
recessed : BOOLEAN);
VAR tagbuf : ARRAY[0..2] OF TagItem;
BEGIN
IF ~recessed THEN
G.DrawBevelBoxA(gui^.window^.rPort, left, top, width, height,
TAG(tagbuf, gtVisualInfo, gui^.visual, tagEnd));
ELSE
G.DrawBevelBoxA(gui^.window^.rPort, left, top, width, height,
TAG(tagbuf, gtVisualInfo, gui^.visual,
gtbbRecessed, TRUE, tagEnd));
END;
END DrawBox;
PROCEDURE RedrawGadgets(gui : GUIInfoPtr; setGads:BOOLEAN) : INTEGER;
VAR ginfo : GUIGadgetInfoPtr;
firstEGadNbr, i : INTEGER;
tagbuf : ARRAY[0..3] OF TagItem;
myTag : TagItem;
BEGIN
IF (rememberGadTags IN gui^.status) AND
(gui^.gadlist # NIL) THEN (* gibt es ⁿberhaupt Gadgets *)
IF gui^.firstEGad # NIL THEN
firstEGadNbr := CAST(GUIGadgetInfoPtr, gui^.firstEGad^.userData)^.v3;
END;
(* Alte Gadgets entfernen *)
IF I.RemoveGList(gui^.window, gui^.gadlist, -1) = 0 THEN END;
G.FreeGadgets(gui^.gadlist);
(* Window-Inhalt l÷schen *)
ClearWindow(gui);
(* neue Gadget-Liste erstellen ! *)
gui^.gadlist := NIL;
gui^.gad := G.CreateContext(gui^.gadlist);
EXCL(gui^.status, gadgetsSet);
IF gui^.gadlist # NIL THEN
gui^.actgad := 0;
ginfo := gui^.firstGad;
WHILE ginfo # NIL DO
IF ginfo^.nbrTags = 0 THEN
ginfo^.tags := ADR(myTag);
ginfo^.impTags := ADR(myTag);
END;
ginfo^.impTags^.tag := tagMore;
CASE ginfo^.kind OF
mxKind : ginfo^.impTags^.data := TAG(tagbuf,
gtmxActive, ginfo^.v0, tagEnd);
| checkboxKind : ginfo^.impTags^.data := TAG(tagbuf,
gtcbChecked, ginfo^.v0B, tagEnd);
| cycleKind : ginfo^.impTags^.data := TAG(tagbuf,
gtcyActive, ginfo^.v0, tagEnd);
| sliderKind: ginfo^.impTags^.data := TAG(tagbuf,
gtslMin, ginfo^.v2S,
gtslMax, ginfo^.v1S,
gtslLevel, ginfo^.v0S, tagEnd);
| scrollerKind:ginfo^.impTags^.data := TAG(tagbuf,
gtscTop, ginfo^.v0S,
gtscVisible, ginfo^.v1S,
gtscTotal, ginfo^.v2S, tagEnd);
| listviewKind:ginfo^.impTags^.data := TAG(tagbuf,
gtlvSelected, ginfo^.v1,tagEnd);
| paletteKind :ginfo^.impTags^.data := TAG(tagbuf,
gtpaColorOffset, ginfo^.v2,
gtpaColor, ginfo^.v0, tagEnd);
ELSE
ginfo^.impTags^.tag := tagEnd;
END;
IF ginfo^.kind > guiToolsKinds THEN
WITH gui^.gadgets^[gui^.actgad]^ DO
leftEdge := ginfo^.gadDesc.leftEdge;
topEdge := ginfo^.gadDesc.topEdge;
width := ginfo^.gadDesc.width;
height := ginfo^.gadDesc.height;
gadgetText^.iText := ginfo^.gadDesc.gadgetText;
gadgetText^.iTextFont := ginfo^.gadDesc.textAttr;
END;
CalcText(gui, gui^.gadgets^[gui^.actgad]);
IF setGads THEN
DrawGadget(gui, gui^.gadgets^[gui^.actgad], ginfo);
END;
ELSE
gui^.gad := G.CreateGadgetA(ginfo^.kind, gui^.gad^,
ginfo^.gadDesc, ginfo^.tags);
IF gui^.gad # NIL THEN (* GUIGadgetInfo in userData eintragen !*)
gui^.gadgets^[gui^.actgad] := gui^.gad;
ELSE
ginfo := NIL;
END;
END;
IF ginfo # NIL THEN
gui^.gadgets^[gui^.actgad]^.userData := ginfo;
INC(gui^.actgad);
IF ginfo^.nbrTags = 0 THEN
ginfo^.tags := NIL;
ginfo^.impTags := NIL;
END;
ginfo := ginfo^.nextGadInfo;
END;
END;
IF gui^.gad # NIL THEN
IF gui^.firstEGad # NIL THEN
(* Verkettung der E-Gads wieder aufbauen *)
gui^.firstEGad := gui^.gadgets^[firstEGadNbr];
ginfo := gui^.firstEGad^.userData;
WHILE ginfo # NIL DO
IF ginfo^.nextEGad # NIL THEN
IF ginfo^.nextEGadNbr = CAST(GUIGadgetInfoPtr,
gui^.firstEGad^.userData)^.v3S THEN
ginfo^.nextEGad := gui^.firstEGad;
ginfo := NIL;
ELSE
ginfo^.nextEGad := gui^.gadgets^[ginfo^.nextEGadNbr];
ginfo := ginfo^.nextEGad^.userData;
END;
ELSE
ginfo := NIL;
END;
END;
END;
IF setGads THEN
IF I.AddGList(gui^.window, gui^.gadlist, -1, -1, NIL) = 0 THEN END;
I.RefreshGList(gui^.gadlist, gui^.window, NIL, -1);
G.GTRefreshWindow(gui^.window, NIL);
FOR i := 0 TO gui^.actgad-1 DO
IF ~(CAST(GUIGadgetInfoPtr,
gui^.gadgets^[i]^.userData)^.gadActive) THEN
GadgetStatus(gui, i, FALSE);
END;
END;
IF activateFirstEGad IN gui^.flags THEN
IF I.ActivateGadget(gui^.firstEGad, gui^.window, NIL) THEN END;
END;
INCL(gui^.status, gadgetsSet);
ELSE
INCL(gui^.status, redrawGads);
END;
ELSE
SetGUIError(gui, gadgetError);
END;
ELSE
SetGUIError(gui, rdGUIContextError);
END;
END;
RETURN gui^.firstError;
END RedrawGadgets;
PROCEDURE RedrawMenu(gui : GUIInfoPtr) : INTEGER;
VAR buffer : ARRAY[0..1] OF TagItem;
BEGIN
IF (menuSet IN gui^.status) THEN
I.ClearMenuStrip(gui^.window);
G.FreeMenus(gui^.menus);
EXCL(gui^.status, menuSet);
gui^.menus := G.CreateMenusA(ADDRESS(gui^.newMenus), NIL);
IF gui^.menus # NIL THEN
IF G.LayoutMenusA(gui^.menus, gui^.visual, TAG(buffer,
gtmnTextAttr, ADR(gui^.font), tagEnd)) THEN
IF I.SetMenuStrip(gui^.window, gui^.menus) THEN
INCL(gui^.status, menuSet);
ELSE
SetGUIError(gui, menuSetError);
G.FreeMenus(gui^.menus);
gui^.menus := NIL;
END;
ELSE
SetGUIError(gui, menuLayoutError);
G.FreeMenus(gui^.menus);
gui^.menus := NIL;
END;
ELSE
SetGUIError(gui, menuError);
END;
END;
RETURN gui^.firstError;
END RedrawMenu;
PROCEDURE ResizeGadget(gui : GUIInfoPtr;
nbr : INTEGER;
left, top, width, height : INTEGER);
BEGIN
WITH CAST(GUIGadgetInfoPtr, gui^.gadgets^[nbr]^.userData)^ DO
IF addBorderDims IN gui^.flags THEN
IF left # preserve THEN INC(left, gui^.window^.borderLeft) END;
IF top # preserve THEN INC(top, gui^.window^.borderTop) END;
END;
IF left # preserve THEN gadDesc.leftEdge := left END;
IF top # preserve THEN gadDesc.topEdge := top END;
IF width # preserve THEN gadDesc.width := width END;
IF height # preserve THEN gadDesc.height := height END;
END;
END ResizeGadget;
PROCEDURE NewGadgetFont(gui : GUIInfoPtr;
nbr : INTEGER;
font : TextAttrPtr);
BEGIN
WITH CAST(GUIGadgetInfoPtr, gui^.gadgets^[nbr]^.userData)^ DO
gadDesc.textAttr := font;
END;
END NewGadgetFont;
PROCEDURE NewGadgetText(gui : GUIInfoPtr;
nbr : INTEGER;
text : ADDRESS);
BEGIN
WITH CAST(GUIGadgetInfoPtr, gui^.gadgets^[nbr]^.userData)^ DO
gadDesc.gadgetText := text;
END;
END NewGadgetText;
PROCEDURE RemoveGadgets(gui : GUIInfoPtr; erase : BOOLEAN);
VAR ginfo : GUIGadgetInfoPtr;
ggad : GadgetPtr;
i : INTEGER;
BEGIN
WITH gui^ DO
IF (gadlist # NIL) AND (gadgetsSet IN status) THEN
IF I.RemoveGList(window, gadlist, -1) = 0 THEN END;
END;
IF erase THEN
WHILE firstGad # NIL DO (* Infostrukturen freigeben *)
ginfo := firstGad;
firstGad := firstGad^.nextGadInfo;
IF (ginfo^.tags # NIL) AND (ginfo^.nbrTags > 0) THEN
FreeMem(ginfo^.tags, SIZE(TagItem) * ginfo^.nbrTags);
END;
FreeMem(ginfo, SIZE(GUIGadgetInfo));
END;
WHILE spezialGad # NIL DO (* Special-Gadgets freigeben *)
ggad := spezialGad;
spezialGad := spezialGad^.nextGadget;
FreeMem(ggad, SPEZIALGADSIZE);
END;
IF gadlist # NIL THEN G.FreeGadgets(gadlist) END;
gui^.gad := G.CreateContext(gui^.gadlist);
IF gadlist = NIL THEN SetGUIError(gui, gadgetError) END;
newgad.gadgetText := NIL;
newgad.gadgetID := 0;
newgad.flags := NewGadgetFlagSet{};
actgad := 0;
firstEGad := NIL;
lastEGad := NIL;
FOR i := 0 TO 25 DO
keys[i] := noKeyEqu;
END;
END;
EXCL(status, gadgetsSet);
END;
END RemoveGadgets;
PROCEDURE RemoveMenu(gui : GUIInfoPtr; erase : BOOLEAN);
BEGIN
WITH gui^ DO
IF (menuSet IN status) AND (menus # NIL) THEN
I.ClearMenuStrip(window);
END;
IF menus # NIL THEN
G.FreeMenus(menus);
menus := NIL;
END;
IF erase THEN
actmenu := 0;
newMenus^[0].type := nmEnd;
END;
EXCL(status, menuSet);
END;
END RemoveMenu;
PROCEDURE NewFontAllGadgets(gui : GUIInfoPtr;
font: TextAttrPtr);
VAR i : INTEGER;
BEGIN
FOR i := 0 TO gui^.actgad-1 DO
CAST(GUIGadgetInfoPtr,
gui^.gadgets^[i]^.userData)^.gadDesc.textAttr := font;
END;
END NewFontAllGadgets;
PROCEDURE ClearWindow(gui : GUIInfoPtr);
VAR oldPen : INTEGER;
BEGIN
WITH gui^.window^ DO
oldPen := rPort^.fgPen;
SetAPen(rPort, rPort^.bgPen);
RectFill(rPort, borderLeft, borderTop+2, width-borderRight-1,
height-borderBottom-1);
SetAPen(rPort, oldPen);
END;
END ClearWindow;
PROCEDURE CreateSpecialGadget(gui : GUIInfoPtr;
left : INTEGER;
top : INTEGER;
width : INTEGER;
height : INTEGER;
kind : LONGCARD;
tags : TagItemPtr);
VAR next : TagItemPtr;
spGadget : GadgetPtr;
ginfo : GUIGadgetInfoPtr;
text : IntuiTextPtr;
oldtags : TagItemPtr;
BEGIN
oldtags := tags;
IF ((kind = progressIndicatorKind) OR (kind = bevelboxKind)) AND
(gui^.gad # NIL) AND (~(gadgetsSet IN gui^.status)) THEN
IF gui^.actgad < gui^.maxgads THEN
WITH gui^ DO
newgad.leftEdge := left;
newgad.topEdge := top;
newgad.width := width;
newgad.height := height;
IF addBorderDims IN flags THEN
INC(newgad.leftEdge, window^.borderLeft);
INC(newgad.topEdge, window^.borderTop);
END;
END;
IF tags # NIL THEN
next := NextTagItem(oldtags);
WHILE next # NIL DO
IF next^.tag = Tag(sgGadgetText) THEN
gui^.newgad.gadgetText := ADDRESS(next^.data);
ELSIF next^.tag = Tag(sgGadgetFlags) THEN
gui^.newgad.flags := CAST(NewGadgetFlagSet, next^.data);
END;
next := NextTagItem(oldtags);
END;
END;
spGadget := AllocMem(SPEZIALGADSIZE, MemReqSet{memClear});
IF spGadget # NIL THEN
ginfo := AllocMem(SIZE(GUIGadgetInfo), MemReqSet{memClear});
IF ginfo # NIL THEN
text := ADDRESS(spGadget);
INC(text, SIZE(Gadget));
spGadget^.userData := ginfo;
ginfo^.kind := kind;
ScanGadget(ginfo, tags, TRUE);
WITH gui^ DO
(* Zeiger auf GUIGadgetInfo-Struktur merken *)
IF firstGad = NIL THEN
firstGad := ginfo;
ELSE (* alle weiteren mitteinander verketten *)
CAST(GUIGadgetInfoPtr,
gadgets^[actgad-1]^.userData)^.nextGadInfo := ginfo;
END;
(* Zeiger auf Special-Gadgets merken *)
spGadget^.nextGadget := spezialGad;
spezialGad := spGadget;
gadgets^[actgad] := spGadget;
spGadget^.gadgetText := text;
text^.iText := newgad.gadgetText;
text^.iTextFont := newgad.textAttr;
spGadget^.specialInfo := CAST(ADDRESS, newgad.flags);
spGadget^.leftEdge := newgad.leftEdge;
spGadget^.topEdge := newgad.topEdge;
spGadget^.width := newgad.width;
spGadget^.height := newgad.height;
spGadget^.gadgetID := newgad.gadgetID;
(* Gad-Desc merken *)
ginfo^.gadDesc := newgad;
newgad.gadgetText := NIL;
INC(actgad);
INC(newgad.gadgetID);
END;
CalcText(gui, spGadget);
ELSE
SetGUIError(gui, memError);
FreeMem(spGadget, SIZE(Gadget)+SIZE(IntuiText));
END;
ELSE
SetGUIError(gui, memError);
gui^.gad := NIL;
END;
ELSE
SetGUIError(gui, tooManyGadsError);
gui^.gad := NIL;
END;
ELSE
SetGUIError(gui, noGUIToolsGadKind);
gui^.gad := NIL;
END;
END CreateSpecialGadget;
PROCEDURE BeginRefresh(gui : GUIInfoPtr);
VAR spGadget : GadgetPtr;
BEGIN
G.GTBeginRefresh(gui^.window);
spGadget := gui^.spezialGad;
WHILE spGadget # NIL DO
DrawGadget(gui, spGadget, spGadget^.userData);
spGadget := spGadget^.nextGadget;
END;
END BeginRefresh;
PROCEDURE EndRefresh(gui : GUIInfoPtr; complete : BOOLEAN);
BEGIN
G.GTEndRefresh(gui^.window, complete);
IF refreshWF IN gui^.status THEN I.RefreshWindowFrame(gui^.window) END;
END EndRefresh;
PROCEDURE ShowRequester(gui : GUIInfoPtr; text : ADDRESS;
kind : LONGCARD; tags : TagItemPtr) : LONGINT;
VAR window : WindowPtr;
easyReq: EasyStructPtr;
next : TagItemPtr;
idcmpP : POINTER TO IDCMPFlagSet;
args : ADDRESS;
return : LONGINT;
idcmp : IDCMPFlagSet;
BEGIN
return := reqCancel;
idcmp := IDCMPFlagSet{};
args := NIL;
idcmpP := ADR(idcmp);
IF gui # NIL THEN
window := gui^.window;
ELSE
window := CAST(ProcessPtr, FindTask(NIL))^.windowPtr;
END;
easyReq := AllocMem(SIZE(EasyStruct), MemReqSet{memClear});
IF easyReq # NIL THEN
WITH easyReq^ DO
structSize := SIZE(EasyStruct);
textFormat := text;
IF kind = okReqKind THEN gadgetFormat := ADR('OK');
ELSIF kind = doitReqKind THEN gadgetFormat := ADR('YES|NO');
ELSIF kind = yncReqKind THEN gadgetFormat := ADR('YES|NO|CANCEL');
END;
END;
IF tags # NIL THEN
next := NextTagItem(tags);
WHILE next # NIL DO
IF next^.tag = Tag(srGadgets) THEN
easyReq^.gadgetFormat := ADDRESS(next^.data);
ELSIF next^.tag = Tag(srArgs) THEN
args := ADDRESS(next^.data);
ELSIF next^.tag = Tag(srFlags) THEN
easyReq^.flags := CAST(LONGSET, next^.data);
ELSIF next^.tag = Tag(srTitle) THEN
easyReq^.title := ADDRESS(next^.data);
ELSIF next^.tag = Tag(srIDCMP) THEN
idcmpP := ADDRESS(next^.data);
ELSIF next^.tag = Tag(srReqWindow) THEN
window := ADDRESS(next^.data);
END;
next := NextTagItem(tags);
END;
END;
IF CAST(LONGINT, window) # -1 THEN
return := I.EasyRequestArgs(window, easyReq^, idcmpP^, args);
END;
FreeMem(easyReq, SIZE(EasyStruct));
END;
RETURN return;
END ShowRequester;
PROCEDURE ShowRequesterP(gui : GUIInfoPtr; text : ADDRESS;
kind : LONGCARD; tags : TagItemPtr);
BEGIN
IF ShowRequester(gui, text, kind, tags) = 0 THEN END;
END ShowRequesterP;
PROCEDURE SetProcessWindow(window : WindowPtr):WindowPtr;
VAR oldwin : WindowPtr;
BEGIN
oldwin := CAST(ProcessPtr, FindTask(NIL))^.windowPtr;
CAST(ProcessPtr, FindTask(NIL))^.windowPtr := window;
RETURN oldwin;
END SetProcessWindow;
PROCEDURE SimpleReq(text : ADDRESS; kind : LONGCARD):LONGINT;
BEGIN
RETURN ShowRequester(NIL, text, kind, NIL);
END SimpleReq;
PROCEDURE SimpleReqP(text : ADDRESS; kind : LONGCARD);
BEGIN
IF ShowRequester(NIL, text, kind, NIL) = 0 THEN END;
END SimpleReqP;
BEGIN
END GUITools.