Sujets sur : script fenetre avec scrollbar personnalisable
Cours ActionScript 3 ‘script fenetre avec scrollbar personnalisable’
Comment créer et personnaliser une Liste en AS3 ?
Dans ce tutoriel, nous allons créer et personnaliser le Composant AS3 List.
Vous verrez comment définir les méthodes de la classe List. Et comment la personnaliser avec l’utilisation des Skins graphiques.
I – Cahier Des Charges Fonctionnel de la List
Un composant de type List peut se comparer visuellement à une maison.
Dans une maison (en général), l’espace habitable ne se limite pas à ce que l’on peut distinguer par la fenêtre. Depuis l’extérieur, nous n’en voyons donc qu’une partie.
Le composant List est à la fois : la maison et la fenêtre.
Il peut contenir autant d’objets graphiques que l’on souhaite ( comme une maison peut contenir un certain nombre de meubles ). Toutefois, il ne pourra en afficher qu’une partie ( la fenêtre ).
Le Composant List innove par rapport à la maison. Effectivement, il est possible de faire défiler tous les objets graphiques qu’il contient par le biais d’une scrollBar ( verticale ou horizontale ). Ainsi, l’ensemble de son contenu pourra être visualisé.
C’est un peu comme si vous aviez une scrollBar sur la fenêtre de votre maison, qui déplacerait vos meubles, de sorte qu’ils arrivent automatiquement devant la fenêtre.
Maintenant que nous avons défini ce qu’est un composant List, nous allons pouvoir nous attaquer à sa conception.
Comme pour le Composant ScrollBar, le sujet augmente en difficulté, au fur et à mesure de la création des Composants AS3 Facile.
Nous allons ainsi nous simplifier la vie en implémentant un Composant List :
- qui gère uniquement le scroll vertical.
- qui va éditer pour nous les positions de l’ensemble des objets graphiques qu’il recevra. Dans le but que ceux-ci apparaissent à la “queue leu leu”.
Un Composant List est constitué de 4 entités :
- Un clip conteneur ( la maison ), qui va se charger de réceptionner des objets graphiques. La taille du conteneur augmente et diminue en fonction du nombre d’objets graphiques qu’il contient.
- Un clip masque ( la fenêtre ), qui nous servira à cacher une partie des objets graphiques.
- Un clip background ( le papier peint ) qui servira juste de fond à notre composant, ceci est purement esthétique et vous n’êtes en aucun cas obligé de l’implémenter.
- Une scrollBar verticale qui s’affichera uniquement lorsque la taille du conteneur dépassera les dimensions de la fenêtre.
Pour compléter notre CDCF, la taille du masque peut être éditée. De plus, le fond et la scrollBar sont personnalisables graphiquement.
Avec toutes ces informations dans notre CDCF (Cahier Des Charges Fonctionnel), nous pouvons passer à la rédaction du CDCT (Cahier Des Charges Technique).
II – Cahier Des Charges Techniques de la List
Nous allons donc traduire, en termes techniques, les spécifications fonctionnelles de notre composant List.
La Classe List
- Un clip conteneur ( la maison ) va se charger de réceptionner des objets graphiques. La taille du conteneur augmente et diminue en fonction du nombre d’objets graphiques qu’il contient.
En lieu et place d’un clip, nous allons utiliser un objet Sprite.
- Un clip masque ( la fenêtre ), qui nous servira à cacher une partie des objets graphiques.
Ici, un simple objet de type Shape suffira largement.
- Un clip background ( le papier peint ) qui servira juste de fond à notre composant. Celui-ci est purement esthétique et vous n’êtes en aucun cas obligé de l’implémenter.
Un objet de type Sprite qui contiendra le fond du composant List.
- Une scrollBar verticale qui ne s’affichera que lorsque la taille du conteneur dépassera les dimensions de la fenêtre.
Un objet de type com.actionscriptfacile.ui.scroll.components.VerticalScrollBar ( veuillez lire le Tutoriel 5 sur la Création du Composant Vertical ScrollBar ).
- La taille du masque peut être éditée.
Pour cela, nous allons overrider la méthode de base resize de la classe parente UIComponent.
- Le fond personnalisable graphiquement ainsi que la scrollBar.
Pour cette fonctionnalité, nous allons effectuer un override de la méthode de base applySkin de la classe parente UIComponent.
La classe UIMargins
Et comme toujours, nous allons ajouter une petite difficulté en intégrant une fonctionnalité supplémentaire à notre composant. J’ai nommé : les marges!
Le conteneur doit pouvoir appliquer des marges au contenu dans les 4 directions suivantes :
- Haut
- Bas
- Gauche
- Droite
La solution technique reste simple :
- Pour respecter la marge gauche nous décalerons le masque et le conteneur vers la droite.
- Pour respecter la marge haute nous décalerons le masque et le conteneur vers le bas.
- Pour respecter la marge droite nous réduirons la largeur du masque.
- Pour respecter la marge basse nous réduirons la hauteur du masque.
Pour définir nos marges, nous allons créer une classe nommée UIMargins. Elle se trouvera dans le package com.actionscriptfacile.ui.utils.
Conclusion
Et voila, notre composant List est terminé. Regardez le résultat ci-dessous.
1 | http://e6msyji6epr.exactdn.com/wp-content/uploads/2010/09/list_exemple.swf |
Dans le prochain tutoriel AS3, nous attaquerons notre dernier composant : la ComboBox! ( ou liste déroulante ).
Évolutions des fonctionnalités
Pour améliorer notre Composant AS3 List, voici quelques exemples de fonctionnalités supplémentaires à implémenter. Proposez vos exemples dans les commentaires.
Allez, maintenant, c’est à vous de jouer !
List avec une ScrollBar Horizontale
Ajoutez au composant List la gestion d’une ScrollBar Horizontale.
Dans le tutoriel précédent (Création d’un Composant AS3 Vertical Scrollbar), un des exercices consistait à concevoir une ScrollBar Horizontale. Il suffit de réutiliser cette classe et de l’instancier / afficher (si besoin) par le composant List.
List avec des composants Button
Vous pouvez également remplacer les différents éléments de la List par des objets de type Button (lisez le Tutoriel 4 : Création du Composant AS3 Button).
Puis vous écoutez les évènements des objets Button. Et vous avez la possibilité de créer une action spécifique, en fonction du Button sélectionné par l’utilisateur.
Sources commentées
- com.actionscriptfacile.ui.list.List.as
- com.actionscriptfacile.ui.utils.UIMargins.as
- ListExample.as
- com.as3facileexemple.skin.classic.DefaultListSkin.as
Vous trouverez ci-dessous l’ensemble des classes créées. Elles sont commentées pour vous permettre de comprendre au mieux leur fonctionnement.
Vous pouvez télécharger le fichier zip : Télécharger “Composant List du Framework AS3 Facile” component_list_framework_actionscript-facile.zip – Téléchargé 1287 fois – 68,96 Ko
Et vous, quels graphismes avez-vous créé pour votre List ?
Je suis curieux de visualiser les différentes utilisations que vous avez utilisé pour le Composant AS3 List.
Ajoutez vos réalisations dans les commentaires juste en dessous.
[codesyntax lang= »actionscript3″ title= »com.actionscriptfacile.ui.list.List.as » bookmarkname= »com.actionscriptfacile.ui.list.List.as »]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 | package com.actionscriptfacile.ui.list { import com.actionscriptfacile.skin.ISkin; import com.actionscriptfacile.ui.scroll.components.VerticalScrollBar; import com.actionscriptfacile.ui.UIComponent; import com.actionscriptfacile.ui.utils.UIMargins; import flash.display.DisplayObject; import flash.display.Shape; import flash.display.Sprite; /** * Un composant List est un objet graphique qui peut stocker d'autres objets graphiques au sein d'un clip conteneur qui * lui-même, est masqué. * * A chaque fois qu'un objet est ajouté au composant, celui-ci se charge d'éditer la position ".y" du dit objet afin de * le placer à la suite des autres. * * * @author Matthieu */ public class List extends UIComponent { static public const LIST_BACKGROUND_SKIN:String = 'LIST_BACKGROUND_SKIN'; // constantes pour le skin private var m_scrollBar:VerticalScrollBar; // objet de type VerticalScrollBar private var m_containerMask:Shape; // masque du clip conteneur private var m_container:Sprite; // conteneur private var m_background:Sprite; // background ou "fond" du composant. private var m_margins:UIMargins; // objet servant à définir les marges à appliquer au contenu. public function List() { init(); } private function init():void { m_margins = new UIMargins(); // Marges = 0 dans toutes les directions m_scrollBar = new VerticalScrollBar(); // on crée une scrollBar m_containerMask = new Shape(); // on crée le mask m_container = new Sprite(); // on crée le conteneur m_background = new Sprite(); // on crée le fond /** * On dessiner le masque */ m_containerMask.graphics.beginFill( 0XFF0000, .5 ); m_containerMask.graphics.drawRect( 0, 0, 100, 100 ); m_containerMask.graphics.endFill(); /** * On dessine un fond par défaut */ m_background.graphics.beginFill( 0X999999, .1 ); m_background.graphics.drawRect( 0, 0, 100, 100 ); m_background.graphics.endFill(); /** * Puis nous ajoutons tout les éléments de notre composant que nous avons crée au préalable à sa displayList */ addChild( m_scrollBar ); addChild( m_background ); addChild( m_container ); addChild( m_containerMask ); // on applique le masque au conteneur m_container.mask = m_containerMask; // on cache la scrollBar m_scrollBar.hide(); } /** * Fonction permettant de gérer la customisation des différents éléments * graphiques d'un objet de type List * * @param p_skin Objet implémentant l'interface ISkin */ override public function applySkin( p_skin:ISkin ):void { // on applique la skin à la scrollBar m_scrollBar.applySkin( p_skin ); // nous récuperons la définition de classe pour le background de l'objet List var definition:Class = p_skin.getSkin( LIST_BACKGROUND_SKIN ) as Class; // si la définition a été trouvée if ( definition ) { // nous vidons proprement l'objet background var child:DisplayObject; while ( m_background.numChildren > 0 ) { child = m_background.removeChildAt( 0 ); child = null; } // puis nous ajoutons une instance de cette définition au conteneur background m_background = addChildAt( new definition(), 0 ) as Sprite; } } /** * * Fonction permettant d'ajouter un clip graphique au conteneur. * * @param p_element Un objet de type flash.display.DisplayObject * @return Retourne une référence vers le DisplayObject ajouté. */ public function addElement( p_element:DisplayObject ):DisplayObject { // On place p_element dans la displayList du conteneur m_container.addChild( p_element ); // puis on effectue un redraw. redraw(); // enfin, nous retournons l'élément envoyé en paramètre return p_element; } /** * * Fonction permettant d'enlever un clip graphique au conteneur. * * @param p_element Un objet de type flash.display.DisplayObject * @return Retourne une référence vers le DisplayObject supprimé de la displayList du conteneur. */ public function removeElement( p_element:DisplayObject ):DisplayObject { // on enlève p_element de la displayList du conteneur m_container.removeChild( p_element ); // on effectue un redraw redraw(); // puis on retourne l'élément envoyé en paramètre return p_element; } /** * * Fonction interne permettant d'actualiser l'état graphique des différents * éléments d'un composant de type List * * @param p_width Nouvelle taille en largeur du composant * @param p_height Nouvelle taille en hauteur du composant */ private function redraw( p_width:Number = -1, p_height:Number = - 1 ):void { // on effectue des contrôles sur les paramètres envoyés if ( p_width < 0 ) p_width = m_background.width; if ( p_height < 0 ) p_height = m_background.height; var curY:Number = 0; // y maximum courant, au départ il est égal à 0 var max:int = m_container.numChildren; // nombre d'enfants du clip conteneur var i:int = 0; var child:DisplayObject; for ( ; i < max; i++ ) { // nous récupérons l'enfant du conteneur à l'index i child = m_container.getChildAt( i ); // nous actualisons sa position en y ( verticale ) child.y = curY; // puis on ajoute la hauteur de l'enfant à la variable curY // ainsi le prochain enfant sera placé juste après de façon verticale. curY += child.height; } // On actualise la largeur et la hauteur du background m_background.width = p_width; m_background.height = p_height; // la largeur du masque est égale à la largeur passée en paramètre - la marge de gauche + celle de droite m_containerMask.width = p_width - m_margins.marginLeft - m_margins.marginRight; // la hauteur du masque est égale à la hauteur passée en paramètre - la marge du haut + celle du bas m_containerMask.height = p_height - m_margins.marginTop - m_margins.marginBottom; // si la taille du conteneur ( la maison ) ne dépasse pas les dimensions du masque ( la fenêtre ) alors if ( m_container.height < m_containerMask.height ) { // on cache la scrollBar m_scrollBar.hide(); } else // sinon { // on affiche la scrollBar m_scrollBar.show(); // la largeur du masque diminue encore pour laisser de la place afin de laisse de la place à la scrollBar m_containerMask.width -= m_scrollBar.width; // on positionne la scrollBar juste à droite du masque m_scrollBar.x = m_background.width - m_scrollBar.width - m_margins.marginRight; // enfin on actualise la hauteur de la scrollBar m_scrollBar.resize( m_scrollBar.width, m_containerMask.height ); } // on positionne le masque et le conteneur de façon à respecter la marge de gauche m_containerMask.x = m_container.x = m_margins.marginLeft; // Même chose pour la marge du haut avec la scrollBar en plus m_scrollBar.y = m_containerMask.y = m_container.y = m_margins.marginTop; // on dit bien à la scrollBar que le contenu qu'elle doit scroller est le conteneur... m_scrollBar.content = m_container; // et que la zone de scroll correspond aux dimensions du masque ( la fenêtre ). m_scrollBar.scrollArea = m_containerMask.getRect(this); } /** * * Fonction permettant de gérer intelligemment le redimensionnement * d'un objet de type List * * @param p_width la nouvelle largeur ( en pixels ) du composant * @param p_height la nouvelle hauteur ( en pixels ) du composant */ override public function resize( p_width:Number, p_height:Number ):void { // on effectue un redraw redraw( p_width, p_height ); } /** * Retourne une référence de l'objet VerticalScrollBa utilisé au sein du composant */ public function get scrollBar():VerticalScrollBar { return m_scrollBar; } /** * Retourne une référence de l'objet UIMargins utilisé pour définir les marges des contenus */ public function get margins():UIMargins { return m_margins; } /** * Définit les marges à appliquer aux contenus */ public function set margins( p_margins:UIMargins ):void { // on change les margins actuelles puis on effectue un redraw m_margins = p_margins; redraw( m_background.width, m_background.height ); } /** * Détruit proprement un objet de type List */ override public function destroy():void { // on tue proprement l'objet UIMargins m_margins = null; // on tue proprement la scrollBar m_scrollBar.destroy(); /** * Nous tuons tous les enfants du conteneur */ var child:DisplayObject; while ( m_container.numChildren > 0 ) { child = m_container.removeChildAt( 0 ); if ( child is UIComponent ) { UIComponent( child ).destroy(); } child = null; } // Enfin, on supprime le conteneur, son masque et le fond removeChild( m_container ); removeChild( m_containerMask ); removeChild( m_background ); m_container = null; m_containerMask = null; m_background = null; m_scrollBar = null; // on appelle la fonction de destruction parente par précaution super.destroy(); } } } |
[/codesyntax]
[codesyntax lang= »actionscript3″ title= »com.actionscriptfacile.ui.utils.UIMargins.as » bookmarkname= »com.actionscriptfacile.ui.utils.UIMargins.as »]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package com.actionscriptfacile.ui.utils { /** * Permet de définir des marges à tout type d'élément * * @author Matthieu */ public class UIMargins { private var m_marginLeft:Number; private var m_marginRight:Number; private var m_marginBottom:Number; private var m_marginTop:Number; public function UIMargins( p_margTop:Number = 0, p_margRight:Number = 0, p_margBottom:Number = 0, p_margLeft:Number = 0 ) { m_marginTop = p_margTop; m_marginLeft = p_margLeft; m_marginBottom = p_margBottom; m_marginRight = p_margRight; } public function get marginLeft():Number { return m_marginLeft; } public function set marginLeft(value:Number):void { m_marginLeft = value; } public function get marginRight():Number { return m_marginRight; } public function set marginRight(value:Number):void { m_marginRight = value; } public function get marginBottom():Number { return m_marginBottom; } public function set marginBottom(value:Number):void { m_marginBottom = value; } public function get marginTop():Number { return m_marginTop; } public function set marginTop(value:Number):void { m_marginTop = value; } } } |
[/codesyntax]
[codesyntax lang= »actionscript3″ title= »ListExample.as » bookmarkname= »ListExample.as »]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | package { import com.actionscriptfacile.ui.text.UITextField; import com.actionscriptfacile.ui.list.List; import com.actionscriptfacile.ui.utils.UIMargins; import com.as3facileexemple.skin.classic.DefaultListSkin;// import du skin de la VerticalScrollBar import flash.display.Shape; import flash.display.Sprite; /** * Exemple d'utilisation du composant List. * @author Matthieu */ public class ListExample extends Sprite { public function ListExample() { // création d'une liste var list:List = new List(); // Application de la skin par défaut // [ Attention ! Cette skin utilise le fichier ui.swc qui doit être ajouté à la liste des composants à passer au compilateur ] list.applySkin( new DefaultListSkin() ); // définition de la taille de la List list.resize( 230, 150 ); // ajout de plusieurs éléments dans la liste for ( var i:int = 0; i < 35; i++ ) { list.addElement( getListElement(i+1) ); } // détermination de la position de la List list.x = 30; list.y = 30; // affichage - ajout à la displaylist addChild( list ); // ajout des marges au contenu de la liste list.margins = new UIMargins( 5, 5, 5, 5 ); } /** * Création des éléments du composant List */ private function getListElement(id:Number):Sprite { // création de l'élément var oElement:Sprite = new Sprite(); // ajout d'un fond avec une couleur aléatoire var shp:Shape = new Shape(); var color:int = Math.random() * 0X00FFFFFF; shp.graphics.beginFill( color ); shp.graphics.drawRect( 0, 0, 200, 30 ); shp.graphics.endFill(); // ajout d'un texte var oTxt:UITextField = new UITextField(); // définition de la taille du texte oTxt.height = oTxt.maxHeight = 25; oTxt.width = oTxt.maxWidth = 195; oTxt.selectable = false; oTxt.changeFormat("color", 0xffffff);// changement de la couleur du texte oTxt.changeFormat("size", 14);// changement de la taille de la police du texte oTxt.changeFormat("font", "Arial");// changement de la police du texte oTxt.text = "Élément "+id; oTxt.alignCenter(); oTxt.background = false; oTxt.backgroundColor = 0xff33ff; // ajout à la displaylist (le fond et le texte) de l'élément oElement.addChild(shp); oElement.addChild(oTxt); return oElement; } } } |
[/codesyntax]
[codesyntax lang= »actionscript3″ title= »com.as3facileexemple.skin.classic.DefaultListSkin.as » bookmarkname= »com.as3facileexemple.skin.classic.DefaultListSkin.as »]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package com.as3facileexemple.skin.classic { import com.actionscriptfacile.skin.Skin; import com.actionscriptfacile.ui.list.List; import com.actionscriptfacile.ui.scroll.components.VerticalScrollBar; // Import des classes gérant la partie graphique du composant dans le fla (movieclip) // Provient de ui.swc (créé avec la compilation de UI.fla) import com.as3facile.skin.list.ListBackgroundSkin; import com.as3facile.skin.scroll.ScrollBarBackgroundSkin; import com.as3facile.skin.scroll.ScrollBottomButtonSkin; import com.as3facile.skin.scroll.ScrollerButtonSkin; import com.as3facile.skin.scroll.ScrollUpButtonSkin; /** * Définition du skin utilisé pour un composant List * * @author Matthieu */ public class DefaultListSkin extends Skin { public function DefaultListSkin() { setSkin( List.LIST_BACKGROUND_SKIN, ListBackgroundSkin ); setSkin( VerticalScrollBar.SCROLL_VERTICAL_BACKGROUND_SKIN, ScrollBarBackgroundSkin ); setSkin( VerticalScrollBar.SCROLL_VERTICAL_BOTTOM_SKIN, ScrollBottomButtonSkin ); setSkin( VerticalScrollBar.SCROLL_VERTICAL_UP_SKIN, ScrollUpButtonSkin ); setSkin( VerticalScrollBar.SCROLL_VERTICAL_SCROLLER_SKIN, ScrollerButtonSkin ); } } } |
[/codesyntax]