X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fmacosx%2Fcontrols.m;h=ffecbac7691be84bf919d0a7be726f6797f87ee7;hb=b58dfe3584f7a60fcd5afbdac903b513f7082804;hp=cdfbc016f4b0964efc34bc62427ddeb32c2ee0f8;hpb=e56eff610ae3c0c4386b860710256f0c24bd1a29;p=vlc diff --git a/modules/gui/macosx/controls.m b/modules/gui/macosx/controls.m index cdfbc016f4..ffecbac769 100644 --- a/modules/gui/macosx/controls.m +++ b/modules/gui/macosx/controls.m @@ -1,12 +1,13 @@ /***************************************************************************** - * controls.m: MacOS X interface plugin + * controls.m: MacOS X interface module ***************************************************************************** - * Copyright (C) 2002 VideoLAN - * $Id: controls.m,v 1.13 2003/01/24 00:53:41 hartman Exp $ + * Copyright (C) 2002-2005 the VideoLAN team + * $Id$ * * Authors: Jon Lech Johansen * Christophe Massiot - * Derk-Jan Hartman + * Derk-Jan Hartman + * Benjamin Pracht * * 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 @@ -20,7 +21,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** @@ -30,217 +31,96 @@ #include /* for MAXPATHLEN */ #include -#include -#include -#include - -#include -#include - #include "intf.h" #include "vout.h" - -/***************************************************************************** - * VLCControls interface - *****************************************************************************/ -@interface VLCControls : NSObject -{ - IBOutlet id o_open; - IBOutlet id o_main; - IBOutlet id o_mi_mute; - IBOutlet id o_volumeslider; - int i_ff; -} - -- (IBAction)play:(id)sender; -- (IBAction)stop:(id)sender; -- (IBAction)faster:(id)sender; -- (IBAction)slower:(id)sender; -- (IBAction)slowMotion:(id)sender; -- (IBAction)fastForward:(id)sender; - -- (IBAction)prev:(id)sender; -- (IBAction)next:(id)sender; -- (IBAction)loop:(id)sender; - -- (IBAction)volumeUp:(id)sender; -- (IBAction)volumeDown:(id)sender; -- (IBAction)mute:(id)sender; -- (IBAction)volumeSliderUpdate:(id)sender; -- (IBAction)fullscreen:(id)sender; -- (IBAction)deinterlace:(id)sender; - -- (IBAction)toggleProgram:(id)sender; -- (IBAction)toggleTitle:(id)sender; -- (IBAction)toggleChapter:(id)sender; -- (IBAction)toggleLanguage:(id)sender; -- (IBAction)toggleVar:(id)sender; - -- (void)setVolumeSlider; - -@end +#include "open.h" +#include "controls.h" +#include /***************************************************************************** * VLCControls implementation *****************************************************************************/ @implementation VLCControls +- (void)awakeFromNib +{ + [o_specificTime_mi setTitle: _NS("Go To Position")]; + [o_specificTime_cancel_btn setTitle: _NS("Cancel")]; + [o_specificTime_ok_btn setTitle: _NS("OK")]; + [o_specificTime_sec_lbl setStringValue: _NS("sec.")]; + [o_specificTime_goTo_lbl setStringValue: _NS("Go to specific position")]; +} + - (IBAction)play:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); - if( p_playlist == NULL ) + FIND_ANYWHERE ); + if( p_playlist ) { - return; - } - - if ( p_intf->p_sys->p_input != NULL && p_intf->p_sys->p_input->stream.control.i_status != PAUSE_S) - { - input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE ); - vlc_object_release( p_playlist ); - } - else - { - /* If the playlist is empty, open a file requester instead */ vlc_mutex_lock( &p_playlist->object_lock ); - if( p_playlist->i_size ) + if( p_playlist->i_size <= 0 ) { vlc_mutex_unlock( &p_playlist->object_lock ); - playlist_Play( p_playlist ); vlc_object_release( p_playlist ); + [o_main intfOpenFileGeneric: (id)sender]; } else { vlc_mutex_unlock( &p_playlist->object_lock ); vlc_object_release( p_playlist ); - - [o_open openFile: nil]; } + } + val.i_int = config_GetInt( p_intf, "key-play-pause" ); + var_Set( p_intf->p_vlc, "key-pressed", val ); } - (IBAction)stop:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); - if( p_playlist == NULL ) - { - return; - } - - playlist_Stop( p_playlist ); - vlc_object_release( p_playlist ); - p_intf->p_sys->b_stopping = 1; + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; + val.i_int = config_GetInt( p_intf, "key-stop" ); + var_Set( p_intf->p_vlc, "key-pressed", val ); } - (IBAction)faster:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - - if( p_intf->p_sys->p_input == NULL ) - { - return; - } - - input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_FASTER ); + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; + val.i_int = config_GetInt( p_intf, "key-faster" ); + var_Set( p_intf->p_vlc, "key-pressed", val ); } - (IBAction)slower:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - - if( p_intf->p_sys->p_input == NULL ) - { - return; - } - - input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_SLOWER ); + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; + val.i_int = config_GetInt( p_intf, "key-slower" ); + var_Set( p_intf->p_vlc, "key-pressed", val ); } -- (IBAction)slowMotion:(id)sender +- (IBAction)prev:(id)sender { - i_ff++; - switch( [[NSApp currentEvent] type] ) - { - case NSPeriodic: - if ( i_ff == 1 ) - { - [self slower:sender]; - } - break; - - case NSLeftMouseUp: - if ( i_ff > 1 ) - { - intf_thread_t * p_intf = [NSApp getIntf]; - - [self faster:sender]; - if ( p_intf->p_sys->p_input != NULL && - p_intf->p_sys->p_input->stream.control.i_status != PAUSE_S) - { - input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE ); - } - } - i_ff = 0; - break; - - default: - break; - } + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; + val.i_int = config_GetInt( p_intf, "key-prev" ); + var_Set( p_intf->p_vlc, "key-pressed", val ); } -- (IBAction)fastForward:(id)sender +- (IBAction)next:(id)sender { - playlist_t * p_playlist = vlc_object_find( [NSApp getIntf], VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); - - i_ff++; - switch( [[NSApp currentEvent] type] ) - { - /* A button does not send a NSLeftMouseDown unfortunately. - * Therefore we need to count. I know, it is ugly. We could have used - * a bool as well, but now we can also accellerate after a certain period. - * Currently this method is called every second if the button is pressed. - * You can set this value in intf.m (hartman) - */ - case NSPeriodic: - if ( i_ff == 1 ) - { - [self faster:self]; - } - else if ( i_ff == 5 ) - { - [self faster:self]; - } - else if ( i_ff == 15 ) - { - [self faster:self]; - } - break; - - case NSLeftMouseUp: - i_ff = 0; - - vlc_mutex_lock( &p_playlist->object_lock ); - int i_playlist_size = p_playlist->i_size ; - vlc_mutex_unlock( &p_playlist->object_lock ); - if( i_playlist_size ) - { - playlist_Play( p_playlist ); - } - break; - - default: - break; - } - vlc_object_release( p_playlist ); + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; + val.i_int = config_GetInt( p_intf, "key-next" ); + var_Set( p_intf->p_vlc, "key-pressed", val ); } -- (IBAction)prev:(id)sender +- (IBAction)random:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist == NULL ) @@ -248,13 +128,27 @@ return; } - playlist_Prev( p_playlist ); + var_Get( p_playlist, "random", &val ); + val.b_bool = !val.b_bool; + var_Set( p_playlist, "random", val ); + if( val.b_bool ) + { + vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Random On" ) ); + } + else + { + vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Random Off" ) ); + } + + p_intf->p_sys->b_playmode_update = VLC_TRUE; + p_intf->p_sys->b_intf_update = VLC_TRUE; vlc_object_release( p_playlist ); } -- (IBAction)next:(id)sender +- (IBAction)repeat:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist == NULL ) @@ -262,14 +156,31 @@ return; } - playlist_Next( p_playlist ); + var_Get( p_playlist, "repeat", &val ); + if (!val.b_bool) + { + var_Set( p_playlist, "loop", val ); + } + val.b_bool = !val.b_bool; + var_Set( p_playlist, "repeat", val ); + if( val.b_bool ) + { + vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat One" ) ); + } + else + { + vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) ); + } + + p_intf->p_sys->b_playmode_update = VLC_TRUE; + p_intf->p_sys->b_intf_update = VLC_TRUE; vlc_object_release( p_playlist ); } - (IBAction)loop:(id)sender { - NSMenuItem * o_mi = (NSMenuItem *)sender; - intf_thread_t * p_intf = [NSApp getIntf]; + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist == NULL ) @@ -277,254 +188,416 @@ return; } - if( p_intf->p_sys->b_loop ) + var_Get( p_playlist, "loop", &val ); + if (!val.b_bool) + { + var_Set( p_playlist, "repeat", val ); + } + val.b_bool = !val.b_bool; + var_Set( p_playlist, "loop", val ); + if( val.b_bool ) { - [o_mi setState: NSOffState]; - config_PutInt( p_playlist, "loop", 0 ); + vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat All" ) ); } else { - [o_mi setState: NSOnState]; - config_PutInt( p_playlist, "loop", 1 ); + vout_OSDMessage( p_intf, DEFAULT_CHAN, _( "Repeat Off" ) ); } - p_intf->p_sys->b_loop = !p_intf->p_sys->b_loop; - + p_intf->p_sys->b_playmode_update = VLC_TRUE; + p_intf->p_sys->b_intf_update = VLC_TRUE; vlc_object_release( p_playlist ); } +- (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_vlc, "key-pressed", val ); +} + +- (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_vlc, "key-pressed", val ); +} + + - (IBAction)volumeUp:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - if ( p_aout != NULL ) - { - if (p_intf->p_sys->b_mute) - { - [self mute:o_mi_mute]; - } - aout_VolumeUp( p_aout, 1, NULL ); - vlc_object_release( (vlc_object_t *)p_aout ); - } - [self setVolumeSlider]; + 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_vlc, "key-pressed", val ); + /* Manage volume status */ + [o_main manageVolumeSlider]; } - (IBAction)volumeDown:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - if ( p_aout != NULL ) - { - if (p_intf->p_sys->b_mute) - { - [self mute:o_mi_mute]; - } - aout_VolumeDown( p_aout, 1, NULL ); - vlc_object_release( (vlc_object_t *)p_aout ); - } - [self setVolumeSlider]; + 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_vlc, "key-pressed", val ); + /* Manage volume status */ + [o_main manageVolumeSlider]; } - (IBAction)mute:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - audio_volume_t i_volume; - - if ( p_aout != NULL ) - { - aout_VolumeMute( p_aout, &i_volume ); - vlc_object_release( (vlc_object_t *)p_aout ); - } - - p_intf->p_sys->b_mute = (i_volume == 0); - [o_mi_mute setState: p_intf->p_sys->b_mute ? NSOnState : NSOffState]; - [o_volumeslider setEnabled: p_intf->p_sys->b_mute ? FALSE : TRUE]; - [self setVolumeSlider]; + 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_vlc, "key-pressed", val ); + /* Manage volume status */ + [o_main manageVolumeSlider]; } -- (IBAction)volumeSliderUpdate:(id)sender +- (IBAction)volumeSliderUpdated:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - audio_volume_t i_volume; - - if ( p_aout != NULL ) - { - i_volume = (int) [sender floatValue]; - aout_VolumeSet( p_aout, i_volume * AOUT_VOLUME_STEP); - vlc_object_release( (vlc_object_t *)p_aout ); - } + intf_thread_t * p_intf = VLCIntf; + audio_volume_t i_volume = (audio_volume_t)[sender intValue]; + int i_volume_step = 0; + i_volume_step = config_GetInt( p_intf->p_vlc, "volume-step" ); + aout_VolumeSet( p_intf, i_volume * i_volume_step ); + /* Manage volume status */ + [o_main manageVolumeSlider]; } -- (void)setVolumeSlider +- (IBAction)windowAction:(id)sender { - intf_thread_t * p_intf = [NSApp getIntf]; - aout_instance_t * p_aout = vlc_object_find( p_intf, VLC_OBJECT_AOUT, - FIND_ANYWHERE ); - audio_volume_t i_volume; - - if ( p_aout != NULL ) + id o_window = [NSApp keyWindow]; + NSString *o_title = [sender title]; + NSArray *o_windows = [NSApp orderedWindows]; + NSEnumerator *o_enumerator = [o_windows objectEnumerator]; + vout_thread_t *p_vout = vlc_object_find( VLCIntf, VLC_OBJECT_VOUT, + FIND_ANYWHERE ); + + if( p_vout != NULL ) { - aout_VolumeGet( p_aout, &i_volume ); - vlc_object_release( (vlc_object_t *)p_aout ); - [o_volumeslider setFloatValue: (float) (i_volume / AOUT_VOLUME_STEP)]; + id o_embedded_vout_list = [[VLCMain sharedInstance] getEmbeddedList]; + while ((o_window = [o_enumerator nextObject])) + { + id o_vout_view = nil; + /* We have an embedded vout */ + if( [o_embedded_vout_list windowContainsEmbedded: o_window] ) + { + o_vout_view = [o_embedded_vout_list getViewForWindow: o_window]; + } + /* We have a detached Vout */ + else if( [[o_window className] isEqualToString: @"VLCWindow"] ) + { + msg_Dbg( VLCIntf, "detached vout controls.m call getVoutView" ); + o_vout_view = [o_window getVoutView]; + } + + if( o_vout_view ) + { + if( [o_title isEqualToString: _NS("Half Size") ] ) + [o_vout_view scaleWindowWithFactor: 0.5]; + else if( [o_title isEqualToString: _NS("Normal Size") ] ) + [o_vout_view scaleWindowWithFactor: 1.0]; + else if( [o_title isEqualToString: _NS("Double Size") ] ) + [o_vout_view scaleWindowWithFactor: 2.0]; + else if( [o_title isEqualToString: _NS("Float on Top") ] ) + [o_vout_view toggleFloatOnTop]; + else if( [o_title isEqualToString: _NS("Fit to Screen") ] ) + { + if( ![o_window isZoomed] ) + [o_window performZoom:self]; + } + else if( [o_title isEqualToString: _NS("Snapshot") ] ) + { + [o_vout_view snapshot]; + } + else + { + [o_vout_view toggleFullscreen]; + } + break; + } + } + vlc_object_release( (vlc_object_t *)p_vout ); } else { - [o_volumeslider setFloatValue: config_GetInt( p_intf, "volume" )]; - } -} + playlist_t * p_playlist = vlc_object_find( VLCIntf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); -- (IBAction)fullscreen:(id)sender -{ - id o_window = [NSApp keyWindow]; - NSArray *o_windows = [NSApp windows]; - NSEnumerator *o_enumerator = [o_windows objectEnumerator]; - - while ((o_window = [o_enumerator nextObject])) - { - if( [[o_window className] isEqualToString: @"VLCWindow"] ) + if( p_playlist && ( [o_title isEqualToString: _NS("Fullscreen")] || + [sender isKindOfClass:[NSButton class]] ) ) { - [o_window toggleFullscreen]; + vlc_value_t val; + var_Get( p_playlist, "fullscreen", &val ); + var_Set( p_playlist, "fullscreen", (vlc_value_t)!val.b_bool ); } + if( p_playlist ) vlc_object_release( (vlc_object_t *)p_playlist ); } + } -- (IBAction)deinterlace:(id)sender +- (void)setupVarMenuItem:(NSMenuItem *)o_mi + target:(vlc_object_t *)p_object + var:(const char *)psz_variable + selector:(SEL)pf_callback { - intf_thread_t * p_intf = [NSApp getIntf]; - BOOL bEnable = [sender state] == NSOffState; + vlc_value_t val, text; + int i_type = var_Type( p_object, psz_variable ); - if( bEnable ) + switch( i_type & VLC_VAR_TYPE ) { - config_PutPsz( p_intf, "filter", "deinterlace" ); - config_PutPsz( p_intf, "deinterlace-mode", - [[sender title] lossyCString] ); + case VLC_VAR_VOID: + case VLC_VAR_BOOL: + case VLC_VAR_VARIABLE: + case VLC_VAR_STRING: + case VLC_VAR_INTEGER: + break; + default: + /* Variable doesn't exist or isn't handled */ + return; } - else + + /* Make sure we want to display the variable */ + if( i_type & VLC_VAR_HASCHOICE ) { - config_PutPsz( p_intf, "filter", NULL ); + var_Change( p_object, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL ); + if( val.i_int == 0 ) return; + if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 ) + return; } -} - -- (IBAction)toggleProgram:(id)sender -{ - NSMenuItem * o_mi = (NSMenuItem *)sender; - intf_thread_t * p_intf = [NSApp getIntf]; + + /* 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 ? + text.psz_string : strdup( psz_variable ) ]]; - if( [o_mi state] == NSOffState ) + var_Get( p_object, psz_variable, &val ); + if( i_type & VLC_VAR_HASCHOICE ) { - u16 i_program_id = [o_mi tag]; + NSMenu *o_menu = [o_mi submenu]; - input_ChangeProgram( p_intf->p_sys->p_input, i_program_id ); - input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PLAY ); + [self setupVarMenu: o_menu forMenuItem: o_mi target:p_object + var:psz_variable selector:pf_callback]; + + if( text.psz_string ) free( text.psz_string ); + return; } + + VLCMenuExt *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]]]; + 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]]]; + if( !( i_type & VLC_VAR_ISCOMMAND ) ) + [o_mi setState: val.b_bool ? TRUE : FALSE ]; + break; + + default: + if( 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 ); } -- (IBAction)toggleTitle:(id)sender + +- (void)setupVarMenu:(NSMenu *)o_menu + forMenuItem: (NSMenuItem *)o_parent + target:(vlc_object_t *)p_object + var:(const char *)psz_variable + selector:(SEL)pf_callback { - NSMenuItem * o_mi = (NSMenuItem *)sender; - intf_thread_t * p_intf = [NSApp getIntf]; + vlc_value_t val, val_list, text_list; + int i_type, i, i_nb_items; - if( [o_mi state] == NSOffState ) + /* remove previous items */ + i_nb_items = [o_menu numberOfItems]; + for( i = 0; i < i_nb_items; i++ ) { - int i_title = [o_mi tag]; - -#define p_input p_intf->p_sys->p_input - input_ChangeArea( p_input, p_input->stream.pp_areas[i_title] ); - input_SetStatus( p_input, INPUT_STATUS_PLAY ); -#undef p_input + [o_menu removeItemAtIndex: 0]; } -} -- (IBAction)toggleChapter:(id)sender -{ - NSMenuItem * o_mi = (NSMenuItem *)sender; - intf_thread_t * p_intf = [NSApp getIntf]; + /* Check the type of the object variable */ + i_type = var_Type( p_object, psz_variable ); + + /* Make sure we want to display the variable */ + if( i_type & VLC_VAR_HASCHOICE ) + { + var_Change( p_object, psz_variable, VLC_VAR_CHOICESCOUNT, &val, NULL ); + if( val.i_int == 0 ) return; + if( (i_type & VLC_VAR_TYPE) != VLC_VAR_VARIABLE && val.i_int == 1 ) + return; + } + else + { + return; + } - if( [o_mi state] == NSOffState ) + switch( i_type & VLC_VAR_TYPE ) { - int i_chapter = [o_mi tag]; + case VLC_VAR_VOID: + case VLC_VAR_BOOL: + case VLC_VAR_VARIABLE: + case VLC_VAR_STRING: + case VLC_VAR_INTEGER: + break; + default: + /* Variable doesn't exist or isn't handled */ + return; + } -#define p_input p_intf->p_sys->p_input - p_input->stream.p_selected_area->i_part = i_chapter; - input_ChangeArea( p_input, p_input->stream.p_selected_area ); - input_SetStatus( p_input, INPUT_STATUS_PLAY ); -#undef p_input + if( var_Get( p_object, psz_variable, &val ) < 0 ) + { + return; } -} -- (IBAction)toggleLanguage:(id)sender -{ - NSMenuItem * o_mi = (NSMenuItem *)sender; - intf_thread_t * p_intf = [NSApp getIntf]; + if( var_Change( p_object, psz_variable, VLC_VAR_GETLIST, + &val_list, &text_list ) < 0 ) + { + if( (i_type & VLC_VAR_TYPE) == VLC_VAR_STRING ) free( val.psz_string ); + return; + } -#define p_input p_intf->p_sys->p_input + /* make (un)sensitive */ + [o_parent setEnabled: ( val_list.p_list->i_count > 1 )]; - if( !p_intf->p_sys->b_audio_update ) + for( i = 0; i < val_list.p_list->i_count; i++ ) { - NSValue * o_value = [o_mi representedObject]; - es_descriptor_t * p_es = [o_value pointerValue]; + vlc_value_t another_val; + NSMenuItem * o_lmi; + NSString *o_title = @""; + VLCMenuExt *o_data; - if( [o_mi state] == NSOnState ) + switch( i_type & VLC_VAR_TYPE ) { - /* we just have one ES to disable */ - input_ToggleES( p_input, p_es, 0 ); - } - else - { - unsigned int i; - int i_cat = [o_mi tag]; + case VLC_VAR_STRING: + another_val.psz_string = + strdup(val_list.p_list->p_values[i].psz_string); - vlc_mutex_lock( &p_input->stream.stream_lock ); + o_title = [[VLCMain sharedInstance] localizedString: text_list.p_list->p_values[i].psz_string ? + text_list.p_list->p_values[i].psz_string : val_list.p_list->p_values[i].psz_string ]; -#define ES p_input->stream.pp_selected_es[i] + 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_lmi setTarget: self]; - /* unselect the selected ES in the same class */ - for( i = 0; i < p_input->stream.i_selected_es_number; i++ ) - { - if( ES->i_cat == i_cat ) - { - vlc_mutex_unlock( &p_input->stream.stream_lock ); - input_ToggleES( p_input, ES, 0 ); - vlc_mutex_lock( &p_input->stream.stream_lock ); - break; - } - } + if( !strcmp( val.psz_string, val_list.p_list->p_values[i].psz_string ) && !( i_type & VLC_VAR_ISCOMMAND ) ) + [o_lmi setState: TRUE ]; + + break; -#undef ES + case VLC_VAR_INTEGER: - vlc_mutex_unlock( &p_input->stream.stream_lock ); + o_title = text_list.p_list->p_values[i].psz_string ? + [[VLCMain sharedInstance] localizedString: strdup( text_list.p_list->p_values[i].psz_string )] : + [NSString stringWithFormat: @"%d", + val_list.p_list->p_values[i].i_int]; - input_ToggleES( p_input, p_es, 1 ); + 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 setTarget: self]; + + if( val_list.p_list->p_values[i].i_int == val.i_int && !( i_type & VLC_VAR_ISCOMMAND ) ) + [o_lmi setState: TRUE ]; + break; + + default: + break; } } -#undef p_input + /* 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 ); } - (IBAction)toggleVar:(id)sender { - NSMenuItem * o_mi = (NSMenuItem *)sender; + NSMenuItem *o_mi = (NSMenuItem *)sender; + VLCMenuExt *o_data = [[o_mi representedObject] pointerValue]; + [NSThread detachNewThreadSelector: @selector(toggleVarThread:) + toTarget: self withObject: o_data]; - if( [o_mi state] == NSOffState ) + return; +} + +- (int)toggleVarThread: (id)_o_data +{ + vlc_object_t *p_object; + NSAutoreleasePool * o_pool = [[NSAutoreleasePool alloc] init]; + VLCMenuExt *o_data = (VLCMenuExt *)_o_data; + + vlc_thread_set_priority( VLCIntf , VLC_THREAD_PRIORITY_LOW ); + + p_object = (vlc_object_t *)vlc_object_get( VLCIntf, + [o_data objectID] ); + + if( p_object != NULL ) { - const char * psz_variable = (const char *)[o_mi tag]; - const char * psz_value = [[o_mi title] cString]; - vlc_object_t * p_object = (vlc_object_t *) - [[o_mi representedObject] pointerValue]; - vlc_value_t val; - /* psz_string sucks */ - val.psz_string = (char *)psz_value; + var_Set( p_object, strdup([o_data name]), [o_data value] ); + vlc_object_release( p_object ); + [o_pool release]; + return VLC_TRUE; + } + [o_pool release]; + return VLC_EGENERIC; +} - if ( var_Set( p_object, psz_variable, val ) < 0 ) +- (IBAction)goToSpecificTime:(id)sender +{ + if( sender == o_specificTime_cancel_btn ) + { + [NSApp endSheet: o_specificTime_win]; + [o_specificTime_win close]; + } + else if( sender == o_specificTime_ok_btn ) + { + input_thread_t * p_input = (input_thread_t *)vlc_object_find( VLCIntf, \ + VLC_OBJECT_INPUT, FIND_ANYWHERE ); + if( p_input ) { - msg_Warn( p_object, "cannot set variable (%s)", psz_value ); + input_Control( p_input, INPUT_SET_TIME, \ + (int64_t)([o_specificTime_enter_fld intValue] * 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 ); + if( p_input ) + { + /* we can obviously only do that if an input is available */ + vlc_value_t pos, length; + var_Get( p_input, "time", &pos ); + [o_specificTime_enter_fld setIntValue: (pos.i_time / 1000000)]; + var_Get( p_input, "length", &length ); + [o_specificTime_stepper setMaxValue: (length.i_time / 1000000)]; + + [NSApp beginSheet: o_specificTime_win modalForWindow: \ + [NSApp mainWindow] modalDelegate: self didEndSelector: nil \ + contextInfo: nil]; + [o_specificTime_win makeKeyWindow]; + vlc_object_release( p_input ); } } } @@ -536,19 +609,25 @@ - (BOOL)validateMenuItem:(NSMenuItem *)o_mi { BOOL bEnabled = TRUE; - NSMenu * o_menu = [o_mi menu]; - intf_thread_t * p_intf = [NSApp getIntf]; + vlc_value_t val; + intf_thread_t * p_intf = VLCIntf; + playlist_t * p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + FIND_ANYWHERE ); + + if( p_playlist != NULL ) + { + vlc_mutex_lock( &p_playlist->object_lock ); + } + else return FALSE; + +#define p_input p_playlist->p_input if( [[o_mi title] isEqualToString: _NS("Faster")] || [[o_mi title] isEqualToString: _NS("Slower")] ) { - if( p_intf->p_sys->p_input != NULL ) + if( p_input != NULL ) { -#define p_input p_intf->p_sys->p_input - vlc_mutex_lock( &p_input->stream.stream_lock ); - bEnabled = p_input->stream.b_pace_control; - vlc_mutex_unlock( &p_input->stream.stream_lock ); -#undef p_input + bEnabled = p_input->input.b_can_pace_control; } else { @@ -557,74 +636,167 @@ } else if( [[o_mi title] isEqualToString: _NS("Stop")] ) { - bEnabled = p_intf->p_sys->p_input != NULL; + if( p_input == NULL ) + { + bEnabled = FALSE; + } + [o_main setupMenus]; /* Make sure input menu is up to date */ } else if( [[o_mi title] isEqualToString: _NS("Previous")] || [[o_mi title] isEqualToString: _NS("Next")] ) { - playlist_t * p_playlist = vlc_object_find( p_intf, - VLC_OBJECT_PLAYLIST, - FIND_ANYWHERE ); - if( p_playlist == NULL ) - { - bEnabled = FALSE; - } - else - { - vlc_mutex_lock( &p_playlist->object_lock ); bEnabled = p_playlist->i_size > 1; - vlc_mutex_unlock( &p_playlist->object_lock ); - vlc_object_release( p_playlist ); + } + else if( [[o_mi title] isEqualToString: _NS("Random")] ) + { + int i_state; + var_Get( p_playlist, "random", &val ); + i_state = val.b_bool ? NSOnState : NSOffState; + [o_mi setState: i_state]; + } + else if( [[o_mi title] isEqualToString: _NS("Repeat One")] ) + { + int i_state; + var_Get( p_playlist, "repeat", &val ); + i_state = val.b_bool ? NSOnState : NSOffState; + [o_mi setState: i_state]; + } + else if( [[o_mi title] isEqualToString: _NS("Repeat All")] ) + { + int i_state; + var_Get( p_playlist, "loop", &val ); + i_state = val.b_bool ? NSOnState : NSOffState; + [o_mi setState: i_state]; + } + else if( [[o_mi title] isEqualToString: _NS("Step Forward")] || + [[o_mi title] isEqualToString: _NS("Step Backward")] ) + { + if( p_input != NULL ) + { + var_Get( p_input, "seekable", &val); + bEnabled = val.b_bool; } } - else if( [[o_mi title] isEqualToString: _NS("Fullscreen")] ) + else if( [[o_mi title] isEqualToString: _NS("Mute")] ) + { + [o_mi setState: p_intf->p_sys->b_mute ? NSOnState : NSOffState]; + [o_main setupMenus]; /* Make sure audio menu is up to date */ + } + else if( [[o_mi title] isEqualToString: _NS("Half Size")] || + [[o_mi title] isEqualToString: _NS("Normal Size")] || + [[o_mi title] isEqualToString: _NS("Double Size")] || + [[o_mi title] isEqualToString: _NS("Fit to Screen")] || + [[o_mi title] isEqualToString: _NS("Snapshot")] || + [[o_mi title] isEqualToString: _NS("Fullscreen")] || + [[o_mi title] isEqualToString: _NS("Float on Top")] ) { id o_window; - NSArray *o_windows = [NSApp windows]; + NSArray *o_windows = [NSApp orderedWindows]; NSEnumerator *o_enumerator = [o_windows objectEnumerator]; bEnabled = FALSE; - while ((o_window = [o_enumerator nextObject])) + vout_thread_t *p_vout = vlc_object_find( p_intf, VLC_OBJECT_VOUT, + FIND_ANYWHERE ); + if( p_vout != NULL ) { - if( [[o_window className] isEqualToString: @"VLCWindow"] ) + if( [[o_mi title] isEqualToString: _NS("Float on Top")] ) { - bEnabled = TRUE; - break; + var_Get( p_vout, "video-on-top", &val ); + [o_mi setState: val.b_bool ? NSOnState : NSOffState]; } - } - } - else if( o_menu != nil && - [[o_menu title] isEqualToString: _NS("Deinterlace")] ) - { - char * psz_filter = config_GetPsz( p_intf, "filter" ); - - if( psz_filter != NULL ) - { - free( psz_filter ); - psz_filter = config_GetPsz( p_intf, "deinterlace-mode" ); - } - - if( psz_filter != NULL ) - { - if( strcmp( psz_filter, [[o_mi title] lossyCString] ) == 0 ) - { - [o_mi setState: NSOnState]; - } - else + while( (o_window = [o_enumerator nextObject])) { - [o_mi setState: NSOffState]; + if( [[o_window className] isEqualToString: @"VLCWindow"] || + [[[VLCMain sharedInstance] getEmbeddedList] + windowContainsEmbedded: o_window]) + { + bEnabled = TRUE; + break; + } } - - free( psz_filter ); - } - else + vlc_object_release( (vlc_object_t *)p_vout ); + } + else if( [[o_mi title] isEqualToString: _NS("Fullscreen")] ) { - [o_mi setState: NSOffState]; + var_Get( p_playlist, "fullscreen", &val ); + [o_mi setState: val.b_bool]; + bEnabled = TRUE; } - } + [o_main setupMenus]; /* Make sure video menu is up to date */ + } + + vlc_mutex_unlock( &p_playlist->object_lock ); + vlc_object_release( p_playlist ); return( bEnabled ); } @end + +/***************************************************************************** + * VLCMenuExt implementation + ***************************************************************************** + * Object connected to a playlistitem which remembers the data belonging to + * the variable of the autogenerated menu + *****************************************************************************/ +@implementation VLCMenuExt + +- (id)initWithVar: (const char *)_psz_name Object: (int)i_id + Value: (vlc_value_t)val ofType: (int)_i_type +{ + self = [super init]; + + if( self != nil ) + { + psz_name = strdup( _psz_name ); + i_object_id = i_id; + value = val; + i_type = _i_type; + } + + return( self ); +} + +- (void)dealloc +{ + free( psz_name ); + [super dealloc]; +} + +- (char *)name +{ + return psz_name; +} + +- (int)objectID +{ + return i_object_id; +} + +- (vlc_value_t)value +{ + return value; +} + +- (int)type +{ + return i_type; +} + +@end + + +/***************************************************************************** + * VLCTimeField implementation + ***************************************************************************** + * we need this to catch our click-event in the controller window + *****************************************************************************/ + +@implementation VLCTimeField +- (void)mouseDown: (NSEvent *)ourEvent +{ + if( [ourEvent clickCount] > 1 ) + [[[VLCMain sharedInstance] getControls] goToSpecificTime: nil]; +} +@end