5.6 Eingabe von Parametern mit on getPropertyDescriptionList und on runPropertyDialog

Eine der herausragendsten Eigenschaften von Verhalten ist das Eingeben von Eigenschaftswerten über eine Dialogbox. Wird ein Verhalten in das Drehbuch oder auf die Bühne gezogen bzw. der Parameter-Button im Verhaltensinspektor gedrückt, öffnet sich ein Dialogfenster zur komfortablen Eingabe der individuellen Werte. Diese gelten nur für die aktuelle Instanz, jede neue Instanz erhält eigene Werte. Die Werte werden automatisch mit dem Director-Film abgespeichert.

Zum Erstellen dieses Dialogs dient der Handler on getBehaviorDescriptionList. Dieser Handler ist optional, er muss also nur für die Verhalten implementiert werden, die die Eingabe von Werten erwarten. Er gibt eine Eigenschaftsliste zurück, die für jede zu setzende Eigenschaft des Verhaltens eine Beschreibung über Format und Standardwert sowie die Form des Eingabefeldes enthält. Diese Beschreibung ist wieder eine Eigenschaftsliste. Da bei mehreren Eigenschaften diese Liste schnell unübersichtlich wird, empfiehlt es sich, das Erstellen der Liste in mehrere Programmzeilen aufzugliedern, wie es im folgenden Skript geschieht:

on getBehaviorDescriptionList
description = [:]

description.addProp(#Eigenschaftsname1, Beschreibungsliste1)
description.addProp(#Eigenschaftsname2, Beschreibungsliste2)
...
return description
end getBehaviorDescriptionList

Die Eigenschaften müssen mit dem property-Schlüsselwort als solche definiert sein, da sie sonst nicht gespeichert werden. Sie werden als Symbol, also mit vorangestelltem # angegeben, da Lingo sonst versucht, ihren Wert zu interpretieren.

Die Beschreibungsliste, ebenfalls eine Eigenschaftsliste, muss folgende Eigenschaften definieren14:

#comment: "Kommentartext" Der Text, der Auskunft über die einzugebende Eigenschaft gibt.
#format: #Datentyp Der erwartete Datentyp. Zulässige Werte sind: #boolean, #bitmap, #button, #digitalvideo, #field, #filmloop, #float, #frame, #graphic, #ink, #integer, #marker, #member, #movie, #ole, #palette, #picture, #richtext, #script, #shape, #sound, #string, #symbol, #transition, #xtra
#default: Standardwert

Dieser Wert ist standardmäßig im Dialogfenster ausgewählt.

Die Definition der Eigenschaft mTon in unserem Soundskript sieht beispielsweise folgendermaßen aus:

on getPropertyDescriptionList
description = [:]
description.addProp(#mTon, [ #comment: "Soundname ohne Endung:",
#format: #string,
#default: ""])
...
return description
end getPropertyDescriptionList

Wir legen fest, dass mTon eine Zeichenkette sein soll und als Standardwert nichts im Eingabefeld stehen soll. Das Dialogfenster sieht so aus:

Wichtig ist, dass das Fenster alle eingegebenen Werte auch tatsächlich in dem Format zurückgibt, das für #format eingegeben wurde. Eine nachträgliche Konvertierung, hier z.B. mit der Funktion string() erübrigt sich also.

Die Datentypen, die für Format anzugeben sind, lassen sich in zwei Gruppen aufteilen: Darstellertypen, also Datentypen, die in der Besetzung gespeichert werden, und Nicht-Darstellertypen.

Bei der Angabe eines Darstellertypen, z.B. #bitmap, stellt Director automatisch eine Liste aller verfügbaren Darsteller in der Besetzung zusammen und zeigt diese in einem Pull-Down-Menü an. Ein Verhalten, dass einen Darsteller auf der Bühne durch einen anderen austauscht, sobald die Maus über ihm liegt, könnte seine Eigenschaft mRolloverMember wie folgt definieren:

on getPropertyDescriptionList
description = [:]
if the currentSpriteNum > 0 then
memberNumber = sprite(the currentSpriteNum).member.number
description.addProp(#mRolloverMember,
[#comment: "Rollover-Darsteller:",
#format: #bitmap,
#default: member (memberNumber + 1)])
end if
return description
end getPropertyDescriptionList

Das Skript benutzt einen ausgefeilteren Standardwert, nämlich immer den Bitmap-Darsteller, der auf den Darsteller folgt, auf den das Skript gezogen wurde. Wird das Skript in den Spritkanal gezogen, wird gar kein Dialog angezeigt. (Ab Director 8 ist es möglich zu verhindern, dass Skripte in die falschen Kanäle gezogen werden; siehe "Anhang: Neue Befehle in Director 8": on isOkToAttach).

Das Dialogfenster zeigt automatisch alle Bitmap-Darsteller in den Besetzungen zur Auswahl an:

Quellcode des Beispiels

Die folgende Tabelle zeigt alle verfügbaren Darstellertypen an. In der Spalte "the type of member" steht, welchen Werten der Eigenschaft member("...").type (bzw. the type of member) der Datentyp entspricht.15

Format the type of member Beschreibung
#bitmap #bitmap Bitmap-Darsteller
#button #button Button-Darsteller
#digitalVideo #digitalVideo (ohne #quickTimeMedia) Video-Darsteller, aber keine Quicktime-Darsteller
#field #field (nicht #text) Field-Darsteller, aber keine Richtext-Darsteller
#filmLoop #filmLoop Filmschleifen
#graphic #animgif, #bitmap, #button, #digitalVideo, #flash, #field, #filmLoop, #movie, #ole, #picture, #text, #shape, #swa, #vectorShape Jeder Darsteller, der in einem Sprite-Kanal benutzt werden kann
#member alle aus #graphic, plus #font, #palette, #script, #sound und #transition alle Darsteller
#movie #movie Film-Darsteller
#ole #ole OLE-Darsteller
#palette #palette alle Director-Paletten plus Paletten-Darsteller der Besetzung
#picture #picture PICT-Darsteller
#richText #text Richtext-Darsteller
#script #script Skripte
#shape #shape Shape-Darsteller (Rechtecke, Ovale, Linien)
#sound #sound (nicht #swa) Sound-Darsteller, aber kein Shockwave-Sound
#transition #transition Alle Director-Transitions plus Transition-Darsteller der Besetzung

Unter Nicht-Darstellertypen fallen alle primitiven Lingo-Datentypen wie #integer oder #symbol, und allgemeine Datentypen, z.B. #cursor.16

Format Werte Bemerkung
#boolean TRUE und FALSE Wird als Checkbox angezeigt.
#cursor verfügbare System-Cursor (keine Bitmap-Cursor) Cursor sind systemabhängig. Für Bitmap-Cursor #bitmap benutzen.
#float Komma-Zahlen Es kann mit #min und #max ein Minimum und ein Maximum angegeben werden.
#ink alle Inks Inks werden im Popup-Fenster als Text angegeben, intern aber als Ganzzahl entsprechend der Eigenschaft the ink of sprite gespeichert.
#integer Ganzzahlen Es kann mit #min und #max ein Minimum und ein Maximum angegeben werden.
#marker previous; loop; next und alle Marker im Drehbuch Previous, loop und next werden als Symbole gehandhabt, Drehbuchmarker als Zeichenketten.
#string Zeichenkette  
#symbol Symbol  

Alle Datentypen können in ihrer Beschreibung eine optionale #range-Eigenschaft definieren. Damit lässt sich der Auswahlbereich auf eine definierte Zahl von Einträgen eingrenzen. Die Werte werden in Form einer linearen Liste angegeben und lassen sich dann per Pull-Down-Menü auswählen.

Im folgenden Handler kann man beispielsweise nur eine der drei Sprachen "Deutsch", "Englisch" und "Französisch" für die Eigenschaft mSprache auswählen:

on getPropertyDescriptionList
description = [:]
range = ["Englisch", "Französisch", "Deutsch"]
description.addProp(#mSprache,
[#comment: "Sprache:",
#format: #string,
#default: range[1],
#range: range])
return description
end getPropertyDescriptionList

Für die numerischen Datentypen Integer und Float lassen sich alternativ die minimal und maximal zulässigen Werte angeben. Dazu wird #range eine weitere Eigenschaftsliste mit den Eigenschaften #min für den kleinsten und #max für den größten zulässigen Wert zugeordnet. Die Eingabe erfolgt dann per Schieberegler.

Als Beispiel soll hier noch mal unser Soundwiedergabe-Skript dienen. Hier sind für die Eigenschaft mSoundkanal nur ganzzahlige Werte zwischen 1 und 4 sinnvoll:

on getPropertyDescriptionList
description = [:]
description.addProp(#mTon, [ #comment: "Soundname ohne Endung:",
#format: #string,
#default: ""])
description.addProp(#mSoundKanal, [ #comment: "SoundKanal:",
#format: #integer,
#default: 1,
#range: [#min:1, #max:4] ])
return description
end getPropertyDescriptionList

Quellcode des Beispiels

Eine weitere, jedoch undokumentierte Eigenschaft für Float-Werte ist #jump, die festlegt, um welchen Betrag sich der Zeiger weiterbewegt, wenn auf den Schieberegler geklickt wird. Dieser Wert spiegelt sich in der Darstellung der Skala wider.

Man muss sich bei der Anzeige der Dialogfenster aber nicht auf Director verlassen. Es ist ebenso möglich, ein eigenes Dialogfenster zu öffnen, z.B. um Grafiken anzuzeigen. Dazu lässt sich das MUI-Xtra verwenden, das mit Director installiert wird.17 Der dazu notwenige Programmcode wird in den on runPropertyDialog-Handler geschrieben. Ist dieser vorhanden, öffnet Director nicht selbstständig ein Eingabefenster, sondern ruft diesen Handler auf. Als erstes Argument erhält er die Objektreferenz des Verhaltens (also immer me angeben!) , als zweites Argument die Liste, die der Handler on getPropertyDescriptionList zurückgibt. Als Rückgabewert sollte der Handler eine Eigenschaftsliste der Form [#Eigenschaftsname1, Eigenschaftswert1, ...] zurückliefern. Es ist natürlich auch möglich, überhaupt kein Fenster zu öffnen und z.B. feste oder errechnete Werte zurückzuliefern.


Bemerkung
Genaugenommen ist also nicht on getPropertyDescriptionList, sondern on runPropertyDialog für die Darstellung des Standard-Eingabedialoges zuständig. Intern passiert folgendes: Wird ein Verhalten in das Drehbuch gezogen, ruft Director runPropertyDialog auf. Als Argument erhält dieser Hander eine Propertyliste, in der alle gesetzten Eigenschaften mit ihrem aktuellen Wert stehen. Daraufhin wird getPropertyDescriptionList aufgerufen um die Beschreibungsliste des Eingabefensters abzurufen. Die Standardimplementierung dieses Handlers erzeugt daraus mit Hilfe des MUI-Xtras das Eingabefenster. Wenn wir nun selbst runPropertyDialog definieren, überschreiben wird diese Methode. Die eigene Methode ersetzt folglich die von Director bereitgestellte.

5.5 Anzeige von Informationen mit on getBehaviorDescription und on getBehaviorTooltip 5.7 Beispiel 9: Eigenschaften-Dialogfenster zur Auswahl einer Datei