source: trunk/fl5/src/com/longtailvideo/jwplayer/view/components/PlaylistComponent.as @ 455

Revision 455, 13.0 KB checked in by pablo, 4 years ago (diff)

Playlist over state / fullscreen fix
PlaylistEvent.ITEM triggers play regardless of player state

Line 
1package com.longtailvideo.jwplayer.view.components {
2        import com.longtailvideo.jwplayer.events.PlayerStateEvent;
3        import com.longtailvideo.jwplayer.events.PlaylistEvent;
4        import com.longtailvideo.jwplayer.model.PlaylistItem;
5        import com.longtailvideo.jwplayer.player.Player;
6        import com.longtailvideo.jwplayer.player.PlayerState;
7        import com.longtailvideo.jwplayer.plugins.PluginConfig;
8        import com.longtailvideo.jwplayer.utils.Draw;
9        import com.longtailvideo.jwplayer.utils.Stacker;
10        import com.longtailvideo.jwplayer.utils.Stretcher;
11        import com.longtailvideo.jwplayer.utils.Strings;
12        import com.longtailvideo.jwplayer.view.PlayerLayoutManager;
13        import com.longtailvideo.jwplayer.view.interfaces.IPlaylistComponent;
14       
15        import flash.display.DisplayObject;
16        import flash.display.Loader;
17        import flash.display.MovieClip;
18        import flash.display.Sprite;
19        import flash.events.Event;
20        import flash.events.MouseEvent;
21        import flash.geom.ColorTransform;
22        import flash.net.URLRequest;
23        import flash.utils.clearInterval;
24        import flash.utils.setInterval;
25       
26       
27        public class PlaylistComponent extends CoreComponent implements IPlaylistComponent {
28                /** Reference to the playlist MC. **/
29                public var clip:MovieClip;
30                /** Array with all button instances **/
31                private var buttons:Array;
32                /** Height of a button (to calculate scrolling) **/
33                private var buttonheight:Number;
34                /** Currently active button. **/
35                private var active:Number;
36                /** Proportion between clip and mask. **/
37                private var proportion:Number;
38                /** Interval ID for scrolling **/
39                private var scrollInterval:Number;
40                /** Image dimensions. **/
41                private var image:Array;
42                /** Color object for backcolor. **/
43                private var back:ColorTransform;
44                /** Color object for frontcolor. **/
45                private var front:ColorTransform;
46                /** Color object for lightcolor. **/
47                private var light:ColorTransform;
48               
49               
50                public function PlaylistComponent(player:Player) {
51                        super(player);
52                        player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM, itemHandler);
53                        player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_LOADED, playlistHandler);
54                        player.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_UPDATED, playlistHandler);
55                        player.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE, stateHandler);
56                        clip = _player.skin.getSWFSkin().getChildByName("playlist") as MovieClip;
57                        addChild(clip);
58                        buttonheight = clip.list.button.height;
59                        clip.list.button.visible = false;
60                        clip.list.mask = clip.masker;
61                        clip.list.addEventListener(MouseEvent.CLICK, clickHandler);
62                        clip.list.addEventListener(MouseEvent.MOUSE_OVER, overHandler);
63                        clip.list.addEventListener(MouseEvent.MOUSE_OUT, outHandler);
64                        clip.slider.buttonMode = true;
65                        clip.slider.mouseChildren = false;
66                        clip.slider.addEventListener(MouseEvent.MOUSE_DOWN, sdownHandler);
67                        clip.slider.addEventListener(MouseEvent.MOUSE_OVER, soverHandler);
68                        clip.slider.addEventListener(MouseEvent.MOUSE_OUT, soutHandler);
69                        clip.slider.visible = false;
70                        buttons = new Array();
71                        try {
72                                image = new Array(clip.list.button.image.width, clip.list.button.image.height);
73                        } catch (err:Error) {
74                        }
75                        if (clip.list.button['back']) {
76                                setColors();
77                        }
78                        playlistHandler();
79                }
80               
81               
82                /** Handle a button rollover. **/
83                private function overHandler(evt:MouseEvent):void {
84                        var idx:Number = Number(evt.target.name);
85                        if (front && back) {
86                                for (var itm:String in _player.playlist.getItemAt(idx)) {
87                                        if (buttons[idx].c[itm] && typeof(buttons[idx].c[itm]) == "object") {
88                                                buttons[idx].c[itm].textColor = back.color;
89                                        }
90                                }
91                                buttons[idx].c['back'].transform.colorTransform = light;
92                        }
93                        buttons[idx].c.gotoAndStop('over');
94                };
95               
96               
97                /** Handle a button rollover. **/
98                private function outHandler(evt:MouseEvent):void {
99                        var idx:Number = Number(evt.target.name);
100                        if (front && back) {
101                                for (var itm:String in _player.playlist.getItemAt(idx)) {
102                                        if (buttons[idx].c[itm] && typeof(buttons[idx].c[itm]) == "object") {
103                                                if (idx == active) {
104                                                        buttons[idx].c[itm].textColor = light.color;
105                                                } else {
106                                                        buttons[idx].c[itm].textColor = front.color;
107                                                }
108                                        }
109                                }
110                                buttons[idx].c['back'].transform.colorTransform = back;
111                        }
112                        if (idx == active) {
113                                buttons[idx].c.gotoAndStop('active');
114                        } else {
115                                buttons[idx].c.gotoAndStop('out');
116                        }
117                };
118               
119               
120                /** Setup all buttons in the playlist **/
121                private function buildPlaylist(clr:Boolean):void {
122                        if (!_player.playlist) {
123                                return;
124                        }
125                        var wid:Number = clip.back.width;
126                        var hei:Number = clip.back.height;
127                        clip.masker.height = hei;
128                        clip.masker.width = wid;
129                        proportion = _player.playlist.length * buttonheight / hei;
130                        if (proportion > 1.01) {
131                                wid -= clip.slider.width;
132                                buildSlider();
133                        } else {
134                                clip.slider.visible = false;
135                        }
136                        if (clr) {
137                                clip.list.y = clip.masker.y;
138                                for (var j:Number = 0; j < buttons.length; j++) {
139                                        clip.list.removeChild(buttons[j].c);
140                                }
141                                buttons = new Array();
142                        } else {
143                                if (proportion > 1) {
144                                        scrollEase();
145                                }
146                        }
147                        for (var i:Number = 0; i < _player.playlist.length; i++) {
148                                if (clr) {
149                                        var btn:MovieClip = Draw.clone(clip.list.button, true) as MovieClip;
150                                        var stc:Stacker = new Stacker(btn);
151                                        btn.y = i * buttonheight;
152                                        btn.buttonMode = true;
153                                        btn.mouseChildren = false;
154                                        btn.name = i.toString();
155                                        buttons.push({c: btn, s: stc});
156                                        setContents(i);
157                                }
158                                buttons[i].s.rearrange(wid);
159                        }
160                }
161               
162               
163                /** Setup the scrollbar component **/
164                private function buildSlider():void {
165                        var scr:MovieClip = clip.slider;
166                        scr.visible = true;
167                        scr.x = clip.back.width - scr.width;
168                        var dif:Number = clip.back.height - scr.height - scr.y;
169                        scr.back.height += dif;
170                        scr.rail.height += dif;
171                        scr.icon.height = Math.round(scr.rail.height / proportion);
172                }
173               
174               
175                /** Make sure the playlist is not out of range. **/
176                private function scrollEase(ips:Number = -1, cps:Number = -1):void {
177                        var scr:MovieClip = clip.slider;
178                        if (ips != -1) {
179                                scr.icon.y = Math.round(ips - (ips - scr.icon.y) / 1.5);
180                                clip.list.y = Math.round((cps - (cps - clip.list.y) / 1.5));
181                        }
182                        if (clip.list.y > 0 || scr.icon.y < scr.rail.y) {
183                                clip.list.y = clip.masker.y;
184                                scr.icon.y = scr.rail.y;
185                        } else if (clip.list.y < clip.masker.height - clip.list.height || scr.icon.y > scr.rail.y + scr.rail.height - scr.icon.height) {
186                                scr.icon.y = scr.rail.y + scr.rail.height - scr.icon.height;
187                                clip.list.y = clip.masker.y + clip.masker.height - clip.list.height;
188                        }
189                };
190               
191               
192                /** Scrolling handler. **/
193                private function scrollHandler():void {
194                        var scr:MovieClip = clip.slider;
195                        var yps:Number = scr.mouseY - scr.rail.y;
196                        var ips:Number = yps - scr.icon.height / 2;
197                        var cps:Number = clip.masker.y + clip.masker.height / 2 - proportion * yps;
198                        scrollEase(ips, cps);
199                };
200               
201               
202                /** Init the colors. **/
203                private function setColors():void {
204                        if (_player.config.backcolor) {
205                                back = new ColorTransform();
206                                back.color = _player.config.backcolor;
207                                clip.back.transform.colorTransform = back;
208                                clip.slider.back.transform.colorTransform = back;
209                        }
210                        if (_player.config.frontcolor) {
211                                front = new ColorTransform();
212                                front.color = _player.config.frontcolor;
213                                try {
214                                        clip.slider.icon.transform.colorTransform = front;
215                                        clip.slider.rail.transform.colorTransform = front;
216                                } catch (err:Error) {
217                                }
218                                if (_player.config.lightcolor) {
219                                        light = new ColorTransform();
220                                        light.color = _player.config.lightcolor;
221                                } else {
222                                        light = front;
223                                }
224                        }
225                };
226               
227               
228                /** Setup button elements **/
229                private function setContents(idx:Number):void {
230                        var playlistItem:PlaylistItem = _player.playlist.getItemAt(idx);
231                        buttons[idx].c.gotoAndStop(0);
232                        if (playlistItem.image) {
233                                if (config['thumbs'] != false && _player.config.playlist != 'none' && _player.playlist.getItemAt(idx).image) {
234                                        var img:MovieClip = buttons[idx].c.image;
235                                        var msk:Sprite = Draw.rect(buttons[idx].c, '0xFF0000', img.width, img.height, img.x, img.y);
236                                        var ldr:Loader = new Loader();
237                                        img.mask = msk;
238                                        img.addChild(ldr);
239                                        ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderHandler);
240                                        if (_player.playlist.getItemAt(idx).image) {
241                                                ldr.load(new URLRequest(_player.playlist.getItemAt(idx).image));
242                                        }
243                                }
244                        }
245                        if (playlistItem.duration) {
246                                if (_player.playlist.getItemAt(idx).duration > 0) {
247                                        buttons[idx].c['duration'].text = Strings.digits(_player.playlist.getItemAt(idx).duration);
248                                        if (front) {
249                                                buttons[idx].c['duration'].textColor = front.color;
250                                        }
251                                }
252                        }
253                        try {
254                                if (playlistItem.description) {
255                                        buttons[idx].c['description'].htmlText = _player.playlist.getItemAt(idx).description;
256                                } else {
257                                        buttons[idx].c['description'].text = _player.playlist.getItemAt(idx).description;
258                                }
259                                if (front) {
260                                        buttons[idx].c['description'].textColor = front.color;
261                                }
262                        } catch (e:Error) {
263                        }
264                        if (buttons[idx].c['image'] && (!_player.playlist.getItemAt(idx).image || config['thumbs'] == false)) {
265                                buttons[idx].c['image'].visible = false;
266                        }
267                        if (back) {
268                                buttons[idx].c['back'].transform.colorTransform = back;
269                        }
270                };
271               
272               
273                /** Loading of image completed; resume loading **/
274                private function loaderHandler(evt:Event):void {
275                        var ldr:Loader = Loader(evt.target.loader);
276                        Stretcher.stretch(ldr, image[0], image[1], Stretcher.FILL);
277                };
278               
279               
280                /** Start scrolling the playlist on mousedown. **/
281                private function sdownHandler(evt:MouseEvent):void {
282                        clearInterval(scrollInterval);
283                        clip.stage.addEventListener(MouseEvent.MOUSE_UP, supHandler);
284                        scrollHandler();
285                        scrollInterval = setInterval(scrollHandler, 50);
286                };
287               
288               
289                /** Revert the highlight on mouseout. **/
290                private function soutHandler(evt:MouseEvent):void {
291                        if (front) {
292                                clip.slider.icon.transform.colorTransform = front;
293                        } else {
294                                clip.slider.icon.gotoAndStop('out');
295                        }
296                };
297               
298               
299                /** Highlight the icon on rollover. **/
300                private function soverHandler(evt:MouseEvent):void {
301                        if (front) {
302                                clip.slider.icon.transform.colorTransform = light;
303                        } else {
304                                clip.slider.icon.gotoAndStop('over');
305                        }
306                };
307               
308               
309                /** Stop scrolling the playlist on mouseout. **/
310                private function supHandler(evt:MouseEvent):void {
311                        clearInterval(scrollInterval);
312                        clip.stage.removeEventListener(MouseEvent.MOUSE_UP, supHandler);
313                };
314               
315               
316                /** Handle a click on a button. **/
317                private function clickHandler(evt:MouseEvent):void {
318                        _player.playlistItem(Number(evt.target.name));
319                }
320               
321               
322                /** Process resizing requests **/
323                public function resize(width:Number, height:Number):void {
324                        clip.x = 0;
325                        clip.y = 0;
326                        clip.back.width = width;
327                        clip.back.height =  height;
328                        buildPlaylist(false);
329                        if (config['position'] == 'over') {
330                                stateHandler();
331                        } else if (PlayerLayoutManager.testPosition(config['position'])) {
332                                clip.visible = true;
333                        } else {
334                                clip.visible = false;
335                        }
336                }
337               
338               
339                /** Switch the currently active item */
340                protected function itemHandler(evt:PlaylistEvent = null):void {
341                        var idx:Number = _player.config.item;
342                        clearInterval(scrollInterval);
343                        if (proportion > 1.01) {
344                                scrollInterval = setInterval(scrollEase, 50, idx * buttonheight / proportion, -idx * buttonheight + clip.masker.y);
345                        }
346                        if (light) {
347                                for (var itm:String in _player.playlist.getItemAt(idx)) {
348                                        if (buttons[idx].c[itm]) {
349                                                try {
350                                                        buttons[idx].c[itm].textColor = light.color;
351                                                } catch (err:Error) {
352                                                }
353                                        }
354                                }
355                        }
356                        if (back) {
357                                buttons[idx].c['back'].transform.colorTransform = back;
358                        }
359                        buttons[idx].c.gotoAndStop('active');
360                        if (!isNaN(active)) {
361                                if (front) {
362                                        for (var act:String in _player.playlist.getItemAt(active)) {
363                                                if (buttons[active].c[act]) {
364                                                        try {
365                                                                buttons[active].c[act].textColor = front.color;
366                                                        } catch (err:Error) {
367                                                        }
368                                                }
369                                        }
370                                }
371                                buttons[active].c.gotoAndStop('out');
372                        }
373                        active = idx;
374                }
375               
376               
377                /** New playlist loaded: rebuild the playclip. **/
378                protected function playlistHandler(evt:PlaylistEvent = null):void {
379                        clearInterval(scrollInterval);
380                        active = undefined;
381                        buildPlaylist(true);
382                        resize(width, height);
383                }
384               
385               
386                /** Process state changes **/
387                protected function stateHandler(evt:PlayerStateEvent = null):void {
388                        if (config['position'] == 'over') {
389                                if (player.state == PlayerState.PLAYING || player.state == PlayerState.PAUSED || player.state == PlayerState.BUFFERING) {
390                                        visible = false;
391                                } else {
392                                        visible = true;
393                                }
394                        }
395                }
396               
397               
398                protected function get config():PluginConfig {
399                        return player.config.pluginConfig('playlist');
400                }
401               
402               
403                protected function getSkinElement(component:String, element:String):DisplayObject {
404                        return _player.skin.getSkinElement(component, element);
405                }
406        }
407}
Note: See TracBrowser for help on using the repository browser.