Call Handler - Behavior (10/2001, Dir 8)

In diesem Bereich befinden sich Artikel und Tutorials zum Thema Director.

Moderatoren: Bär, Admin

Antworten
Admin
Site Admin
Beiträge: 41344
Registriert: 07.02.2006, 2006 16:09
Wohnort: München
Kontaktdaten:

Call Handler - Behavior (10/2001, Dir 8)

Beitrag von Admin » 11.02.2006, 2006 17:31

Call Handler - Behavior

Seit der Einführung von Behaviors in Director, ist das Verknüpfen von Interface Elementen wie Buttons, Schiebereglern etc. mit bestimmten durch Lingo gesteuerten Funktionalitäten sehr viel einfacher und insbesondere leichter zu verwalten geworden.
Die mitgelieferten Behavior-Libraries von Macromedia bieten darüber hinaus bereits eine breite Palette fertiger Behaviors für unterschiedliche Anwendungsbereiche, und mit der Erstellung eigener Behaviors erschließt sich dann sogar eine noch größere Breite an Gestaltungsmöglichkeiten um das eigene Arbeiten etwas angenehmen und effizienter zu machen.

Grundlegendes Merkmal bei der Arbeit mit Behaviors ist der Behavior-Dialog, durch den die jeweils für das Behavior benötigten Eigenschaften optional mit Werten versehen werden können. Über die Funktion getPropertyDescriptionList() können alle oder wahlweise auch nur einige der Behavior Properties in Form einer Liste mit Werten entsprechend ihrem Datentyp versehen werden und im Behavior-Dialog angezeigt werden. Innerhalb dieser Liste können für jedes Property bestimmte Eigenschaften wie z.B. der Default Wert zur Steuerung des Dialogs angegeben werden. Ausführlichere Informationen dazu finden sich in der Lingo Online Hilfe.

Über die #Format Eigenschaft im Behavior-Dialog kann der jeweilige Datentyp z.B. #string, #symbol, #member etc. für eine Auswahl im Dialog bzw. für das jeweilige Property gesetzt werden. Außerdem kann über die Eigenschaft #range eine Auswahlliste möglicher Werte angegeben und im Dialog angezeigt werden. Dies ist sehr nützlich, da so eventuellen Schreibfehlern vorgebeugt und insbesondere viel Zeit gespart werden kann.

Eine typische Anwendung für einen solchen Fall ist z.B. ein klassisches Rollover-Button Behavior. Im Behavior-Dialog sollen dabei lediglich Bitmap Darsteller aus einer Liste ausgewählt werden können, die alle Bitmap Darsteller des jeweiligen Films enthält. Director erstellt diese Liste bei der Angabe des jeweiligen Formats, z.B. #bitmap für den Behavior Dialog sogar automatisch. Aber auch eigene Listen z.B. für die Auswahl bestimmte String, Symbole oder Integer Werte können angegeben werden.

Nehmen wir aber nun an, der eben erwähnte Rollover Button soll beim #mouseDown Event einen bestimmten Handler in einem Movie Script aufrufen, z.B. um eine Eingabe zu überprüfen und anschließend zu einem bestimmten Frame zu springen.
Nun könnte diese Funktionalität sicherlich in das Behavior selbst in den "on mouseDown ()" Handler geschrieben werden. Allerdings ist dann das eben noch so schöne generische Script nun plötzlich nicht mehr für andere Buttons zu verwenden, da die Funktionalität schon direkt im Behavior festgelegt wurde.

Es wäre also praktisch die Funktionalität des Buttons beim Mausklick ebenfalls über den Behavior-Dialog festlegen zu können, und damit für alle weiteren Buttons im Projekt immer nur dieses eine Behavior zu verwenden, anstatt viele unterschiedliche jeweils angepasste Rollover-Behaviors zu erstellen. Bei einer späteren Änderung oder Erweiterung der Funktionalität muss dann lediglich ein einziges Behavior geändert werden, selbst bei Hunderten von Buttons in einem Projekt.


Das Behavior

Zu genau diesem Zweck soll ein Behavior erstellt werden, das in einer Auswahlliste alle im aktuellen Film vorhandenen Handler zur Auswahl stellt und exemplarisch beim #mouseDown Event aufruft. Außerdem sollen dem jeweiligen Handler noch beliebig viele Parameter übergeben werden können.

Der Schlüssel zum Erfolg ist dabei der schon erwähnte getPropertyDescriptionList () Handler des Behaviors.
Um eine Liste mit den vorhandenen Handlern zu erstellen, werden alle Darstellerbibliotheken nach Darstellern des Darstellertyps #script und des Scripttyps #movie durchsucht (Handler in Behaviors bzw. Parent Scripts sind nicht direkt erreichbar, da diese stets über die jeweilige Instanz des Behaviors bzw. Parent Scripts angesprochen werden müssen, daher werden hier exemplarisch zunächst nur Movie Scripts berücksichtigt).

Wird ein Movie Script gefunden, so können über die handlers() Funktion alle Handler des jeweiligen Darstellers in Form einer linearen Liste abgefragt werden. Diese Handler werden dann einfach an eine Gesamtliste angehängt, die schließlich im Dialog über das #range Propertty angezeigt werden kann:

Code: Alles auswählen

property pHandler
property pParams
property pParamList

on getPropertyDescriptionList (me)

  -- create list of handlers
  handlerList = []
  castLibCount = the number of castLibs
  repeat with i = 1 to castLibCount
    memCount = the number of members of castLib i
    repeat with j = 1 to memCount
      if member(j, castLib i).type = #script then
        if member(j, castLib i).scriptType = #movie then
          thisHandlerList = member(j, castLib i).script.handlers()
          repeat with myHandler in thisHandlerList
            handlerList.append(myHandler)
          end repeat
        end if
      end if
    end repeat
  end repeat

  pList = [ \
    #pHandler: \
    [ \
      #comment: "Global handler to call", \
      #format: #symbol, \
      #range: handlerList,\
      #default: ""\
    ], \
    #pParams: \
    [ \
      #comment: "Parameters to handler", \
      #format: #string, \
      #default: ""\
    ] \
  ] 
  return pList

end getPropertyDescriptionList

Aufruf des Handlers

Beim Aufruf des Behavior Dialogs wird nun stets eine aktuelle Liste der verfügbaren Handler zusammengestellt und angezeigt.
Zusätzlich kann optional eine Liste von Parametern in Form von durch Kommata getrennten String angegeben werden. Beim späteren #beginSprite Event, wird dieser Parameter String in eine Liste umgewandelt, da die Parameter wie gleich noch erklärt wird nur in Form einer Liste übergeben werden können:

Code: Alles auswählen

on beginSprite (me)
  me.initParamList()
end beginSprite 

on initParamList (me)
  -- turn the param string into a list
  pParamList = []
  the itemDelimiter = ","
  itemCount = pParams.items.count
  repeat with i = 1 to itemCount
    pParamList.add(pParams.item[i])
  end repeat
end initParamList
Die eigentliche Funktionalität, nämlich der Aufruf des Handlers inklusive Parameter Liste findet nun beim #mouseDown Event statt. Hier wird nun der "do" Befehl benutzt um den Handler, dessen Name ja in einer Variablen gespeichert ist, aufrufen zu können.

Der "do" Befehl ist eine äußerst nützliche Besonderheit in Lingo, da er den ihm übergebenen Wert in Form eines Strings oder einer Variablen in Form eines Strings als Lingo Befehl interpretiert. Aus diesem Grund müssen eventuell vorhandene Parameter auch in Form einer Liste übergeben werden, da die Strings ansonsten als Befehle interpretiert werden und nicht als String Werte an den aufgerufenen Handler übergeben werden:

Code: Alles auswählen

on mouseUp (me)
  -- call handler
  cmd = string(pHandler) && "(" & pParamList & ")"
  do cmd
end mouseUp 
Zum Testen lässt sich am besten ein einfacher Handler erstellen, der das Ergebnis des Aufrufs ausgibt:

Code: Alles auswählen

on test (args)
  args = value(args)
  if not(listP(args)) then exit
  argC = args.count
  put "Test Param Count:" && argC
  repeat with i = 1 to argC
    put "Param:" && args[i]
  end repeat
end test
Anschließend erstellt man einen Testbutton und weist diesem das Behavior zu. Im Behavior Dialog erscheint nun der eben erstellte "test" Handler in der Auswahlliste, die zugegebenermaßen noch keine wirkliche Auswahl an Handlern bietet. Zusätzlich kann eine exemplarische Parameter Liste "LingoPark,2001" mit zwei Parameterwerten angeben werden. Nach dem Start des Films und anschließendem Mausklick auf den Button werden die entsprechenden Testergebnisse im Nachrichtenfenster ausgegeben:

Code: Alles auswählen

-- Test Param Count: 2
-- Param: LingoPark
-- Param: 2001

Fazit

Diese Technik eigene Handler im Film über ein generisches Behavior aufzurufen, ist in vielen Fällen sehr hilfreich da globale Handler übersichtlich in einem Movie Script verwaltet werden können, anstatt die Funktionalität direkt ins Behavior schreiben zu müssen. Auch die Erweiterbarkeit der Funktionalität des Behaviors ist dadurch losgelöst von eventuellen Funktionsaufrufen innerhalb des Behaviors.

Natürlich kann diese Vorgehensweise im Behavior noch sehr viel weiter ausgebaut werden. Beispielsweise können auch Parent Scripts, andere Behaviors oder sogar Sprites über definierte sendSprite oder sendAllSprites Aufrufe angesprochen werden. Außerdem könnten mehrere Handler angegeben werden und zusätzlich der bzw. die unterschiedlichen Events definiert werden, zu den oder die Handler aufgerufen werden. Die Möglichkeiten sind wie immer weitreichend und sollen einladen selbst ein bisschen damit zu experimentieren.

Beispielfilm als Download: upload/call_handler.zip


Autor: Martin Kloss

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 0 Gäste