root/trunk/as3/com/jeroenwijering/views/ControlbarView.as @ 1

Revision 1, 10.0 kB (checked in by jeroen, 18 months ago)

initial commit of old repository into public one

  • Property svn:executable set to *
Line 
1/**
2* Display a controlbar and direct the search externally.
3**/
4package com.jeroenwijering.views {
5
6
7import com.jeroenwijering.events.*;
8import com.jeroenwijering.player.View;
9import com.jeroenwijering.utils.Strings;
10import flash.display.MovieClip;
11import flash.events.MouseEvent;
12import flash.geom.Rectangle;
13import flash.utils.setTimeout;
14import flash.utils.clearTimeout;
15import fl.transitions.*;
16import fl.transitions.easing.*;
17
18
19public class ControlbarView {
20
21
22        /** Reference to the view. **/
23        private var view:View;
24        /** A list with all controls docked to the left. **/
25        private var left:Array;
26        /** A list with all controls docked to the right. **/
27        private var right:Array;
28        /** Reference to the controlbar **/
29        private var bar:MovieClip;
30        /** Save whether slading is enabled. **/
31        private var sliding:Boolean;
32        /** Timeout for hiding the bar. **/
33        private var hiding:Number;
34
35
36        /** Constructor. **/
37        public function ControlbarView(vie:View) {
38                view = vie;
39                view.addControllerListener(ControllerEvent.CAPTION,captionHandler);
40                view.addControllerListener(ControllerEvent.ITEM,itemHandler);
41                view.addControllerListener(ControllerEvent.MUTE,muteHandler);
42                view.addControllerListener(ControllerEvent.RESIZE,resizeHandler);
43                view.addControllerListener(ControllerEvent.VOLUME,volumeHandler);
44                view.addModelListener(ModelEvent.LOADED,loadedHandler);
45                view.addModelListener(ModelEvent.STATE,stateHandler);
46                view.addModelListener(ModelEvent.TIME,timeHandler);
47                bar = view.skin['controlbar'];
48                bar.addEventListener(MouseEvent.CLICK, clickHandler);
49                bar.timeSlider.addEventListener(MouseEvent.MOUSE_DOWN,timeslideHandler);
50                bar.timeSlider.addEventListener(MouseEvent.MOUSE_OUT,outHandler);
51                bar.volumeSlider.addEventListener(MouseEvent.MOUSE_DOWN,volumeslideHandler);
52                bar.volumeSlider.addEventListener(MouseEvent.MOUSE_OUT,outHandler);
53                checkButtons();
54                loadedHandler(new ModelEvent(ModelEvent.LOADED,{loaded:0,total:0}));
55                captionHandler(new ControllerEvent(ControllerEvent.CAPTION,{percentage:view.config['caption']}));
56                muteHandler(new ControllerEvent(ControllerEvent.MUTE,{state:view.config['mute']}));
57                stateHandler(new ModelEvent(ModelEvent.STATE,{newstate:ModelStates.IDLE}));
58                timeHandler(new ModelEvent(ModelEvent.TIME,{position:0,duration:0}));
59                volumeHandler(new ControllerEvent(ControllerEvent.VOLUME,{percentage:view.config['volume']}));
60        };
61
62
63        /** Handle a change in the current item **/
64        private function captionHandler(evt:ControllerEvent) {
65                if(evt.data.state == true) {
66                        bar.captionButton.icn.visible = true;
67                        bar.captionButton.alt.visible = false;
68                } else {
69                        bar.captionButton.icn.visible = false;
70                        bar.captionButton.alt.visible = true;
71                }
72        };
73
74
75        /** Check which buttons are available and save their positions. **/
76        private function checkButtons() {
77                var mid = bar.width/2;
78                left = new Array();
79                right = new Array();
80                for(var i=0; i<bar.numChildren; i++) {
81                        var clp = bar.getChildAt(i);
82                        clp.buttonMode = true;
83                        clp.mouseChildren = false;
84                        if(clp.x < mid) {
85                                left.push({c:clp,x:clp.x,n:clp.name,w:clp.width});
86                        } else {
87                                right.push({c:clp,x:clp.x,n:clp.name,w:clp.width});
88                        }
89                }
90                left.sortOn(['x','n'],[Array.NUMERIC,Array.CASEINSENSITIVE]);
91                right.sortOn('x',Array.DESCENDING | Array.NUMERIC);
92        };
93
94
95        /** Handle clicks from all buttons **/
96        private function clickHandler(evt:MouseEvent) {
97                if(evt.target.name.indexOf('Button') > 0) {
98                        var str = evt.target.name.substr(0,-6).toUpperCase();
99                        view.sendEvent(str);
100                } else if (evt.target.name == 'timeSlider') {
101                        sendScrub(evt);
102                } else if (evt.target.name == 'volumeSlider') {
103                        sendVolume(evt);
104                }
105                sliding = false;
106        };
107
108
109        /** Returns whether the control should be hidden. **/
110        private function hideButton(nam:String):Boolean {
111                var obj = view.playlist[view.config['item']];
112                switch(nam) {
113                        case 'prevButton':
114                        case 'nextButton':
115                                if(view.playlist.length < 2) {
116                                        return true;
117                                }
118                                break;
119                        case 'elapsedText':
120                        case 'remainingText':
121                        case 'totalText':
122                                if(bar.back.width < 200) {
123                                        return true;
124                                }
125                                break;
126                        case 'linkButton':
127                                if(!obj || !obj['link']) {
128                                        return true;
129                                }
130                                break;
131                        case 'fullscreenButton':
132                                if(view.config['fullscreen'] == false || bar.stage.displayState == null) {
133                                        return true;
134                                }
135                                break;
136                        case 'captionButton':
137                                if(!obj || !obj['captions']) {
138                                        return true;
139                                }
140                                break;
141                }
142                return false;
143        };
144
145
146        /** Handle a change in the current item **/
147        private function itemHandler(evt:ControllerEvent) {
148                setButtons();
149        };
150
151
152        /** Process bytesloaded updates given by the model. **/
153        private function loadedHandler(evt:ModelEvent) {
154                var pc1 = 0;
155                if(evt.data.total > 0) {
156                        pc1 = evt.data.loaded/evt.data.total;
157                }
158                var pc2 = 0;
159                if(evt.data.offset) {
160                        pc2 = evt.data.offset/evt.data.total;
161                }
162                var wid = bar.timeSlider.bck.width;
163                bar.timeSlider.bar.x = Math.round(pc2*wid);
164                bar.timeSlider.bar.width = Math.round(pc1*wid); 
165        };
166
167
168        /** Show above controlbar on mousemove. **/
169        private function moveHandler(evt:MouseEvent) {
170                bar.visible = true;
171                clearTimeout(hiding);
172                hiding = setTimeout(moveTimeout,1000);
173        };
174
175
176        /** Hide above controlbar again when move has timed out. **/
177        private function moveTimeout() {
178                if(bar.mouseY < -10) {
179                        bar.visible = false;
180                }
181        };
182
183
184        /** Show a mute icon if playing. **/
185        private function muteHandler(evt:ControllerEvent) {
186                if(evt.data.state == true) {
187                        bar.muteButton.icn.visible = false;
188                        bar.muteButton.alt.visible = true;
189                        bar.volumeSlider.bar.visible = false;
190                } else {
191                        bar.muteButton.icn.visible = true;
192                        bar.muteButton.alt.visible = false;
193                        bar.volumeSlider.bar.visible = true;
194                }
195        };
196
197
198        /** Handle mouseouts from all buttons **/
199        private function outHandler(evt:MouseEvent) {
200                if(sliding) { clickHandler(evt); }
201        };
202
203
204        /** Process resizing requests **/
205        private function resizeHandler(evt:ControllerEvent) {
206                if(view.config['controlbar'] == 'above' || evt.data.fullscreen == true) {
207                        bar.y = evt.data.height - view.config['controlbarsize']*2;
208                        if(evt.data.width > 640) {
209                                bar.x = Math.round(evt.data.width/2 - 300);
210                                bar.back.width = 600;
211                        } else {
212                                bar.x = view.config['controlbarsize'];
213                                bar.back.width = evt.data.width - view.config['controlbarsize']*2;
214                        }
215                } else {
216                        bar.x = 0;
217                        bar.back.width = evt.data.width;
218                        bar.y = evt.data.height;
219                        if(view.config['playlist'] == 'right') {
220                                bar.back.width += view.config['playlistsize'];
221                        }
222                }
223                if(evt.data.fullscreen == true) {
224                        bar.fullscreenButton.icn.visible = false;
225                        bar.fullscreenButton.alt.visible = true;
226                } else {
227                        bar.fullscreenButton.icn.visible = true;
228                        bar.fullscreenButton.alt.visible = false;
229                }
230                setButtons();
231        };
232
233
234        /** Send the new scrub position to the controller **/
235        private function sendScrub(evt:MouseEvent) {
236                bar.timeSlider.icn.stopDrag();
237                var xps = bar.timeSlider.icn.x - bar.timeSlider.bck.x;
238                var dur = view.playlist[view.config['item']]['duration'];
239                var pct = Math.round(xps*dur*10/bar.timeSlider.bck.width)/10;
240                view.sendEvent(ViewEvent.SEEK,pct);
241        }
242
243
244        /** Send the new volume to the controlbar **/
245        private function sendVolume(evt:MouseEvent) {
246                bar.volumeSlider.icn.stopDrag();
247                var xps = bar.volumeSlider.icn.x - bar.volumeSlider.sld.x;
248                var pct = Math.round(xps*100/bar.volumeSlider.sld.width);
249                view.sendEvent(ViewEvent.VOLUME,pct);
250        };
251
252
253        /** Set all buttons to their correct positions. **/
254        private function setButtons() {
255                var rdf = bar.back.width-left[0].w;
256                var ldf = 0;
257                for(var i=0; i<right.length; i++) {
258                        if(hideButton(right[i].n)) {
259                                right[i].c.visible = false;
260                                rdf += right[i-1].x - right[i].x;
261                        } else {
262                                right[i].c.visible = true;
263                                right[i].c.x = right[i].x + rdf;
264                        }
265                }
266                for(var j=0; j<left.length; j++) {
267                        if(hideButton(left[j].n)) {
268                                left[j].c.visible = false;
269                                ldf += left[j+1].x - left[j].x;
270                        } else {
271                                left[j].c.visible = true;
272                                left[j].c.x = left[j].x - ldf;
273                        }
274                        if(left[j].n == 'timeSlider') {
275                                var old = bar.timeSlider.bck.width;
276                                var wid = left[j].w+rdf+ldf;
277                                bar.timeSlider.bck.width = wid;
278                                bar.timeSlider.bar.width *= wid/old;
279                                bar.timeSlider.bar.x *= wid/old;
280                                bar.timeSlider.icn.x = Math.round(bar.timeSlider.icn.x*wid/old);
281                        }
282                }
283        };
284
285
286        /** Process state changes **/
287        private function stateHandler(evt:ModelEvent) {
288                switch(evt.data.newstate) {
289                        case ModelStates.PLAYING:
290                                if(view.config['controlbar'] == 'above') {
291                                        hiding = setTimeout(moveTimeout,1000);
292                                        view.skin.addEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
293                                }
294                        case ModelStates.BUFFERING:
295                                bar.playButton.icn.visible = false;
296                                bar.playButton.alt.visible = true;
297                                break;
298                        default:
299                                if(view.config['controlbar'] == 'above') {
300                                        clearTimeout(hiding);
301                                        bar.visible = true;
302                                        view.skin.removeEventListener(MouseEvent.MOUSE_MOVE, moveHandler);
303                                }
304                                bar.playButton.icn.visible = true;
305                                bar.playButton.alt.visible = false;
306                                break;
307                }
308        }
309
310
311        /** Process time updates given by the model. **/
312        private function timeHandler(evt:ModelEvent) {
313                var dur = evt.data.duration;
314                try {
315                        bar.elapsedText.txt.text = Strings.digits(evt.data.position);
316                        bar.totalText.txt.text = Strings.digits(evt.data.duration);
317                } catch(err:Error) {}
318                var pct = evt.data.position/evt.data.duration;
319                var xps = Math.floor(pct*bar.timeSlider.bck.width);
320                if (dur <= 0) {
321                        bar.timeSlider.icn.visible = false;
322                } else {
323                        bar.timeSlider.icn.visible = true;
324                        bar.timeSlider.icn.x = xps;
325                }
326        };
327
328
329        /** Handle a move over the timeslider **/
330        private function timeslideHandler(evt:MouseEvent) {
331                var rct = new Rectangle(bar.timeSlider.bck.x,bar.timeSlider.icn.y,bar.timeSlider.bck.width,0);
332                bar.timeSlider.icn.startDrag(true,rct);
333                sliding = true;
334        };
335
336
337        /** Reflect the new volume in the controlbar **/
338        private function volumeHandler(evt:ControllerEvent) {
339                bar.volumeSlider.bar.scaleX = evt.data.percentage/100;
340        };
341
342
343        /** Handle a move over the volume bar **/
344        private function volumeslideHandler(evt:MouseEvent) {
345                var rct = new Rectangle(bar.volumeSlider.sld.x,bar.volumeSlider.icn.y,bar.volumeSlider.sld.width,0);
346                bar.volumeSlider.icn.startDrag(true,rct);
347                sliding = true;
348        };
349
350
351};
352
353
354}
Note: See TracBrowser for help on using the browser.