source: trunk/fl5/src/com/longtailvideo/jwplayer/view/components/ControlbarComponent.as @ 728

Revision 728, 18.5 KB checked in by zach, 3 years ago (diff)
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.Strings;
13        import com.longtailvideo.jwplayer.view.interfaces.IControlbarComponent;
14       
15        import flash.display.DisplayObject;
16        import flash.display.MovieClip;
17        import flash.display.Sprite;
18        import flash.events.MouseEvent;
19        import flash.geom.ColorTransform;
20        import flash.text.TextField;
21        import flash.text.TextFieldAutoSize;
22        import flash.text.TextFormat;
23        import flash.ui.Mouse;
24        import flash.utils.clearTimeout;
25        import flash.utils.setTimeout;
26
27
28        /**
29         * Sent when the user interface requests that the player play the currently loaded media
30         *
31         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_PLAY
32         */
33        [Event(name="jwPlayerViewPlay", type="com.longtailvideo.jwplayer.events.ViewEvent")]
34        /**
35         * Sent when the user interface requests that the player pause the currently playing media
36         *
37         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_PAUSE
38         */
39        [Event(name="jwPlayerViewPause", type="com.longtailvideo.jwplayer.events.ViewEvent")]
40        /**
41         * Sent when the user interface requests that the player stop the currently playing media
42         *
43         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_STOP
44         */
45        [Event(name="jwPlayerViewStop", type="com.longtailvideo.jwplayer.events.ViewEvent")]
46        /**
47         * Sent when the user interface requests that the player play the next item in its playlist
48         *
49         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_NEXT
50         */
51        [Event(name="jwPlayerViewNext", type="com.longtailvideo.jwplayer.events.ViewEvent")]
52        /**
53         * Sent when the user interface requests that the player play the previous item in its playlist
54         *
55         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_PREV
56         */
57        [Event(name="jwPlayerViewPrev", type="com.longtailvideo.jwplayer.events.ViewEvent")]
58        /**
59         * Sent when the user interface requests that the player navigate to the playlist item's <code>link</code> property
60         *
61         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_LINK
62         */
63        [Event(name="jwPlayerViewLink", type="com.longtailvideo.jwplayer.events.ViewEvent")]
64        /**
65         *
66         *
67         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_MUTE
68         */
69        [Event(name="jwPlayerViewMute", type="com.longtailvideo.jwplayer.events.ViewEvent")]
70        /**
71         *
72         *
73         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_FULLSCREEN
74         */
75        [Event(name="jwPlayerViewFullscreen", type="com.longtailvideo.jwplayer.events.ViewEvent")]
76        /**
77         *
78         *
79         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_VOLUME
80         */
81        [Event(name="jwPlayerViewVolume", type="com.longtailvideo.jwplayer.events.ViewEvent")]
82        /**
83         *
84         *
85         * @eventType com.longtailvideo.jwplayer.events.ViewEvent.JWPLAYER_VIEW_SEEK
86         */
87        [Event(name="jwPlayerViewSeek", type="com.longtailvideo.jwplayer.events.ViewEvent")]
88        public class ControlbarComponent extends CoreComponent implements IControlbarComponent {
89                protected var _buttons:Object = {};
90                protected var _dividers:Array;
91                protected var _defaultLayout:String = "[play|stop|prev|next|elapsed][time][duration|blank|fullscreen|mute volume]";
92                protected var _currentLayout:String;
93                protected var _layoutManager:ControlbarLayoutManager;
94                protected var _width:Number;
95                protected var _height:Number;
96
97                protected var controlbarConfig:PluginConfig;
98                protected var animations:Animations;
99                protected var hiding:Number;
100               
101                public function ControlbarComponent(player:IPlayer) {
102                        super(player, "controlbar");
103                        _layoutManager = new ControlbarLayoutManager(this);
104                        _dividers = [];
105                        setupBackground();
106                        setupDefaultButtons();
107                        addEventListeners();
108                        updateControlbarState();
109                        setTime(0, 0);
110                        updateVolumeSlider();
111                        controlbarConfig = _player.config.pluginConfig(_name);
112                        animations = new Animations(this);
113                }
114
115                private function addEventListeners():void {
116                        player.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE, stateHandler);
117                        player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_LOADED, playlistHandler);
118                        player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_UPDATED, playlistHandler);
119                        player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM, playlistHandler);
120                        player.addEventListener(MediaEvent.JWPLAYER_MEDIA_MUTE, stateHandler);
121                        player.addEventListener(MediaEvent.JWPLAYER_MEDIA_VOLUME, updateVolumeSlider);
122                        player.addEventListener(MediaEvent.JWPLAYER_MEDIA_BUFFER, mediaHandler);
123                        player.addEventListener(MediaEvent.JWPLAYER_MEDIA_TIME, mediaHandler);
124                        player.addEventListener(PlayerEvent.JWPLAYER_LOCKED, lockHandler);
125                        player.addEventListener(PlayerEvent.JWPLAYER_UNLOCKED, lockHandler);
126                }
127
128
129                private function lockHandler(evt:PlayerEvent):void {
130                        if (_player.locked) {
131                                getSlider('time').lock();
132                                getSlider('volume').lock();
133                        } else {
134                                getSlider('time').unlock();
135                                getSlider('volume').unlock();
136                        }
137                }
138
139
140                private function playlistHandler(evt:PlaylistEvent):void {
141                        getSlider('time').reset();
142                        updateControlbarState();
143                        redraw();
144                }
145
146               
147                private function startFader():void {
148                        if (controlbarConfig['position'] == 'over' || (_player.fullscreen && controlbarConfig['position'] != 'none')) {
149                                if (!isNaN(hiding)) {
150                                        clearTimeout(hiding);
151                                }
152                                hiding = setTimeout(moveTimeout, 2000);
153                                _player.controls.display.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
154                        }
155                }
156               
157                private function stopFader():void {
158                        if (!isNaN(hiding)) {
159                                clearTimeout(hiding);
160                                try {
161                                        _player.controls.display.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
162                                } catch (e:Error) {}
163                        }
164                        Mouse.show();
165                        animations.fade(1, 0.5);
166                }
167               
168                /** Show above controlbar on mousemove. **/
169                private function moveHandler(evt:MouseEvent=null):void {
170                        if (alpha == 0) {
171                                animations.fade(1, 0.5);
172                        }
173                        clearTimeout(hiding);
174                        hiding = setTimeout(moveTimeout, 2000);
175                        Mouse.show();
176                }
177               
178               
179                /** Hide above controlbar again when move has timed out. **/
180                private function moveTimeout():void {
181                        animations.fade(0, 0.5);
182                        Mouse.hide();
183                }
184               
185                private function stateHandler(evt:PlayerEvent=null):void {
186                        switch(_player.state) {
187                                case PlayerState.BUFFERING:
188                                case PlayerState.PLAYING:
189                                        startFader();
190                                        break;
191                                case PlayerState.PAUSED:
192                                case PlayerState.IDLE:
193                                        stopFader();
194                                        break;
195                        }
196                        updateControlbarState();
197                        redraw();
198                }
199
200
201                private function updateControlbarState():void {
202                        var newLayout:String = _defaultLayout;
203                        newLayout = removeButtonFromLayout("blank", newLayout);
204                        if (player.state == PlayerState.PLAYING) {
205                                newLayout = newLayout.replace('play', 'pause');
206                                hideButton('play');
207                        } else if (player.state == PlayerState.IDLE) {
208                                getSlider('time').reset();
209                                if (_player.playlist.currentItem) {
210                                        setTime(0, _player.playlist.currentItem.duration);
211                                }
212                                hideButton('pause');
213                        } else {
214                                hideButton('pause');
215                        }
216                        if (player.playlist.length <= 1) {
217                                newLayout = newLayout.replace("|prev|next", "");
218                                hideButton('prev');
219                                hideButton('next');
220                        }
221                        if (player.mute) {
222                                newLayout = newLayout.replace("mute", "unmute");
223                                hideButton("mute");
224                        } else {
225                                hideButton("unmute");
226                        }
227                        if (player.fullscreen) {
228                                newLayout = newLayout.replace("fullscreen", "normalscreen");
229                                hideButton("fullscreen");
230                        } else {
231                                hideButton("normalscreen");
232                        }
233                        _currentLayout = removeInactive(newLayout);
234                }
235
236
237                private function removeInactive(layout:String):String {
238                        var buttons:Array = _defaultLayout.match(/\W*([A-Za-z0-9]+?)\W/g);
239                        for (var i:Number = 0; i < buttons.length; i++) {
240                                var button:String = (buttons[i] as String).replace(/\W/g, "");
241                                if (!_buttons[button]) {
242                                        layout = removeButtonFromLayout(button, layout);
243                                }
244                        }
245                        return layout;
246                }
247
248
249                private function removeButtonFromLayout(button:String, layout:String):String {
250                        layout = layout.replace(button, "");
251                        layout = layout.replace("||", "|");
252                        return layout;
253                }
254
255
256                private function mediaHandler(evt:MediaEvent):void {
257                        var scrubber:Slider = getSlider('time');
258                        switch (evt.type) {
259                                case MediaEvent.JWPLAYER_MEDIA_BUFFER:
260                                        //setTime(evt.position, evt.duration);
261                                        if (scrubber) {
262                                                //scrubber.setProgress(evt.position / evt.duration *100);
263                                                scrubber.setBuffer(evt.bufferPercent);
264                                        }
265                                        break;
266                                case MediaEvent.JWPLAYER_MEDIA_TIME:
267                                        setTime(evt.position, evt.duration);
268                                        if (scrubber) {
269                                                scrubber.setProgress(evt.position / evt.duration * 100);
270                                                if (evt.bufferPercent >= 0) {
271                                                        scrubber.setBuffer(evt.bufferPercent);
272                                                }
273                                        }
274                                        break;
275                                default:
276                                        scrubber.reset();
277                                        break;
278                        }
279                }
280
281
282                private function updateVolumeSlider(evt:MediaEvent=null):void {
283                        var volume:Slider = getSlider('volume');
284                        if (volume) {
285                                if (!_player.config.mute) {
286                                        volume.setBuffer(100);
287                                        volume.setProgress(_player.config.volume);
288                                        volume.resize(getSkinElement("volumeSliderRail").width, volume.height);
289                                } else {
290                                        volume.reset();
291                                        volume.resize(getSkinElement("volumeSliderRail").width, volume.height);
292                                }
293                        }
294                }
295
296
297                private function setTime(position:Number, duration:Number):void {
298                        if (position < 0) {
299                                position = 0;
300                        }
301                        if (duration < 0) {
302                                duration = 0;
303                        }
304                        var elapsedText:TextField = getButton('elapsed') as TextField;
305                        elapsedText.text = Strings.digits(position);
306                        var durationField:TextField = getButton('duration') as TextField;
307                        durationField.text = Strings.digits(duration);
308                        redraw();
309                }
310
311
312                private function setupBackground():void {
313                        var back:DisplayObject = getSkinElement("background");
314                        var capLeft:DisplayObject = getSkinElement("capLeft");
315                        var capRight:DisplayObject = getSkinElement("capRight");
316                        //var shade:DisplayObject = getSkinElement("shade");
317
318                        if (!back) {
319                                var newBackground:Sprite = new Sprite();
320                                newBackground.name = "background";
321                                newBackground.graphics.beginFill(0, 1);
322                                newBackground.graphics.drawRect(0, 0, 1, 1);
323                                newBackground.graphics.endFill();
324                                back = newBackground as DisplayObject;
325                        }
326
327                        _buttons['background'] = back;
328                        addChild(back);
329                        _height = back.height;
330                        player.config.pluginConfig("controlbar")['size'] = back.height;
331
332                        if (capLeft) {
333                                _buttons['capLeft'] = capLeft;
334                                addChild(capLeft);
335                        }
336
337                        if (capRight) {
338                                _buttons['capRight'] = capRight;
339                                addChild(capRight);
340                        }
341
342                /*if (shade) {
343                   _buttons['shade'] = shade;
344                   addChild(shade);
345                 }*/
346                }
347
348
349                private function setupDefaultButtons():void {
350                        addComponentButton('play', ViewEvent.JWPLAYER_VIEW_PLAY);
351                        addComponentButton('pause', ViewEvent.JWPLAYER_VIEW_PAUSE);
352                        addComponentButton('prev', ViewEvent.JWPLAYER_VIEW_PREV);
353                        addComponentButton('next', ViewEvent.JWPLAYER_VIEW_NEXT);
354                        addComponentButton('stop', ViewEvent.JWPLAYER_VIEW_STOP);
355                        addComponentButton('fullscreen', ViewEvent.JWPLAYER_VIEW_FULLSCREEN, true);
356                        addComponentButton('normalscreen', ViewEvent.JWPLAYER_VIEW_FULLSCREEN, false);
357                        addComponentButton('unmute', ViewEvent.JWPLAYER_VIEW_MUTE, false);
358                        addComponentButton('mute', ViewEvent.JWPLAYER_VIEW_MUTE, true);
359                        addTextField('elapsed');
360                        addTextField('duration');
361                        addSlider('time', Slider.HORIZONTAL, ViewEvent.JWPLAYER_VIEW_CLICK, seekHandler);
362                        addSlider('volume', Slider.HORIZONTAL, ViewEvent.JWPLAYER_VIEW_CLICK, volumeHandler);
363                }
364
365
366                private function addComponentButton(name:String, event:String, eventData:*=null):void {
367                        var button:ComponentButton = new ComponentButton();
368                        button.name = name;
369                        button.setOutIcon(getSkinElement(name + "Button"));
370                        button.setOverIcon(getSkinElement(name + "ButtonOver"));
371                        button.setBackground(getSkinElement(name + "ButtonBack"));
372                        button.outColor = player.config.lightcolor;
373                        button.overColor = player.config.backcolor;
374                        button.clickFunction = function():void {
375                                forward(new ViewEvent(event, eventData));
376                        }
377                        if (getSkinElement(name + "Button") || getSkinElement(name + "ButtonOver") || getSkinElement(name + "ButtonBack")) {
378                                button.init();
379                                addButtonDisplayObject(button, name);
380                        }
381                }
382
383
384                private function addSlider(name:String, orientation:String, event:String, callback:Function):void {
385                        var slider:Slider = new Slider(getSkinElement(name + "SliderRail"), getSkinElement(name + "SliderBuffer"), getSkinElement(name + "SliderProgress"), getSkinElement(name + "SliderThumb"), orientation);
386                        slider.addEventListener(event, callback);
387                        slider.name = name;
388                        _buttons[name] = slider;
389                }
390
391
392                private function addTextField(name:String):void {
393                        var textFormat:TextFormat = new TextFormat();
394                        textFormat.font = "_sans";
395                        textFormat.size = 10;
396                        textFormat.bold = true;
397                        textFormat.color = player.config.frontcolor.color;
398                        var textField:TextField = new TextField();
399                        textField.defaultTextFormat = textFormat;
400                        textField.selectable = false;
401                        textField.autoSize = TextFieldAutoSize.LEFT;
402                        textField.name = name;
403                        addChild(textField);
404                        _buttons[name] = textField;
405                }
406
407
408                private function forward(evt:ViewEvent):void {
409                        dispatchEvent(evt);
410                }
411
412
413                private function volumeHandler(evt:ViewEvent):void {
414                        if (!_player.mute) {
415                                var volume:Number = Math.round(evt.data * 100);
416                                if (!_player.locked) {
417                                        var volumeEvent:MediaEvent = new MediaEvent(MediaEvent.JWPLAYER_MEDIA_VOLUME);
418                                        volumeEvent.volume = volume;
419                                        updateVolumeSlider(volumeEvent);
420                                }
421                                dispatchEvent(new ViewEvent(ViewEvent.JWPLAYER_VIEW_VOLUME, volume));
422                        }
423                }
424
425
426                private function seekHandler(evt:ViewEvent):void {
427                        var duration:Number = 0;
428                        try {
429                                duration = player.playlist.currentItem.duration;
430                        } catch (err:Error) {
431                        }
432                        var percent:Number = Math.round(duration * evt.data);
433                        dispatchEvent(new ViewEvent(ViewEvent.JWPLAYER_VIEW_SEEK, percent));
434                }
435
436
437                private function addButtonDisplayObject(icon:DisplayObject, name:String, handler:Function=null):MovieClip {
438                        if (icon) {
439                                var clipMC:MovieClip = new MovieClip();
440                                if (handler != null) {
441                                        clipMC.addEventListener(MouseEvent.CLICK, handler);
442                                }
443                                clipMC.name = name;
444                                clipMC.addChild(icon);
445                                _buttons[name] = clipMC;
446                                return clipMC;
447                        }
448                        return null;
449                }
450
451
452                public function addButton(icon:DisplayObject, name:String, handler:Function=null):MovieClip {
453                        _defaultLayout = _defaultLayout.replace("|blank","|blank|"+name);
454                        icon.x = icon.y = 0;
455                        var button:ComponentButton = new ComponentButton();
456                        button.name = name;
457                        var outBackground:DisplayObject = getSkinElement("blankButton");
458                        if (outBackground) {
459                                var outImage:Sprite = new Sprite();
460                                var outIcon:DisplayObject = icon;
461                                if (_player.config.frontcolor){
462                                        var outTransform:ColorTransform = new ColorTransform();
463                                        outTransform.color = _player.config.frontcolor.color;
464                                        outIcon.transform.colorTransform = outTransform;
465                                }
466                                var outOffset:Number = Math.round((outBackground.height - outIcon.height) / 2);
467                                outBackground.width = outIcon.width + 2 * outOffset;
468                                outImage.addChild(outBackground);
469                                outImage.addChild(outIcon);
470                                outIcon.x = outIcon.y = outOffset;
471                                button.setOutIcon(outImage);
472
473                                button.init();
474                                return addButtonDisplayObject(button, name, handler);
475                        }
476                        return null;
477                }
478
479
480                public function removeButton(name:String):void {
481                        _buttons[name] = null;
482                        redraw();
483                }
484
485
486                private function hideButton(name:String):void {
487                        if (_buttons[name]) {
488                                _buttons[name].visible = false;
489                        }
490                }
491
492
493                public function getButton(buttonName:String):DisplayObject {
494                        if (buttonName == "divider") {
495                                var divider:DisplayObject = getSkinElement("divider");
496                                if (divider) {
497                                        _dividers.push(divider);
498                                }
499                                return divider;
500                        }
501                        return _buttons[buttonName];
502                }
503
504
505                public function getSlider(sliderName:String):Slider {
506                        return getButton(sliderName) as Slider;
507                }
508
509
510                public function resize(width:Number, height:Number):void {
511                        if (getConfigParam('position') == "none") {
512                                visible = false;
513                                return;
514                        }
515                       
516                        _width = width;
517
518                        if (getConfigParam('position') == 'over' || _player.fullscreen == true) {
519                                x = getConfigParam('margin');
520                                y = height - background.height - getConfigParam('margin');
521                                _width = width - 2 * getConfigParam('margin');
522                        }
523
524                        //shade.width = _width;
525
526                        var backgroundWidth:Number = _width;
527
528                        backgroundWidth -= capLeft.width;
529                        capLeft.x = 0;
530
531                        backgroundWidth -= capRight.width;
532                        capRight.x = _width - capRight.width;
533
534                        background.width = backgroundWidth;
535                        background.x = capLeft.width;
536                        setChildIndex(capLeft, numChildren - 1);
537                        setChildIndex(capRight, numChildren - 1);
538
539                        stopFader();
540                        stateHandler();
541                        redraw();
542                }
543
544
545                private function redraw():void {
546                        clearDividers();
547                        _layoutManager.resize(_width, _height);
548                }
549
550
551                private function clearDividers():void {
552                        for (var i:Number = 0; i < _dividers.length; i++) {
553                                _dividers[i].visible = false;
554                                _dividers[i] = null;
555                        }
556                        _dividers = [];
557                }
558
559
560                public function get layout():String {
561                        return _currentLayout;
562                }
563
564
565                private function getFont(textField:TextField):String {
566                        var result:String;
567                        if (textField) {
568                                textField.getTextFormat().font;
569                        }
570                        return result;
571                }
572
573
574                private function get background():DisplayObject {
575                        if (_buttons['background']) {
576                                return _buttons['background'];
577                        }
578                        return (new Sprite());
579                }
580
581
582                /*private function get shade():DisplayObject {
583                   if (_buttons['shade']) {
584                   return _buttons['shade'];
585                   }
586                   return (new Sprite());
587                 }*/
588
589                private function get capLeft():DisplayObject {
590                        if (_buttons['capLeft']) {
591                                return _buttons['capLeft'];
592                        }
593                        return (new Sprite());
594                }
595
596
597                private function get capRight():DisplayObject {
598                        if (_buttons['capRight']) {
599                                return _buttons['capRight'];
600                        }
601                        return (new Sprite());
602                }
603        }
604}
Note: See TracBrowser for help on using the repository browser.