X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fcontrols.m;h=b0aea74328193724cc1ea00ed15ccd8cb341bd40;hb=223286529bb015c350f9839b4fcdb03ea59b2c7a;hp=862e54bb3e82392365c283c12d08d420613025a6;hpb=2a2b478368aa26cfbf613f5205bc5ba1298a34ad;p=vlc diff --git a/modules/gui/macosx/controls.m b/modules/gui/macosx/controls.m index 862e54bb3e..b0aea74328 100644 --- a/modules/gui/macosx/controls.m +++ b/modules/gui/macosx/controls.m @@ -1,20 +1,20 @@ /***************************************************************************** * controls.m: MacOS X interface module ***************************************************************************** - * Copyright (C) 2002-2006 the VideoLAN team + * Copyright (C) 2002-2009 the VideoLAN team * $Id$ * * Authors: Jon Lech Johansen * Christophe Massiot * Derk-Jan Hartman * Benjamin Pracht - * Felix KŸhne + * Felix Paul Kühne * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -40,8 +40,9 @@ #include #include +#pragma mark - /***************************************************************************** - * VLCControls implementation + * VLCControls implementation *****************************************************************************/ @implementation VLCControls @@ -59,102 +60,140 @@ [o_specificTime_ok_btn setTitle: _NS("OK")]; [o_specificTime_sec_lbl setStringValue: _NS("sec.")]; [o_specificTime_goTo_lbl setStringValue: _NS("Jump to time")]; + + o_repeat_off = [NSImage imageNamed:@"repeat_embedded"]; + + [self controlTintChanged]; + + [[NSNotificationCenter defaultCenter] addObserver: self + selector: @selector( controlTintChanged ) + name: NSControlTintDidChangeNotification + object: nil]; } -- (IBAction)play:(id)sender +- (void)controlTintChanged { - vlc_value_t val; - intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + int i_repeat = 0; + if( [o_btn_repeat image] == o_repeat_single ) + i_repeat = 1; + else if( [o_btn_repeat image] == o_repeat_all ) + i_repeat = 2; - vlc_mutex_lock( &p_playlist->object_lock ); - if( playlist_IsEmpty( p_playlist ) ) + if( [NSColor currentControlTint] == NSGraphiteControlTint ) { - vlc_mutex_unlock( &p_playlist->object_lock ); - vlc_object_release( p_playlist ); - [o_main intfOpenFileGeneric: (id)sender]; + o_repeat_single = [NSImage imageNamed:@"repeat_single_embedded_graphite"]; + o_repeat_all = [NSImage imageNamed:@"repeat_embedded_graphite"]; + + [o_btn_shuffle setAlternateImage: [NSImage imageNamed: @"shuffle_embedded_graphite"]]; + [o_btn_addNode setAlternateImage: [NSImage imageNamed: @"add_embedded_graphite"]]; } else { - vlc_mutex_unlock( &p_playlist->object_lock ); - vlc_object_release( p_playlist ); + o_repeat_single = [NSImage imageNamed:@"repeat_single_embedded_blue"]; + o_repeat_all = [NSImage imageNamed:@"repeat_embedded_blue"]; + + [o_btn_shuffle setAlternateImage: [NSImage imageNamed: @"shuffle_embedded_blue"]]; + [o_btn_addNode setAlternateImage: [NSImage imageNamed: @"add_embedded_blue"]]; } + + /* update the repeat button, but keep its state */ + if( i_repeat == 1 ) + [self repeatOne]; + else if( i_repeat == 2 ) + [self repeatAll]; + else + [self repeatOff]; +} - val.i_int = config_GetInt( p_intf, "key-play-pause" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver: self]; + + [o_repeat_single release]; + [o_repeat_all release]; + [o_repeat_off release]; + + [super dealloc]; } -/* Small helper method */ +- (IBAction)play:(id)sender +{ + intf_thread_t * p_intf = VLCIntf; + playlist_t * p_playlist = pl_Hold( p_intf ); + bool empty; + + PL_LOCK; + empty = playlist_IsEmpty( p_playlist ); + PL_UNLOCK; + + pl_Release( p_intf ); --(id) getVoutView + if( empty ) + [o_main intfOpenFileGeneric: (id)sender]; + + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PLAY_PAUSE ); +} + +- (id)voutView { id o_window; - id o_vout_view = nil; - id o_embedded_vout_list = [[VLCMain sharedInstance] getEmbeddedList]; + id o_voutView = nil; + id o_embeddedViewList = [[VLCMain sharedInstance] embeddedList]; NSEnumerator *o_enumerator = [[NSApp orderedWindows] objectEnumerator]; - while( !o_vout_view && ( o_window = [o_enumerator nextObject] ) ) + while( !o_voutView && ( o_window = [o_enumerator nextObject] ) ) { /* We have an embedded vout */ - if( [o_embedded_vout_list windowContainsEmbedded: o_window] ) + if( [o_embeddedViewList windowContainsEmbedded: o_window] ) { - o_vout_view = [o_embedded_vout_list getViewForWindow: o_window]; + o_voutView = [o_embeddedViewList viewForWindow: o_window]; } /* We have a detached vout */ else if( [[o_window className] isEqualToString: @"VLCVoutWindow"] ) { - msg_Dbg( VLCIntf, "detached vout controls.m call getVoutView" ); - o_vout_view = [o_window getVoutView]; + o_voutView = [o_window voutView]; } } - return o_vout_view; + return [[o_voutView retain] autorelease]; } - - (IBAction)stop:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-stop" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_STOP ); + /* Close the window directly, because we do know that there + * won't be anymore video. It's currently waiting a bit. */ + [[[self voutView] window] orderOut:self]; } - (IBAction)faster:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-faster" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_FASTER ); } - (IBAction)slower:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-slower" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_SLOWER ); } - (IBAction)prev:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-prev" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_PREV ); } - (IBAction)next:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-next" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_NEXT ); } - (IBAction)random:(id)sender { vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + playlist_t * p_playlist = pl_Hold( p_intf ); var_Get( p_playlist, "random", &val ); val.b_bool = !val.b_bool; @@ -170,41 +209,48 @@ config_PutInt( p_playlist, "random", 0 ); } - p_intf->p_sys->b_playmode_update = VLC_TRUE; - p_intf->p_sys->b_intf_update = VLC_TRUE; - vlc_object_release( p_playlist ); + p_intf->p_sys->b_playmode_update = true; + p_intf->p_sys->b_intf_update = true; + pl_Release( p_intf ); } /* three little ugly helpers */ - (void)repeatOne { - [o_btn_repeat setImage: [NSImage imageNamed:@"repeat_single_embedded_blue"]]; - [o_btn_repeat setAlternateImage: [NSImage imageNamed:@"repeat_embedded_blue"]]; + [o_btn_repeat setImage: o_repeat_single]; + [o_btn_repeat setAlternateImage: o_repeat_all]; + [o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeatOneOn"]]; } - (void)repeatAll { - [o_btn_repeat setImage: [NSImage imageNamed:@"repeat_embedded_blue"]]; - [o_btn_repeat setAlternateImage: [NSImage imageNamed:@"repeat_embedded"]]; + [o_btn_repeat setImage: o_repeat_all]; + [o_btn_repeat setAlternateImage: o_repeat_off]; + [o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeatOn"]]; } - (void)repeatOff { - [o_btn_repeat setImage: [NSImage imageNamed:@"repeat_embedded"]]; - [o_btn_repeat setAlternateImage: [NSImage imageNamed:@"repeat_single_embedded_blue"]]; + [o_btn_repeat setImage: o_repeat_off]; + [o_btn_repeat setAlternateImage: o_repeat_single]; + [o_btn_repeat_embed setImage: [NSImage imageNamed:@"sidebarRepeat"]]; } - (void)shuffle { vlc_value_t val; - playlist_t *p_playlist = pl_Yield( VLCIntf ); + playlist_t *p_playlist = pl_Hold( VLCIntf ); var_Get( p_playlist, "random", &val ); [o_btn_shuffle setState: val.b_bool]; - vlc_object_release( p_playlist ); + if(val.b_bool) + [o_btn_shuffle_embed setImage: [NSImage imageNamed:@"sidebarShuffleOn"]]; + else + [o_btn_shuffle_embed setImage: [NSImage imageNamed:@"sidebarShuffle"]]; + pl_Release( VLCIntf ); } - (IBAction)repeatButtonAction:(id)sender { vlc_value_t looping,repeating; intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + playlist_t * p_playlist = pl_Hold( p_intf ); var_Get( p_playlist, "repeat", &repeating ); var_Get( p_playlist, "loop", &looping ); @@ -212,59 +258,59 @@ if( !repeating.b_bool && !looping.b_bool ) { /* was: no repeating at all, switching to Repeat One */ - + /* set our button's look */ [self repeatOne]; - + /* prepare core communication */ - repeating.b_bool = VLC_TRUE; - looping.b_bool = VLC_FALSE; + repeating.b_bool = true; + looping.b_bool = false; config_PutInt( p_playlist, "repeat", 1 ); - config_PutInt( p_playlist, "loop", 0 ); - + config_PutInt( p_playlist, "loop", 0 ); + /* show the change */ vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat One" ) ); } else if( repeating.b_bool && !looping.b_bool ) { /* was: Repeat One, switching to Repeat All */ - + /* set our button's look */ [self repeatAll]; - + /* prepare core communication */ - repeating.b_bool = VLC_FALSE; - looping.b_bool = VLC_TRUE; - config_PutInt( p_playlist, "repeat", 0 ); - config_PutInt( p_playlist, "loop", 1 ); - + repeating.b_bool = false; + looping.b_bool = true; + config_PutInt( p_playlist, "repeat", 0 ); + config_PutInt( p_playlist, "loop", 1 ); + /* show the change */ vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat All" ) ); } else { /* was: Repeat All or bug in VLC, switching to Repeat Off */ - + /* set our button's look */ [self repeatOff]; - + /* prepare core communication */ - repeating.b_bool = VLC_FALSE; - looping.b_bool = VLC_FALSE; - config_PutInt( p_playlist, "repeat", 0 ); - config_PutInt( p_playlist, "loop", 0 ); - + repeating.b_bool = false; + looping.b_bool = false; + config_PutInt( p_playlist, "repeat", 0 ); + config_PutInt( p_playlist, "loop", 0 ); + /* show the change */ vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) ); } /* communicate with core and the main intf loop */ var_Set( p_playlist, "repeat", repeating ); - var_Set( p_playlist, "loop", looping ); - p_intf->p_sys->b_playmode_update = VLC_TRUE; - p_intf->p_sys->b_intf_update = VLC_TRUE; + var_Set( p_playlist, "loop", looping ); + p_intf->p_sys->b_playmode_update = true; + p_intf->p_sys->b_intf_update = true; - vlc_object_release( p_playlist ); + pl_Release( p_intf ); } @@ -272,7 +318,7 @@ { vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + playlist_t * p_playlist = pl_Hold( p_intf ); var_Get( p_playlist, "repeat", &val ); if (!val.b_bool) @@ -291,17 +337,17 @@ vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) ); config_PutInt( p_playlist, "repeat", 0 ); } - - p_intf->p_sys->b_playmode_update = VLC_TRUE; - p_intf->p_sys->b_intf_update = VLC_TRUE; - vlc_object_release( p_playlist ); + + p_intf->p_sys->b_playmode_update = true; + p_intf->p_sys->b_intf_update = true; + pl_Release( p_intf ); } - (IBAction)loop:(id)sender { vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); + playlist_t * p_playlist = pl_Hold( p_intf ); var_Get( p_playlist, "loop", &val ); if (!val.b_bool) @@ -321,54 +367,45 @@ config_PutInt( p_playlist, "loop", 0 ); } - p_intf->p_sys->b_playmode_update = VLC_TRUE; - p_intf->p_sys->b_intf_update = VLC_TRUE; - vlc_object_release( p_playlist ); + p_intf->p_sys->b_playmode_update = true; + p_intf->p_sys->b_intf_update = true; + pl_Release( p_intf ); } - (IBAction)forward:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-jump+short" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_JUMP_FORWARD_SHORT ); } - (IBAction)backward:(id)sender { vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-jump-short" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_JUMP_BACKWARD_SHORT ); } - (IBAction)volumeUp:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-vol-up" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_VOL_UP ); /* Manage volume status */ [o_main manageVolumeSlider]; } - (IBAction)volumeDown:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-vol-down" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_VOL_DOWN ); /* Manage volume status */ [o_main manageVolumeSlider]; } - (IBAction)mute:(id)sender { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-vol-mute" ); - var_Set( p_intf->p_libvlc, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_VOL_MUTE ); /* Manage volume status */ [o_main manageVolumeSlider]; } @@ -390,21 +427,19 @@ FIND_ANYWHERE ); if( p_vout != NULL ) { - vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - val.i_int = config_GetInt( p_intf, "key-position" ); - var_Set( p_intf, "key-pressed", val ); + var_SetInteger( p_intf->p_libvlc, "key-action", ACTIONID_POSITION ); vlc_object_release( (vlc_object_t *)p_vout ); } } - (IBAction)toogleFullscreen:(id)sender { - NSMenuItem *o_mi = [[NSMenuItem alloc] initWithTitle: _NS("Fullscreen") action: nil keyEquivalent:@""]; - [self windowAction: [o_mi autorelease]]; + NSMenuItem *o_mi = [[NSMenuItem alloc] initWithTitle: _NS("Fullscreen") action: nil keyEquivalent:@""]; + [self windowAction: [o_mi autorelease]]; } - (BOOL) isFullscreen { - id o_vout_view = [self getVoutView]; + id o_vout_view = [self voutView]; if( o_vout_view ) { return [o_vout_view isFullscreen]; @@ -420,7 +455,7 @@ FIND_ANYWHERE ); if( p_vout != NULL ) { - id o_vout_view = [self getVoutView]; + id o_vout_view = [self voutView]; if( o_vout_view ) { if( [o_title isEqualToString: _NS("Half Size") ] ) @@ -433,7 +468,7 @@ [o_vout_view toggleFloatOnTop]; else if( [o_title isEqualToString: _NS("Fit to Screen") ] ) { - id o_window = [o_vout_view getWindow]; + id o_window = [o_vout_view voutWindow]; if( ![o_window isZoomed] ) [o_window performZoom:self]; } @@ -443,6 +478,7 @@ } else { + /* Fullscreen state for next time will be saved here too */ [o_vout_view toggleFullscreen]; } } @@ -450,7 +486,7 @@ } else { - playlist_t * p_playlist = pl_Yield( VLCIntf ); + playlist_t * p_playlist = pl_Hold( VLCIntf ); if( [o_title isEqualToString: _NS("Fullscreen")] || [sender isKindOfClass:[NSButton class]] ) @@ -460,27 +496,116 @@ var_Set( p_playlist, "fullscreen", (vlc_value_t)!val.b_bool ); } - vlc_object_release( p_playlist ); + pl_Release( VLCIntf ); } } -- (void)scrollWheel:(NSEvent *)theEvent +- (IBAction)telxTransparent:(id)sender +{ + intf_thread_t * p_intf = VLCIntf; + vlc_object_t *p_vbi; + p_vbi = (vlc_object_t *) vlc_object_find_name( p_intf, + "zvbi", FIND_ANYWHERE ); + if( p_vbi ) + { + var_SetBool( p_vbi, "vbi-opaque", [sender state] ); + [sender setState: ![sender state]]; + vlc_object_release( p_vbi ); + } +} + +- (IBAction)telxNavLink:(id)sender { intf_thread_t * p_intf = VLCIntf; - float f_absvalue = [theEvent deltaY] > 0.0f ? [theEvent deltaY] : -[theEvent deltaY]; - int i, i_vlckey; + vlc_object_t *p_vbi; + int i_page = 0; + + if( [[sender title] isEqualToString: _NS("Index")] ) + i_page = 'i' << 16; + else if( [[sender title] isEqualToString: _NS("Red")] ) + i_page = 'r' << 16; + else if( [[sender title] isEqualToString: _NS("Green")] ) + i_page = 'g' << 16; + else if( [[sender title] isEqualToString: _NS("Yellow")] ) + i_page = 'y' << 16; + else if( [[sender title] isEqualToString: _NS("Blue")] ) + i_page = 'b' << 16; + if( i_page == 0 ) return; + + p_vbi = (vlc_object_t *) vlc_object_find_name( p_intf, + "zvbi", FIND_ANYWHERE ); + if( p_vbi ) + { + var_SetInteger( p_vbi, "vbi-page", i_page ); + vlc_object_release( p_vbi ); + } +} - f_absvalue = f_absvalue/2.0f + 1.0f; +- (IBAction)addSubtitleFile:(id)sender +{ + NSInteger i_returnValue = 0; + input_thread_t * p_input = pl_CurrentInput( VLCIntf ); + if( !p_input ) return; + + input_item_t *p_item = input_GetItem( p_input ); + if( !p_item ) return; + + char *path = input_item_GetURI( p_item ); + if( !path ) path = strdup( "" ); + + NSOpenPanel * openPanel = [NSOpenPanel openPanel]; + [openPanel setCanChooseFiles: YES]; + [openPanel setCanChooseDirectories: NO]; + [openPanel setAllowsMultipleSelection: YES]; + i_returnValue = [openPanel runModalForDirectory: [NSString stringWithUTF8String: path] file: nil types: [NSArray arrayWithObjects: @"cdg",@"@idx",@"srt",@"sub",@"utf",@"ass",@"ssa",@"aqt",@"jss",@"psb",@"rt",@"smi", nil]]; + free( path ); + + if( i_returnValue == NSOKButton ) + { + NSUInteger c = 0; + if( !p_input ) return; + + c = [[openPanel filenames] count]; + NSLog( @"count: %i", c ); + for (int i = 0; [[openPanel filenames] count] > i ; i++) + { + msg_Dbg( VLCIntf, "loading subs from %s", [[[openPanel filenames] objectAtIndex: i] UTF8String] ); + if( input_AddSubtitle( p_input, [[[openPanel filenames] objectAtIndex: i] UTF8String], TRUE ) ) + msg_Warn( VLCIntf, "unable to load subtitles from '%s'", + [[[openPanel filenames] objectAtIndex: i] UTF8String] ); + i++; + } + } +} + +- (void)scrollWheel:(NSEvent *)theEvent +{ + intf_thread_t * p_intf = VLCIntf; + float f_yabsvalue = [theEvent deltaY] > 0.0f ? [theEvent deltaY] : -[theEvent deltaY]; + float f_xabsvalue = [theEvent deltaX] > 0.0f ? [theEvent deltaX] : -[theEvent deltaX]; + int i, i_yvlckey, i_xvlckey; if ([theEvent deltaY] < 0.0f) - i_vlckey = KEY_MOUSEWHEELDOWN; + i_yvlckey = KEY_MOUSEWHEELDOWN; + else + i_yvlckey = KEY_MOUSEWHEELUP; + + if ([theEvent deltaX] < 0.0f) + i_xvlckey = KEY_MOUSEWHEELRIGHT; else - i_vlckey = KEY_MOUSEWHEELUP; + i_xvlckey = KEY_MOUSEWHEELLEFT; /* Send multiple key event, depending on the intensity of the event */ - for (i = 0; i < (int)f_absvalue; i++) - var_SetInteger( p_intf->p_libvlc, "key-pressed", i_vlckey ); + for (i = 0; i < (int)(f_yabsvalue/4.+1.) && f_yabsvalue > 0.05 ; i++) + var_SetInteger( p_intf->p_libvlc, "key-pressed", i_yvlckey ); + + /* Prioritize Y event (sound volume) over X event */ + if (f_yabsvalue < 0.05) + { + for (i = 0; i < (int)(f_xabsvalue/6.+1.) && f_xabsvalue > 0.05; i++) + var_SetInteger( p_intf->p_libvlc, "key-pressed", i_xvlckey ); + } } - (BOOL)keyEvent:(NSEvent *)o_event @@ -497,7 +622,7 @@ /* Escape */ if( key == (unichar) 0x1b ) { - id o_vout_view = [self getVoutView]; + id o_vout_view = [self voutView]; if( o_vout_view && [o_vout_view isFullscreen] ) { [o_vout_view toggleFullscreen]; @@ -535,7 +660,7 @@ /* Variable doesn't exist or isn't handled */ return; } - + /* Make sure we want to display the variable */ if( i_type & VLC_VAR_HASCHOICE ) { @@ -544,7 +669,7 @@ if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 ) return; } - + /* Get the descriptive name of the variable */ var_Change( p_object, psz_variable, VLC_VAR_GETTEXT, &text, NULL ); [o_mi setTitle: [[VLCMain sharedInstance] localizedString: text.psz_string ? @@ -557,35 +682,35 @@ [self setupVarMenu: o_menu forMenuItem: o_mi target:p_object var:psz_variable selector:pf_callback]; - - if( text.psz_string ) free( text.psz_string ); + + free( text.psz_string ); return; } - VLCMenuExt *o_data; + VLCAutoGeneratedMenuContent *o_data; switch( i_type & VLC_VAR_TYPE ) { case VLC_VAR_VOID: - o_data = [[VLCMenuExt alloc] initWithVar: psz_variable Object: p_object->i_object_id - Value: val ofType: i_type]; - [o_mi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]]; + o_data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName: psz_variable ofObject: p_object + andValue: val ofType: i_type]; + [o_mi setRepresentedObject: [o_data autorelease]]; break; case VLC_VAR_BOOL: - o_data = [[VLCMenuExt alloc] initWithVar: psz_variable Object: p_object->i_object_id - Value: val ofType: i_type]; - [o_mi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]]; + o_data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName: psz_variable ofObject: p_object + andValue: val ofType: i_type]; + [o_mi setRepresentedObject: [o_data autorelease]]; if( !( i_type & VLC_VAR_ISCOMMAND ) ) [o_mi setState: val.b_bool ? TRUE : FALSE ]; break; default: - if( text.psz_string ) free( text.psz_string ); + free( text.psz_string ); return; } if( ( i_type & VLC_VAR_TYPE ) == VLC_VAR_STRING ) free( val.psz_string ); - if( text.psz_string ) free( text.psz_string ); + free( text.psz_string ); } @@ -649,12 +774,23 @@ /* make (un)sensitive */ [o_parent setEnabled: ( val_list.p_list->i_count > 1 )]; + /* special case for the subtitles items */ + if( [[o_parent title] isEqualToString: _NS("Subtitles Track")] == YES ) + { + NSMenuItem * o_lmi_tmp; + o_lmi_tmp = [o_menu addItemWithTitle: _NS("Open File...") action: @selector(addSubtitleFile:) keyEquivalent: @""]; + [o_lmi_tmp setTarget: self]; + [o_lmi_tmp setEnabled: YES]; + [o_parent setEnabled: YES]; + [o_menu addItem: [NSMenuItem separatorItem]]; + } + for( i = 0; i < val_list.p_list->i_count; i++ ) { vlc_value_t another_val; NSMenuItem * o_lmi; NSString *o_title = @""; - VLCMenuExt *o_data; + VLCAutoGeneratedMenuContent *o_data; switch( i_type & VLC_VAR_TYPE ) { @@ -666,9 +802,9 @@ text_list.p_list->p_values[i].psz_string : val_list.p_list->p_values[i].psz_string ]; o_lmi = [o_menu addItemWithTitle: o_title action: pf_callback keyEquivalent: @""]; - o_data = [[VLCMenuExt alloc] initWithVar: strdup(psz_variable) Object: p_object->i_object_id - Value: another_val ofType: i_type]; - [o_lmi setRepresentedObject: [NSValue valueWithPointer:[o_data retain]]]; + o_data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName: strdup(psz_variable) ofObject: p_object + andValue: another_val ofType: i_type]; + [o_lmi setRepresentedObject: [o_data autorelease]]; [o_lmi setTarget: self]; if( !strcmp( val.psz_string, val_list.p_list->p_values[i].psz_string ) && !( i_type & VLC_VAR_ISCOMMAND ) ) @@ -683,10 +819,10 @@ [NSString stringWithFormat: @"%d", val_list.p_list->p_values[i].i_int]; - o_lmi = [[o_menu addItemWithTitle: o_title action: pf_callback keyEquivalent: @""] retain ]; - o_data = [[VLCMenuExt alloc] initWithVar: strdup(psz_variable) Object: p_object->i_object_id - Value: val_list.p_list->p_values[i] ofType: i_type]; - [o_lmi setRepresentedObject: [NSValue valueWithPointer:[ o_data retain]]]; + o_lmi = [o_menu addItemWithTitle: o_title action: pf_callback keyEquivalent: @""]; + o_data = [[VLCAutoGeneratedMenuContent alloc] initWithVariableName: strdup(psz_variable) ofObject: p_object + andValue: val_list.p_list->p_values[i] ofType: i_type]; + [o_lmi setRepresentedObject: [o_data autorelease]]; [o_lmi setTarget: self]; if( val_list.p_list->p_values[i].i_int == val.i_int && !( i_type & VLC_VAR_ISCOMMAND ) ) @@ -698,38 +834,47 @@ } } + /* special case for the subtitles sub-menu + * In case that we don't have any subs, we don't want a separator item at the end */ + if( [[o_parent title] isEqualToString: _NS("Subtitles Track")] == YES ) + { + if( [o_menu numberOfItems] == 2 ) + [o_menu removeItemAtIndex: 1]; + } + /* clean up everything */ if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string ); - var_Change( p_object, psz_variable, VLC_VAR_FREELIST, &val_list, &text_list ); + var_FreeList( &val_list, &text_list ); } - (IBAction)toggleVar:(id)sender { NSMenuItem *o_mi = (NSMenuItem *)sender; - VLCMenuExt *o_data = [[o_mi representedObject] pointerValue]; + VLCAutoGeneratedMenuContent *o_data = [o_mi representedObject]; [NSThread detachNewThreadSelector: @selector(toggleVarThread:) toTarget: self withObject: o_data]; return; } -- (int)toggleVarThread: (id)_o_data +- (int)toggleVarThread: (id)data { vlc_object_t *p_object; NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; - VLCMenuExt *o_data = (VLCMenuExt *)_o_data; + + assert([data isKindOfClass:[VLCAutoGeneratedMenuContent class]]); + VLCAutoGeneratedMenuContent *menuContent = (VLCAutoGeneratedMenuContent *)data; vlc_thread_set_priority( VLCIntf , VLC_THREAD_PRIORITY_LOW ); - p_object = (vlc_object_t *)vlc_object_get( VLCIntf, - [o_data objectID] ); + p_object = [menuContent vlcObject]; if( p_object != NULL ) { - var_Set( p_object, strdup([o_data name]), [o_data value] ); + var_Set( p_object, [menuContent name], [menuContent value] ); vlc_object_release( p_object ); [o_pool release]; - return VLC_TRUE; + return true; } [o_pool release]; return VLC_EGENERIC; @@ -744,13 +889,12 @@ } else if( sender == o_specificTime_ok_btn ) { - input_thread_t * p_input = (input_thread_t *)vlc_object_find( VLCIntf, \ - VLC_OBJECT_INPUT, FIND_ANYWHERE ); + input_thread_t * p_input = pl_CurrentInput( VLCIntf ); if( p_input ) { unsigned int timeInSec = 0; NSString * fieldContent = [o_specificTime_enter_fld stringValue]; - if( [[fieldContent componentsSeparatedByString: @":"] count] > 1 && + if( [[fieldContent componentsSeparatedByString: @":"] count] > 1 && [[fieldContent componentsSeparatedByString: @":"] count] <= 3 ) { NSArray * ourTempArray = \ @@ -774,14 +918,13 @@ input_Control( p_input, INPUT_SET_TIME, (int64_t)(timeInSec * 1000000)); vlc_object_release( p_input ); } - + [NSApp endSheet: o_specificTime_win]; [o_specificTime_win close]; } else { - input_thread_t * p_input = (input_thread_t *)vlc_object_find( VLCIntf, \ - VLC_OBJECT_INPUT, FIND_ANYWHERE ); + input_thread_t * p_input = pl_CurrentInput( VLCIntf ); if( p_input ) { /* we can obviously only do that if an input is available */ @@ -800,7 +943,7 @@ } } -- (id)getFSPanel +- (id)fspanel { if( o_fs_panel ) return o_fs_panel; @@ -820,18 +963,15 @@ BOOL bEnabled = TRUE; vlc_value_t val; intf_thread_t * p_intf = VLCIntf; - playlist_t * p_playlist = pl_Yield( p_intf ); - - vlc_mutex_lock( &p_playlist->object_lock ); - -#define p_input p_playlist->p_input + playlist_t * p_playlist = pl_Hold( p_intf ); + input_thread_t * p_input = playlist_CurrentInput( p_playlist ); if( [[o_mi title] isEqualToString: _NS("Faster")] || [[o_mi title] isEqualToString: _NS("Slower")] ) { if( p_input != NULL ) { - bEnabled = p_input->b_can_pace_control; + bEnabled = var_GetBool( p_input, "can-rate" ); } else { @@ -849,8 +989,10 @@ else if( [[o_mi title] isEqualToString: _NS("Previous")] || [[o_mi title] isEqualToString: _NS("Next")] ) { - /** \todo fix i_size use */ - bEnabled = p_playlist->items.i_size > 1; + /** \todo fix i_size use */ + PL_LOCK; + bEnabled = p_playlist->items.i_size > 1; + PL_UNLOCK; } else if( [[o_mi title] isEqualToString: _NS("Random")] ) { @@ -879,7 +1021,7 @@ { if( p_input != NULL ) { - var_Get( p_input, "seekable", &val); + var_Get( p_input, "can-seek", &val); bEnabled = val.b_bool; } else bEnabled = FALSE; @@ -901,7 +1043,7 @@ NSArray *o_windows = [NSApp orderedWindows]; NSEnumerator *o_enumerator = [o_windows objectEnumerator]; bEnabled = FALSE; - + vout_thread_t *p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE ); if( p_vout != NULL ) @@ -915,16 +1057,17 @@ while( (o_window = [o_enumerator nextObject])) { if( [[o_window className] isEqualToString: @"VLCVoutWindow"] || - [[[VLCMain sharedInstance] getEmbeddedList] + [[[VLCMain sharedInstance] embeddedList] windowContainsEmbedded: o_window]) { bEnabled = TRUE; break; } } + vlc_object_release( (vlc_object_t *)p_vout ); } - else if( [[o_mi title] isEqualToString: _NS("Fullscreen")] ) + if( [[o_mi title] isEqualToString: _NS("Fullscreen")] ) { var_Get( p_playlist, "fullscreen", &val ); [o_mi setState: val.b_bool]; @@ -933,8 +1076,21 @@ [o_main setupMenus]; /* Make sure video menu is up to date */ } - vlc_mutex_unlock( &p_playlist->object_lock ); - vlc_object_release( p_playlist ); + /* Special case for telx menu */ + if( [[o_mi title] isEqualToString: _NS("Normal Size")] ) + { + NSMenuItem *item = [[o_mi menu] itemWithTitle:_NS("Teletext")]; + bool b_telx = p_input && var_GetInteger( p_input, "teletext-es" ) >= 0; + + [[item submenu] setAutoenablesItems:NO]; + for( int k=0; k < [[item submenu] numberOfItems]; k++ ) + { + [[[item submenu] itemAtIndex:k] setEnabled: b_telx]; + } + } + + if( p_input ) vlc_object_release( p_input ); + pl_Release( p_intf ); return( bEnabled ); } @@ -942,24 +1098,24 @@ @end /***************************************************************************** - * VLCMenuExt implementation + * VLCAutoGeneratedMenuContent implementation ***************************************************************************** * Object connected to a playlistitem which remembers the data belonging to * the variable of the autogenerated menu *****************************************************************************/ -@implementation VLCMenuExt +@implementation VLCAutoGeneratedMenuContent -- (id)initWithVar: (const char *)_psz_name Object: (int)i_id - Value: (vlc_value_t)val ofType: (int)_i_type +-(id) initWithVariableName:(const char *)name ofObject:(vlc_object_t *)object + andValue:(vlc_value_t)val ofType:(int)type { self = [super init]; if( self != nil ) { - psz_name = strdup( _psz_name ); - i_object_id = i_id; + psz_name = strdup( name ); + _vlc_object = vlc_object_hold( object ); value = val; - i_type = _i_type; + i_type = type; } return( self ); @@ -967,25 +1123,27 @@ - (void)dealloc { + vlc_object_release( _vlc_object ); free( psz_name ); [super dealloc]; } -- (char *)name +- (const char *)name { return psz_name; } -- (int)objectID +- (vlc_value_t)value { - return i_object_id; + return value; } -- (vlc_value_t)value +- (vlc_object_t *)vlcObject { - return value; + return vlc_object_hold( _vlc_object ); } + - (int)type { return i_type; @@ -995,7 +1153,7 @@ /***************************************************************************** - * VLCTimeField implementation + * VLCTimeField implementation ***************************************************************************** * we need this to catch our click-event in the controller window *****************************************************************************/ @@ -1004,6 +1162,8 @@ - (void)mouseDown: (NSEvent *)ourEvent { if( [ourEvent clickCount] > 1 ) - [[[VLCMain sharedInstance] getControls] goToSpecificTime: nil]; + [[[VLCMain sharedInstance] controls] goToSpecificTime: nil]; + else + [[VLCMain sharedInstance] timeFieldWasClicked: self]; } @end