source: trunk/as3/com/jeroenwijering/views/ControlbarView.as @ 2

Revision 2, 10.3 KB checked in by jeroen, 5 years ago (diff)

fixes in skinning and controlbar

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