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
| /*----------------------------------------------------------------------------
*
* classe MonComposant v1.0
*
* Lorenzo le 01/02/2009
*
*
* AS >= 3.0
* package commun Flash et Flex
------------------------------------------------------------------------------- */
package {
import flash.geom.Point;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.DisplayObject;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.MouseEvent;
import MonComposantEvent;
/**
* @description
* Définir une zone réactive au clique et au déplacement de la souris, peut servir de base a tout type de
* classe : Slider/ScrollBar ...
* Classe servant à indiquer la bonne maniere de créer un composant visuelle en AS3 sous Flash et Flex.
* Inclus une "bonne utilisation" (d'aprés moi) des commentaires ASDOC, des commentaires,
* des evenements.
*
* @example
* <listing version="3.0">
* var mcp:MonComposant = new MonComposant();
* mcp.x = 100;
* mcp.y = 100;
* mcp.largeur = 350;
* mcp.hauteur = 200;
* mcp.addEventListener(MonComposantEvent.CHANGE, evtChangeMcp);
* this.addChild(mcp);
*
* function evtChangeMcp(ev:MonComposantEvent){
* trace(ev.posX, ev.posY);
* }
* </listing>
*
* @see MonComposantEvent
*/
public class MonComposant extends Sprite{
// -----------------------------------------------------------------------------------
// DECLARATIONS
// -----------------------------------------------------------------------------------
// ----------------------------------- Paramètres utilisateur -----------------------------------
// La largeur de la zone réactive
private var _largeur:Number = 100;
// La hauteur de la zone réactive
private var _hauteur:Number = 100;
// La position en X du curseur relative à l'occurence
private var _posX:Number = 0;
// La position en Y du curseur relative à l'occurence
private var _posY:Number = 0;
/**
* Evenement déclenché lors du clique ou du déplacement de la souris aprés un clique sur la zone réactive
*
* @eventType MonComposantEvent.CHANGE
*/
[Event(name="change", type="MonComposantEvent")]
// ----------------------------------- Paramètres classe -----------------------------------
// le nombre total d'occurence de cette classe
private static var totalOccurence:uint = 0;
// indique si l'occurence du composant à été ajouté à la liste d'affichage
private var _surScene:Boolean = false;
// La forme contenant le dessin de la zone réactive
private var _shapeZone:Shape;
// -----------------------------------------------------------------------------------
// CONSTRUCTEUR
// -----------------------------------------------------------------------------------
/**
* Constructeur de MonComposant
*
* -initialisation de la classe parent (Sprite) en utilisant super();
* -définition des 2 evenements qui vont gérer la création/destruction visuelle de l'occurence,
* evenements a créer en reference faible pour permettre la destruction complete des données de
* l'occurence tout en laissant la possibilité a l'utilisateur d'ajouter/enlever plusieurs fois
* l'occurence de la liste d'affichage.
* -initialisation divers : tout ce qui n'a pas besoin d'être re-initialisé plusieurs fois meme
* quand les valeurs des propriétés changent.
*/
public function MonComposant() {
super();
this.addEventListener(Event.ADDED_TO_STAGE, this.evtThisAddedToStage, false, 1, true);
this.addEventListener(Event.REMOVED_FROM_STAGE, this.evtThisRemovedFromStage, false, 1, true);
this._shapeZone = new Shape();
this._shapeZone.name = "shapeZone";
this.buttonMode = true;
this.name = "MonComposant_" + totalOccurence;
totalOccurence++;
}
// -----------------------------------------------------------------------------------
// METHODES
// -----------------------------------------------------------------------------------
private function dessiner():void {
if ( !this._surScene ) {
return;
}
// on efface son contenu + dessin pour eviter que son contenu soit copié sur lui meme quand
// on redemande de dessiner le composant ->
// ex : aprés un changement de propriété alors que le composant est déja dans la liste d'affichage
while(this.numChildren){
this.removeChildAt(0);
}
this.graphics.clear();
// création de la partie visuelle
with(this.graphics){//juste la pour justifier le graphics.clear() afin que l'eleve comprenne bien qu'on efface TOUT avant de faire ou refaire !
lineStyle(0, 0x006699, 0.2);
drawRect(0, 0, this._largeur, this._hauteur);
}
with(this._shapeZone.graphics){
lineStyle(0, 0, 0);
beginFill(0x006699, 0.1);
drawRect(0, 0, this._largeur, this._hauteur);
endFill();
}
this.addChild(this._shapeZone);
}
private function definirPosition(px:Number, py:Number):void {
var ptTmp:Point = this.globalToLocal(new Point(px, py));
this._posX = ptTmp.x;
this._posY = ptTmp.y;
if( this.hasEventListener(MonComposantEvent.CHANGE) ){
this.dispatchEvent(new MonComposantEvent(MonComposantEvent.CHANGE, false, false, this._posX, this._posY));
}
}
// -----------------------------------------------------------------------------------
// EVENEMENTS
// -----------------------------------------------------------------------------------
// --------- gestion de la classe dans la liste d'affichage ---------
// l'occurence vient d'être ajouté a la liste d'affichage
// -on dessine/ajoute ce qui doit l'être
// -on définit les evenements utilisateur
// this._surScene = true sert a éviter l'execution de la méthode dessiner() lors de la definitions des propriétés (ex : set largeur)
// de la classe alors que l'occurence n'a pas encore été ajouté a la liste d'affichage ni toutes les prorpriétés défini
private function evtThisAddedToStage(ev:Event):void {
this._surScene = true;
this.dessiner();
this.addEventListener(MouseEvent.MOUSE_DOWN, this.evtThisMouseDown);
}
// l'occurence est enlevé de la liste d'affichage
// -on efface tout ce qui à été dessiné ou tracé
// -on vire tous les enfants
// -on vire les evenements utilisateur
// mais on laisse les 2 evenements ADDED_TO_STAGE/REMOVED_FROM_STAGE pour laisser à l'utilisateur
// la possibilité de re-ajouter l'occurence a la liste d'affichage !
private function evtThisRemovedFromStage(ev:Event):void {
this._surScene = false;
while(this.numChildren){
this.removeChildAt(0);
}
this.graphics.clear();
this.removeEventListener(MouseEvent.MOUSE_DOWN, this.evtThisMouseDown);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, this.evtStageMouseUp);
this.removeEventListener(MouseEvent.MOUSE_MOVE, this.evtStageMouseMove);
}
// --------- gestion des evenements souris ---------
private function evtThisMouseDown(ev:MouseEvent):void {
this.addEventListener(MouseEvent.MOUSE_MOVE, this.evtStageMouseMove);
this.stage.addEventListener(MouseEvent.MOUSE_UP, this.evtStageMouseUp);
this.definirPosition(ev.stageX, ev.stageY);
}
private function evtStageMouseUp(ev:MouseEvent):void {
this.removeEventListener(MouseEvent.MOUSE_MOVE, this.evtStageMouseMove);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, this.evtStageMouseUp);
}
private function evtStageMouseMove(ev:MouseEvent):void {
this.definirPosition(ev.stageX, ev.stageY);
}
// -----------------------------------------------------------------------------------
// GET/SET
// -----------------------------------------------------------------------------------
/**
* La largeur de la zone réactive
* @default 100
*/
public function get largeur():Number {
return this._largeur;
}
public function set largeur(val:Number):void {
this._largeur = val;
this.dessiner();
}
/**
* La hauteur de la zone réactive
* @default 100
*/
public function get hauteur():Number {
return this._hauteur;
}
public function set hauteur(val:Number):void {
this._hauteur = val;
this.dessiner();
}
/**
* La position en X du curseur relative à l'occurence
* @default 0
*/
public function get posX():Number {
return this._posX;
}
/**
* La position en Y du curseur relative à l'occurence
* @default 0
*/
public function get posY():Number {
return this._posY;
}
}
} |