ActionScript Facile
Chapitre 3
Les fonctionnalités de base d'une bibliothèque de composants
Date de publication : 26 octobre 2010
Par
Matthieu (Accueil) (Blog)
I. Introduction
II. Bibliothèque de composants : le CDCF
III. Bibliothèque de composants : le CDCT
IV. Conclusion
V. Remerciements / Téléchargements
I. Introduction
Dans ce chapitre, nous allons enfin aborder la pratique. En effet, nous allons coder les
fonctionnalités de base de notre bibliothèque de composants ou «
components framework ».
Comme nous l'avons vu précédemment (
Chapitre 2 : Comment créer des composants ?), nous allons suivre chacune des étapes conseillées.
Commençons déjà par décrire quelles sont ces fonctionnalités au sein d'un CDCF (Cahier des Charges Fonctionnels).
II. Bibliothèque de composants : le CDCF
 | "Un composant est un élément qui apporte une interaction avec l'utilisateur, il est possible de le faire apparaître ou disparaître à volonté et il se doit d'être personnalisable au niveau de l'apparence."
|
C'est une description courte, qui résume au niveau fonctionnel, ce que doit être composant graphique.
Les points importants d'un composant :
- Le composant doit apporter une interaction avec l'utilisateur, il s'agira donc bien entendu d'un objet graphique.
- Il est possible de le faire apparaître et disparaître à volonté : en effet, un composant doit pouvoir être supprimé et ajouté à la display list (la liste d'affichage) sans aucun effort.
- Il doit être personnalisable au niveau de l'apparence : notre composant devra pouvoir changer de style graphique, et ce, de la manière la plus simple qui soit.
Notre CDCF (Cahier des Charges Fonctionnels) est certes un peu court, toutefois, nous n'avons pas besoin de plus de précisions, celles-ci seront données dans le CDCT (Cahier des Charges Techniques).
III. Bibliothèque de composants : le CDCT
C'est la partie la plus intéréssante, la description technique des fonctionnalités de base de l'ensemble de nos futurs composants, commençons sans plus tarder en reprenant le CDCT (Cahier des Charges Techniques).
Le composant apporte une interaction avec l'utilisateur
Notre classe de base sera donc un objet graphique, nous choisissons d'étendre la classe graphique de base flash.display.Sprite.
Possibilité de le faire apparaître ou disparaître à volonté
En as3, nous pouvons manipuler la liste d'affichage ( aussi appelée display list ) avec les méthodes classiques de chaque objet graphique. Cependant, nous allons ajouter quelques fonctionnalités supplémentaires.
- Une méthode hide, qui nous permettra de "cacher" notre objet graphique en le supprimant de la display list, tout en sauvegardant son ancien objet parent dans une propriété "lastParent".
- Un getter lastParent qui nous permettra de récupérer le dernier parent du composant.
- Une méthode show qui nous permettra de rajouter notre objet graphique à la display list de son lastParent.
Avec ces fonctionnalités communes à tous les composants, nous pouvons cacher / supprimer et montrer / ajouter un objet à la display list de manière extrêmement simplifiée, avec une seule méthode.
Personnalisable au niveau de l'apparence
Les composants doivent pouvoir être customisables, en anglais nous appelons cela le "skin" ( skin = peau ).
Ainsi, nous allons donc créer un objet "Skin" qui permet d'associer des valeurs de constantes à des noms de classe.
Nous enverrons ensuite cet objet "Skin" à une méthode nommée "applySkin", définie dans une interface Iskinnable. Cette interface sera implémentée par tous nos composants.
Ajout de quelques fonctionnalités supplémentaires :
- Une méthode destroy, qui permet de détruire proprement notre composant.
- Une méthode resize, qui permet de redimensionner proprement notre composant.
- Une méthode onAdded qui s'exécute lorsque le composant sera ajouté à la display list d'un objet graphique, pour le premier.
- Une méthode onAddedToStage qui s'exécute lorsque le composant ou son parent sera ajouté à la display list du stage. Pour simplifier, cette méthode est appelée dès que la propriété stage du composant est disponible.
- Une méthode onRemoved qui s'exécute lorsque le composant est enlevé de la display list de son parent.
- Une méthode onRemovedFromStage qui s'exécute lorsque le composant est enlevé de la display list du stage.
- Un getter / setter de type Tooltip, nous reviendrons sur ce point plus tard, lorsque nous aborderons le chapitre relatif au composant Tooltip.
- Nous redévelopperons également le comportement d'un évènement bien pratique qui a disparu lors du passage à l'as3. L'évènement onReleaseOutside, qui s'éxécute lorsque l'utilisateur relâche le clic gauche de la souris en dehors de l'objet dans lequel a été capturé le mouseDown.
IV. Conclusion
Nous disposons désormais des bases essentielles pour coder nos différents composants, ceux-ci hériteront tous de la classe UIComponent qui est notre classe de composant de base.
Dans le prochain chapitre, nous allons attaquer notre premier vrai composant utile, un bouton.
Sources commentées
- com.actionscriptfacile.skin.ISkinnable
- com.actionscriptfacile.skin.Skin
- com.actionscriptfacile.skin.ISkin
- com.actionscriptfacile.ui.IComponent
- com.actionscriptfacile.ui.UIComponent
Vous trouverez ci-dessous l'ensemble des classes créées. Elles sont commentées pour vous permettre de comprendre leur fonctionnement.
N'hésitez pas à poser vos questions sur le
Forum AS3 Developpez.
| com.actionscriptfacile.skin.ISkinnable |
package com.actionscriptfacile.skin
{
import com.actionscriptfacile.skin.ISkin;
public interface ISkinnable
{
function applySkin( p_skin:ISkin ):void;
}
}
|
| com.actionscriptfacile.skin.Skin |
package com.actionscriptfacile.skin
{
import com.actionscriptfacile.skin.ISkin;
import flash.utils.Dictionary;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
public class Skin implements ISkin
{
private var m_data:Dictionary;
public function Skin()
{
m_data = new Dictionary();
}
public function setSkin( p_skinName:String, p_skinDefinition:Class ):void
{
m_data[ p_skinName ] = p_skinDefinition;
}
public function getSkin(p_skinName:String) :Class
{
return m_data[ p_skinName ];
}
public function clone():ISkin
{
var definition:Class = getDefinitionByName( getQualifiedClassName( this ) ) as Class;
var skin:ISkin = new definition() as ISkin;
skin.setSkins( m_data );
return skin;
}
public function setSkins(p_skins:Dictionary):void{ m_data = p_skins; }
public function getSkins():Dictionary { return m_data; }
public function destroy():void
{
m_data = null;
delete this;
}
}
}
|
| com.actionscriptfacile.skin.ISkin |
package com.actionscriptfacile.skin
{
import flash.utils.Dictionary;
public interface ISkin
{
function setSkin( p_skinName:String, p_skinDefinition:Class ):void;
function getSkin( p_skinName:String ):Class;
function setSkins( p_skins:Dictionary ):void;
function getSkins():Dictionary;
function clone():ISkin;
function destroy():void;
}
}
|
| com.actionscriptfacile.ui.IComponent |
package com.actionscriptfacile.ui
{
import com.actionscriptfacile.skin.ISkinnable;
import flash.display.DisplayObjectContainer;
import com.actionscriptfacile.ui.tooltip.Tooltip;
public interface IComponent extends ISkinnable
{
function destroy():void;
function hide():void;
function show():void;
function onAdded():void;
function onRemoved():void;
function onAddedToStage():void;
function onRemovedFromStage():void;
function resize( p_width:Number , p_height:Number ):void;
function set tooltip( p_toolTip:Tooltip ):void;
function get tooltip():Tooltip;
function get lastParent():DisplayObjectContainer;
}
}
|
| com.actionscriptfacile.ui.UIComponent |
package com.actionscriptfacile.ui
{
import com.actionscriptfacile.skin.ISkin;
import com.actionscriptfacile.ui.tooltip.Tooltip;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;
import flash.events.Event;
import com.actionscriptfacile.ui.IComponent;
import flash.events.MouseEvent;
public class UIComponent extends Sprite implements IComponent
{
private var m_lastParent:DisplayObjectContainer;
private var m_tooltip:Tooltip;
static public const RELEASE_OUTSIDE:String = 'RELEASE_OUTSIDE';
public function UIComponent()
{
m_lastParent = null;
m_tooltip = null;
addEventListener( Event.ADDED, addedHandler );
addEventListener( Event.ADDED_TO_STAGE, addedHandler );
addEventListener( Event.REMOVED, removeHandler );
addEventListener( Event.REMOVED_FROM_STAGE, removeHandler );
addEventListener( MouseEvent.MOUSE_DOWN, downUpHandler );
addEventListener( MouseEvent.ROLL_OVER, overOutHandler );
addEventListener( MouseEvent.ROLL_OUT, overOutHandler );
}
private function overOutHandler(e:MouseEvent):void
{
if ( m_tooltip == null )
{
return;
}
if ( e.type == MouseEvent.ROLL_OUT )
{
m_tooltip.hide();
}
else
{
m_tooltip.show();
}
}
private function downUpHandler(e:MouseEvent):void
{
if ( e.type == MouseEvent.MOUSE_DOWN )
{
stage.addEventListener( MouseEvent.MOUSE_UP, downUpHandler );
stage.addEventListener( MouseEvent.MOUSE_UP, downUpHandler, true );
}
else
{
stage.removeEventListener( MouseEvent.MOUSE_UP, downUpHandler );
stage.removeEventListener( MouseEvent.MOUSE_UP, downUpHandler, true );
if ( ! hitTestPoint( e.stageX, e.stageY , false ) )
{
dispatchEvent( new Event( RELEASE_OUTSIDE, true, true ) );
}
}
}
private function addedHandler( e:Event ):void
{
if ( parent != null )
{
m_lastParent = parent;
}
if ( e.type == Event.ADDED )
{
onAdded();
}
else
{
onAddedToStage();
}
}
private function removeHandler( e:Event ):void
{
if ( parent != null )
{
m_lastParent = parent;
}
if ( e.type == Event.REMOVED )
{
onRemoved();
}
else
{
onRemovedFromStage();
}
}
public function destroy():void
{
if ( parent != null && parent.contains( this ) )
{
parent.removeChild( this );
}
while ( numChildren > 0 )
{
var child:DisplayObject = removeChildAt( 0 );
child = null;
}
m_lastParent = null;
removeEventListener( Event.ADDED, addedHandler );
removeEventListener( Event.ADDED_TO_STAGE, addedHandler );
removeEventListener( Event.REMOVED, removeHandler );
removeEventListener( Event.REMOVED_FROM_STAGE, removeHandler );
removeEventListener( MouseEvent.MOUSE_DOWN, downUpHandler );
removeEventListener( MouseEvent.ROLL_OVER, overOutHandler );
removeEventListener( MouseEvent.ROLL_OUT, overOutHandler );
stage.removeEventListener( MouseEvent.MOUSE_UP, downUpHandler );
stage.removeEventListener( MouseEvent.MOUSE_UP, downUpHandler, true );
delete this;
}
public function hide():void
{
if ( parent != null && parent.contains( this ) )
{
m_lastParent = parent;
parent.removeChild( this );
}
}
public function show():void
{
visible = true;
if ( m_lastParent == null )
return;
m_lastParent.addChild( this );
}
public function onAdded():void { }
public function onRemoved():void { }
public function onAddedToStage():void { }
public function onRemovedFromStage():void { }
public function applySkin(p_skin:ISkin):void { }
public function resize(p_width:Number, p_height:Number):void
{
}
public function set tooltip(p_toolTip:Tooltip):void
{ m_tooltip = addChild( p_toolTip ) as Tooltip; m_tooltip.hide(); }
public function get tooltip():Tooltip { return m_tooltip; }
public function get lastParent():DisplayObjectContainer{ return m_lastParent; }
}
}
|
V. Remerciements / Téléchargements
Je tiens ici à remercier
La Rédactrice Kalyparker
pour la mise au gabarit de l'article original au format Developpez.com.
Merci beaucoup à l'équipe Developpez.com de contribuer à la diffusion du Framework ActionScript-Facile.


Copyright © 2010 Matthieu - www.actionscript-facile.com. Aucune reproduction, même partielle, ne peut être faite
de ce site et de l'ensemble de son contenu : textes, documents, images, etc.
sans l'autorisation expresse de l'auteur.
Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 €
de dommages et intérêts.
Cette page est déposée.