source: trunk/as3/com/jeroenwijering/player/Controller.as @ 13

Revision 13, 9.7 KB checked in by jeroen, 5 years ago (diff)

various small bugfixes 4.0

  • Property svn:executable set to *
Line 
1/**
2* Process all input from the views and modifies the model.
3**/
4package com.jeroenwijering.player {
5
6
7import com.jeroenwijering.events.*;
8import com.jeroenwijering.player.*;
9import com.jeroenwijering.utils.*;
10import flash.display.MovieClip;
11import flash.events.*;
12import flash.geom.Rectangle;
13import flash.net.*;
14import flash.system.Capabilities;
15
16
17public class Controller extends EventDispatcher {
18
19
20        /** Configuration object **/
21        private var config:Object;
22        /** Reference to the skin; for stage event subscription. **/
23        private var skin:MovieClip;
24        /** Object that manages the playlist. **/
25        private var playlister:Playlister;
26        /** Reference to the player's model. **/
27        private var model:Model;
28        /** Reference to the player's view. **/
29        private var view:View;
30        /** object that provides randomization. **/
31        private var randomizer:Randomizer;
32
33
34        /** Constructor, set up stage and playlist listeners. **/
35        public function Controller(cfg:Object,skn:MovieClip) {
36                config = cfg;
37                skin = skn;
38                skin.stage.scaleMode = "noScale";
39                skin.stage.align = "TL";
40                skin.stage.addEventListener(Event.RESIZE,resizeHandler);
41                playlister = new Playlister();
42                playlister.addEventListener(Event.COMPLETE,playlistHandler);
43                playlister.addEventListener(ErrorEvent.ERROR,errorHandler);
44        };
45
46
47        /** Register view and model with controller, start loading playlist. **/
48        public function start(mdl:Model,vie:View) {
49                model= mdl;
50                model.addEventListener(ModelEvent.META,metaHandler);
51                model.addEventListener(ModelEvent.TIME,metaHandler);
52                model.addEventListener(ModelEvent.STATE,stateHandler);
53                view = vie;
54                view.addEventListener(ViewEvent.CAPTION,captionHandler);
55                view.addEventListener(ViewEvent.FULLSCREEN,fullscreenHandler);
56                view.addEventListener(ViewEvent.ITEM,itemHandler);
57                view.addEventListener(ViewEvent.LINK,linkHandler);
58                view.addEventListener(ViewEvent.LOAD,loadHandler);
59                view.addEventListener(ViewEvent.MUTE,muteHandler);
60                view.addEventListener(ViewEvent.NEXT,nextHandler);
61                view.addEventListener(ViewEvent.PLAY,playHandler);
62                view.addEventListener(ViewEvent.PREV,prevHandler);
63                view.addEventListener(ViewEvent.QUALITY,qualityHandler);
64                view.addEventListener(ViewEvent.SEEK,seekHandler);
65                view.addEventListener(ViewEvent.STOP,stopHandler);
66                view.addEventListener(ViewEvent.VOLUME,volumeHandler);
67                resizeHandler(new Event(Event.RESIZE));
68                if(config['file']) { playlister.load(config); }
69        };
70
71
72        /** Save new state of the dub/caption switches. **/
73        private function captionHandler(evt:ViewEvent) {
74                if(evt.data.state && evt.data.state != config['caption']) {
75                        config['caption'] = evt.data.state;
76                } else {
77                        config['caption'] = !config['caption'];
78                }
79                Configger.saveCookie('caption',config['caption']);
80                dispatchEvent(new ControllerEvent(ControllerEvent.CAPTION,{state:config['caption']}));
81        };
82
83
84        /** Catch errors dispatched by the playlister. **/
85        private function errorHandler(evt:ErrorEvent) {
86                dispatchEvent(new ControllerEvent(ControllerEvent.ERROR,{message:evt.text}));
87        };
88
89
90        /** Switch fullscreen state. **/
91        private function fullscreenHandler(evt:ViewEvent) {
92                if(skin.stage.displayState == 'fullScreen') {
93                        skin.stage.displayState = 'normal';
94                } else {
95                        skin.stage["fullScreenSourceRect"] = new Rectangle(0,0,
96                                Capabilities.screenResolutionX/2,Capabilities.screenResolutionY/2);
97                        skin.stage.displayState = 'fullScreen';
98                }
99        };
100
101
102        /** Jump to a userdefined item in the playlist. **/
103        private function itemHandler(evt:ViewEvent) {
104                if(playlist[config['item']]['author'] == 'commercial') { return; }
105                var itm = evt.data.index;
106                if (itm < 0) {
107                        playItem(0);
108                } else if (itm > playlist.length-1) {
109                        playItem(playlist.length-1);
110                } else if (!isNaN(itm)) {
111                        playItem(itm);
112                }
113        };
114
115
116        /** Jump to the link of a playlistitem. **/
117        private function linkHandler(evt:ViewEvent) {
118                var itm = evt.data.index;
119                if (itm  == undefined) {
120                        itm = config['item'];
121                }
122                var lnk = playlist[itm]['link'];
123                if(lnk != undefined) {
124                        navigateToURL(new URLRequest(lnk),config['linktarget']);
125                }
126        };
127
128
129        /** Load a new playlist. **/
130        private function loadHandler(evt:ViewEvent) {
131                try {
132                        playlister.load(evt.data.object);
133                } catch (err:Error) {
134                        dispatchEvent(new ControllerEvent(ControllerEvent.ERROR,{message:err.message}));
135                }
136        };
137
138
139
140        /** Update playlist item duration. **/
141        private function metaHandler(evt:ModelEvent) {
142                if(evt.data.duration) {
143                        var dur = Math.round(evt.data.duration*10)/10
144                        playlister.update(config['item'],'duration',dur);
145                }
146        };
147
148
149        /** Save new state of the mute switch and send volume. **/
150        private function muteHandler(evt:ViewEvent) {
151                if(evt.data.state) {
152                        if(evt.data.state == config['mute']) {
153                                return;
154                        } else {
155                                config['mute'] = evt.data.state;
156                        }
157                } else {
158                        config['mute'] = !config['mute'];
159                }
160                Configger.saveCookie('mute',config['mute']);
161                dispatchEvent(new ControllerEvent(ControllerEvent.MUTE,{state:config['mute']}));
162        };
163
164
165        /** Jump to the next item in the playlist. **/
166        private function nextHandler(evt:ViewEvent) {
167                if(playlist[config['item']]['author'] == 'commercial') { return; }
168                if(config['shuffle'] == true) {
169                        playItem(randomizer.pick());
170                } else if (config['item'] == playlist.length-1) {
171                        playItem(0);
172                } else {
173                        playItem(config['item']+1);
174                }
175        };
176
177
178        /** Change the playback state. **/
179        private function playHandler(evt:ViewEvent) {
180                if(evt.data.state != false && config['state'] == ModelStates.PAUSED) {
181                        dispatchEvent(new ControllerEvent(ControllerEvent.PLAY,{state:true}));
182                } else if (evt.data.state != false && config['state'] == ModelStates.COMPLETED) {
183                        dispatchEvent(new ControllerEvent(ControllerEvent.SEEK,{position:playlist[config['item']]['start']}));
184                } else if(evt.data.state != false && config['state'] == ModelStates.IDLE) {
185                        playItem();
186                } else if (evt.data.state != true && (config['state'] == ModelStates.PLAYING || config['state'] == ModelStates.BUFFERING)) {
187                        dispatchEvent(new ControllerEvent(ControllerEvent.PLAY,{state:false}));
188                }
189        };
190
191
192        /** Direct the model to play a new item. **/
193        private function playItem(nbr:Number=undefined) {
194                if(nbr > -1) {
195                        if(playlist[nbr]['file'] == playlist[config['item']]['file']) {
196                                playlist[nbr]['duration'] = playlist[config['item']]['duration'];
197                        }
198                        config['item'] = nbr;
199                }
200                dispatchEvent(new ControllerEvent(ControllerEvent.ITEM,{index:config['item']}));
201        };
202
203
204        /** Manage loading of a new playlist. **/
205        private function playlistHandler(evt:Event) {
206                dispatchEvent(new ControllerEvent(ControllerEvent.PLAYLIST,{playlist:playlist}));
207                if(config['shuffle'] == true) {
208                        randomizer = new Randomizer(playlist.length);
209                        config['item'] = randomizer.pick();
210                }
211                if(config['autostart'] == true) {
212                        playItem();
213                }
214        };
215
216
217        /** Jump to the previous item in the playlist. **/
218        private function prevHandler(evt:ViewEvent) {
219                if(playlist[config['item']]['author'] == 'commercial') { return; }
220                if (config['item'] == 0) {
221                        playItem(playlist.length-1);
222                } else {
223                        playItem(config['item']-1);
224                }
225        };
226
227
228        /** Switch playback quality. **/
229        private function qualityHandler(evt:ViewEvent) {
230                if(evt.data.state && evt.data.state != config['quality']) {
231                        config['quality'] = evt.data.state;
232                } else {
233                        config['quality'] = !config['quality'];
234                }
235                Configger.saveCookie('quality',config['quality']);
236                dispatchEvent(new ControllerEvent(ControllerEvent.QUALITY,{state:config['quality']}));
237        };
238
239
240        /** Forward a resizing of the stage. **/
241        private function resizeHandler(evt:Event) {
242                var dat = {
243                        height:skin.stage.stageHeight,
244                        width:skin.stage.stageWidth,
245                        fullscreen:false
246                };
247                if(config['controlbar'] == 'bottom') {
248                        dat.height -= config['controlbarheight'];
249                }
250                if(config['playlist'] == 'right') {
251                        dat.width -= config['playlistsize'];
252                } else if(config['playlist'] == 'bottom') {
253                        dat.height -= config['playlistsize'];
254                }
255                if(skin.stage.displayState == 'fullScreen') {
256                        dat.fullscreen = true;
257                        dat.height = skin.stage.stageHeight;
258                        dat.width = skin.stage.stageWidth;
259                }
260                config['height'] = dat.height;
261                config['width'] = dat.width;
262                dispatchEvent(new ControllerEvent(ControllerEvent.RESIZE,dat));
263        };
264
265
266        /** Seek to a specific part in a mediafile. **/
267        private function seekHandler(evt:ViewEvent) {
268                if(playlist[config['item']]['author'] != 'commercial' &&
269                        config['state'] != ModelStates.IDLE &&
270                        playlist[config['item']]['duration'] > 0) {
271                        var pos = evt.data.position;
272                        if(pos < 2) {
273                                pos = 0;
274                        } else if (pos > playlist[config['item']]['duration']-2) {
275                                pos = playlist[config['item']]['duration']-2;
276                        }
277                        dispatchEvent(new ControllerEvent(ControllerEvent.SEEK,{position:pos}));
278                }
279        };
280
281
282        /** Stop all playback and buffering. **/
283        private function stopHandler(evt:ViewEvent) {
284                dispatchEvent(new ControllerEvent(ControllerEvent.STOP));
285        };
286
287
288        /** Manage playback state changes. **/
289        private function stateHandler(evt:ModelEvent) {
290                if(evt.data.newstate == ModelStates.COMPLETED && (config['repeat'] == true ||
291                        (config['shuffle'] == true && randomizer.length > 0) ||
292                        (config['shuffle'] == false && config['item'] < playlist.length-1))) {
293                        if(config['shuffle'] == true) {
294                                playItem(randomizer.pick());
295                        } else if(config['item'] == playlist.length-1) {
296                                playItem(0);
297                        } else {
298                                playItem(config['item']+1);
299                        }
300                }
301        };
302
303
304        /** Save new state of the mute switch and send volume. **/
305        private function volumeHandler(evt:ViewEvent) {
306                var vol = evt.data.percentage;
307                if (vol < 1) {
308                        muteHandler(new ViewEvent(ViewEvent.MUTE,{state:true}));
309                } else if (!isNaN(vol) && vol < 101) {
310                        if(config['mute'] == true) {
311                                muteHandler(new ViewEvent(ViewEvent.MUTE,{state:false}));
312                        }
313                        config['volume'] = vol;
314                        Configger.saveCookie('volume',vol);
315                        dispatchEvent(new ControllerEvent(ControllerEvent.VOLUME,{percentage:vol}));
316                }
317        };
318
319
320        /** Getter for the playlist. **/
321        public function get playlist():Array {
322                return playlister.playlist;
323        };
324
325
326}
327
328
329}
Note: See TracBrowser for help on using the repository browser.