Im ersten Teil des Kurses haben Sie das Konzept von faceVALUE kennengelernt und können nun Menüs und einfache Dialoge erstellen, aufrufen und auswerten. In diesem Kursteil sollen die noch nicht behandelten Spezialobjekte von faceVALUE erläutert werden. Anschließend wird auf Alertboxen, Busydialoge und animierte Mauszeiger eingegangen.
Vielleicht kennen Sie noch aus den älteren Zeiten die Soundgeneratorprogramme, mit denen man dem ATARI-Soundchip seine Klänge entlocken kann. Im folgenden werden wir ein solches Programm mit Hilfe von faceVALUE entwickeln, wenngleich es nicht die komplette Funktionsvielfalt des Soundchips abdecken wird. Abbildung 1 zeigt das geplante Programm in Aktion. Wir beginnen im RCS-Programm und öffnen eine neue RSC-Datei SOUNDGEN.RSC. Binden Sie die Bäume aus Tabelle 1 ein. faceVALUE liegt hierzu die Datei TREES.RSC bei, aus der Sie die benötigten Bäume nur zu kopieren brauchen. Der SYSTEM-Dialog wird wie gewohnt unserem SOUNDGEN-Projekt angepasst. Erweitern Sie den Dialog FVT_ALST um den Text einer Alertbox, die später als "Über SOUNDGEN..."-Dialog dienen soll. Wählen Sie als Text z.Bsp. "[8][SOUNDGEN Aus dem faceVALUE-Kurs. ][OK]" und geben Sie dem Objekt den Namen ALABOUT. Auch die Titelstrings der Dialoge FVT_ALTR, FVT_ASCI, FVT_WORK und FVT_PROG können angepasst werden. Achten Sie aber darauf, dass die Objektstruktur der Bäume nicht verändert wird. Das Menü muss schließlich noch um einen Eintrag für das Soundgenerator-Fenster erweitert werden (Abb. 1). Als Namen für die Menüeinträge habe ich MMABOUT, MMSOUNDG und MMQUIT gewählt.
faceVALUE bietet zwei Möglichkeiten, Popupmenüs zu realisieren. Zum einen gibt es die "normalen" Popups. Der Inhalt dieser Popupmenüs wird in der Resourcedatei im Baum FVT_POPU festgelegt (Abb. 2). Dieser Baum enthält alle Popupmenüs in der endgültigen Form im aufgeklappten Zustand. Für jedes Menü kann man entweder Strings (für Textpopups) oder Images (für Imagepopups) einsetzen. Erstellen Sie für das SOUNDGEN-Programm die abgebildeten Popupmenüs. Ein Menü besteht dabei nur aus einer schattierten Box als Mutterobjekt und den Texten oder Bildern als Kindobjekte. Die andere Form der Popupmenüs bilden die Listboxen. Im Unterschied zu den normalen Popups werden die Listboxen erst später im Programm mit ihren Einträgen gefüttert, da ihr Inhalt variabel ist. Ein Beispiel wäre die Auswahl des Empfängers für ein Telefax. Welche und wie viele Empfänger in der Listbox zur Verfügung stehen, hängt von der Mächtigkeit des Adressbuches ab, das der Benutzer der FAX-Software angelegt hat. faceVALUE kennt nur Textlistboxen. Die Einträge der Listboxen werden vom Programmierer sehr einfach durch Stringarrays festgelegt und verändert, hierzu später mehr. Popups und Listboxen können sinnvoll angewendet sehr viel Übersicht schaffen. faceVALUE bietet die Möglichkeit, Radiobuttons, Checkbuttons wie auch normale Buttons in Popups und Listboxen zu verlegen: Radiopopups, Radiolistboxen, Checklistboxen, Menüpopups und Menülistboxen. Zufälligerweise ist der geplante Hauptdialog unseres Klanggenerators in dieser Hinsicht sehr ergiebig, und wir können die Funktionsweise und die Programmierung der einzelnen Popup-Typen damit näher kennenlernen.
Wenn Sie nun gemäß Abbildung 3 den Hauptdialog SOUNDGEN entwerfen, ist es sehr hilfreich, alle faceVALUE- Spezialobjekte aus der faceVALUE beiliegenden Datei OBJECTS.RSC zu kopieren. Die Datei enthält alle Spezialobjekte mit bereits richtig gesetzten erweiterten Objektdaten, sie brauchen in der Regel nur noch die Objektgrößen und die Textinhalte anzupassen. Eine Ausnahme hierzu bilden die Knöpfe der "normalen" Popups. Diese müssen noch mit ihren Popupmenüs aus dem FVT_POPU-Baum verknüpft werden, damit die Engine später weiß, welches Menü bei welchem Knopf geöffnet werden soll. Realisiert wird diese Verknüpfung über den erweiterten Objekttyp der Popupknöpfe. Durch das Setzen des erweiterten Objekttyps von SGOKTAVE auf 33 (33=1+32) und von SGFORM auf 34 (34=2+32) öffnet die Engine beim Benutzen dieser Popup-Knöpfe das erste bzw. das zweite Popupmenü aus FVT_POPU.
Auch bei Numberscrollern benötigt die Engine noch Informationen, die bereits in der RSC-Datei festgelegt werden: der minimale und der maximale vom Benutzer einstellbare Wert. Wieder werden diese Informationen über den erweiterten Objekttyp angegeben. Der minimale Wert wird in den X-Type des linken Pfeiles und der maximale Wert in den X-Type des rechten Pfeiles eingetragen. Dabei können Sie auch negative Werte angeben, indem Sie zugleich den X-State 11 einschalten. In unserem Beispiel soll der Numberscroller Werte von 1 bis 100 darstellen können. Der X-Type des linken Pfeiles muss also auf 1, der X-Type des rechten Pfeiles auf 100 gesetzt werden. Außerdem müssen sowohl der X-State 11 des linken, als auch der des rechten Pfeiles gelöscht sein, da beide Werte positiv sind. An diesem Punkt angelangt ist die RSC-Datei komplett fertig. Zur Sicherheit können Sie alle Bäume und Unterbäume noch einmal durchsortieren, damit es keine Probleme mit den Popupverweisen oder mit in falscher Reihenfolge angelegten Objekten gibt. Lassen Sie nun durch faceVALUE das Programmgrüst erstellen und mergen Sie es in den Interpreter ein. Denken Sie daran, die INLINE zu laden und mergen Sie die Prozedur rsc_ob_reset aus dem ersten Kursteil ebenfalls hinzu.
Wenn Sie tatsächlich zu der hartnäckigen Sorte von Lesern gehören sollten und noch nicht in Listing 1 gespitzelt haben, dürfen Sie dies nun nachholen. Das Listing enthält alle notwendigen Einträge in die Userroutinen, um das Programm vollständig zum Laufen zu bringen. In der Prozedur user_rsc_var_init werden zunächst die Dialogelemente mit ihren Startwerten vorbelegt. Die Listboxen haben von faceVALUE gleich mehrere Statusvariablen erhalten: Zunächst wäre da das Array mit der Endung _arr$() und seiner Indexvariablen mit der Endung _ndx&. In das Array werden die Texteinträge eingetragen, die beim TMffnen in der Listbox zur Auswahl stehen sollen. Das Feld sgton_arr$() wird z.Bsp., da die Listbox SGTON später der Auswahl eines Grundtones dienen soll, mit den Texten "C", "Cis", "D", "Dis" usw. gefüllt. Mit Hilfe der Indexvariablen teilen Sie der Engine mit, wie viele Einträge aus dem Array in der Listbox erscheinen sollen (hier: sgton_ndx&=12). Je nach Typ (gleiches gilt hier übrigens auch für normale Popups) wurden die Listboxen noch mit weiteren Statusvariablen ausgestattet. Radiolistboxen und Radiopopups haben genau wie Radiobuttons eine Word-Variable mit der Endung _var&, die die Nummer des gerade angewählten Eintrags enthält. Checklistboxen sind schon weitaus anspruchsvoller. Sie benötigen das Boolarray _arr!(), da jeder einzelne Eintrag vom Benutzer selektiert und deselektiert werden kann und vom Programmierer natürlich auch angesprochen und abgefragt werden können muss. SGOPTION ist eine solche Listbox. Den dritten Typ bilden die Menülistboxen (SGVORDEF) und Menüpopups. Diese Popups erhalten statt einer Statusvariablen direkte Einträge in der Prozedur user_rsc_interact, da die Auswahl eines Menüeintrages zu einer Programmaktion führen soll. Mit diesem Hintergrundwissen dürfte es Ihnen nun gelingen, auch den restlichen Teil des Quelltextes nachzuvollziehen. In den sgvordef-Feldern werden zu Beginn (in user_rsc_var_init) die Daten einiger vordefinierter Klänge abgelegt. Wählt der Benutzer später einen Eintrag aus der Menülistbox SGVORDEF aus, springt die Engine in den entsprechenden CASE-Zweig der Prozedur user_rsc_interact(). Hier werden dann die Statusvariablen aller betroffenen Dialogobjekte entsprechend der vordefinierten Werte des ausgewählten Eintrages gesetzt. Der anschließende Aufruf der Prozedur rsc_ob_reset erledigt alles weitere, sprich das Setzen der Objektdaten gemäß der neuen Werte der Statusvariablen und das Neuzeichnen des Dialoges (Objekt 0 = gesamter Baum). Alle weiteren Ergänzungen in user_rsc_interact sind durch einen Blick in Listing 1 bestimmt leichter zu verstehen als durch seitenlange Erklärungen. Man sieht hier sehr gut, mit wie wenig Programmieraufwand ein faceVALUE-Programm zum Laufen zu bringen ist. Die Arbeit im Interpreter konzentriert sich dabei in der Tat nur noch auf die eigentliche Funktionalität des Programms.
Wie Alertboxen in faceVALUE-Programmen aufgerufen werden, haben Sie bestimmt schon in Listing 1 entdeckt. faceVALUE- Alertboxen haben einige Besonderheiten. Sie sind nicht systemmodal, man kann die Alertboxen mit beliebigen weiteren Icons aufrufen (die Icons brauchen nur in den Baum FVT_ALIC einzufügt zu werden) und faceVALUE kann in Alertboxen auch animierte Icons darstellen. Die Datei ANIMICON.RSC enthält einige Beispielanimationen. Um diese Icons in eigenen Programmen verwenden zu können, müssen die betreffenden Bäume in die RSC-Datei eingebunden sein. SOUNDGEN nutzt z.Bsp. das EYEWALK-Icon. In FVT_ALIC fügt man schließlich ein String (statt eines Icons) hinzu, der die Nummer das Baumes des animierten Icons enthält. Die Zählung beginnt bei 0. Beim öffnen der Alertbox wird dann die Nummer dieses Strings als Iconnummer angeben, und die Engine benutzt stattdessen das entsprechende animierte Icon (Abb. 4).
So schön und einfach die Oberflächenprogrammierung mit faceVALUE auch sein mag, die meisten Programme enthalten Teile, in denen der Rechner nicht nur auf Benutzereingaben wartet, sondern wirklich etwas arbeiten soll. Hierbei kommt es zu Konflikten mit der Benutzeroberfläche: der Benutzer soll im Normalfall weiterhin Fenster, Menüs und Dialoge bedienen können, und es wäre die Aufgabe der Engine, auf diese Benutzeraktivitäten zu reagieren. Während das Programm aber in einer Ihrer Prozeduren hängt, kann die faceVALUE-Engine nicht zum Zuge kommen. Es gibt nun im Wesentlichen zwei Möglichkeiten, diesen Konflikt zu lösen.
Die erste Möglichkeit ist mit Sicherheit die uneleganteste. Sie besteht darin, Bildschirm und Maus zu sperren und damit weder dem Benutzer noch anderen Programmen eine Aktion zu ermöglichen, die den Aufruf der Engine erfordern würde. Man sperrt hierfür zu Beginn der rechenintensiven Prozedur den Bildschirm und die Maus durch Aufruf der Prozedur aes_screen_lock und verdeutlicht dem Benutzer diesen Zustand, indem man die Maus in eine Biene verwandelt: ~GRAF_MOUSE(2,0). Statt einer Biene bietet faceVALUE zudem die Möglichkeit, eigene und sogar animierte Mauszeiger darzustellen. Dazu müssen die Mauszeiger im RSC-File eingebunden sein. Die Datei BUSYMOUS.RSC enthält einen Baum mit vielen solcher animierten Mauszeiger, den Sie zu diesem Zweck (auch teilweise) in Ihre RSC-Datei einbinden können. Statt mit GRAF_MOUSE werden solche Mauszeiger mit @mouse_form(objekt&) für normale bzw. @mouse_busy(objekt&) für animierte Mauszeiger eingeschaltet. Jedesmal wenn @mouse_busy(objekt&) aufgerufen wird, schaltet die faceVALUE-Engine den animierten Mauszeiger um ein Bild weiter. Am Ende der rechenintensiven Prozedur schaltet man die Maus mit @mouse_form(-1) wieder in einen Pfeil zurück und ruft @aes_clear_buffers sowie @aes_screen_unlock auf, um Maus und Bildschirm wieder freizugeben (Listing 2).
Die zweite Möglichkeit ist um Längen eleganter und mit faceVALUE nicht schwerer zu realisieren. Man öffnet einen programmodalen Busydialog, der den Benutzer darüber informiert, was genau das Programm gerade wichtiges zu tun gedenkt und springt in regelmäßigen Abständen selbst die Engine an. Das restliche System kann dadurch weiterlaufen. Der Aufruf der Engine wird durch @evnt_multi_loop erreicht und sollte mindestens ein bis zwei mal je Sekunde erfolgen. Bitte beachten Sie, dass diese Prozedur erst seit faceVALUE 1.1 implementiert ist und sie auch dort im faceVALUE-Maindialog angewählt werden muss, um eingebunden zu werden. Zur unserer Erleichterung liegen faceVALUE (schon ab Version 1.0) zwei vorgefertigte Busydialoge bei, für deren Aufruf sogar eigene Prozeduren zur Verfügung stehen. Zum einen gibt es den schlichten "Busydialog". Er ähnelt einer Alertbox und ebenso wie in Alertboxen können in diesem Dialog auch animierte Icons Verwendung finden. Zum anderen bietet faceVALUE den "Progressdialog" an. Dieser Dialog ist zwar nicht mit einem Icon, dafür aber mit einem Ablaufbalken ausgestattet. Beide Dialoge bieten optional einen Abbruchknopf. Wenn Sie einen dieser Dialoge benutzen, ist der Aufruf der Prozedur evnt_multi_loop nicht von Nöten. Dementsprechend müssen natürlich andere Prozeduren angesprungen werden (Listings 3 und 4 sagen mehr als tausend Worte). In der nächsten Ausgabe werden wir das Territorium der einfachen Dialoge verlassen und uns den Userfenstern zuwenden. Wie gehen die Bildschirmausgaben dort von statten? Wie wird auf Mausklicks und Tastendrücke reagiert? Der Schwerpunkt wird dabei auf die Verwaltung von Textlisten in Userfenstern gelegt.
Tabelle 1 | ||
Baum 0 | SYSTEM | Programmparameter |
Baum 1 | FVT_POPU | s. Abb. 2 |
Baum 2 | FVT_ALST | Alertstrings (hier die About-Alert anfügen) |
Baum 3 | FVT_ALIC | Alert-Icons (ein String-Objekt mit dem Inhalt "8" anfügen. 8 ist die Baumnummer von EYEWALK) |
Baum 4 | FVT_ALTR | Alertbox |
Baum 5 | FVT_ASCI | ASCII-Tabelle |
Baum 6 | FVT_LSBX | Listbox-Dialog |
Baum 7 | FVT_MAUS | diverse Mauszeiger (Objektname MACBUSYMOUSE bei ORCS in BUSYMOUS umbenennen, wegen der 8-Buchstaben-Grenze) |
Baum 8 | EYEWALK | Animiertes Icon (aus ANIMICON.RSC) |
Baum 9 | FVT_WORK | Busydialog (X-Type des Icons auf 8 setzen, also der Baumnummer des animierten Icons) |
Baum 10 | FVT_PROG | Progressdialog |
Baum 11 | MENU | Hauptmenü (anpassen, s. Text) |
Baum 12 | SOUNDGEN | Hauptdialog, siehe Text |