source: trunk/fl5/src/com/longtailvideo/jwplayer/view/components/ControlbarComponentV4.as @ 588

Revision 588, 19.3 KB checked in by pablo, 4 years ago (diff)

V5 Skin update

Line 
1package com.longtailvideo.jwplayer.view.components {
2        import com.longtailvideo.jwplayer.events.MediaEvent;
3        import com.longtailvideo.jwplayer.events.PlayerEvent;
4        import com.longtailvideo.jwplayer.events.PlayerStateEvent;
5        import com.longtailvideo.jwplayer.events.PlaylistEvent;
6        import com.longtailvideo.jwplayer.events.ViewEvent;
7        import com.longtailvideo.jwplayer.player.IPlayer;
8        import com.longtailvideo.jwplayer.player.PlayerState;
9        import com.longtailvideo.jwplayer.plugins.PluginConfig;
10        import com.longtailvideo.jwplayer.utils.Animations;
11        import com.longtailvideo.jwplayer.utils.Draw;
12        import com.longtailvideo.jwplayer.utils.Logger;
13        import com.longtailvideo.jwplayer.utils.Stacker;
14        import com.longtailvideo.jwplayer.utils.Strings;
15        import com.longtailvideo.jwplayer.view.PlayerLayoutManager;
16        import com.longtailvideo.jwplayer.view.interfaces.IControlbarComponent;
17       
18        import flash.accessibility.AccessibilityProperties;
19        import flash.display.DisplayObject;
20        import flash.display.MovieClip;
21        import flash.display.Sprite;
22        import flash.events.MouseEvent;
23        import flash.geom.ColorTransform;
24        import flash.geom.Rectangle;
25        import flash.text.TextField;
26        import flash.ui.Mouse;
27        import flash.utils.clearTimeout;
28        import flash.utils.setTimeout;
29       
30       
31        public class ControlbarComponentV4 extends CoreComponent implements IControlbarComponent {
32                /** Reference to the original skin **/
33                private var skin:Sprite;
34                /** A list with all controls. **/
35                private var stacker:Stacker;
36                /** Timeout for hiding the  **/
37                private var hiding:Number;
38                /** When scrubbing, icon shouldn't be set. **/
39                private var scrubber:MovieClip;
40                /** Color object for frontcolor. **/
41                private var front:ColorTransform;
42                /** Color object for lightcolor. **/
43                private var light:ColorTransform;
44                /** The actions for all controlbar buttons. **/
45                private var BUTTONS:Object;
46                /** The actions for all sliders **/
47                private var SLIDERS:Object = {timeSlider: ViewEvent.JWPLAYER_VIEW_SEEK, volumeSlider: ViewEvent.JWPLAYER_VIEW_VOLUME};
48                /** The button to clone for all custom buttons. **/
49                private var clonee:MovieClip;
50                /** Saving the block state of the controlbar. **/
51                private var blocking:Boolean;
52                /** Controlbar config **/
53                private var controlbarConfig:PluginConfig;
54                /** Animations handler **/
55                private var animations:Animations;
56               
57                public function ControlbarComponentV4(player:IPlayer) {
58                        super(player, "controlbar");
59                        animations = new Animations(this);
60                        controlbarConfig = _player.config.pluginConfig("controlbar");
61                        controlbarConfig['margin'] = 20;
62                        // TODO: Remove Link button
63                        BUTTONS = {
64                                playButton: ViewEvent.JWPLAYER_VIEW_PLAY,
65                                pauseButton: ViewEvent.JWPLAYER_VIEW_PAUSE,
66                                stopButton: ViewEvent.JWPLAYER_VIEW_STOP,
67                                prevButton: ViewEvent.JWPLAYER_VIEW_PREV,
68                                nextButton: ViewEvent.JWPLAYER_VIEW_NEXT,
69                                fullscreenButton: ViewEvent.JWPLAYER_VIEW_FULLSCREEN,
70                                normalscreenButton: ViewEvent.JWPLAYER_VIEW_FULLSCREEN,
71                                muteButton: ViewEvent.JWPLAYER_VIEW_MUTE,
72                                unmuteButton: ViewEvent.JWPLAYER_VIEW_MUTE
73                        };
74                        skin = _player.skin.getSWFSkin().getChildByName('controlbar') as Sprite;
75                        skin.x = 0;
76                        skin.y = 0;
77                        addChild(skin);
78                        _player.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE, stateHandler);
79                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_TIME, timeHandler);
80                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_MUTE, muteHandler);
81                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_VOLUME, volumeHandler);
82                        _player.addEventListener(MediaEvent.JWPLAYER_MEDIA_BUFFER, bufferHandler);
83                        _player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_LOADED, itemHandler);
84                        _player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_UPDATED, itemHandler);
85                        _player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM, itemHandler);
86                        stacker = new Stacker(skin as MovieClip);
87                        try { getSkinComponent("linkButton").visible = false; } catch (e:Error) {}
88                        setButtons();
89                        setColors();
90                        itemHandler();
91                        muteHandler();
92                        stateHandler();
93                        timeHandler();
94                        volumeHandler();
95                }
96               
97               
98                /**
99                 * Add a new button to the control
100                 *
101                 * @param icn   A graphic to show as icon
102                 * @param nam   Name of the button
103                   getSkinComponent('* @param hdl       The function to call when clicking the Button').
104                 **/
105                public function addButton(icon:DisplayObject, name:String, handler:Function = null):MovieClip {
106                        var btn:MovieClip;
107                        if (getSkinComponent('linkButton') && getSkinElementChild('linkButton', 'back')) {
108                                btn = Draw.clone(getSkinComponent('linkButton') as MovieClip) as MovieClip;
109                                btn.name = name + 'Button';
110                                btn.visible = true;
111                                btn.tabEnabled = true;
112                                btn.tabIndex = 6;
113                                var acs:AccessibilityProperties = new AccessibilityProperties();
114                                acs.name = name + 'Button';
115                                btn.accessibilityProperties = acs;
116                                addChild(btn);
117                                var off:Number = Math.round((btn.height - icon.height) / 2);
118                                Draw.clear(btn['icon']);
119                                btn['icon'].addChild(icon);
120                                icon.x = icon.y = 0;
121                                btn['icon'].x = btn['icon'].y = off;
122                                btn['back'].width = icon.width + 2 * off;
123                                btn.buttonMode = true;
124                                btn.mouseChildren = false;
125                                btn.addEventListener(MouseEvent.CLICK, handler);
126                                if (front) {
127                                        btn['icon'].transform.colorTransform = front;
128                                        btn.addEventListener(MouseEvent.MOUSE_OVER, overHandler);
129                                        btn.addEventListener(MouseEvent.MOUSE_OUT, outHandler);
130                                }
131                                stacker.insert(btn, getSkinComponent('linkButton') as MovieClip);
132                        }
133                        return btn;
134                }
135               
136               
137                public function removeButton(name:String):void {
138                        skin.removeChild(getSkinComponent(name));
139                }
140               
141               
142                public function resize(width:Number, height:Number):void {
143                        if ( !(PlayerLayoutManager.testPosition(controlbarConfig['position']) || controlbarConfig['position'] == "over") ) {
144                                skin.visible = false;
145                                return;
146                        }
147                       
148                        var wid:Number = width;
149                        if (controlbarConfig['position'] == 'over' || _player.fullscreen == true) {
150                                skin.x = controlbarConfig['margin'];
151                                skin.y = height - skin.height - controlbarConfig['margin'];
152                                wid = width - 2 * controlbarConfig['margin'];
153                        } else {
154                                skin.x = 0;
155                                skin.y = 0;
156                        }
157                        try {
158                                getSkinComponent('fullscreenButton').visible = false;
159                                getSkinComponent('normalscreenButton').visible = false;
160                                if (stage['displayState'] && _player.config.height > 40) {
161                                        if (_player.fullscreen) {
162                                                getSkinComponent('fullscreenButton').visible = false;
163                                                getSkinComponent('normalscreenButton').visible = true;
164                                        } else {
165                                                getSkinComponent('fullscreenButton').visible = true;
166                                                getSkinComponent('normalscreenButton').visible = false;
167                                        }
168                                }
169                        } catch (err:Error) {
170                        }
171                        stacker.rearrange(wid);
172                        stateHandler();
173                        fixTime();
174                        Mouse.show();
175                }
176               
177               
178                public function getButton(buttonName:String):DisplayObject {
179                        return null;
180                }
181               
182               
183                /** Hide the controlbar **/
184                public function block(stt:Boolean):void {
185                        blocking = stt;
186                        timeHandler();
187                }
188               
189               
190                /** Handle clicks from all buttons. **/
191                private function clickHandler(evt:MouseEvent):void {
192                        var act:String = BUTTONS[evt.target.name];
193                        var data:Object = null;
194                        if (blocking != true || act == ViewEvent.JWPLAYER_VIEW_FULLSCREEN || act == ViewEvent.JWPLAYER_VIEW_MUTE) {
195                                switch (act) {
196                                        case ViewEvent.JWPLAYER_VIEW_FULLSCREEN:
197                                                data = Boolean(!_player.fullscreen);
198                                                break;
199                                        case ViewEvent.JWPLAYER_VIEW_PAUSE:
200                                                data = Boolean(_player.state == PlayerState.IDLE || _player.state == PlayerState.PAUSED);
201                                                break;
202                                        case ViewEvent.JWPLAYER_VIEW_MUTE:
203                                                data = Boolean(!_player.mute);
204                                                break;
205                                }
206                                var event:ViewEvent = new ViewEvent(act, data);
207                                dispatchEvent(event);
208                        }
209                }
210               
211               
212                /** Handle mouse presses on sliders. **/
213                private function downHandler(evt:MouseEvent):void {
214                        scrubber = MovieClip(evt.target);
215                        if (blocking != true || scrubber.name == 'volumeSlider') {
216                                var rct:Rectangle = new Rectangle(scrubber.rail.x, scrubber.icon.y, scrubber.rail.width - scrubber.icon.width, 0);
217                                scrubber.icon.startDrag(true, rct);
218                                stage.addEventListener(MouseEvent.MOUSE_UP, upHandler);
219                        } else {
220                                scrubber = undefined;
221                        }
222                }
223               
224               
225                /** Handle a change in the current item **/
226                private function itemHandler(evt:PlaylistEvent = null):void {
227                        try {
228                                if (_player.playlist && _player.playlist.length > 1) {
229                                        getSkinComponent('prevButton').visible = getSkinComponent('nextButton').visible = true;
230                                } else {
231                                        getSkinComponent('prevButton').visible = getSkinComponent('nextButton').visible = false;
232                                }
233                        } catch (err:Error) {
234                        }
235                        timeHandler();
236                        stacker.rearrange();
237                        fixTime();
238                }
239               
240               
241                /** Show above controlbar on mousemove. **/
242                private function moveHandler(evt:MouseEvent = null):void {
243                        if (alpha == 0) {
244                                animations.fade(1);
245                        }
246                        clearTimeout(hiding);
247                        hiding = setTimeout(moveTimeout, 2000);
248                        Mouse.show();
249                }
250               
251               
252                /** Hide above controlbar again when move has timed out. **/
253                private function moveTimeout():void {
254                        animations.fade(0);
255                }
256               
257               
258                /** Show a mute icon if playing. **/
259                private function muteHandler(evt:MediaEvent = null):void {
260                        if (_player.mute == true) {
261                                try {
262                                        getSkinComponent('muteButton').visible = false;
263                                        getSkinComponent('unmuteButton').visible = true;
264                                } catch (err:Error) {
265                                }
266                                try {
267                                        getSkinElementChild('volumeSlider', 'mark').visible = false;
268                                        getSkinElementChild('volumeSlider', 'icon').x = getSkinElementChild('volumeSlider', 'rail').x;
269                                } catch (err:Error) {
270                                }
271                        } else {
272                                try {
273                                        getSkinComponent('muteButton').visible = true;
274                                        getSkinComponent('unmuteButton').visible = false;
275                                } catch (err:Error) {
276                                }
277                                try {
278                                        getSkinElementChild('volumeSlider', 'mark').visible = true;
279                                        volumeHandler();
280                                } catch (err:Error) {
281                                }
282                        }
283                }
284               
285               
286                /** Handle mouseouts from all buttons **/
287                private function outHandler(evt:MouseEvent):void {
288                        if (front && evt.target['icon']) {
289                                evt.target['icon'].transform.colorTransform = front;
290                        } else {
291                                evt.target.gotoAndPlay('out');
292                        }
293                }
294               
295               
296                /** Handle clicks from all buttons **/
297                private function overHandler(evt:MouseEvent):void {
298                        if (front && evt.target['icon']) {
299                                evt.target['icon'].transform.colorTransform = light;
300                        } else {
301                                evt.target.gotoAndPlay('over');
302                        }
303                }
304               
305               
306                /** Clickhandler for all buttons. **/
307                private function setButtons():void {
308                        for (var btn:String in BUTTONS) {
309                                if (getSkinComponent(btn)) {
310                                        (getSkinComponent(btn) as MovieClip).mouseChildren = false;
311                                        (getSkinComponent(btn) as MovieClip).buttonMode = true;
312                                        getSkinComponent(btn).addEventListener(MouseEvent.CLICK, clickHandler);
313                                        getSkinComponent(btn).addEventListener(MouseEvent.MOUSE_OVER, overHandler);
314                                        getSkinComponent(btn).addEventListener(MouseEvent.MOUSE_OUT, outHandler);
315                                }
316                        }
317                        for (var sld:String in SLIDERS) {
318                                if (getSkinComponent(sld)) {
319                                        (getSkinComponent(sld) as MovieClip).mouseChildren = false;
320                                        (getSkinComponent(sld) as MovieClip).buttonMode = true;
321                                        getSkinComponent(sld).addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
322                                        getSkinComponent(sld).addEventListener(MouseEvent.MOUSE_OVER, overHandler);
323                                        getSkinComponent(sld).addEventListener(MouseEvent.MOUSE_OUT, outHandler);
324                                }
325                        }
326                }
327               
328               
329                /** Init the colors. **/
330                private function setColors():void {
331                        if (_player.config.backcolor && getSkinElementChild('playButton', 'icon')) {
332                                var clr:ColorTransform = new ColorTransform();
333                                clr.color = _player.config.backcolor.color;
334                                getSkinComponent('back').transform.colorTransform = clr;
335                        }
336                        if (_player.config.frontcolor) {
337                                try {
338                                        front = new ColorTransform();
339                                        front.color = _player.config.frontcolor.color;
340                                        for (var btn:String in BUTTONS) {
341                                                if (getSkinComponent(btn)) {
342                                                        getSkinElementChild(btn, 'icon').transform.colorTransform = front;
343                                                }
344                                        }
345                                        for (var sld:String in SLIDERS) {
346                                                if (getSkinComponent(sld)) {
347                                                        getSkinElementChild(sld, 'icon').transform.colorTransform = front;
348                                                        getSkinElementChild(sld, 'mark').transform.colorTransform = front;
349                                                        getSkinElementChild(sld, 'rail').transform.colorTransform = front;
350                                                }
351                                        }
352                                        (getSkinComponent('elapsedText') as TextField).textColor = front.color;
353                                        (getSkinComponent('totalText') as TextField).textColor = front.color;
354                                } catch (err:Error) {
355                                }
356                        }
357                        if (_player.config.lightcolor) {
358                                light = new ColorTransform();
359                                light.color = _player.config.lightcolor.color;
360                        } else {
361                                light = front;
362                        }
363                        if (light) {
364                                try {
365                                        getSkinElementChild('timeSlider', 'done').transform.colorTransform = light;
366                                        getSkinElementChild('volumeSlider', 'mark').transform.colorTransform = light;
367                                } catch (err:Error) {
368                                }
369                        }
370                }
371               
372               
373                /** Process state changes **/
374                private function stateHandler(evt:PlayerEvent = undefined):void {
375                        // TODO: Fix non-working fading
376                        clearTimeout(hiding);
377                        try {
378                                _player.controls.display.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
379                        } catch (e:Error) {}
380                        try {
381                                var dps:String = stage['displayState'];
382
383                                switch (_player.state) {
384                                        case PlayerState.PLAYING:
385                                                getSkinComponent('playButton').visible = false;
386                                                getSkinComponent('pauseButton').visible = true;
387
388                                                if (controlbarConfig['position'] == 'over' || dps == 'fullScreen') {
389                                                        Mouse.show();
390                                                        animations.fade(1);
391                                                }
392                                                break;
393                                        case PlayerState.PAUSED:
394                                                getSkinComponent('playButton').visible = true;
395                                                getSkinComponent('pauseButton').visible = false;
396                                               
397                                                if (controlbarConfig['position'] == 'over' || dps == 'fullScreen') {
398                                                        Mouse.show();
399                                                        animations.fade(1);
400                                                }
401                                                break;
402                                        case PlayerState.BUFFERING:
403                                                getSkinComponent('playButton').visible = false;
404                                                getSkinComponent('pauseButton').visible = true;
405                                               
406                                                if (controlbarConfig['position'] == 'over' || (dps == 'fullScreen' && controlbarConfig['position'] != 'none')) {
407                                                        hiding = setTimeout(moveTimeout, 2000);
408                                                        try {
409                                                                _player.controls.display.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
410                                                        } catch (e:Error) {}
411                                                } else {
412                                                        animations.fade(1);
413                                                }
414                                                break;
415                                        case PlayerState.IDLE:
416                                                getSkinComponent('playButton').visible = true;
417                                                getSkinComponent('pauseButton').visible = false;
418                                                timeHandler();
419                                               
420                                                if (controlbarConfig['position'] == 'over' || dps == 'fullScreen') {
421                                                        Mouse.show();
422                                                        animations.fade(1);
423                                                }
424                                                break;
425                                }
426                        } catch (e:Error) {}
427                }
428               
429                /** Process time updates given by the model. **/
430                private function timeHandler(evt:MediaEvent = null):void {
431                        var dur:Number = 0;
432                        var pos:Number = 0;
433                        if (evt) {
434                                if (evt.duration >= 0) {
435                                        dur = evt.duration;
436                                }
437                                if (evt.position >= 0) {
438                                        pos = evt.position;
439                                }
440                        } else if (_player.playlist.length > 0 && _player.playlist.currentItem) {
441                                if (_player.playlist.currentItem.duration >= 0) {
442                                        dur = _player.playlist.currentItem.duration;
443                                }
444                        }
445                        var pct:Number = pos / dur;
446                        if (isNaN(pct)) {
447                                pct = 1;
448                        }
449                        try {
450                                (getSkinComponent('elapsedText') as TextField).text = Strings.digits(pos);
451                                (getSkinComponent('totalText') as TextField).text = Strings.digits(dur);
452                        } catch (err:Error) {
453                                Logger.log(err);
454                        }
455                        try {
456                                var xps:Number = Math.round(pct * (getSkinElementChild('timeSlider', 'rail').width - getSkinElementChild('timeSlider', 'icon').width));
457                                if (dur > 0) {
458                                        getSkinElementChild('timeSlider', 'icon').visible = _player.state != PlayerState.IDLE;
459                                        getSkinElementChild('timeSlider', 'mark').visible = _player.state != PlayerState.IDLE;
460                                        if (!scrubber) {
461                                                getSkinElementChild('timeSlider', 'icon').x = xps;
462                                                getSkinElementChild('timeSlider', 'done').width = xps;
463                                        }
464                                        bufferHandler(evt);
465                                        getSkinElementChild('timeSlider', 'done').visible = _player.state != PlayerState.IDLE;
466                                } else {
467                                        if (_player.state != PlayerState.PLAYING) {
468                                                getSkinElementChild('timeSlider', 'icon').visible = false;
469                                                getSkinElementChild('timeSlider', 'mark').visible = false;
470                                                getSkinElementChild('timeSlider', 'done').visible = false;
471                                        }
472                                }
473                        } catch (err:Error) {
474                        }
475                }
476               
477               
478                private function bufferHandler(evt:MediaEvent):void {
479                        if (evt.bufferPercent < 0)
480                                return;
481                       
482                        var mark:DisplayObject = getSkinElementChild('timeSlider', 'mark');
483                        var railWidth:Number = getSkinElementChild('timeSlider', 'rail').width;
484                        var markWidth:Number = _player.state == PlayerState.IDLE ? 0 : Math.round((evt.bufferPercent / 100) * railWidth);
485                        var offsetRatio:Number = evt.offset / evt.duration;
486                       
487                        try {
488                                mark.x = evt.duration > 0 ? Math.round(railWidth * offsetRatio) : 0;
489                                mark.width = markWidth * (1 - offsetRatio);
490                                mark.visible = _player.state != PlayerState.IDLE;
491                        } catch (e:Error) {}
492                }
493               
494               
495                /** Fix the timeline display. **/
496                private function fixTime():void {
497                        try {
498                                var scp:Number = getSkinComponent('timeSlider').scaleX;
499                                getSkinComponent('timeSlider').scaleX = 1;
500                                getSkinElementChild('timeSlider', 'icon').x = scp * getSkinElementChild('timeSlider', 'icon').x;
501                                getSkinElementChild('timeSlider', 'mark').x = scp * getSkinElementChild('timeSlider', 'mark').x;
502                                getSkinElementChild('timeSlider', 'mark').width = scp * getSkinElementChild('timeSlider', 'mark').width;
503                                getSkinElementChild('timeSlider', 'rail').width = scp * getSkinElementChild('timeSlider', 'rail').width;
504                                getSkinElementChild('timeSlider', 'done').x = scp * getSkinElementChild('timeSlider', 'done').x;
505                                getSkinElementChild('timeSlider', 'done').width = scp * getSkinElementChild('timeSlider', 'done').width;
506                        } catch (err:Error) {
507                        }
508                }
509               
510               
511                /** Handle mouse releases on sliders. **/
512                private function upHandler(evt:MouseEvent):void {
513                        var mpl:Number = 0;
514                        var sliderType:String = scrubber.name;
515                       
516                        stage.removeEventListener(MouseEvent.MOUSE_UP, upHandler);
517                        scrubber.icon.stopDrag();
518                        if (sliderType == 'timeSlider' && _player.playlist) {
519                                mpl = _player.playlist.currentItem.duration;
520                        } else if (sliderType == 'volumeSlider') {
521                                if (_player.mute) return;
522                                else mpl = 100;
523                        }
524                        var pct:Number = (scrubber.icon.x - scrubber.rail.x) / (scrubber.rail.width - scrubber.icon.width) * mpl;
525                        scrubber = undefined;
526                        dispatchEvent(new ViewEvent(SLIDERS[sliderType], Math.round(pct)));
527                }
528               
529               
530                /** Reflect the new volume in the controlbar **/
531                private function volumeHandler(evt:MediaEvent = null):void {
532                        try {
533                                var vsl:MovieClip = getSkinComponent('volumeSlider') as MovieClip;
534                                vsl.mark.width = _player.config.volume * (vsl.rail.width - vsl.icon.width / 2) / 100;
535                                vsl.icon.x = vsl.mark.x + _player.config.volume * (vsl.rail.width - vsl.icon.width) / 100;
536                        } catch (err:Error) {
537                        }
538                }
539               
540               
541                private function getSkinComponent(element:String):DisplayObject {
542                        return skin.getChildByName(element) as DisplayObject;
543                }
544               
545               
546                private function getSkinElementChild(element:String, child:String):DisplayObject {
547                        return (skin.getChildByName(element) as MovieClip).getChildByName(child);
548                }
549        }
550}
Note: See TracBrowser for help on using the repository browser.