utiliser les meta-tag inspectable en actionscript 3
Pour rappel les propriétés inspectables permettent de modifier simplement certaines valeurs d'un composant directement depuis l'interface Flash, ceci est donc très pratique pour les personnes plutôt orientées design mais cela s'avère également avantageux pour les profils plutôt développeurs.
Pour voir ces propriétés ajoutez sur la scène un composant Adobe Button ( ctrl + F7 > deployer “User Interface” ). Sélectionnez ce dernier sur la scène et afficher le panneau de propriété ( ctrl + F3 puis onglet “Paramètres” ) ou le panneau d'inspection ( shift + F7 ). On peut ici, par exemple modifier directement le texte du bouton en modifiant la propriété “label”.
- Maitrise de la créations de symboles et d'occurrences avec leur nom d'occurrence.
- Compréhension des classes et du “document class”.
- Notions sur la créations de composants.
Création de notre première propriété inspectable
Créons donc notre classe avec sa propriété inspectable.
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable] public var constructeur : String = ""; public function Voiture () { } } }
Nous avons donc crée une classe Voiture avec une propriété constructeur qui va être “inspectable” donc modifiable depuis flash grâce au tag ”[Inspectable]” placé juste avant celle-ci 'notez qu'il n'y a pas de ”;” à la fin de la ligne).
Créons ensuite notre composants dans flash et lions le à cette classe. Créez donc un symbole (ctrl + F8) que vous nommez voiture et liez le à la classe Voiture dans ses propriétés de linkage (clic droit sur le symbole de la bibliothèque). Pour que notre symbole profite des propriétés inspectables il faut que celui-ci soit défini comme un composant. Faites donc à nouveau un clic droit sur ce symbole, sélectionnez “définition du composant…”, remplissez alors le champs “classe” avec le nom de votre classe (ici Voiture) et validez. L'icône du symbole de la bibliothèque change pour montrer que celui-ci est maintenant un composant.
Si nous répétons la manipulation de l'introduction nous voyons apparaitre la propriété “constructeur”. Glissez votre composant sur la scène, sélectionnez le et afficher le panneau propriété ou le panneau d'inspection de composants.
Manipulons un peu cette propriété. Pour cela ajoutons un calque “action” sur notre scène ou l'on va simplement afficher la valeur de notre propriété (pensez à donner le nom d'instance (ici maVoiture) à votre occurrence sur la scène):
trace( "maVoiture constructeur :" , maVoiture.constructeur );
En compilant notre projet la fenêtre de sortie affiche:
maVoiture constructeur :
car notre constructeur n'a pas de valeur par défaut.
Modifiez donc votre propriété dans le panneau où celle-ci est affichée, en tapant “audi” par exemple et en recompilant notre projet cette fois la fenêtre de sortie affiche :
maVoiture constructeur : audi
Voyons maintenant comment affecter une valeur par défaut à notre propriété :
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable(defaultValue="audi")] public var constructeur : String = "audi"; public function Voiture () { } } }
Pour cela nous ajoutons donc une propriété “defaultValue” à notre meta-tag ”[Inspactable]”. les propriétés meta-tag se trouvent entre parenthèses et séparées par une virgule s'il y en a plusieurs (nous verrons les autres propriétés un peu plus loin).
A noter également qu'il est important d'indiquer la même valeur dans le “defaultValue” du tag et dans la valeur par défaut de la propriété pour garder une cohérence entre les instance créées directement sur la scène et celles créées en code. En effet lorsque vous créez une instance par le code les propriétés inspectable sont ignorées.
Maintenant que nous avons modifié notre classe il faut redéfinir notre composant (clic droit sur notre symbole de la bibliothèque puis “définition du composant…” puis validez).
Cela n'aura pas d'effet sur notre symbole déjà posé sur la scène, supprimé le de la scène et glissez en un nouveau, nous voyons cette fois que la propriété “constructeur” est pré-remplis avec la valeur “audi”. Pensez à renommer votre nom d'instance avec “maVoiture” puisque nous avons supprimer l'ancien symbole et en avons glissé un nouveau.
Les principales propriétés du meta-tag inspectable
Nous avons vu qu'il est possible d'ajouter des propriétés au tag inspectable avec “defaultValue”, voici les autres propriétés utiles :
enumeration
La propriété “enumeration” permet de limiter les valeurs possibles d'une propriété.
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable(defaultValue="audi",enumeration="audi,renault,toyota,ford")] public var constructeur : String = "audi"; public function Voiture () { } } }
Pensez à redéfinir à nouveau le composant depuis la bibliothèque. Vous pouvez remarquer que maintenant lorsque vous essayez de modifier la propriété inspectable depuis le panneau une liste apparait pour sélectionner la valeur, vous ne pouvez donc plus injecter n'importe quel valeur.
name
La propriété “name” permet de modifier le nom de la variable afficher dans le panneau.
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable(name="marque",defaultValue="audi",enumeration="audi,renault,toyota,ford")] public var constructeur : String = "audi"; public function Voiture () { } } }
Redéfinissez à nouveau le composant et vous voyer que dans le panneau la propriété est renommée en “marque”. Cela est toutefois déconseillé d'utiliser cette propriété pour une question de cohérence avec le code. Cela peut en effet être perturbant d'avoir un nom de propriété différent entre le panneau et son vrai nom que l'on pourrait utiliser dans le code.
type
La propriété “type” permet de définir comme son nom l'indique le type d'une variable.
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable(name="marque",type="String",defaultValue="audi",enumeration="audi,renault,toyota,ford")] public var constructeur : String = "audi"; public function Voiture () { } } }
Cette propriété n'est pas vraiment nécessaire puisque le type est automatiquement détecté avec le typage de la variable, elle est cependant indispensable dans le cas de type “Color”, “Font Name” ou “List” :
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable(name="marque",defaultValue="audi",enumeration="audi,renault,toyota,ford")] public var constructeur : String = "audi"; [Inspectable(type="Color",defaultValue="#000000")] public var color : uint = 0x000000; public function Voiture () { } } }
Grâce au type “Color” vous avez un colorPicker qui apparait lorsque vous esssayer de modifier la propriété color dans le panneau (notez le ”#” à la place du classique “0x” pour définir un code couleur).
Subtilité par rapport à l'actionscript 2
En as2 les meta-tag inspectable pouvaient être placés sur des propriétés privées, en as3 celles-ci peuvent uniquement être placées sur des propriétés public (il est bien sur évidemment possible de les placer au dessus de getter/setter dans ce cas il suffit de la placer soit sur le getter soit sur le setter).
En as2 les propriétés inspectables étaient appliquées avant le constructeur ce qui permettait de pouvoir utiliser immédiatement dans le constructeur une propriété inspectable avec la valeur qui à été indiquée dans le panneau. En as3 les propriétés sont appliquées après le constructeur et cela peut dans certain cas précis être un vrai problème qu'on ne peut malheureusement pas toujours contourner comme on le souhaiterait. Un petit exemple pour mettre en avant ce changement :
package { import flash.display.Sprite; import flash.events.Event; public class Voiture extends Sprite { [Inspectable(name="marque",defaultValue="audi",enumeration="audi,renault,toyota,ford")] public var constructeur : String = "audi"; [Inspectable(type="Color",defaultValue="#000000")] public var color : uint = 0x000000; public function Voiture () { trace( constructeur ); addEventListener( Event.ENTER_FRAME , _enterFrame , false , 0 , true ); } protected function _enterFrame( e : Event ) : void { trace( constructeur ); removeEventListener( Event.ENTER_FRAME , _enterFrame ); } } }
Modifiez la valeur par défaut dans le panneau de la propriété constructeur avec toyota par exemple et compilez votre projet, la fenêtre de sortie indique :
audi toyota
Directement lié au problème précédent si nous essayons de modifier une propriété trop tôt par le code nous pouvons avoir la surprise de voir que notre modification n'a pas d'effet, mettons cela en avant :
Créons d'abord une classe que nous allons liée à notre scène pour externaliser le code du scénario (supprimez votre code du scénario s'il est encore présent).
package { import flash.display.Sprite; import flash.events.Event; public class Application extends Sprite { public var maVoiture : Voiture; public function Application () { maVoiture.constructeur = "toyota"; trace( maVoiture.constructeur ); addEventListener( Event.ENTER_FRAME , _enterFrame , false , 0 , true ); } protected function _enterFrame( e : Event ) : void { trace( maVoiture.constructeur ); removeEventListener( Event.ENTER_FRAME , _enterFrame ); } } }
Pensez à supprimer ou commenter les traces présents dans la classe Voiture pour bien vous rendre compte du résultat, assurez vous également que votre nom d'instance de l'objet voiture sur la scène est bien “maVoiture” et que vous avez décocher la checkbox “déclarer automatiquement les instances” dans les paramètres de publications > onglet flash > bouton “paramètres” à coter de “ActionScript 3.0”.
Enfin sélectionnez une valeur pour la propriété “constructeur” autre que celle que nous avons utiliser dans notre code (toyota), remettez par exemple la valeur par défaut “audi” et modifier la couleur par défaut (j'expliquerais après pourquoi). En publiant vous avez le résultat suivant :
toyota audi
Notre modification par le code est donc écrasée par celle affectée dans le panneau, c'est le cas d'ailleurs avec le set de composant Adobe et pourtant des solutions existent.
Pourquoi avons nous modifier la propriété color : pour forcer l'application des propriétés du panneau. En effet en as3 soit nous ne modifions rien dans le panneau des propriétés inspectables et à ce moment la aucune de celles-ci sont appliquées puisque ce sont les valeurs par défaut, soit nous modifions une ou plusieurs propriétés et dans ce cas celle-ci sont toutes appliquées même si ce sont des valeurs par défaut.
Pour en revenir à notre dernier problème il existe cette fois plusieurs solutions. La première qui parait évidente et d'attendre une frame pour modifier notre valeur :
package { import flash.display.Sprite; import flash.events.Event; public class Application extends Sprite { public var maVoiture : Voiture; public function Application () { addEventListener( Event.ENTER_FRAME , _enterFrame , false , 0 , true ); } protected function _enterFrame( e : Event ) : void { maVoiture.constructeur = "toyota"; removeEventListener( Event.ENTER_FRAME , _enterFrame ); } } }
Malheureusement cela devient vite lourd à l'usage et une solution plus élégante existe.
En as3 il est maintenant possible de savoir si la propriété est modifier par le panneau ou par le code grâce à la propriété “componentInspectorSetting”
package { import flash.display.Sprite; public class Voiture extends Sprite { [Inspectable(name="marque",defaultValue="audi",enumeration="audi,renault,toyota,ford")] public var constructeur : String = "audi"; [Inspectable(type="Color",defaultValue="#000000")] public var color : uint = 0x000000; protected var _inspector : Boolean; public function get componentInspectorSetting() : Boolean { return _inspector; } public function set componentInspectorSetting ( b : Boolean ) : void { trace( "componentInspectorSetting" , b ); _inspector = b; } public function Voiture () { } } }
Nous pouvons mettre en avant ce qui a été dis précédemment, si vous laissez les paramètres par défaut dans le panneau rien ne s'affiche à la publication, mais dès que vous modifiez une valeur la fenêtre de sortie affiche :
componentInspectorSetting true componentInspectorSetting false
Grâce à cela nous allons pouvoir contourner notre problème en utilisant un getter/setter plutôt qu'une simple propriété et en utilisant également la détection du “livepreview” dont je ne rentrerais pas en détails dans cette article :
package { import flash.display.Sprite; import flash.utils.getQualifiedClassName; public class Voiture extends Sprite { protected var _isLivePreview : Boolean; protected var _constructeur : String = "audi"; [Inspectable(name="marque",defaultValue="audi",enumeration="audi,renault,toyota,ford")] public function get constructeur() : String { return _constructeur; } public function set constructeur( s : String ) : void { // ici nous vérifions que _constructeur n'a pas été modifié avant que les valeurs // du panneau soit appliquées (uniquement lorsque nous ne sommes pas en livePreview). if( !_isLivePreview && _inspector && _constructeur != "audi" ) return; _constructeur = s; } [Inspectable(type="Color",defaultValue="#000000")] public var color : uint = 0x000000; protected var _inspector : Boolean; public function get componentInspectorSetting() : Boolean { return _inspector; } public function set componentInspectorSetting ( b : Boolean ) : void { trace( "componentInspectorSetting" , b ); _inspector = b; } public function Voiture () { _isLivePreview = _checkLivePreview(); } protected function _checkLivePreview( ) : Boolean { if( parent == null ) return false; var className : String; try { className = getQualifiedClassName( parent ); } catch( e : Error ) { } return className == "fl.livepreview::LivePreviewParent"; } } }
package { import flash.display.Sprite; import flash.events.Event; public class Application extends Sprite { public var maVoiture : Voiture; public function Application () { maVoiture.constructeur = "toyota"; addEventListener( Event.ENTER_FRAME , _enterFrame , false , 0 , true ); } protected function _enterFrame( e : Event ) : void { trace( maVoiture.constructeur ); removeEventListener( Event.ENTER_FRAME , _enterFrame ); } } }
Cette fois même en modifiant notre propriété dans le panneau, notre modification en code est bien devenu prioritaire et n'est donc pas écrasée.
Conclusions
Nous avons donc vu ensemble comment utiliser les propriétés inspectables en as3, il existe évidemment d'autres meta-tag que “inspectable” mais ceux-ci ne sont pas forcément liés à la création de composants ([Embed] par exemple), il existe bien sur beaucoup d'autres chose liés à la création des composants que nous verrons peut être lors d'un prochain article
En savoir plus
* La doc flash sur la balise "Inspactable" Assez léger comme documentation.
* AS3 et inspectable quel “chiotte” Un ancien article sur le même sujet sur mon blog.
* myLib Adobe AS3 components alternative Mon projet open source de composants qui utilise évidemment les propriétés inspectables et les solutions évoquées dans cette article.
By SamYStudiO [Samuel EMINET] [contact@samystudio.net]
