source: trunk/fl5/src/com/longtailvideo/jwplayer/view/View.as @ 979

Revision 979, 14.3 KB checked in by pablo, 3 years ago (diff)

Fixed controlbar indexes so that the buttons are ordered for accessibility as they appear visually (733)

Line 
1package com.longtailvideo.jwplayer.view {
2        import com.longtailvideo.jwplayer.events.GlobalEventDispatcher;
3        import com.longtailvideo.jwplayer.events.IGlobalEventDispatcher;
4        import com.longtailvideo.jwplayer.events.MediaEvent;
5        import com.longtailvideo.jwplayer.events.PlayerEvent;
6        import com.longtailvideo.jwplayer.events.PlayerStateEvent;
7        import com.longtailvideo.jwplayer.events.PlaylistEvent;
8        import com.longtailvideo.jwplayer.events.ViewEvent;
9        import com.longtailvideo.jwplayer.model.Model;
10        import com.longtailvideo.jwplayer.player.IPlayer;
11        import com.longtailvideo.jwplayer.player.PlayerState;
12        import com.longtailvideo.jwplayer.player.PlayerV4Emulation;
13        import com.longtailvideo.jwplayer.plugins.IPlugin;
14        import com.longtailvideo.jwplayer.plugins.PluginConfig;
15        import com.longtailvideo.jwplayer.utils.Draw;
16        import com.longtailvideo.jwplayer.utils.Logger;
17        import com.longtailvideo.jwplayer.utils.RootReference;
18        import com.longtailvideo.jwplayer.utils.Stretcher;
19        import com.longtailvideo.jwplayer.view.interfaces.IControlbarComponent;
20        import com.longtailvideo.jwplayer.view.interfaces.IDisplayComponent;
21        import com.longtailvideo.jwplayer.view.interfaces.IDockComponent;
22        import com.longtailvideo.jwplayer.view.interfaces.IPlayerComponent;
23        import com.longtailvideo.jwplayer.view.interfaces.IPlaylistComponent;
24        import com.longtailvideo.jwplayer.view.interfaces.ISkin;
25       
26        import flash.display.Bitmap;
27        import flash.display.DisplayObject;
28        import flash.display.Loader;
29        import flash.display.MovieClip;
30        import flash.display.Sprite;
31        import flash.display.Stage;
32        import flash.display.StageAlign;
33        import flash.display.StageDisplayState;
34        import flash.display.StageScaleMode;
35        import flash.events.ErrorEvent;
36        import flash.events.Event;
37        import flash.events.IOErrorEvent;
38        import flash.events.MouseEvent;
39        import flash.net.URLRequest;
40        import flash.system.LoaderContext;
41
42
43        public class View extends GlobalEventDispatcher {
44                protected var _player:IPlayer;
45                protected var _model:Model;
46                protected var _skin:ISkin;
47                protected var _components:IPlayerComponents;
48                protected var _fullscreen:Boolean = false;
49                protected var stage:Stage;
50
51                protected var _root:MovieClip;
52
53                protected var _backgroundLayer:MovieClip;
54                protected var _mediaLayer:MovieClip;
55                protected var _imageLayer:MovieClip;
56                protected var _componentsLayer:MovieClip;
57                protected var _pluginsLayer:MovieClip;
58                protected var _plugins:Object;
59
60                protected var _displayMasker:MovieClip;
61
62                protected var _image:Loader;
63                protected var _logo:Logo;
64
65                protected var layoutManager:PlayerLayoutManager;
66
67                [Embed(source="../../../../../assets/flash/loader/loader.swf")]
68                protected var LoadingScreen:Class;
69
70                [Embed(source="../../../../../assets/flash/loader/error.swf")]
71                protected var ErrorScreen:Class;
72
73                protected var loaderScreen:Sprite;
74                protected var loaderAnim:DisplayObject;
75               
76                protected var currentLayer:Number = 0;
77
78
79                public function View(player:IPlayer, model:Model) {
80                        _player = player;
81                        _model = model;
82
83                        RootReference.stage.scaleMode = StageScaleMode.NO_SCALE;
84                        RootReference.stage.stage.align = StageAlign.TOP_LEFT;
85
86                        loaderScreen = new Sprite();
87                        loaderScreen.name = 'loaderScreen';
88
89                        loaderAnim = new LoadingScreen() as DisplayObject;
90                        loaderScreen.addChild(loaderAnim);
91
92                        RootReference.stage.addChildAt(loaderScreen, 0);
93
94                        if (RootReference.stage.stageWidth > 0) {
95                                resizeStage();
96                        } else {
97                                RootReference.stage.addEventListener(Event.RESIZE, resizeStage);
98                                RootReference.stage.addEventListener(Event.ADDED_TO_STAGE, resizeStage);
99                        }
100
101                        _root = new MovieClip();
102                }
103
104
105                protected function resizeStage(evt:Event=null):void {
106                        RootReference.stage.removeEventListener(Event.RESIZE, resizeStage);
107                        RootReference.stage.removeEventListener(Event.ADDED_TO_STAGE, resizeStage);
108
109                        loaderScreen.graphics.clear();
110                        loaderScreen.graphics.beginFill(0, 1);
111                        loaderScreen.graphics.drawRect(0, 0, RootReference.stage.stageWidth, RootReference.stage.stageHeight);
112                        loaderScreen.graphics.endFill();
113
114                        loaderAnim.x = (RootReference.stage.stageWidth - loaderAnim.width) / 2;
115                        loaderAnim.y = (RootReference.stage.stageHeight - loaderAnim.height) / 2;
116                }
117
118
119                public function get skin():ISkin {
120                        return _skin;
121                }
122
123
124                public function set skin(skn:ISkin):void {
125                        _skin = skn;
126                }
127
128
129                public function setupView():void {
130                        RootReference.stage.addChildAt(_root, 0);
131                        _root.visible = false;
132
133                        setupLayers();
134                        setupComponents();
135
136                        RootReference.stage.addEventListener(Event.RESIZE, resizeHandler);
137
138                        _model.addEventListener(MediaEvent.JWPLAYER_MEDIA_LOADED, mediaLoaded);
139                        _model.playlist.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM, itemHandler);
140                        //_model.playlist.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_LOADED, itemHandler);
141                        _model.playlist.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_UPDATED, itemHandler);
142                        _model.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE, stateHandler);
143
144                        layoutManager = new PlayerLayoutManager(_player);
145                        setupRightClick();
146
147                        redraw();
148                }
149               
150                protected function setupRightClick():void {
151                        var menu:RightclickMenu = new RightclickMenu(_player, _root);
152                        menu.addGlobalListener(forward);
153                }
154
155                public function completeView(isError:Boolean=false, errorMsg:String=""):void {
156                        if (!isError) {
157                                _root.visible = true;
158                                loaderScreen.parent.removeChild(loaderScreen);
159                        } else {
160                                loaderScreen.removeChild(loaderAnim);
161                                var errorScreen:DisplayObject = new ErrorScreen() as DisplayObject;
162                                errorScreen.x = (loaderScreen.width - errorScreen.width) / 2;
163                                errorScreen.y = (loaderScreen.height - errorScreen.height) / 2;
164                                loaderScreen.addChild(errorScreen);
165                        }
166                }
167
168
169                protected function setupLayers():void {
170                        _backgroundLayer = setupLayer("background", currentLayer++);
171                        setupBackground();
172
173                        _mediaLayer = setupLayer("media", currentLayer++);
174                        _mediaLayer.visible = false;
175
176                        _imageLayer = setupLayer("image", currentLayer++);
177                        _image = new Loader();
178                        _image.contentLoaderInfo.addEventListener(Event.COMPLETE, imageComplete);
179                        _image.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, imageError);
180
181                        setupLogo();
182
183                        _componentsLayer = setupLayer("components", currentLayer++);
184
185                        _pluginsLayer = setupLayer("plugins", currentLayer++);
186                        _plugins = {};
187                       
188                }
189                       
190                protected function setupLogo():void {
191                        _logo = new Logo(_player);
192                }
193
194
195                protected function setupLayer(name:String, index:Number):MovieClip {
196                        var layer:MovieClip = new MovieClip();
197                        _root.addChildAt(layer, index);
198                        layer.name = name;
199                        layer.x = 0;
200                        layer.y = 0;
201                        return layer;
202                }
203
204
205                protected function setupBackground():void {
206                        var background:MovieClip = new MovieClip();
207                        background.name = "background";
208                        _backgroundLayer.addChild(background);
209                        background.graphics.beginFill(_player.config.screencolor ? _player.config.screencolor.color : 0x000000, 1);
210                        background.graphics.drawRect(0, 0, 1, 1);
211                        background.graphics.endFill();
212                }
213
214
215                protected function setupDisplayMask():void {
216                        _displayMasker = new MovieClip();
217                        _displayMasker.graphics.beginFill(0x000000, 1);
218                        _displayMasker.graphics.drawRect(0, 0, _player.config.width, _player.config.height);
219                        _displayMasker.graphics.endFill();
220
221                        _backgroundLayer.mask = _displayMasker;
222                        _imageLayer.mask = _displayMasker;
223                        _mediaLayer.mask = _displayMasker;
224                }
225
226
227                protected function setupComponents():void {
228                        var n:Number = 0;
229                       
230                        _components = new PlayerComponents(_player);
231
232                        setupComponent(_components.display, n++);
233                        setupComponent(_components.playlist, n++);
234                        setupComponent(_logo, n++);
235                        setupComponent(_components.controlbar, n++);
236                        setupComponent(_components.dock, n++);
237                }
238
239
240                protected function setupComponent(component:*, index:Number):void {
241                        if (component is IGlobalEventDispatcher) { (component as IGlobalEventDispatcher).addGlobalListener(forward); }
242                        if (component is DisplayObject) { _componentsLayer.addChildAt(component as DisplayObject, index); }
243                }
244
245
246                protected function resizeHandler(event:Event):void {
247                        var currentFSMode:Boolean = (RootReference.stage.displayState == StageDisplayState.FULL_SCREEN);
248                        if (_model.fullscreen != currentFSMode) {
249                                dispatchEvent(new ViewEvent(ViewEvent.JWPLAYER_VIEW_FULLSCREEN, currentFSMode));
250                        }
251
252                        redraw();
253                }
254
255
256                public function fullscreen(mode:Boolean=true):void {
257                        try {
258                                RootReference.stage.displayState = mode ? StageDisplayState.FULL_SCREEN : StageDisplayState.NORMAL;
259                        } catch (e:Error) {
260                                Logger.log("Could not enter fullscreen mode: " + e.message);
261                        }
262                }
263
264
265                /** Redraws the plugins and player components **/
266                public function redraw():void {
267                        layoutManager.resize(RootReference.stage.stageWidth, RootReference.stage.stageHeight);
268
269                        _components.resize(_player.config.width, _player.config.height);
270
271                        resizeBackground();
272                        resizeMasker();
273
274                        if (_imageLayer.numChildren) {
275                                _imageLayer.x = _components.display.x;
276                                _imageLayer.y = _components.display.y;
277                                Stretcher.stretch(_image, _player.config.width, _player.config.height, _player.config.stretching);
278                        }
279
280                        if (_mediaLayer.numChildren && _model.media.display) {
281                                _mediaLayer.x = _components.display.x;
282                                _mediaLayer.y = _components.display.y;
283                                _model.media.resize(_player.config.width, _player.config.height);
284                        }
285
286                        if (_logo) {
287                                _logo.x = _components.display.x;
288                                _logo.y = _components.display.y;
289                                _logo.resize(_player.config.width, _player.config.height);
290                        }
291
292                        for (var i:Number = 0; i < _pluginsLayer.numChildren; i++) {
293                                var plug:IPlugin = _pluginsLayer.getChildAt(i) as IPlugin;
294                                var plugDisplay:DisplayObject = plug as DisplayObject;
295                                if (plug && plugDisplay) {
296                                        var cfg:PluginConfig = _player.config.pluginConfig(plug.id);
297                                        if (cfg['visible']) {
298                                                plugDisplay.visible = true;
299                                                plugDisplay.x = cfg['x'];
300                                                plugDisplay.y = cfg['y'];
301                                                try {
302                                                        plug.resize(cfg.width, cfg.height);
303                                                } catch (e:Error) {
304                                                        Logger.log("There was an error resizing plugin '" + plug.id + "': " + e.message);
305                                                }
306                                        } else {
307                                                plugDisplay.visible = false;
308                                        }
309                                }
310                        }
311
312                        PlayerV4Emulation.getInstance(_player).resize(_player.config.width, _player.config.height);
313                }
314
315
316                protected function resizeBackground():void {
317                        var bg:DisplayObject = _backgroundLayer.getChildByName("background");
318                        bg.width = RootReference.stage.stageWidth;
319                        bg.height = RootReference.stage.stageHeight;
320                        bg.x = 0;
321                        bg.y = 0;
322                }
323
324
325                protected function resizeMasker():void {
326                        if (_displayMasker == null)
327                                setupDisplayMask();
328
329                        _displayMasker.graphics.clear();
330                        _displayMasker.graphics.beginFill(0, 1);
331                        _displayMasker.graphics.drawRect(_components.display.x, _components.display.y, _player.config.width, _player.config.height);
332                        _displayMasker.graphics.endFill();
333                }
334
335
336                public function get components():IPlayerComponents {
337                        return _components;
338                }
339
340                /** This feature, while not yet implemented, will allow the API to replace the built-in components with any class that implements the control interfaces. **/
341                public function overrideComponent(newComponent:IPlayerComponent):void {
342                        if (newComponent is IControlbarComponent) {
343                                // Replace controlbar
344                        } else if (newComponent is IDisplayComponent) {
345                                // Replace display
346                        } else if (newComponent is IDockComponent) {
347                                // Replace dock
348                        } else if (newComponent is IPlaylistComponent) {
349                                // Replace playlist
350                        } else {
351                                dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, "Component must implement a component interface"));
352                        }
353                }
354
355
356                public function addPlugin(id:String, plugin:IPlugin):void {
357                        try {
358                                var plugDO:DisplayObject = plugin as DisplayObject;
359                                if (!_plugins[id] && plugDO != null) {
360                                        _plugins[id] = plugDO;
361                                        _pluginsLayer.addChild(plugDO);
362                                }
363                        } catch (e:Error) {
364                                dispatchEvent(new ErrorEvent(ErrorEvent.ERROR, false, false, e.message));
365                        }
366                }
367
368
369                public function removePlugin(plugin:IPlugin):void {
370                        var id:String = plugin.id.toLowerCase();
371                        if (id && _plugins[id] is IPlugin) {
372                                _pluginsLayer.removeChild(_plugins[id]);
373                                delete _plugins[id];
374                        }
375                }
376
377
378                public function loadedPlugins():Array {
379                        var list:Array = [];
380                        for (var pluginId:String in _plugins) {
381                                if (_plugins[pluginId] is IPlugin) {
382                                        list.push(pluginId);
383                                }
384                        }
385                        return list;
386                }
387
388
389                public function getPlugin(id:String):IPlugin {
390                        return _plugins[id] as IPlugin;
391                }
392
393
394                public function bringPluginToFront(id:String):void {
395                        var plugin:IPlugin = getPlugin(id);
396                        _pluginsLayer.setChildIndex(plugin as DisplayObject, _pluginsLayer.numChildren - 1);
397                }
398
399
400                protected function mediaLoaded(evt:MediaEvent):void {
401                        _mediaLayer.x = _components.display.x;
402                        _mediaLayer.y = _components.display.y;
403                        if (_model.media.display) {
404                                _model.media.resize(_player.config.width, _player.config.height);
405                                _mediaLayer.addChild(_model.media.display);
406                        }
407                }
408
409
410                protected function itemHandler(evt:PlaylistEvent):void {
411                        while (_mediaLayer.numChildren) {
412                                _mediaLayer.removeChildAt(0);
413                        }
414                        while (_imageLayer.numChildren) {
415                                _imageLayer.removeChildAt(0);
416                        }
417                        if (_model.playlist.currentItem && _model.playlist.currentItem.image) {
418                                loadImage(_model.playlist.currentItem.image);
419                        }
420                }
421
422
423                protected function loadImage(url:String):void {
424                        _image.load(new URLRequest(url), new LoaderContext(true));
425                }
426
427
428                protected function imageComplete(evt:Event):void {
429                        if (_image) {
430                                _imageLayer.addChild(_image);
431                                _imageLayer.x = _components.display.x;
432                                _imageLayer.y = _components.display.y;
433                                Stretcher.stretch(_image, _player.config.width, _player.config.height, _player.config.stretching);
434                                try {
435                                        Draw.smooth(_image.content as Bitmap);
436                                } catch (e:Error) {
437                                        Logger.log('Could not smooth preview image: ' + e.message);
438                                }
439                        }
440                }
441
442
443                protected function imageError(evt:ErrorEvent):void {
444                        Logger.log('Error loading preview image: '+evt.text);
445                }
446
447
448                protected function stateHandler(evt:PlayerStateEvent):void {
449                        switch (evt.newstate) {
450                                case PlayerState.IDLE:
451                                        _imageLayer.visible = true;
452                                        _mediaLayer.visible = false;
453                                        if (_logo) _logo.visible = false;
454                                        break;
455                                case PlayerState.PLAYING:
456                                        _mediaLayer.visible = true;
457                                        if (_model.media.display) {
458                                                _imageLayer.visible = false;
459                                        }
460                                        if (_logo) _logo.visible = true;
461                                        break;
462                                case PlayerState.BUFFERING:
463                                        if (_logo) _logo.visible = true;
464                                        break;
465                        }
466                }
467
468
469                protected function forward(evt:Event):void {
470                        if (evt is PlayerEvent)
471                                dispatchEvent(evt);
472                }
473        }
474}
Note: See TracBrowser for help on using the repository browser.