Toutes les langues

une slidebar AS3 sans les composants

En développant un player de vidéo, je me suis rendu compte que l'utilisation du composant slidebar (fl.controls.Slider) posait pas mal de problèmes .. surtout , bien qu'on puisse le skinner comme on veut, c'est à priori impossible d'en skinner deux différent, bien que normalement la fonction setStyle("..) devrait le permettre..
Je me suis bien cassé les dents sur ce problème lorsque j'ai voulu ajouté une barre de volume en plus d'une barre de progression en utilisant ce composant. Impossible de changer l'apparence du "trackSkin" une fois qu'il était affecté dans le .fla. Etrange car l'affectation de l'apparence du bouton (les skins ThumbUp, ThumbDown , ou encore ThumbOver ) fonctionnait correctement lui .

Autre solution que finalement j'ai choisi : créer ma propre classe pour un slider .
Pour interagir avec l'application dans laquelle l'objet se trouve, j'utilise des écouteurs d'évènement, évènements déclenchés par mon slider. Ainsi ma classe "player" a un addEventListener à l'écoute d'un type particulier d'évènement déclenché uniquement par le slider.
Ce fla est surtout là pour illustrer cette façon pratique de programmer via des "écouteurs d'évènements",ce qui permet de rendre totalement indépendants deux objets qui doivent interagir. On évite ainsi d'implémenter tout un tas de fonctions publiques pour que les objets commmuniquent.

Pour passer une valeur particulière dans un évènement (en l'occurence ici, un niveau de 0 à 100 ) , on ne peut pas utiliser nativement un Event ou un MouseEvent (en plus le probleme se poserait au niveau de l'écouteur qui réagirait à chaque event générique ). Aussi , j'ai créer une classe SliderEvent, qui hérite de la classe Events, que j'ai implémenté d'une variable dite publique (c'est à dire accessible à toute l'application ) .

Le slider :

//  class AS3 of a vertical Slider
//
// @author Benjamin PETIT
// december 2009

package com.sensue {
    import flash.display.Sprite ;
    import flash.events.MouseEvent ;
    import flash.geom.Rectangle ;
    import fl.transitions.*;
    import fl.transitions.easing.*;
    import fl.transitions.Tween;    

    
    import com.sensue.events.SliderEvent ;
    
    public class Slider extends Sprite {
        
        
        // Public Properties:

        // Private Properties:
        // You need 2 MovieClip/graphics on your scene to have this slider working :
        // 1 . the "track" for the knob
        // 2 . the knob
        // For easier manipulation of  movieclip, i always place them on x=0 and y=0
        // make them exportable trough Flash and give them the right name class aka Knob and TrackSkin
    
        private var _track:TrackSkin = new TrackSkin();
        private var _knob:Knob = new Knob();
        
        // Initialization:
        public function Slider () {
            
            addChild(_track);
            addChild(_knob);
            
            // knob initial position
            var initPos:int = 80 ;
            // vertical bar
            _knob.buttonMode = true ;
            _knob.y = (_track.height * (100-initPos))/ 100 ;
            // center the knob clip : all clips set to 0 , the formula :
            _knob.x = _track.x + _track.width/2 - _knob.width/2 ;
            _knob.addEventListener(MouseEvent.MOUSE_DOWN,beginDragVol);
            _knob.addEventListener(MouseEvent.MOUSE_UP,endDragVol);    
            // the additionnal Mouse up is necessary when still MOUSE_DOWN but not actually anymore on the knob
            _knob.addEventListener(MouseEvent.MOUSE_OUT,endDragVol);        

        }
    
        // Public Methods: set the slider to a position
        public function resetSlider(vol:Number):void{
                _knob.y = (_track.height * (100 - vol))/ 100 ;
                dispatchEvent(new SliderEvent('SliderEvent.VALUE_CHANGED',  vol ));            
        }
        
        // Protected Methods:
        private function beginDragVol(e:MouseEvent):void{
            // limit the startdrag on a 'rectangle' along the track height
             e.currentTarget.startDrag(false, new Rectangle( _knob.x, _track.y,0 ,_track.height-_knob.height)) ;
            _knob.addEventListener(MouseEvent.MOUSE_MOVE,addListenerMove);
        }
        private function addListenerMove(e:MouseEvent):void{
                //calculate the new position compared to the track height
                var newratio:Number = Math.abs ((e.currentTarget.y*100)/_track.height) ;
                var vol:Number = Math.round((100*newratio)/(_track.height-_knob.height))  ;                
                dispatchEvent(new SliderEvent('SliderEvent.VALUE_CHANGED',  vol ));
            
        }
        
        private function endDragVol(e:MouseEvent):void{        
            e.currentTarget.stopDrag();
            _knob.removeEventListener(MouseEvent.MOUSE_MOVE,addListenerMove);
        }
                
        
    }
    
}


La classe SliderEvent :

package com.sensue.events {
    import flash.events.Event ;
    public class SliderEvent extends Event{
        
        // Constants:
        // Public Properties:
        public static const VALUE_CHANGED:String = 'valueChanged' ;
        public var newValue:Number ;
        
        // Private Properties:
    
        // Initialization:
        public function SliderEvent(type:String,newVal:Number) {
                //bubbles and cancellable set to true
                newValue = newVal ;
                super(type, true, true);
                        
        }
        override public function clone() : Event
        {        
                return new SliderEvent(this.type, this.newValue);
        }
        
    
    }
    
}

Enfin, l'objet "player" (qui ne contient que le slider, un ecouteur des évenements qu'il émet et un champ texte)

package {

    import flash.display.MovieClip;
    import flash.text.TextField;
    import flash.text.TextFormat;    
    import com.sensue.events.SliderEvent ;    
    import com.sensue.Slider;    
    public class Player extends MovieClip {
        // UI elements
        private var _slider:Slider ;
        private var _tf:TextField ;         
        private var _tformat:TextFormat = new TextFormat();
        // Constructor
        public function Player():void {    
            _slider = new Slider() ;  
            _tf = new TextField() ;

            _tformat.color = 0x999999;
            _tformat.font = "Verdana"
            _tformat.size = 13;
            addChild(_slider) ;
            addChild(_tf) ;
            _tf.width = 200 ;
            _tf.y = 150 ;
            _slider.y = 40 ;
            _slider.x = 40;

            addEventListener('SliderEvent.VALUE_CHANGED',doSomething) ;
            return ;
            
            
        }
        private function doSomething(e:SliderEvent){
            // potentially , you change the volume Here    with the value             
            _tf.text = "capture : "+e.newValue ;
            _tf.setTextFormat(_tformat);
            

        }
    }
}
Fichier attachéTaille
Player.zip12.64 Ko
»