/*
* Xorax AS2 Player - Action Script 2 flash class for designer
*
* Copyright (c) 2008 Martin Panel (contact@xorax.info)
* licensed under the MIT (MIT-LICENSE.txt)
*/
/**
* @see flash mp3 player as2
* @author Xorax
* @license http://www.opensource.org/licenses/mit-license.php copyright Martin PANEL : MIT license
* @version 20080523
* @description aide l'assignation de fonctions et d'événements sur des objets graphique.
*/
class xorax.player.template extends xorax.player.base {
/**
* assigne l'action qui permet au bouton btn de démarrer la lecture lorsqu'il est cliqué.
* @param btn MovieClip : référence du bouton
* @param src String source du son à jouer (optionnel)
*/
public function addPlay (btn, src:String):Void{
var th = this;
var lastonRelease = btn.onRelease;
btn.onRelease = function(){
th.play(src);
lastonRelease();
}
}
/**
* assigne l'action qui permet au bouton btn de mettre la lecture en pause lorsqu'il est cliqué.
* @param btn référence du bouton
*/
public function addPause (btn):Void{
var th = this;
var lastonRelease = btn.onRelease;
btn.onRelease = function(){
th.pause();
lastonRelease();
}
}
/**
* assigne l'action à un bouton. Lorsque le bouton sera pressé, si le son est en pause ou stoppé, on reprend au niveau de la tête de lecture, sinon on le met en pause.
* @param btn référence du bouton
* @param src source du son à jouer lors quand l'action est appelé (optionnel)
*/
public function addPlayPause(btn, src):Void{
var th = this;
var lastonRelease = btn.onRelease;
btn.onRelease = function(){
if(th.isOnPlaying()){
th.pause();
} else {
th.play(src);
}
lastonRelease();
}
}
/**
* assigne l'action "arrèter le son et rembobiner la tête de lecture" à un bouton
* @param btn référence du bouton
*/
public function addStop (btn):Void{
var th = this;
var lastonRelease = btn.onRelease;
btn.onRelease = function(){
th.stop();
lastonRelease();
}
}
/**
* assigne l'action "augmenter le volume" à un bouton
* @param btn référence du bouton
*/
public function addVolumeInc (btn):Void{
var th = this;
var lastonRelease = btn.onRelease;
btn.onRelease = function(){
th.volumeInc();
lastonRelease();
}
}
/**
* assigne l'action "diminuer le volume" à un bouton
* @param btn référence du bouton
*/
public function addVolumeDec (btn):Void{
var th = this;
var lastonRelease = btn.onRelease;
btn.onRelease = function(){
th.volumeDec();
lastonRelease();
}
}
function addDraggable (btn:MovieClip, onDrag:Function, onStop:Function, lockCenter:Boolean):Void{ //ondrag(x,y,btn): [x,y] | false ; onStop():Void
var th = this;
var lastOnPress = btn.onPress;
var lastOnMouseMove:Function;
btn.onPress = function(){
this.onDragging = true;
var off_x = 0, off_y = 0;
lockCenter = true;
if(!lockCenter){
off_x = this._parent._xmouse - this._x;
off_y = this._parent._ymouse - this._y;
}
var setPosition:Function = function (target:Object)
{
target._x = target._parent._xmouse - off_x;
target._y = target._parent._ymouse - off_y;
};
lastOnMouseMove = btn.onMouseMove;
setPosition(this);
lastOnPress();
if(lockCenter){
onDrag(this);
lastOnMouseMove();
}
this.onMouseMove = function () {
setPosition(this);
onDrag(this);
lastOnMouseMove();
updateAfterEvent();
};
};
var lastOnRelease = btn.onRelease;
btn.onRelease = btn.onReleaseOutside = function(){
this.onDragging = false;
//this.onMouseMove();
onStop(this);
this.onMouseMove = lastOnMouseMove;
}
lastOnRelease();
}
/**
* permet de se servir d'un élément graphique comme d'une bar de chargement.
* Lors du chargement, le clip changera de taille en fonction des paramêtres pLeft et pRight et du nombre de byte chargé
* exemple :
* //btnId est une reference à un clip
* myPlayer.addBarBytesLoaded(btnId, {_width:0}, {_width: 100});
* @param clip référence du clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip
*/
public function addBarBytesLoaded (clip, pLeft, pRight){
if(!pLeft) var pLeft = {};
if(!pRight) var pRight = {};
var pRef = this.defRefPropertyScale(clip, pLeft, pRight);
clip[pRef] = pLeft[pRef];
var th = this;
var listen = { onLoading: function(success) {
if(success) clip[pRef] = pRight[pRef];
else {
clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.position()/th.duration() );
}
}};
this.addListener(listen);
}
function createMaskClip (bar){
var but = bar._parent.createEmptyMovieClip('__'+bar._name+'_but',bar._parent.getNextHighestDepth());
but._alpha = 0;
var tp = bar.getBounds(bar._parent);
but._x = tp.xMin;
but._y = tp.yMin;
but.beginFill(0xFF0000);
but.moveTo(0,0);
but.lineTo(bar._width,0);
but.lineTo(bar._width,bar._height);
but.lineTo(0,bar._height || 1);
but.lineTo(0,0);
but.endFill();
//bar.hitArea(but);
but.useHandCursor = true;
return but;
}
function addResizable (bar, onResize, onStop, pRef){
var but = this.createMaskClip(bar, pRef);
var mRef = (pRef == '_height') ? '_ymouse': '_xmouse';
var sRef = (pRef == '_height') ? '_yscale': '_xscale';
var th = this;
var lastOnPress = but.onPress;
var lastOnMouseMove:Function;
but.onPress = function(){
this.onResizing = true;
lastOnPress();
lastOnMouseMove = but.onMouseMove;
this.onMouseMove = function () {
bar[pRef] = this[mRef]*this[sRef]/100;
onResize(this);
lastOnMouseMove();
updateAfterEvent();
};
};
var lastOnRelease = but.onRelease;
but.onRelease = but.onReleaseOutside = function(){
bar[pRef] = this[mRef]*this[sRef]/100;
onStop(this);
this.onMouseMove = lastOnMouseMove;
lastOnRelease();
this.onResizing = false;
}
return but;
}
/**
* permet de se servir d'un élément graphique comme d'une bar de volume.
* L'utilisateur pourra alor augmenté ou diminué le volume en augmentant ou en diminuant la taille du clip.
* exemple :
* //btnId est une reference à un clip
* myPlayer.addBarVolume(btnId, {_height:0}, {_height: 100});
* @param clip référence du clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip
* @param onMoveFunc fonction appelé à chaque modification du volume
*/
public function addBarVolume(clip, pLeft:Object, pRight:Object, onMoveFunc:Function) :Void{
var pRef = this.defRefPropertyScale(clip, pLeft, pRight);
var th = this;
var onResize = function(){
var rap = th.setPropAccording(clip, pLeft, pRight, pRef);
th.volumeSet(rap*100);
}
onResize();
this.addListener({
onStart: onResize,
onVolumeChange: function(){
clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.volume/100 );
th.setPropAccording(clip, pLeft, pRight, pRef);
}
});
this.addResizable (clip, onResize, onResize, pRef);
}
/**
* permet de se servir d'un élément graphique comme d'un bouton de volume.
* L'utilisateur pourra alor augmenté ou diminué le volume en déplçant le clip
* exemple :
* //btnId est une reference à un clip
* myPlayer.addBarVolume(btnId, {_x:0}, {_x: 100});
* @param clip référence du clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la position minimum que doit avoir le clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la position maximum que doit avoir le clip
* @param onDragFunc fonction appelé à chaque modification du volume
*/
public function addDragVolume (clip, pLeft:Object, pRight:Object, onDragFunc:Function) :Void{
var pRef = this.defRefPropertyPosition(clip, pLeft, pRight);
var th = this;
var onDrag = function(){
var rap = th.setPropAccording(clip, pLeft, pRight, pRef)*100;
th.volumeSet(rap);
}
this.addListener({
onStart: onDrag,
onVolumeChange: function(){
clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.volume/100 );
th.setPropAccording(clip, pLeft, pRight, pRef);
}
});
this.addDraggable(clip, onDrag);
}
/**
* permet de se servir d'un élément graphique comme d'une bar de position de la tête de lecture.
* L'utilisateur pourra alor déplacer la tête de lecture en modifiant la taille clip.
* exemple :
* //btnId est une reference à un clip
* myPlayer.addBarVolume(btnId, {_width:0}, {_width: 100});
* @param clip référence du clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip
* @param onMoveFunc fonction appelé à chaque changement de position de la tête de lecture
*/
public function addBarPosition(clip, pLeft:Object, pRight:Object, onMoveFunc:Function) :Void{
var pRef = this.defRefPropertyScale(clip, pLeft, pRight);
var th = this;
var onResize = function(){
var rap = th.setPropAccording(clip, pLeft, pRight, pRef);
var pos = th.sound.duration/1000;
var t = rap*pos;
if(Math.round(th.sound.position/1000) != Math.round(t)) {
if(th.isOnPause()) {
th.pausedAt = t;
} else {
th.position(t*1000);
}
}
onMoveFunc(rap);
}
//onResize();
var but = this.addResizable (clip, onResize, onResize, pRef);
clip[pRef] = pLeft[pRef];
th.setPropAccording(clip, pLeft, pRight, pRef);
var oldpRef = pRight[pRef];
var posOnload = function(){
if(th.sound.getBytesTotal() > 0){
pRight[pRef] = pLeft[pRef] + ((oldpRef - pLeft[pRef]) * th.sound.duration / th.duration());
}
}
var listen = {
onPlaying: function(){
if(!clip.onResizing){
if(th.isOnLoading()) posOnload();
clip[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.sound.position/th.sound.duration );
th.setPropAccording(clip, pLeft, pRight, pRef);
}
},
onLoading:function(success){
if(success) return pRight[pRef] = oldpRef;
posOnload();
but[pRef] = pRight[pRef];
}
};
this.addListener(listen);
}
/**
* permet de se servir d'un élément graphique comme d'un bouton position de la tête de lecture.
* le déplacement du clip bouton déplacera la tête de lecture.
* exemple :
* //btnId est une reference à un clip
* myPlayer.addDragPosition(btnId, {_x:0, _y:0}, {_x:100, _y: 100});
* L'utilisateur pourra alor déplacer la tête de lecture en déplaçant le clip
* @param clip référence du clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille minimum que doit avoir le clip
* @param pLeft object contenant (au minimum) le _width ou le _left de la taille maximum que doit avoir le clip
* @param onMoveFunc fonction appelé à chaque changement de position de la tête de lecture
*/
public function addDragPosition (btn, pLeft:Object, pRight:Object, onDragFunc:Function):Void{
var pRef = this.defRefPropertyPosition(btn, pLeft, pRight);
btn[pRef] = pLeft[pRef];
var th = this;
var onDrag = function(){
var rap = th.setPropAccording(btn, pLeft, pRight, pRef);
var pos = (th.sound.duration || 0)/1000;
var t = Math.round(rap*pos);
if(Math.round((th.sound.position || 0)/1000) != t) {
if(th.isOnPause()) {
th.pausedAt = t;
} else {
th.sound.start(t);
th.startPlaying();
}
}
onDragFunc(rap);
}
//onDrag();
th.setPropAccording(btn, pLeft, pRight, pRef);
this.addDraggable(btn, onDrag);
var oldpRef = pRight[pRef];
var posOnload = function(){
if(th.sound.getBytesTotal() > 0){
pRight[pRef] = pLeft[pRef] + ((oldpRef - pLeft[pRef]) * (th.sound.getBytesLoaded() || 0)/th.sound.getBytesTotal());
}
}
var listen = {
onPlaying: function(){
if(!btn.onDragging){
if(th.isOnLoading()) posOnload();
btn[pRef] = pLeft[pRef] + ((pRight[pRef]-pLeft[pRef]) * th.sound.position/th.sound.duration);
th.setPropAccording(btn, pLeft, pRight, pRef);
}
},
onLoading:function(success){
if(success) return pRight[pRef] = oldpRef;
posOnload();
th.setPropAccording(btn, pLeft, pRight, pRef);
}
};
this.addListener(listen);
}
private function defRefPropertyPosition (target:MovieClip, pLeft:Object, pRight:Object){
var x = '_x', y = '_y';
var pRef;//, pRefInv;
/*
for(var p in pRight){
if(!(pLeft[p] instanceof Number)) pLeft[p] = target[p];
}*/
for(var p in pLeft){
if(isNaN(pRight[p])){
if(!isNaN(pLeft[p])){
target[p] = pLeft[p];
pRight[p] = pLeft[p];
}
}
}
if(isNaN(pLeft[x]) || pLeft[x] == pRight[x]){
if(isNaN(pLeft[y])){
pRef = x;
pLeft[x] = target[x] - (target._width/2);
pRight[x] = target[x] + (target._width/2);
} else pRef = y;
} else pRef = x;
/*
Pour les concepteurs de flash, 3 n'est pas un nombre (false === 3 instanceof Number) et !isNaN(true) === true.
Y en a qui doivent avoir des ampoules aux pieds à force de coder avec.
pRefInv = (pRef == x) ? y : x;
if(!(pLeft[pRefInv] instanceof Number)) pLeft[pRefInv] = pRight[pRefInv] = target[pRefInv];
*/
return pRef;
}
private function defRefPropertyScale (target:MovieClip, pLeft:Object, pRight:Object){
var h = '_height', w = '_width';
var pRef;
for(var p in pRight){
if(isNaN(pLeft[p])) pLeft[p] = 0;
}
for(var p in pLeft){
if(isNaN(pRight[p])){
target[p] = pLeft[p];
delete pLeft[p];
}
}
if(isNaN(pLeft[w])){
if(isNaN(pLeft[h])){
pRef = w;
pLeft[w] = 0;
pRight[w] = target[w];
} else pRef = h;
} else pRef = w;
return pRef;
}
private function setPropAccording (target:MovieClip, pLeft:Object, pRight:Object, pRef:String):Number {
var rap = (target[pRef]-pLeft[pRef])/(pRight[pRef]-pLeft[pRef]);
if(rap <= 0) rap = 0;
if(rap > 1) rap = 1;
for(var p in pLeft){
if(typeof(pLeft[p]) == 'function'){
pLeft[p](target, rap);
} else {
target[p] = pLeft[p] + rap*(pRight[p]-pLeft[p]);
}
}
return rap;
}
private function addClipToMove (target:MovieClip, pLeft:Object, pRight:Object, funcSet:Function):Function{
var pRef = this.defRefPropertyPosition(target, pLeft, pRight);
/*for(var p in pLeft) if(pRight[p] == undefined){
btn[p] = pLeft[p];
delete pLeft[p];
}*/
var th = this;
var onMove = function(){
var rap = th.setPropAccording(target, pLeft, pRight, pRef);
funcSet(rap, pLeft, pRight);
}
onMove();
return onMove;
}
}