← ST-Computer 07 / 1993

Der Falcon poppt up - Teil 1: Pop-Up-MenĂŒs

Grundlagen

Wer es bereits geschafft hat, in den Besitz eines heißbegehrten Falken zu kommen, mußte sich wohl oder ĂŒbel damit abfinden, auf MultiTOS zu verzichten. Die bisher ausgelieferten Modelle des Falcon030 tragen die TOS-Versionsnummern 4.00 und 4.01 und haben damit, neben den erforderlichen Anpassungen an die neuen FĂ€higkeiten des Falcon im GEM, nur einige optische Verschönerungen erfahren.

True-Color-Icons, 3D-Buttons und Fenster im 3D-Look sind die auffĂ€lligsten Neuerangen, die ATARI am GEM vorgenommen hat. Erst auf den zweiten Blick entdeckt man im DESKTOP ein neues Feature, das zwar in jeder zweiten Anwendung auftaucht, dem Betriebssystem bisher allerdings unbekannt war: in den Dialogboxen des EXTRA-MenĂŒs wurden Pop-Up-MenĂŒs implementiert.

Pop-Up-MenĂŒs sind zwar fĂŒr das irgendwann kommende MultiTOS bereits dokumentiert, wurden aber im Falcon anscheinend schon jetzt eingebaut. Ein kurzer Test bringt es an den Tag: der Falcon beherrscht vier neue AES-Aufrufe, (wobei er einen netterweise mit einer Alertbox daran hindert, AES-Funktionen aufzurufen, die noch nicht implementiert sind). Es handelt sich um die - eigentlich erst im MultiTOS vorgesehenen - Aufrufe 36 bis 39, MENU_POPUP, MENU_ATTACH, MENU_START und MENU_SETTINGS, mit denen die einfache Verwendung von Pop-Up- und SubmenĂŒs möglich ist.

Die genauen Deklarationen entnehmen Sie bitte nebenstehendem Kasten.

Wir wollen uns im ersten Teil zunĂ€chst einmal nur mit den Pop-Up-MenĂŒs beschĂ€ftigen. Im nĂ€chsten Heft werden wir dann daran gehen, Pop-Ups mit Hilfe des MENU_ATTACH-Aufrufes als SubmenĂŒs einzusetzen.

Was ist ein Pop-Up-MenĂŒ?

Als Pop-Up kann man im Prinzip jedes beliebige GEM-Objekt einsetzen. Es wird vom AES auf den Bildschirm gebracht; man kann dann mit der Maus entweder ein Objekt auswĂ€hlen oder außerhalb des Pop-Ups klicken, um kein Objekt auszuwĂ€hlen. Danach wird es wieder gelöscht, und man kann erfragen, ob und was selektiert wurde. Genaugenommen ist jedes MenĂŒ, das aus dem MenĂŒbaum herunterklappt, wenn man einen MenĂŒtitel anwĂ€hlt, ein Pop-Up. Ein Pop-Up kann völlig unabhĂ€ngig von anderen Objekten auf dem Desktop oder in einem Fenster oder z.B. als Auswahlbox zu einem "Pop-Up-Button" einer Dialogbox erscheinen.

Das einfachste Pop-Up besteht, wie ein normales MenĂŒ, aus einem "Kasten", in dem ĂŒbereinander mehrere TexteintrĂ€ge stehen. Der Kasten ist das Vaterobjekt und vom Typ G_BOX, die EintrĂ€ge sind die Kinder und vom Typ G_STRING. Da dieses Pop-Up wie ein normales MenĂŒ aussieht und auch als SubmenĂŒ eingesetzt werden kann, sollte man sich an die allgemeinen Konventionen halten, d.h. vor jedem Eintrag zwei Leerzeichen fĂŒr das "Checked-HĂ€kchen" freilassen und am Ende ein Leerzeichen. Bei Bedarf sind Trennstriche in Form von disabled Strings (?-------") zulĂ€ssig. Solche Pop-Ups - und nur solche - können auf Wunsch vom GEM gescrollt werden und dĂŒrfen damit fast beliebig hoch sein.

Das Scrollen geschieht automatisch, wenn das Pop-Up grĂ¶ĂŸer als die festgelegte Scroll-Höhe ist, auch die dazu notwendigen Scroll-Pfeile werden vom Betriebssystem automatisch erzeugt. (Die meisten kennen das wahrscheinlich schon vom XCONTROL.ACC).

Wenn man auf automatisches Scrollen verzichtet, sind einem bei der Gestaltung beliebiger Pop-Up-MenĂŒs kaum Grenzen gesetzt. Man muß nur dafĂŒr sorgen, daß alle selektierbaren Objekte auf der gleichen Ebene liegen und Kinder eines gemeinsamen Vaterobjekts sind. Man sollte jedoch immer ĂŒberlegen, ob ein Pop-Up an dieser Stelle ĂŒberhaupt sinnvoll ist. Das ist immer dann der Fall, wenn in einer Dialogbox aus einer FĂŒlle von Möglichkeiten genau eine ausgewĂ€hlt werden soll. Aus neueren, sauber programmierten Grafikprogrammen kennen wir Pop-Up-Buttons zum AuswĂ€hlen von Linientypen, Fonts, Mustern, Farben usw. Und genau in so einem Fall sind Pop-Up-Buttons sinnvoller als normale MenĂŒs, weil man sofort sehen kann, was zur Zeit angewĂ€hlt ist. Trotz der FĂŒlle der Gestaltungsmöglichkeiten sollte man Pop-Ups so einfach wie möglich halten und auf verwirrende Elemente verzichten. So tauchen z.B. immer wieder Pop-Ups auf, die eine Fenstertitelzeile besitzen; was nur zu Fehlbedienungen fĂŒhrt, weil man Pop-Ups weder verschieben noch in den Hintergrund klicken kann. Das Objekt-Flag hat ĂŒbrigens bei den Pop-Up-EintrĂ€gen keine Bedeutung -die einzelnen Objekte mĂŒssen nicht SELECTABLE sein, und es muß auch kein EXIT-Objekt existieren.

Sollen Pop-Up-MenĂŒs in Form von sogenannten Pop-Up-Buttons innerhalb von Dialogboxen auftauchen, sollte man sich an die Konventionen halten, die sich inzwischen weitgehend durchgesetzt haben.

Danach ist der Button selbst ein Objekt vom Typ G_BOXTEXT mit dem Objekt-Flag TOUCHEXIT und dem Objektstatus SHADOWED, damit man sofort erkennt, daß es sich um einen Pop-Up-Button handelt. Um den Pop-Up-Button im neuen Falcon-3D-Look erstrahlen zu lassen, muß man noch zusĂ€tzlich den Objektstatus DRAW_3D ($40) und im High-Byte des Objekttyps eine $02 setzen. (Mit diesen beiden Änderungen kann man ĂŒbrigens auch jeden normalen Button in einen 3D-Button verwandeln.)

Im Gegensatz zum SubmenĂŒ gibt es noch keine Möglichkeit, eine Verbindung zwischen dem Button und dem Pop-Up herzustellen, um es automatisch aufzurufen. Man muß also die BetĂ€tigung des Buttons normal abfragen und dann das Pop-Up selbst aufrufen. Hat man ein Pop-Up erstellt und ins Programm eingebunden, muß man noch eine MENU-Struktur anlegen (siehe Kasten). In diese neue AES-Struktur wird zunĂ€chst die Adresse des Pop-Up-MenĂŒ-Baumes eingetragen. Dann folgen der Index des Vaterobjekts der Pop-Up-MenĂŒ-EintrĂ€ge (also des "Kastens") und der Index des AnfangsmenĂŒeintrags, also des Eintrags, an dem das Pop-Up auf dem Bildschirm ausgerichtet wird. Zum Schluß kann man noch angeben, ob bei Bedarf gescrollt werden darf.

Wenn man die GrĂ¶ĂŸe des Pop-Up-Me-nĂŒs benötigt, dann kann man sie am einfachsten durch FORM_CENTER ermitteln lassen. Bei mir passiert es nur am rechten Bildschirmrand, daß ein Pop-Up nicht ganz auf dem Bildschirm erscheint, an den drei anderen Seiten achtet das Betriebssystem darauf, daß es den Schirm nicht verlĂ€ĂŸt. Bevor man ein Pop-Up aufruft, muß man den Bildschirm mittels WIND_UPDATE (BEG_UPDATE) sperren - und ihn nach dem Aufruf selbstverstĂ€ndlich wieder mit WIND_UPDATE (END_UPDATE) freigeben. Bei Pop-Ups, die zu Buttons gehören, ermittelt man die x- und y-Koordinate des Pop-Ups, indem man die x- und y-Koordinate des Buttons mit der Funktion OBJC_OFFSET abfragt. Nach dem eigentlichen Aufruf des Pop-Ups mittels MENU_POPUP erhĂ€lt man in me_return (int_out) eine Null, wenn kein Eintrag ausgewĂ€hlt wurde (was passiert, wenn der Benutzer außerhalb des Pop-Ups geklickt hat). Ist me_return ungleich Null, erhĂ€lt man in einer zweiten MENU-Struktur, die man bei MENU_POPUP in me_mdata ĂŒbergeben hat, den Index des angewĂ€hlten Eintrags. Wurde beim AnwĂ€hlen dieses Eintrages eine der Shift-Tasten (dazu zĂ€hlen auch Alternate und Control) gedrĂŒckt, so steht dies im allerletzten Wort der MENU-Struktur in der AES-ĂŒblichen Bit-Notation. Übergibt man sowohl in me_menu als auch in me_mdata die gleiche Adresse - also dieselbe MenĂŒstruktur -, erhĂ€lt man den angewĂ€hlten Eintrag anstelle des Anfangseintrags zurĂŒck; dieses Verfahren sorgt dafĂŒr, daß der zuletzt gewĂ€hlte Eintrag beim nĂ€chsten Aufruf wieder der Anfangseintrag ist.

Um alles andere muß man sich jedoch selbst kĂŒmmern: Das kann z.B. das Setzen des CHECKED-Status sein, um dem Benutzer mit einem HĂ€kchen anzuzeigen, welches der zuletzt gewĂ€hlte Eintrag war. Auch das Übertragen des gewĂ€hlten Eintrags in den Pop-Up-Button muß man selbst erledigen.

Doch nun zur Praxis. Da es fĂŒr den geneigten C-Programmierer inzwischen eine FĂŒlle von Libraries gibt, mit denen man auf jedem ST/TT/Falcon Pop-Up-und SubmenĂŒs auf einfache Weise nachbilden kann, habe ich mich zur Demonstration der neuen AES-Aufrufe fĂŒr OMIKRON.BASIC entschieden. Erstens kann man neue Betriebssystemfunktionen am besten mit einer Interpreter-Sprache testen, und zweitens lĂ€uft die Version 3.6 auf dem Falcon im Gegensatz zu GFA-BASIC in allen Auflösungen einwandfrei. Man benötigt Version 3.6 des OMIKRON.-BASIC Interpreters, die seit der letzten ATARI-Messe als kostenloses Update zur Version 3.5 erhĂ€ltlich ist. FĂŒr komplexe Pop-Ups und solche innerhalb von Dialogboxen ist ein Resource-Construction-Set erforderlich; normale Text Pop-Ups kann man wesentlich einfacher ohne ein solches erstellen, zumal alle mir bekannten RCS zur Zeit noch kleine Probleme mit betriebssystemeigenen SubmenĂŒs haben. Das Projekt ist in mehrere Module aufgeteilt, die auf der Monatsdiskette als echte OMIKRON.LIBRARIES vorliegen und dann auch mit dem Befehl LIBRARY Xyz, "XYZ.LIB" nachgeladen werden können. ZusĂ€tzlich benötigen Sie die original "GEM.LIB", die ihrem Interpreter beiliegt. Alles weitere finden Sie in den Listings.

Programm 1: Erzeugen und Anzeigen eines Text-Pop-Ups ohne RCS
Programm 2: Demoprogramm fĂŒr komplexe Pop-Up-Buttons in Dialogboxen
Modul 1: GEM33-Zusatz-Library; hier werden die vier neuen AES-Aufrufe definiert, die noch nicht in der GEM.LIB enthalten sind.
Modul 2: Popdef-Library zum Erstellen von eigenen Text-Pop-Ups ohne RCS; benötigt die OBJECT.LIB (Modul 4)
Modul 3: Pop-Up-Library zum Benutzen beliebiger Pop-Up-MenĂŒs; benötigt die GEM33.LIB (Modul 1) und die OBJECT.LIB (Modul 4)
Modul 4: Object-Zusatz-Library fĂŒr den vereinfachten Umgang mit GEM-Objekten

Auf der Monatsdiskette finden Sie außerdem die notwendigen ZusĂ€tze fĂŒr die OM-BASIC.HLP-Datei, um die neuen AES-Funktionen einzubinden.

Im zweiten Teil werden wir uns den SubmenĂŒs zuwenden. Die Gem33-Library wird dabei genauso wieder Verwendung finden wie die Object-Library. Aber vor allem die Popdef-Library eignet sich besser als jedes RCS, um SubmenĂŒs zu erzeugen.

Kai Michael Speck

Literatur:

Hendricks, Herzlinger, Pittelkow: "Das Buch zum ATARI Falcon030", Data Becker Jankowski, Reschke, Rabich: "ATAR] Profibuch ST-STE-TT", Sybex

Hinweis: Aus PlatzgrĂŒnden haben wir die Listings des Artikels nicht abgedruckt. Sie finden sie aber vollstĂ€ndig auf unserer Monatsdiskette (die Redaktion).

Die neuen AES-Aufrufe

dokumentiert ab AES-Version 4.0 (MultiTOS), bereits implementiert im AES 3.31 des zur Zeit ausgelieferten Falcon030

■ MENU_POPUP (AES 36)

Darstellung und Abarbeitung eines Pop-Up-MenĂŒs.

GEM-Arrays:

control = 36
control+2 = 2 EintrÀge in int_in
control+4 = 1 EintrÀge in int_out
control+6 = 2 EintrÀge in addr_in
control+8 = 0 EintrÀge in addr_out
int_in = me_xpos absolute Bildschirmkoordinaten
int_in+2 = me_ypos der linken oberen MenĂŒecke.
int_out = me_return 0 = Fehler: die Daten in me_mdata sind ungĂŒltig.
addr_in = me_menu Zeiger auf die MENU-Struktur des Popup-MenĂŒs
addr_in+4 = me_mdata Zeiger auf die MENU-Struktur, in der die Daten des selektierten MenĂŒeintrages stehen

BASIC-Aufruf: Menu_Popup ( Me_Menu%L , Me_Xpos% , Me_Ypos% , Me_Mdata%L)

Die neue AES-Struktur MENÜ:

struct MENU {
LONG mn_tree; Zeiger auf den Objektbaum des MenĂŒs
WORD mn_menu; Index des den MenĂŒeintrĂ€gen ĂŒbergeordneten Objekts
WORD mn_item; AnfangsmenĂŒeintrag - bestimmt Position des MenĂŒs
WORD mn_scroll; 0 = nicht scrollen, 1 = scrollen
WORD mn_keystate; } Shift-Tastenstatus ([ALT], [CTRL] & [SHIFT])

■ MENU_ATTACH (AES 37)

GEM-Arrays:

control =37
control+2 = 2 EintrÀge in int_in
control+4 = 1 EintrÀge in int_out
control+6 = 2 EintrÀge in addr_in
control+8 = 0 EintrÀge in addr_out
int_in = me_flag 0 = abfragen, 1 = verbinden/Ändern, 2 = löschen
int_in+2 = me_item Index des MenĂŒeintrages im HauptmenĂŒ, mit dem das SubmenĂŒ verbunden werden soll
int_out = me_return 0 = Fehler; die Daten in me_mdata sind ungĂŒltig.
addr_in = me_tree Zeiger auf den Objektbaum des HauptmenĂŒs
addr_in+4 = me_mdata Zeiger auf eine MENU-Struktur

BASIC-Aufruf: Menu_Attach ( Me_Mflag% , Me_Tree%L, Mejtem% , Me_Mdata%L)

■ MENU_ISTART (AES 38)

GEM-Arrays:

control = 38
control+2 = 1 EintrÀge in int_in
control+4 = 1 EintrÀge in int_out
control+6 = 1 EintrÀge in addr_in
control+8 = 0 EintrÀge in addr?out
int_in = me_flag 0 = abfragen, 1 = setzen
int_in+2 = me_menu Objektindex des SubmenĂŒeintrags
int_in+4 = me_item Objektindex des VatermenĂŒeintrags
int_out = me_return 0 = Fehler; das SubmenĂŒ hat keine Verbindung
addr_in = me_tree Zeiger auf den Objektbaum des HauptmenĂŒs

BASIC-Aufruf: Menu_start ( Me_Flag% , Me_Tree%L , Me_lmenu% , Me_ltem%)

■ MENU_SETTINGS (AES 39)

Setzen und Abfragen der Pop-Up- und SubmenĂŒparameter.

GEM-Arrays:

control = 39
control+2 = 1 EintrÀge in int_in
control+4 = 1 EintrÀge in int_out
control+6 = 1 EintrÀge in addr_in
control+8 = 0 EintrÀge in addr_out
int_in = me_flag 0 = abfragen, 1 = setzen
int_out = me_return sollte immer = 1 zurĂŒckliefern
addr_in = me_values Zeiger auf eine MN_SET-Struktur

BASIC-Aufruf: Menu_Settings (Me_Flag% , Me_Values%L)

Die neue AES-Struktur MN_SET:

struct MN_SET
{
LONG Display;              Anzeigeverzögerung
LONG Drag;                  Auswahlverzögerung
LONG Delay;                 Einfachklick Scroll-Verzögerung
LONG Speed;               Scroll-Verzögerung
WORD Height;              Scroll-Höhe (Anzahl der darzustellenden EintrÀge) 
}

Alle Verzögerungszeiten werden in Millisekunden gemessen.

Die Befehle der POPUP.LIB

Struct_Menu (Menu%L , Mn_Tree%L , Mn_Menu% , Mn_ltem% , Mn_Scroll% , Mn_Keystate%)

Anlegen der neuen AES-Struktur "MENÜ".

In Mn_Tree%L ĂŒbergibt man die Adresse des Pop-Up-MenĂŒbaumes, in Mn_Menu% den Index des Vaterobjektes und in Mn_Item% den Anfangseintrag. Mn_Scroll% sollte 0 sein, es sei denn, es handelt sich um ein Text-Pop-Up, das gescrollt werden soll. Mn_Keystate% ist im Moment bedeutungslos. In Menu%L erhĂ€lt man dann die Adresse der Struktur zurĂŒck.

■ FN Mn_Item% (Menu%L)

Anfangseintrag bzw. gewÀhlten Eintrag der Struktur Menu%L abfragen.

■ FN Mn_Scroll% (Menu%L)

Scrollflag der Struktur Menu%L abfragen.

■ FN Mn_Keystate% (Menu%L)

Shift-Tastenstatus der Struktur Menu%L abfragen.

■ Mn_Item (Menu%L, ltem%)

Item% als Anfangseintrag der Struktur Menu%L setzen.

■ Mn_Scroll (Menu%L, Scroll%)

Scroll% als Scrollflag der Struktur Menu%L setzen.

■ Popup (Pop_Str%L , Tree%L , Ob%)

vollstĂ€ndige Bearbeitung eines Text-Pop-Ups bzgl. eines Pop-Up-Buttons. Das Text-Pop-Up, dessen Struktur in Pop_Str%L ĂŒbergeben wird, wird relativ zum Button Ob% des Dialogbaumes Tree%L, gezeichnet. Der selektierte Eintrag wird dann automatisch mit einem HĂ€kchen versehen und der Text in den Button ĂŒbertragen.

■ FN Popup% (Pop_Str%L , X% , Y%)

beliebiges Popup zeichnen und selektierten Eintrag zurĂŒckliefern. Die fvfenĂŒstruktur des Pop-Ups steht in Pop_Str%L, die absoluten Bildschirmkoordinaten in X% und Y%; die Funktion liefert den gewĂ€hlten Eintrag oder eine 0 zurĂŒck.

■ Menu_Settings (Me_Flag%, Display%L , Drag%L , Delay%L , Speed%L , Height%)

MenĂŒ-Settings abfragen oder einstellen. Bei Me_Flag%=0 werden die aktuellen Settings zurĂŒckgeliefert; bei Me_Flag%=1 werden die Parameter als Settings definiert. Vereinfachte Version des AES-Aufrufes MENU_SETTINGS, in der Wirkung aber identisch.

■ Menu_Settings (Height%)

Setzen der Scroll-Höhe. Es wird nur die Scroll-Höhe geÀndert, alle anderen Settings bleiben unverÀndert.

■ FN Menu_Settings%

Abfragen der Scrollhöhe.

Die Befehle der POPDEF.LIB

■ Def_Pop [(Max_W% , Max_H%)]

Definiton eines Pop-Ups einleiten; optional kann die Maximalbreite und -höhe des Pop-Ups (in Zeichen) angegeben werden. Das ist aber nur erforderlich, wenn das Pop-Up sehr groß oder der Speicher sehr klein ist. Die Voreinstellung ist sonst maximal 64 Zeichen Breite und maximal 32 Zeichen Höhe.

■ Pop_Entry (Entry$ , Entry% [, State%])

normalen Eintrag erzeugen
Entry$ enthĂ€lt den Text des Eintrags, und der RĂŒckgabewert Entry% ist das Handle, mit dem spĂ€ter auf den Eintrag zugegriffen wird. Entry$ sollte keine Anfangs- und Endleerzeichen enthalten, sie werden automatisch in der richtigen LĂ€nge erzeugt. Optional kann ein Object State% ĂŒbergeben werden (am besten durch die Gemdefs). In Text-Pop-Ups sind allerdings nur Normal%=0, Checked%=4, Diasbled%=8 sinnvoll. Ohne Angabe von State% wird Normal%=0 eingestellt.

■ Pop_Line

Es wird eine graue Trennlinie (?--------") als Eintrag erzeugt.

■ End_Pop (Pop_Mem%L)

Pop-Up-Definiton beenden und damit Pop-Up-Objektbaum im Speicher anlegen. Die Objekte werden in der GrĂ¶ĂŸe aufeinander abgestimmt und mittels RSRC_OBFIX an die aktuelle Auflösung angepaßt. Die Adresse des Objektbaumes erhĂ€lt man in Pop_Mem%L zurĂŒck. Der so angefertigte Objektbaum kann genau wie jeder mit einem RCS erstellte Objektbaum benutzt werden.

■ Clear_Pop (Pop_Mem%L)

Objektbaum eines Pop-Up-MenĂŒs löschen. Der Speicher, den der Baum belegt hatte, wird wieder freigegeben. Dieser Aufruf ist nur bei knappem Speicher erforderlich -OMIKRON.BASIC gibt beim Programmende sowieso alle Speicherbereiche wieder frei.