1 /*****************************************************************************
2 * controls.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2002-2011 VLC authors and VideoLAN
7 * Authors: Jon Lech Johansen <jon-vl@nanocrew.net>
8 * Christophe Massiot <massiot@via.ecp.fr>
9 * Derk-Jan Hartman <hartman at videolan dot org>
10 * Benjamin Pracht <bigben at videolan doit org>
11 * Felix Paul Kühne <fkuehne at videolan dot org>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
28 /*****************************************************************************
30 *****************************************************************************/
31 #include <stdlib.h> /* malloc(), free() */
32 #include <sys/param.h> /* for MAXPATHLEN */
40 #import "CoreInteraction.h"
44 /*****************************************************************************
45 * VLCControls implementation
46 *****************************************************************************/
47 @implementation VLCControls
51 [o_specificTime_mi setTitle: _NS("Jump To Time")];
52 [o_specificTime_cancel_btn setTitle: _NS("Cancel")];
53 [o_specificTime_ok_btn setTitle: _NS("OK")];
54 [o_specificTime_sec_lbl setStringValue: _NS("sec.")];
55 [o_specificTime_goTo_lbl setStringValue: _NS("Jump to time")];
61 [[NSNotificationCenter defaultCenter] removeObserver: self];
66 - (IBAction)play:(id)sender
68 [[VLCCoreInteraction sharedInstance] play];
71 - (IBAction)stop:(id)sender
73 [[VLCCoreInteraction sharedInstance] stop];
76 - (IBAction)prev:(id)sender
78 [[VLCCoreInteraction sharedInstance] previous];
81 - (IBAction)next:(id)sender
83 [[VLCCoreInteraction sharedInstance] next];
86 - (IBAction)random:(id)sender
88 [[VLCCoreInteraction sharedInstance] shuffle];
91 - (IBAction)repeat:(id)sender
94 intf_thread_t * p_intf = VLCIntf;
95 playlist_t * p_playlist = pl_Get( p_intf );
97 var_Get( p_playlist, "repeat", &val );
99 [[VLCCoreInteraction sharedInstance] repeatOne];
101 [[VLCCoreInteraction sharedInstance] repeatOff];
104 - (IBAction)loop:(id)sender
107 intf_thread_t * p_intf = VLCIntf;
108 playlist_t * p_playlist = pl_Get( p_intf );
110 var_Get( p_playlist, "loop", &val );
112 [[VLCCoreInteraction sharedInstance] repeatAll];
114 [[VLCCoreInteraction sharedInstance] repeatOff];
117 - (IBAction)quitAfterPlayback:(id)sender
120 playlist_t * p_playlist = pl_Get( VLCIntf );
121 var_ToggleBool( p_playlist, "play-and-exit" );
124 - (IBAction)forward:(id)sender
126 [[VLCCoreInteraction sharedInstance] forward];
129 - (IBAction)backward:(id)sender
131 [[VLCCoreInteraction sharedInstance] backward];
134 - (IBAction)volumeUp:(id)sender
136 [[VLCCoreInteraction sharedInstance] volumeUp];
139 - (IBAction)volumeDown:(id)sender
141 [[VLCCoreInteraction sharedInstance] volumeDown];
144 - (IBAction)mute:(id)sender
146 [[VLCCoreInteraction sharedInstance] mute];
149 - (IBAction)volumeSliderUpdated:(id)sender
151 [[VLCCoreInteraction sharedInstance] setVolume: [sender intValue]];
154 - (IBAction)showPosition: (id)sender
156 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
157 if( p_input != NULL )
159 vout_thread_t *p_vout = input_GetVout( p_input );
162 var_SetInteger( VLCIntf->p_libvlc, "key-action", ACTIONID_POSITION );
163 vlc_object_release( (vlc_object_t *)p_vout );
165 vlc_object_release( p_input );
169 - (IBAction)telxTransparent:(id)sender
172 p_vbi = (vlc_object_t *) vlc_object_find_name( pl_Get( VLCIntf ), "zvbi" );
175 var_SetBool( p_vbi, "vbi-opaque", [sender state] );
176 [sender setState: ![sender state]];
177 vlc_object_release( p_vbi );
181 - (IBAction)telxNavLink:(id)sender
183 intf_thread_t * p_intf = VLCIntf;
187 if( [[sender title] isEqualToString: _NS("Index")] )
189 else if( [[sender title] isEqualToString: _NS("Red")] )
191 else if( [[sender title] isEqualToString: _NS("Green")] )
193 else if( [[sender title] isEqualToString: _NS("Yellow")] )
195 else if( [[sender title] isEqualToString: _NS("Blue")] )
197 if( i_page == 0 ) return;
199 p_vbi = (vlc_object_t *) vlc_object_find_name( pl_Get( VLCIntf ), "zvbi" );
202 var_SetInteger( p_vbi, "vbi-page", i_page );
203 vlc_object_release( p_vbi );
207 - (IBAction)lockVideosAspectRatio:(id)sender
209 [[VLCCoreInteraction sharedInstance] setAspectRatioLocked: [sender state]];
210 [sender setState: [[VLCCoreInteraction sharedInstance] aspectRatioIsLocked]];
213 - (IBAction)addSubtitleFile:(id)sender
215 NSInteger i_returnValue = 0;
216 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
217 if( !p_input ) return;
219 input_item_t *p_item = input_GetItem( p_input );
220 if( !p_item ) return;
222 char *path = input_item_GetURI( p_item );
223 if( !path ) path = strdup( "" );
225 NSOpenPanel * openPanel = [NSOpenPanel openPanel];
226 [openPanel setCanChooseFiles: YES];
227 [openPanel setCanChooseDirectories: NO];
228 [openPanel setAllowsMultipleSelection: YES];
229 [openPanel setAllowedFileTypes: [NSArray arrayWithObjects: @"cdg",@"@idx",@"srt",@"sub",@"utf",@"ass",@"ssa",@"aqt",@"jss",@"psb",@"rt",@"smi",@"txt",@"smil", nil]];
230 [openPanel setDirectoryURL:[NSURL fileURLWithPath:[[NSString stringWithUTF8String:path] stringByExpandingTildeInPath]]];
231 i_returnValue = [openPanel runModal];
234 if( i_returnValue == NSOKButton )
237 if( !p_input ) return;
239 c = [[openPanel URLs] count];
241 for (int i = 0; i < c ; i++)
243 msg_Dbg( VLCIntf, "loading subs from %s", [[[[openPanel URLs] objectAtIndex: i] path] UTF8String] );
244 if( input_AddSubtitle( p_input, [[[[openPanel URLs] objectAtIndex: i] path] UTF8String], TRUE ) )
245 msg_Warn( VLCIntf, "unable to load subtitles from '%s'",
246 [[[[openPanel URLs] objectAtIndex: i] path] UTF8String] );
251 - (void)scrollWheel:(NSEvent *)theEvent
253 intf_thread_t * p_intf = VLCIntf;
254 BOOL b_invertedEventFromDevice = NO;
257 if ([theEvent isDirectionInvertedFromDevice])
258 b_invertedEventFromDevice = YES;
261 float f_yabsvalue = [theEvent deltaY] > 0.0f ? [theEvent deltaY] : -[theEvent deltaY];
262 float f_xabsvalue = [theEvent deltaX] > 0.0f ? [theEvent deltaX] : -[theEvent deltaX];
263 int i, i_yvlckey, i_xvlckey;
265 if (b_invertedEventFromDevice)
267 if ([theEvent deltaY] > 0.0f)
268 i_yvlckey = KEY_MOUSEWHEELDOWN;
270 i_yvlckey = KEY_MOUSEWHEELUP;
272 if ([theEvent deltaX] > 0.0f)
273 i_xvlckey = KEY_MOUSEWHEELRIGHT;
275 i_xvlckey = KEY_MOUSEWHEELLEFT;
279 if ([theEvent deltaY] < 0.0f)
280 i_yvlckey = KEY_MOUSEWHEELDOWN;
282 i_yvlckey = KEY_MOUSEWHEELUP;
284 if ([theEvent deltaX] < 0.0f)
285 i_xvlckey = KEY_MOUSEWHEELRIGHT;
287 i_xvlckey = KEY_MOUSEWHEELLEFT;
290 /* Send multiple key event, depending on the intensity of the event */
291 for (i = 0; i < (int)(f_yabsvalue/4.+1.) && f_yabsvalue > 0.05 ; i++)
292 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_yvlckey );
294 /* Prioritize Y event (sound volume) over X event */
295 if (f_yabsvalue < 0.05)
297 for (i = 0; i < (int)(f_xabsvalue/6.+1.) && f_xabsvalue > 0.05; i++)
298 var_SetInteger( p_intf->p_libvlc, "key-pressed", i_xvlckey );
302 - (BOOL)keyEvent:(NSEvent *)o_event
304 BOOL eventHandled = NO;
305 unichar key = [[o_event charactersIgnoringModifiers] characterAtIndex: 0];
309 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
310 if( p_input != NULL )
312 vout_thread_t *p_vout = input_GetVout( p_input );
317 if( key == (unichar) 0x1b )
319 vout_thread_t *p_vout = getVout();
322 if (var_GetBool( p_vout, "fullscreen" ))
324 [[VLCCoreInteraction sharedInstance] toggleFullscreen];
329 else if( key == ' ' )
334 vlc_object_release( (vlc_object_t *)p_vout );
336 vlc_object_release( p_input );
342 - (IBAction)goToSpecificTime:(id)sender
344 if( sender == o_specificTime_cancel_btn )
346 [NSApp endSheet: o_specificTime_win];
347 [o_specificTime_win close];
349 else if( sender == o_specificTime_ok_btn )
351 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
354 int64_t timeInSec = 0;
355 NSString * fieldContent = [o_specificTime_enter_fld stringValue];
356 if( [[fieldContent componentsSeparatedByString: @":"] count] > 1 &&
357 [[fieldContent componentsSeparatedByString: @":"] count] <= 3 )
359 NSArray * ourTempArray = \
360 [fieldContent componentsSeparatedByString: @":"];
362 if( [[fieldContent componentsSeparatedByString: @":"] count] == 3 )
364 timeInSec += ([[ourTempArray objectAtIndex: 0] intValue] * 3600); //h
365 timeInSec += ([[ourTempArray objectAtIndex: 1] intValue] * 60); //m
366 timeInSec += [[ourTempArray objectAtIndex: 2] intValue]; //s
370 timeInSec += ([[ourTempArray objectAtIndex: 0] intValue] * 60); //m
371 timeInSec += [[ourTempArray objectAtIndex: 1] intValue]; //s
375 timeInSec = [fieldContent intValue];
377 input_Control( p_input, INPUT_SET_TIME, (int64_t)(timeInSec * 1000000));
378 vlc_object_release( p_input );
381 [NSApp endSheet: o_specificTime_win];
382 [o_specificTime_win close];
386 input_thread_t * p_input = pl_CurrentInput( VLCIntf );
389 /* we can obviously only do that if an input is available */
390 vlc_value_t pos, length;
391 var_Get( p_input, "time", &pos );
392 [o_specificTime_enter_fld setIntValue: (pos.i_time / 1000000)];
393 var_Get( p_input, "length", &length );
394 [o_specificTime_stepper setMaxValue: (length.i_time / 1000000)];
396 [NSApp beginSheet: o_specificTime_win modalForWindow: \
397 [NSApp mainWindow] modalDelegate: self didEndSelector: nil \
399 [o_specificTime_win makeKeyWindow];
400 vlc_object_release( p_input );