Willkommen zum RapaGUI-Tutorial! Dieses kleine Schritt-für-Schritt-Dokument führt Sie in wenigen Schritten durch den Prozess der Erstellung Ihrer ersten GUI mit RapaGUI. Wir werden eine kleines GUI-Programm erstellen, welches aus einer Listenansicht, einem Texteingabe-Widget und zwei Schaltflächen besteht (Listview, Textentry, Button). Die beiden Schaltflächen sollten so programmiert werden, dass sie das Hinzufügen und Entfernen von Einträgen aus der Listenansicht ermöglichen. Die Daten, die in die Listenansicht eingefügt werden sollen, sind dem Texteingabe-Widget zu entnehmen. So sieht dieses kleine Programm unter Windows aus:
Beginnen wir mit den Grundlagen: In RapaGUI werden GUIs mit Hilfe von XML-Dateien erstellt, die eine Beschreibung einer Reihe von Fenstern enthalten, die eine Vielzahl von GUI-Widgets beinhalten. Hier ist eine minimale GUI-Beschreibung für eine RapaGUI-GUI, die ein Fenster mit einer Listenansicht, einem Texteingabe-Widget und zwei Schaltflächen im XML-Format enthält:
<?xml version="1.0" encoding="iso-8859-1"?>
<application>
<window title="Example GUI">
<vgroup>
<listview>
<column/>
</listview>
<textentry/>
<hgroup>
<button id="add">Add</button>
<button id="rem">Remove</button>
</hgroup>
</vgroup>
</window>
</application>
|
Das Objekt <application> ist das Haupt-MOAI-Objekt
für jede Anwendung und darf nur einmal pro Anwendung verwendet
werden. Alle anderen MOAI-Objekte sind untergeordnete Elemente
der Application-Klasse. Das Wurzelelement
jedes <window>-Objekts muss von der Group-Klasse
(Gruppen) abgeleitet sein, d.h. es muss entweder <vgroup>, <hgroup>
oder <colgroup> sein. Beachten Sie auch, dass pro
Fenster nur ein Wurzelelement vorhanden sein muss.
Um zu sehen, wie unsere obige XML-Definition als GUI aussieht,
müssen wir sie in einer Datei namens GUI.xml speichern
und dann den folgenden Code verwenden, damit RapaGUI sie in
eine native GUI für das Betriebssystem konvertiert, auf dem
Hollywood läuft:
@REQUIRE "RapaGUI"
moai.CreateApp(FileToString("GUI.xml"))
Repeat
WaitEvent
Forever
|
Als Nächstes sollten Sie einige Informationen über Ihr Programm
hinzufügen, indem Sie die Präprozessor-Anweisungen @APPAUTHOR,
@APPCOPYRIGHT, @APPDESCRIPTION, @APPTITLE
und @APPVERSION verwenden. RapaGUI benötigt diese
Informationen für verschiedene Zwecke, z.B. werden die Informationen,
die in @APPTITLE übergeben werden, auch vom MUI-Einstellungsfenster
auf AmigaOS und kompatiblen Systemen verwendet. Hier ist eine
Beispieldefinition dieser Präprozessor-Anweisungen:
@APPTITLE "Tutorial" @APPVERSION "$VER: Tutorial 1.0 (29.12.15)" @APPCOPYRIGHT "Copyright ©2015, Andreas Falkenhahn" @APPAUTHOR "Andreas Falkenhahn" @APPDESCRIPTION "The tutorial app from the RapaGUI guide" |
Als nächstes müssen wir eine Callback-Funktion mit Hilfe des
Hollywood-Befehls InstallEventHandler() installieren,
da unser Hollywood-Skript jedes Mal informiert werden muss, wenn
ein RapaGUI-Ereignis eintrifft. Daher müssen wir unseren Code
wie folgt modifizieren:
@REQUIRE "RapaGUI"
Function p_EventFunc(msg)
; contents follow below
EndFunction
InstallEventHandler({RapaGUI = p_EventFunc})
moai.CreateApp(FileToString("GUI.xml"))
Repeat
WaitEvent
Forever
|
Was wir hier getan haben, ist die Installation der Funktion
p_EventFunc als Callback-Funktion, die immer dann ausgeführt
wird, wenn ein RapaGUI-Ereignis eintritt. Wenn wir ein solches
Ereignis erhalten, müssen wir dann prüfen, welche MOAI-Klasse
und welches Attribut es ausgelöst hat. Dies geschieht, indem
man die Felder msg.Class und msg.Attribute
der Ereignismeldung überprüft, die unsere Callback-Funktion
als ersten Parameter erhält.
Als nächstes wollen wir die Funktionalität hinzufügen, dass der Text im Texteingabe-Widget immer dann als letzter Eintrag in die Listenansicht eingefügt wird, wenn der Benutzer auf die Schaltfläche "Add" (Hinzufügen) klickt. Dazu müssen wir zunächst einen Weg finden, unsere Widgets aus dem Hollywood-Skript zu identifizieren. Dies geschieht durch die Angabe von IDs in der XML-Definition. IDs sind einfache Textzeichenfolgen, die für die Kommunikation mit MOAI-Objekten aus Hollywood-Skripten verwendet werden. Fügen wir also jetzt einige IDs für alle Widgets hinzu, mit denen wir kommunizieren wollen. Wir müssen unsere XML-Definition so modifizieren:
...
<listview id="mylistview">
<column/>
</listview>
<textentry id="mystring"/>
<hgroup>
<button id="mybt1">Add</button>
<button id="mybt2">Remove</button>
</hgroup>
...
|
Nun, da wir dies erledigt haben, können wir etwas Code zu unserer
Callback-Funktion hinzufügen, die den Inhalt des Texteintrag-Widgets
erfasst und am Ende der Liste in unserem Listview-Objekt (Listenansicht) hinzufügt.
Dies geschieht, indem man zuerst moai.Get()
für das Attribut Textentry.Text aufruft, um den Inhalt
des Texteintrag-Widgets zu erhalten und dann die Methode Listview.Insert
ausführt. Fügen Sie mit moai.DoMethod()
den Eintrag in die Listenansicht ein. Hier ist der Code, der
zu diesem Zweck in die Funktion p_EventFunc eingefügt
werden muss:
Switch msg.Class
...
Case "Button":
Switch msg.Attribute
Case "Pressed":
Switch msg.ID
Case "mybt1": ; "Add" button was pressed
Local s$ = moai.Get("mystring", "text")
moai.DoMethod("mylistview", "insert", "bottom", s$)
EndSwitch
EndSwitch
EndSwitch
|
Als nächstes wollen wir die Funktionalität unserer Schaltfläche "Remove" (Entfernen) implementieren. Immer wenn diese Schaltfläche gedrückt wird, soll der aktive Eintrag aus der Listenansicht entfernt werden. Wir können dies tun, indem wir die Methode Listview.Remove in der Listenansicht ausführen. Daher müssen wir unseren Code so modifizieren:
Switch msg.ID
...
Case "mybt2": ; "Remove" button was pressed
moai.DoMethod("mylistview", "remove", "active")
EndSwitch
|
Nun wollen wir, dass der aktive Eintrag der Listenansicht automatisch im Texteingabe-Element angezeigt wird. Dazu müssen wir eine Benachrichtigung für das Attribut Listview.Active einrichten, die immer dann ausgelöst wird, wenn sich der aktive Eintrag der Listenansicht ändert. Daher müssen wir unsere XML-Datei so modifizieren:
...
<listview id="mylistview" notify="active">
<column/>
</listview>
...
|
In unserer Callback-Funktion können wir diese Funktionalität ganz einfach implementieren, indem wir die Methode Listview.GetEntry ausführen und dann den Inhalt des Texteingabe-Widgets mit dem Attribut Textentry.Text setzen. Hier ist der Code dafür:
Switch msg.Class
...
Case "Listview":
Switch msg.Attribute
Case "Active":
Local s$ = moai.DoMethod("mylistview", "getentry", "active")
moai.Set("mystring", "text", s$)
EndSwitch
EndSwitch
|
Wenn Sie diesen Code ausprobieren, werden Sie feststellen, dass das Attribut Listview.Active nicht nur dann ausgelöst wird, wenn der Benutzer mit der Maus einen neuen Listeneintrag auswählt, sondern auch dann, wenn Einträge aus der Listenansicht entfernt werden und somit ein neuer Eintrag aktiv wird.
Als nächstes wollen wir die Schaltfläche "Remove" deaktivieren,
wenn kein Eintrag in der Listenansicht aktiv ist. Wir können
Widgets deaktivieren, indem wir das Attribut Area.Disabled
auf True setzen. Da es zunächst keine Einträge in der Listenansicht
gibt, müssen wir Area.Disabled bereits beim Start
unseres Programms auf True setzen. Also müssen Sie diesen Code
eingeben:
...
moai.CreateApp(FileToString("GUI.xml"))
moai.Set("mybt2", "disabled", True)
...
|
Nun müssen wir einige Änderungen an unserer Callback-Funktion vornehmen. Wann immer wir die Benachrichtigung mit Listview.Active erhalten, müssen wir prüfen, ob sie sich von dem speziellen Wert "Off" unterscheidet. Wenn dies der Fall ist, aktivieren wir die Schaltfläche "Remove". Der spezielle Wert "Off" (-1) wird von Listview.Active zurückgegeben, wenn in der Listenansicht kein aktiver Eintrag vorhanden ist. Wir müssen unseren Code folgendermaßen anpassen:
Switch msg.Class
...
Case "Listview":
Switch msg.Attribute
Case "Active":
Local s$ = moai.DoMethod("mylistview", "getentry", "active")
moai.Set("mystring", "text", s$)
moai.Set("mybt2", "disabled", IIf(msg.triggervalue = -1,
True, False))
EndSwitch
EndSwitch
|
Wir verwenden hier das Feld msg.TriggerValue. Dieser
enthält immer den aktuellen Wert des Attributs, welches das
Ereignis ausgelöst hat, d.h. in unserem Fall den aktuellen Wert
des Attributs Listview.Active. Wir könnten auch moai.Get()
zuerst manuell auf Listview.Active aufrufen, aber
das ist nicht wirklich notwendig, da wir einfach msg.TriggerValue
verwenden können.
Als Letztes fügen wir ein Menü zu unserer GUI hinzu. Alle RapaGUI-Programme sollten über einen Menüpunkt verfügen, der den Benutzer darüber informiert, dass dieses Programm mit RapaGUI erstellt wurde. Sie können diesen Dialog öffnen, indem Sie die Methode Application.AboutRapaGUI ausführen. Um dieses Menü unserem Programm hinzuzufügen, verwenden wir die Menubar-Klasse (Menüleisten). Hier ist der XML-Code, den Sie vor Ihrer Fensterdefinition hinzufügen müssen:
...
<application>
<menubar id="mymenubar">
<menu title="File">
<item id="menabout">About...</item>
<item id="menaboutrapagui">About RapaGUI...</item>
<item/>
<item id="menquit">Quit</item>
</menu>
</menubar>
...
</application>
|
Nachdem wir unser Menüleisten-Objekt mit Hilfe des obigen XML-Codes erstellt haben, müssen wir diese Menüleiste an unserem Fenster anhängen. Dies geschieht durch das Setzen des Attributs Window.Menubar auf unser Menüleisten-Objekt. Hier ist der XML-Code dafür:
<window title="Example GUI" menubar="mymenubar"> |
Nun müssen wir unserer Callback-Funktion Code hinzufügen, der die entsprechende Aktion ausführt, wenn ein Menüpunkt ausgewählt wird. Bevor wir das tun können, müssen wir jedoch unserem Applications-Objekt eine ID zuweisen, damit wir moai.DoMethod() verwenden können. Hier sehen Sie, wie der XML-Code angepasst werden muss:
<application id="app"> |
Jetzt können wir den Code für unsere Callback-Funktion schreiben, welche die Menüeinträge berücksitigt:
Switch msg.Class
...
Case "Menuitem":
Switch msg.Attribute
Case "Selected":
Switch msg.id
Case "menabout":
moai.Request("Test", "Test program\n" ..
"© 2015 by Andreas Falkenhahn", "OK")
Case "menaboutrapagui":
moai.DoMethod("app", "aboutrapagui")
Case "menquit":
End
EndSwitch
EndSwitch
EndSwitch
|
Einige letzte Änderungen an unserem Programm könnten darin bestehen, Online-Hilfe zu unseren Widgets hinzuzufügen, indem man die Attribute Area.Tooltip und Menuitem.Help verwendet, eine Statusleiste und Tastaturkürzel für die Menüeinträge mit dem Unterstrichzeichen hinzufügt. Diese Änderungen werden dem Leser als Übung überlassen.
So sieht unser endgültiges Programm aus. Zuerst die XML-Datei:
<?xml version="1.0" encoding="iso-8859-1"?>
<application id="app">
<menubar id="mymenubar">
<menu title="File">
<item id="menabout">About...</item>
<item id="menaboutrapagui">
About RapaGUI...</item>
<item/>
<item id="menquit">Quit</item>
</menu>
</menubar>
<window title="Example GUI" menubar="mymenubar">
<vgroup>
<listview id="mylistview" notify="active">
<column/>
</listview>
<textentry id="mystring"/>
<hgroup>
<button id="mybt1">Add</button>
<button id="mybt2">Remove</button>
</hgroup>
</vgroup>
</window>
</application>
|
Und hier ist der Code für die Programmlogik:
@REQUIRE "RapaGUI"
@APPTITLE "Tutorial"
@APPVERSION "$VER: Tutorial 1.0 (29.12.15)"
@APPCOPYRIGHT "Copyright ©2015, Andreas Falkenhahn"
@APPAUTHOR "Andreas Falkenhahn"
@APPDESCRIPTION "The tutorial app from the RapaGUI guide"
Function p_EventFunc(msg)
Switch msg.Class
Case "Button":
Switch msg.Attribute
Case "Pressed":
Switch msg.ID
Case "mybt1": ; "Add" button was pressed
Local s$ = moai.Get("mystring", "text")
moai.DoMethod("mylistview", "insert", "bottom", s$)
Case "mybt2": ; "Remove" button was pressed
moai.DoMethod("mylistview", "remove", "active")
EndSwitch
EndSwitch
Case "Listview":
Switch msg.Attribute
Case "Active":
Local s$ = moai.DoMethod("mylistview", "getentry", "active")
moai.Set("mystring", "text", s$)
moai.Set("mybt2", "disabled", IIf(msg.triggervalue = -1,
True, False))
EndSwitch
Case "Menuitem":
Switch msg.Attribute
Case "Selected":
Switch msg.id
Case "menabout":
moai.Request("Test", "Test program\n" ..
"© 2015 by Andreas Falkenhahn", "OK")
Case "menaboutrapagui":
moai.DoMethod("app", "aboutrapagui")
Case "menquit":
End
EndSwitch
EndSwitch
EndSwitch
EndFunction
InstallEventHandler({RapaGUI = p_EventFunc})
moai.CreateApp(FileToString("GUI.xml"))
moai.Set("mybt2", "disabled", True)
Repeat
WaitEvent
Forever
|
Das ist es! Jetzt sollten Sie in der Lage sein, fantastische neue GUI-Programme mit Hollywood und RapaGUI zu erstellen. Vielen Dank für das Lesen dieses Tutorials und genießen Sie die Leistungsfähigkeit moderner GUI-Programmierung mit Hollywood und RapaGUI in Ihren Händen!