]> git.sesse.net Git - vlc/blob - modules/gui/macosx/MainWindow.m
macosx: store counting mode of the time field (default is to count up)
[vlc] / modules / gui / macosx / MainWindow.m
1 /*****************************************************************************
2  * MainWindow.h: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2002-2011 VideoLAN
5  * $Id$
6  *
7  * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
8  *          Jon Lech Johansen <jon-vl@nanocrew.net>
9  *          Christophe Massiot <massiot@via.ecp.fr>
10  *          Derk-Jan Hartman <hartman at videolan.org>
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
25  *****************************************************************************/
26
27 #import "MainWindow.h"
28 #import "intf.h"
29 #import "CoreInteraction.h"
30 #import "AudioEffects.h"
31 #import "MainMenu.h"
32 #import "misc.h"
33 #import "controls.h" // TODO: remove me
34 #import <vlc_playlist.h>
35 #import <vlc_aout_intf.h>
36 #import <vlc_url.h>
37 #import <vlc_strings.h>
38
39 @implementation VLCMainWindow
40 static VLCMainWindow *_o_sharedInstance = nil;
41
42 + (VLCMainWindow *)sharedInstance
43 {
44     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
45 }
46
47 #pragma mark -
48 #pragma mark Initialization
49
50 - (id)init
51 {
52     if( _o_sharedInstance)
53     {
54         [self dealloc];
55         return _o_sharedInstance;
56     }
57     else
58         _o_sharedInstance = [super init];
59
60     return _o_sharedInstance;
61 }
62
63 - (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)styleMask
64                   backing:(NSBackingStoreType)backingType defer:(BOOL)flag
65 {
66 //     styleMask ^= NSTexturedBackgroundWindowMask;
67
68     self = [super initWithContentRect:contentRect styleMask:styleMask //& ~NSTitledWindowMask
69                               backing:backingType defer:flag];
70
71     [[VLCMain sharedInstance] updateTogglePlaylistState];
72
73     /* we want to be moveable regardless of our style */
74     [self setMovableByWindowBackground: YES];
75
76     /* we don't want this window to be restored on relaunch */
77     if ([self respondsToSelector:@selector(setRestorable:)])
78         [self setRestorable:NO];
79
80     return self;
81 }
82
83 - (BOOL)performKeyEquivalent:(NSEvent *)o_event
84 {
85     /* We indeed want to prioritize Cocoa key equivalent against libvlc,
86      so we perform the menu equivalent now. */
87     if([[NSApp mainMenu] performKeyEquivalent:o_event])
88         return TRUE;
89
90     return [[VLCMain sharedInstance] hasDefinedShortcutKey:o_event] || [(VLCControls *)[[VLCMain sharedInstance] controls] keyEvent:o_event];
91 }
92
93 - (void)dealloc
94 {
95     config_PutInt( VLCIntf->p_libvlc, "volume", i_lastShownVolume );
96     [super dealloc];
97 }
98
99 - (void)awakeFromNib
100 {
101     b_dark_interface = config_GetInt( VLCIntf, "macosx-interfacestyle" );
102     i_lastShownVolume = -1;
103
104     [o_play_btn setToolTip: _NS("Play/Pause")];
105     [o_bwd_btn setToolTip: _NS("Backward")];
106     [o_fwd_btn setToolTip: _NS("Forward")];
107     [o_stop_btn setToolTip: _NS("Stop")];
108     [o_playlist_btn setToolTip: _NS("Show/Hide Playlist")];
109     [o_repeat_btn setToolTip: _NS("Repeat")];
110     [o_shuffle_btn setToolTip: _NS("Shuffle")];
111     [o_effects_btn setToolTip: _NS("Effects")];
112     [o_fullscreen_btn setToolTip: _NS("Toggle Fullscreen mode")];
113     [[o_search_fld cell] setPlaceholderString: _NS("Search")];
114     [o_volume_sld setToolTip: _NS("Volume")];
115     [o_volume_down_btn setToolTip: _NS("Mute")];
116     [o_volume_up_btn setToolTip: _NS("Full Volume")];
117     [o_time_sld setToolTip: _NS("Position")];
118
119     if (!b_dark_interface) {
120         [o_bottombar_view setImage: [NSImage imageNamed:@"bottom-background"]];
121         [o_bwd_btn setImage: [NSImage imageNamed:@"back"]];
122         [o_bwd_btn setAlternateImage: [NSImage imageNamed:@"back-pressed"]];
123         o_play_img = [[NSImage imageNamed:@"play"] retain];
124         o_play_pressed_img = [[NSImage imageNamed:@"play-pressed"] retain];
125         o_pause_img = [[NSImage imageNamed:@"pause"] retain];
126         o_pause_pressed_img = [[NSImage imageNamed:@"pause-pressed"] retain];
127         [o_fwd_btn setImage: [NSImage imageNamed:@"forward"]];
128         [o_fwd_btn setAlternateImage: [NSImage imageNamed:@"forward-pressed"]];
129         [o_stop_btn setImage: [NSImage imageNamed:@"stop"]];
130         [o_stop_btn setAlternateImage: [NSImage imageNamed:@"stop-pressed"]];
131         [o_playlist_btn setImage: [NSImage imageNamed:@"playlist"]];
132         [o_playlist_btn setAlternateImage: [NSImage imageNamed:@"playlist-pressed"]];
133         o_repeat_img = [[NSImage imageNamed:@"repeat"] retain];
134         o_repeat_pressed_img = [[NSImage imageNamed:@"repeat-pressed"] retain];
135         o_repeat_all_img  = [[NSImage imageNamed:@"repeat-all"] retain];
136         o_repeat_all_pressed_img = [[NSImage imageNamed:@"repeat-all-pressed"] retain];
137         o_repeat_one_img = [[NSImage imageNamed:@"repeat-one"] retain];
138         o_repeat_one_pressed_img = [[NSImage imageNamed:@"repeat-one-pressed"] retain];
139         o_shuffle_img = [[NSImage imageNamed:@"shuffle"] retain];
140         o_shuffle_pressed_img = [[NSImage imageNamed:@"shuffle-pressed"] retain];
141         o_shuffle_on_img = [[NSImage imageNamed:@"shuffle-blue"] retain];
142         o_shuffle_on_pressed_img = [[NSImage imageNamed:@"shuffle-blue-pressed"] retain];
143         [o_time_sld_left_view setImage: [NSImage imageNamed:@"progression-track-wrapper-left"]];
144         [o_time_sld_middle_view setImage: [NSImage imageNamed:@"progression-track-wrapper-middle"]];
145         [o_time_sld_right_view setImage: [NSImage imageNamed:@"progression-track-wrapper-right"]];
146         [o_volume_down_btn setImage: [NSImage imageNamed:@"volume-low"]];
147         [o_volume_track_view setImage: [NSImage imageNamed:@"volumetrack"]];
148         [o_volume_up_btn setImage: [NSImage imageNamed:@"volume-high"]];
149         [o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons"]];
150         [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed"]];
151         [o_fullscreen_btn setImage: [NSImage imageNamed:@"fullscreen-double-buttons"]];
152         [o_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"fullscreen-double-buttons-pressed"]];
153         [o_time_sld_fancygradient_view loadImagesInDarkStyle:NO];
154     }
155     else
156     {
157         /* TODO: we also need to change the window style here... */
158         [o_bottombar_view setImage: [NSImage imageNamed:@"bottom-background_dark"]];
159         [o_bwd_btn setImage: [NSImage imageNamed:@"back_dark"]];
160         [o_bwd_btn setAlternateImage: [NSImage imageNamed:@"back-pressed_dark"]];
161         o_play_img = [[NSImage imageNamed:@"play_dark"] retain];
162         o_play_pressed_img = [[NSImage imageNamed:@"play-pressed_dark"] retain];
163         o_pause_img = [[NSImage imageNamed:@"pause_dark"] retain];
164         o_pause_pressed_img = [[NSImage imageNamed:@"pause-pressed_dark"] retain];
165         [o_fwd_btn setImage: [NSImage imageNamed:@"forward_dark"]];
166         [o_fwd_btn setAlternateImage: [NSImage imageNamed:@"forward-pressed_dark"]];
167         [o_stop_btn setImage: [NSImage imageNamed:@"stop_dark"]];
168         [o_stop_btn setAlternateImage: [NSImage imageNamed:@"stop-pressed_dark"]];
169         [o_playlist_btn setImage: [NSImage imageNamed:@"playlist_dark"]];
170         [o_playlist_btn setAlternateImage: [NSImage imageNamed:@"playlist-pressed_dark"]];
171         o_repeat_img = [[NSImage imageNamed:@"repeat_dark"] retain];
172         o_repeat_pressed_img = [[NSImage imageNamed:@"repeat-pressed_dark"] retain];
173         o_repeat_all_img  = [[NSImage imageNamed:@"repeat-all-blue_dark"] retain];
174         o_repeat_all_pressed_img = [[NSImage imageNamed:@"repeat-all-blue-pressed_dark"] retain];
175         o_repeat_one_img = [[NSImage imageNamed:@"repeat-one-blue_dark"] retain];
176         o_repeat_one_pressed_img = [[NSImage imageNamed:@"repeat-one-blue-pressed_dark"] retain];
177         o_shuffle_img = [[NSImage imageNamed:@"shuffle_dark"] retain];
178         o_shuffle_pressed_img = [[NSImage imageNamed:@"shuffle-pressed_dark"] retain];
179         o_shuffle_on_img = [[NSImage imageNamed:@"shuffle-blue_dark"] retain];
180         o_shuffle_on_pressed_img = [[NSImage imageNamed:@"shuffle-blue-pressed_dark"] retain];
181         [o_time_fld setTextColor: [NSColor colorWithCalibratedRed:229.0 green:229.0 blue:229.0 alpha:100.0]];
182         [o_time_sld_left_view setImage: [NSImage imageNamed:@"progression-track-wrapper-left_dark"]];
183         [o_time_sld_middle_view setImage: [NSImage imageNamed:@"progression-track-wrapper-middle_dark"]];
184         [o_time_sld_right_view setImage: [NSImage imageNamed:@"progression-track-wrapper-right_dark"]];
185         [o_volume_down_btn setImage: [NSImage imageNamed:@"volume-low_dark"]];
186         [o_volume_track_view setImage: [NSImage imageNamed:@"volume-slider-track_dark"]];
187         [o_volume_up_btn setImage: [NSImage imageNamed:@"volume-high_dark"]];
188         [o_effects_btn setImage: [NSImage imageNamed:@"effects-double-buttons_dark"]];
189         [o_effects_btn setAlternateImage: [NSImage imageNamed:@"effects-double-buttons-pressed_dark"]];
190         [o_fullscreen_btn setImage: [NSImage imageNamed:@"fullscreen-double-buttons_dark"]];
191         [o_fullscreen_btn setAlternateImage: [NSImage imageNamed:@"fullscreen-double-buttons-pressed_dark"]];
192         [o_time_sld_fancygradient_view loadImagesInDarkStyle:YES];
193     }
194     [o_repeat_btn setImage: o_repeat_img];
195     [o_repeat_btn setAlternateImage: o_repeat_pressed_img];
196     [o_shuffle_btn setImage: o_shuffle_img];
197     [o_shuffle_btn setAlternateImage: o_shuffle_pressed_img];
198
199     [o_play_btn setImage: o_play_img];
200     [o_play_btn setAlternateImage: o_play_pressed_img];
201
202     [o_video_view setFrame: [o_split_view frame]];
203     [self setDelegate: self];
204     [self setExcludedFromWindowsMenu: YES];
205     // Set that here as IB seems to be buggy
206     [self setContentMinSize:NSMakeSize(500., 200.)];
207     [self setTitle: _NS("VLC media player")];
208     [o_playlist_btn setEnabled:NO];
209
210     [self updateVolumeSlider];
211     [self updateTimeSlider];
212 }
213
214 #pragma mark -
215 #pragma mark Button Actions
216
217 - (IBAction)play:(id)sender
218 {
219     [[VLCCoreInteraction sharedInstance] play];
220 }
221
222 - (void)resetPreviousButton
223 {
224     if (([NSDate timeIntervalSinceReferenceDate] - last_bwd_event) >= 0.35) {
225         // seems like no further event occured, so let's switch the playback item
226         [[VLCCoreInteraction sharedInstance] previous];
227         just_triggered_previous = NO;
228     }
229 }
230
231 - (void)resetBackwardSkip
232 {
233     // the user stopped skipping, so let's allow him to change the item
234     if (([NSDate timeIntervalSinceReferenceDate] - last_bwd_event) >= 0.35)
235         just_triggered_previous = NO;
236 }
237
238 - (IBAction)bwd:(id)sender
239 {
240     if(!just_triggered_previous)
241     {
242         just_triggered_previous = YES;
243         [self performSelector:@selector(resetPreviousButton)
244                    withObject: NULL
245                    afterDelay:0.40];
246     }
247     else
248     {
249         if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.12 )
250         {
251             // we just skipped 3 "continous" events, otherwise we are too fast
252             [[VLCCoreInteraction sharedInstance] backward];
253             last_bwd_event = [NSDate timeIntervalSinceReferenceDate];
254             [self performSelector:@selector(resetBackwardSkip)
255                        withObject: NULL
256                        afterDelay:0.40];
257         }
258     }
259 }
260
261 - (void)resetNextButton
262 {
263     if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) >= 0.35) {
264         // seems like no further event occured, so let's switch the playback item
265         [[VLCCoreInteraction sharedInstance] next];
266         just_triggered_next = NO;
267     }
268 }
269
270 - (void)resetForwardSkip
271 {
272     // the user stopped skipping, so let's allow him to change the item
273     if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) >= 0.35)
274         just_triggered_next = NO;
275 }
276
277 - (IBAction)fwd:(id)sender
278 {
279    if(!just_triggered_next)
280     {
281         just_triggered_next = YES;
282         [self performSelector:@selector(resetNextButton)
283                    withObject: NULL
284                    afterDelay:0.40];
285     }
286     else
287     {
288         if (([NSDate timeIntervalSinceReferenceDate] - last_fwd_event) > 0.12 )
289         {
290             // we just skipped 3 "continous" events, otherwise we are too fast
291             [[VLCCoreInteraction sharedInstance] forward];
292             last_fwd_event = [NSDate timeIntervalSinceReferenceDate];
293             [self performSelector:@selector(resetForwardSkip)
294                        withObject: NULL
295                        afterDelay:0.40];
296         }
297     }
298 }
299
300 - (IBAction)stop:(id)sender
301 {
302     [[VLCCoreInteraction sharedInstance] stop];
303 }
304
305 - (IBAction)togglePlaylist:(id)sender
306 {
307     NSLog( @"b_videoplayen %i", b_video_playback_enabled );
308     if (b_video_playback_enabled && [o_video_view isHidden]) {
309         [o_video_view setHidden: NO];
310         [o_playlist_table setHidden: YES];
311     }
312     else
313     {
314         [o_playlist_table setHidden: NO];
315         [o_video_view setHidden: YES];
316     }
317 }
318
319 - (void)setRepeatOne
320 {
321     [o_repeat_btn setImage: o_repeat_one_img];
322     [o_repeat_btn setAlternateImage: o_repeat_one_pressed_img];   
323 }
324
325 - (void)setRepeatAll
326 {
327     [o_repeat_btn setImage: o_repeat_all_img];
328     [o_repeat_btn setAlternateImage: o_repeat_all_pressed_img];
329 }
330
331 - (void)setRepeatOff
332 {
333     [o_repeat_btn setImage: o_repeat_img];
334     [o_repeat_btn setAlternateImage: o_repeat_pressed_img];
335 }
336
337 - (IBAction)repeat:(id)sender
338 {
339     vlc_value_t looping,repeating;
340     intf_thread_t * p_intf = VLCIntf;
341     playlist_t * p_playlist = pl_Get( p_intf );
342
343     var_Get( p_playlist, "repeat", &repeating );
344     var_Get( p_playlist, "loop", &looping );
345
346     if( !repeating.b_bool && !looping.b_bool )
347     {
348         /* was: no repeating at all, switching to Repeat One */
349         [[VLCCoreInteraction sharedInstance] repeatOne];
350         [self setRepeatOne];
351     }
352     else if( repeating.b_bool && !looping.b_bool )
353     {
354         /* was: Repeat One, switching to Repeat All */
355         [[VLCCoreInteraction sharedInstance] repeatAll];
356         [self setRepeatAll];
357     }
358     else
359     {
360         /* was: Repeat All or bug in VLC, switching to Repeat Off */
361         [[VLCCoreInteraction sharedInstance] repeatOff];
362         [self setRepeatOff];
363     }
364 }
365
366 - (void)setShuffle
367 {
368     bool b_value;
369     playlist_t *p_playlist = pl_Get( VLCIntf );
370     b_value = var_GetBool( p_playlist, "random" );
371         if(b_value) {
372         [o_shuffle_btn setImage: o_shuffle_on_img];
373         [o_shuffle_btn setAlternateImage: o_shuffle_on_pressed_img];
374     }
375     else
376     {
377         [o_shuffle_btn setImage: o_shuffle_img];
378         [o_shuffle_btn setAlternateImage: o_shuffle_pressed_img];
379     }
380 }
381
382 - (IBAction)shuffle:(id)sender
383 {
384     [[VLCCoreInteraction sharedInstance] shuffle];
385     [self setShuffle];
386 }
387
388 - (IBAction)timeSliderAction:(id)sender
389 {
390     float f_updated;
391     input_thread_t * p_input;
392
393     switch( [[NSApp currentEvent] type] )
394     {
395         case NSLeftMouseUp:
396         case NSLeftMouseDown:
397         case NSLeftMouseDragged:
398             f_updated = [sender floatValue];
399             break;
400
401         default:
402             return;
403     }
404     p_input = pl_CurrentInput( VLCIntf );
405     if( p_input != NULL )
406     {
407         vlc_value_t time;
408         vlc_value_t pos;
409         NSString * o_time;
410         char psz_time[MSTRTIME_MAX_SIZE];
411
412         pos.f_float = f_updated / 10000.;
413         var_Set( p_input, "position", pos );
414         [o_time_sld setFloatValue: f_updated];
415
416         var_Get( p_input, "time", &time );
417
418         mtime_t dur = input_item_GetDuration( input_GetItem( p_input ) );
419         if( [o_time_fld timeRemaining] && dur != -1 )
420         {
421             o_time = [NSString stringWithFormat: @"-%s", secstotimestr( psz_time, ((dur - time.i_time) / 1000000) )];
422         }
423         else
424             o_time = [NSString stringWithUTF8String: secstotimestr( psz_time, (time.i_time / 1000000) )];
425
426         [o_time_fld setStringValue: o_time];
427         [[[[VLCMain sharedInstance] controls] fspanel] setStreamPos: f_updated andTime: o_time];
428         vlc_object_release( p_input );
429     }
430     [self drawFancyGradientEffectForTimeSlider];
431 }
432
433 - (IBAction)volumeAction:(id)sender
434 {
435     if (sender == o_volume_sld)
436         [[VLCCoreInteraction sharedInstance] setVolume: [sender intValue]];
437     else if (sender == o_volume_down_btn)
438         [[VLCCoreInteraction sharedInstance] mute];
439     else
440         [[VLCCoreInteraction sharedInstance] setVolume: 400];
441 }
442
443 - (IBAction)effects:(id)sender
444 {
445     [[VLCMainMenu sharedInstance] showAudioEffects: sender];
446 }
447
448 - (IBAction)fullscreen:(id)sender
449 {
450     NSLog( @"fullscreen mode not yet implemented" );
451     [[VLCCoreInteraction sharedInstance] toggleFullscreen];
452 }
453
454 #pragma mark -
455 #pragma mark Update interface and respond to foreign events
456 - (void)updateTimeSlider
457 {
458     input_thread_t * p_input;
459     p_input = pl_CurrentInput( VLCIntf );
460     if( p_input )
461     {
462         vlc_value_t time;
463         NSString * o_time;
464         vlc_value_t pos;
465         char psz_time[MSTRTIME_MAX_SIZE];
466         float f_updated;
467
468         var_Get( p_input, "position", &pos );
469         f_updated = 10000. * pos.f_float;
470         [o_time_sld setFloatValue: f_updated];
471
472         var_Get( p_input, "time", &time );
473
474         mtime_t dur = input_item_GetDuration( input_GetItem( p_input ) );
475         if( [o_time_fld timeRemaining] && dur != -1 )
476         {
477             o_time = [NSString stringWithFormat: @"-%s", secstotimestr( psz_time, ((dur - time.i_time) / 1000000))];
478         }
479         else
480             o_time = [NSString stringWithUTF8String: secstotimestr( psz_time, (time.i_time / 1000000) )];
481
482         [o_time_fld setStringValue: o_time];
483         [o_time_fld setNeedsDisplay:YES];
484 //        [[[[VLCMain sharedInstance] controls] fspanel] setStreamPos: f_updated andTime: o_time];
485     }
486     else
487     {
488         [o_time_sld setFloatValue: 0.0];
489         [o_time_fld setStringValue: @"00:00"];
490     }
491         
492     [self performSelectorOnMainThread:@selector(drawFancyGradientEffectForTimeSlider) withObject:nil waitUntilDone:NO];
493 }
494
495 - (void)updateVolumeSlider
496 {
497     audio_volume_t i_volume;
498     playlist_t * p_playlist = pl_Get( VLCIntf );
499
500     i_volume = aout_VolumeGet( p_playlist );
501
502     if( i_volume != i_lastShownVolume )
503     {
504         i_lastShownVolume = i_volume;
505         int i_volume_step = 0;
506         i_volume_step = config_GetInt( VLCIntf->p_libvlc, "volume-step" );
507         [o_volume_sld setFloatValue: (float)i_lastShownVolume / i_volume_step];
508 //        [[[[VLCMain sharedInstance] controls] fspanel] setVolumeLevel: (float)i_lastShownVolume / i_volume_step];
509     }
510 }
511
512 - (void)updateName
513 {
514     input_thread_t * p_input;
515
516     p_input = pl_CurrentInput( VLCIntf );
517     if( p_input )
518     {
519         NSString *aString;
520         char *format = var_InheritString( VLCIntf, "input-title-format" );
521         char *formated = str_format_meta( p_input, format );
522         free( format );
523         aString = [NSString stringWithUTF8String:formated];
524         free( formated );
525
526         char *uri = input_item_GetURI( input_GetItem( p_input ) );
527
528         if ([aString isEqualToString:@""])
529         {
530
531             char *file = uri ? strrchr( uri, '/' ) : NULL;
532             if( file != NULL )
533             {
534                 decode_URI( ++file );
535                 aString = [NSString stringWithUTF8String:file];
536             }
537             else
538                 aString = [NSString stringWithUTF8String:uri];
539         }
540
541         NSMutableString *o_mrl = [NSMutableString stringWithUTF8String: decode_URI(uri)];
542         free( uri );
543         NSRange prefix_range = [o_mrl rangeOfString: @"file:"];
544         if( prefix_range.location != NSNotFound )
545             [o_mrl deleteCharactersInRange: prefix_range];
546
547         if( [o_mrl characterAtIndex:0] == '/' )
548         {
549             /* it's a local file */
550             [self setRepresentedFilename: o_mrl];
551         }
552         else
553         {
554             /* it's from the network or somewhere else,
555              * we clear the previous path */
556             [self setRepresentedFilename: @""];
557         }
558
559         [self setTitle: aString];
560         [[[[VLCMain sharedInstance] controls] fspanel] setStreamTitle: aString];
561     }
562     else
563     {
564         [self setTitle: _NS("VLC media player")];
565         [self setRepresentedFilename: @""];
566     }
567 }
568
569 - (void)updateWindow
570 {
571     bool b_input = false;
572     bool b_plmul = false;
573     bool b_control = false;
574     bool b_seekable = false;
575     bool b_chapters = false;
576
577     playlist_t * p_playlist = pl_Get( VLCIntf );
578
579     PL_LOCK;
580     b_plmul = playlist_CurrentSize( p_playlist ) > 1;
581     PL_UNLOCK;
582
583     input_thread_t * p_input = playlist_CurrentInput( p_playlist );
584
585     bool b_buffering = NO;
586
587     if( ( b_input = ( p_input != NULL ) ) )
588     {
589         /* seekable streams */
590         cachedInputState = input_GetState( p_input );
591         if ( cachedInputState == INIT_S || cachedInputState == OPENING_S )
592             b_buffering = YES;
593
594         /* seekable streams */
595         b_seekable = var_GetBool( p_input, "can-seek" );
596
597         /* check whether slow/fast motion is possible */
598         b_control = var_GetBool( p_input, "can-rate" );
599
600         /* chapters & titles */
601         //FIXME! b_chapters = p_input->stream.i_area_nb > 1;
602         vlc_object_release( p_input );
603     }
604
605     if( b_buffering )
606     {
607         [o_progress_bar startAnimation:self];
608         [o_progress_bar setIndeterminate:YES];
609         [o_progress_bar setHidden:NO];
610     } else {
611         [o_progress_bar stopAnimation:self];
612         [o_progress_bar setHidden:YES];
613     }
614
615     [o_stop_btn setEnabled: b_input];
616     [o_fwd_btn setEnabled: (b_seekable || b_plmul || b_chapters)];
617     [o_bwd_btn setEnabled: (b_seekable || b_plmul || b_chapters)];
618     [[VLCMainMenu sharedInstance] setRateControlsEnabled: b_control];
619
620
621     [o_time_sld setEnabled: b_seekable];
622     [self updateTimeSlider];
623     [[[[VLCMain sharedInstance] controls] fspanel] setSeekable: b_seekable];
624 }
625
626 - (void)setPause
627 {
628     [o_play_btn setImage: o_pause_img];
629     [o_play_btn setAlternateImage: o_pause_pressed_img];
630     [o_play_btn setToolTip: _NS("Pause")];
631 }
632
633 - (void)setPlay
634 {
635     [o_play_btn setImage: o_play_img];
636     [o_play_btn setAlternateImage: o_play_pressed_img];
637     [o_play_btn setToolTip: _NS("Play")];
638 }
639
640 - (void)drawFancyGradientEffectForTimeSlider
641 {
642     float f_value = ([o_time_sld_middle_view frame].size.width -5) * ([o_time_sld intValue] / [o_time_sld maxValue]);
643     if (f_value > 5.0)
644     {
645         if (f_value != [o_time_sld_fancygradient_view frame].size.width)
646         {
647             [o_time_sld_fancygradient_view setHidden: NO];
648             [o_time_sld_fancygradient_view setFrame: NSMakeRect( [o_time_sld_fancygradient_view frame].origin.x, [o_time_sld_fancygradient_view frame].origin.y, f_value, [o_time_sld_fancygradient_view frame].size.height )];
649             [o_time_sld_fancygradient_view setNeedsDisplay:YES];
650             [o_time_sld_middle_view setNeedsDisplay:YES];
651         }
652     }
653     else
654     {
655         [o_time_sld_fancygradient_view setHidden: YES];
656     }
657 }
658
659 #pragma mark -
660 #pragma mark Video Output handling
661
662 - (id)videoView
663 {
664     return o_video_view;
665 }
666
667 - (void)setVideoplayEnabled:(BOOL)b_value
668 {
669     NSLog( @"setVideoplayEnabled:%i", b_value );
670     if (b_value) {
671         b_video_playback_enabled = YES;
672         [o_playlist_btn setEnabled: YES];
673     }
674     else
675     {
676         b_video_playback_enabled = NO;
677         [o_playlist_btn setEnabled: NO];
678     }
679 }
680
681 @end
682
683 @implementation VLCProgressBarGradientEffect
684 - (void)loadImagesInDarkStyle: (BOOL)b_value
685 {
686     if (b_value)
687     {
688         o_time_sld_gradient_left_img = [NSImage imageNamed:@"progressbar-fill-left_dark"];
689         o_time_sld_gradient_middle_img = [NSImage imageNamed:@"progressbar-fill-middle_dark"];
690         o_time_sld_gradient_right_img = [NSImage imageNamed:@"progressbar-fill-right_dark"];
691     }
692     else
693     {
694         o_time_sld_gradient_left_img = [NSImage imageNamed:@"progression-fill-left"];
695         o_time_sld_gradient_middle_img = [NSImage imageNamed:@"progression-fill-middle"];
696         o_time_sld_gradient_right_img = [NSImage imageNamed:@"progression-fill-right"];
697     }
698 }
699
700 - (void)drawRect:(NSRect)rect
701 {
702     NSRect bnds = [self bounds];
703     NSDrawThreePartImage( bnds, o_time_sld_gradient_left_img, o_time_sld_gradient_middle_img, o_time_sld_gradient_right_img, NO, NSCompositeSourceOver, 1, NO );
704 }
705 @end