]> git.sesse.net Git - vlc/blob - modules/gui/macosx/controls.m
cc7195b0167806a710d02dd6a0c9fdfdb2e17334
[vlc] / modules / gui / macosx / controls.m
1 /*****************************************************************************
2  * controls.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2002-2013 VLC authors and VideoLAN
5  * $Id$
6  *
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>
12  *
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.
17  *
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.
22  *
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  *****************************************************************************/
27
28 /*****************************************************************************
29  * Preamble
30  *****************************************************************************/
31 #include <stdlib.h>                                      /* malloc(), free() */
32 #include <sys/param.h>                                    /* for MAXPATHLEN */
33 #include <string.h>
34
35 #import "intf.h"
36 #import "VideoView.h"
37 #import "open.h"
38 #import "controls.h"
39 #import "playlist.h"
40 #import "MainMenu.h"
41 #import "CoreInteraction.h"
42 #import <vlc_keys.h>
43
44 #pragma mark -
45 /*****************************************************************************
46  * VLCControls implementation
47  *****************************************************************************/
48 @implementation VLCControls
49
50 - (void)awakeFromNib
51 {
52     [o_specificTime_mi setTitle: _NS("Jump To Time")];
53     [o_specificTime_cancel_btn setTitle: _NS("Cancel")];
54     [o_specificTime_ok_btn setTitle: _NS("OK")];
55     [o_specificTime_sec_lbl setStringValue: _NS("sec.")];
56     [o_specificTime_goTo_lbl setStringValue: _NS("Jump to time")];
57 }
58
59
60 - (void)dealloc
61 {
62     [[NSNotificationCenter defaultCenter] removeObserver: self];
63
64     [super dealloc];
65 }
66
67 - (IBAction)play:(id)sender
68 {
69     [[VLCCoreInteraction sharedInstance] play];
70 }
71
72 - (IBAction)stop:(id)sender
73 {
74     [[VLCCoreInteraction sharedInstance] stop];
75 }
76
77 - (IBAction)prev:(id)sender
78 {
79     [[VLCCoreInteraction sharedInstance] previous];
80 }
81
82 - (IBAction)next:(id)sender
83 {
84     [[VLCCoreInteraction sharedInstance] next];
85 }
86
87 - (IBAction)random:(id)sender
88 {
89     [[VLCCoreInteraction sharedInstance] shuffle];
90 }
91
92 - (IBAction)repeat:(id)sender
93 {
94     vlc_value_t val;
95     intf_thread_t * p_intf = VLCIntf;
96     playlist_t * p_playlist = pl_Get(p_intf);
97
98     var_Get(p_playlist, "repeat", &val);
99     if (! val.b_bool)
100         [[VLCCoreInteraction sharedInstance] repeatOne];
101     else
102         [[VLCCoreInteraction sharedInstance] repeatOff];
103 }
104
105 - (IBAction)loop:(id)sender
106 {
107     vlc_value_t val;
108     intf_thread_t * p_intf = VLCIntf;
109     playlist_t * p_playlist = pl_Get(p_intf);
110
111     var_Get(p_playlist, "loop", &val);
112     if (! val.b_bool)
113         [[VLCCoreInteraction sharedInstance] repeatAll];
114     else
115         [[VLCCoreInteraction sharedInstance] repeatOff];
116 }
117
118 - (IBAction)quitAfterPlayback:(id)sender
119 {
120     vlc_value_t val;
121     playlist_t * p_playlist = pl_Get(VLCIntf);
122     var_ToggleBool(p_playlist, "play-and-exit");
123 }
124
125 - (IBAction)forward:(id)sender
126 {
127     [[VLCCoreInteraction sharedInstance] forward];
128 }
129
130 - (IBAction)backward:(id)sender
131 {
132     [[VLCCoreInteraction sharedInstance] backward];
133 }
134
135 - (IBAction)volumeUp:(id)sender
136 {
137     [[VLCCoreInteraction sharedInstance] volumeUp];
138 }
139
140 - (IBAction)volumeDown:(id)sender
141 {
142     [[VLCCoreInteraction sharedInstance] volumeDown];
143 }
144
145 - (IBAction)mute:(id)sender
146 {
147     [[VLCCoreInteraction sharedInstance] setMute: YES];
148 }
149
150 - (IBAction)volumeSliderUpdated:(id)sender
151 {
152     [[VLCCoreInteraction sharedInstance] setVolume: [sender intValue]];
153 }
154
155 - (IBAction)showPosition: (id)sender
156 {
157     input_thread_t * p_input = pl_CurrentInput(VLCIntf);
158     if (p_input != NULL) {
159         vout_thread_t *p_vout = input_GetVout(p_input);
160         if (p_vout != NULL) {
161             var_SetInteger(VLCIntf->p_libvlc, "key-action", ACTIONID_POSITION);
162             vlc_object_release(p_vout);
163         }
164         vlc_object_release(p_input);
165     }
166 }
167
168 - (IBAction)telxTransparent:(id)sender
169 {
170     vlc_object_t *p_vbi;
171     p_vbi = (vlc_object_t *) vlc_object_find_name(pl_Get(VLCIntf), "zvbi");
172     if (p_vbi) {
173         var_SetBool(p_vbi, "vbi-opaque", [sender state]);
174         [sender setState: ![sender state]];
175         vlc_object_release(p_vbi);
176     }
177 }
178
179 - (IBAction)telxNavLink:(id)sender
180 {
181     intf_thread_t * p_intf = VLCIntf;
182     vlc_object_t *p_vbi;
183     int i_page = 0;
184
185     if ([[sender title] isEqualToString: _NS("Index")])
186         i_page = 'i' << 16;
187     else if ([[sender title] isEqualToString: _NS("Red")])
188         i_page = 'r' << 16;
189     else if ([[sender title] isEqualToString: _NS("Green")])
190         i_page = 'g' << 16;
191     else if ([[sender title] isEqualToString: _NS("Yellow")])
192         i_page = 'y' << 16;
193     else if ([[sender title] isEqualToString: _NS("Blue")])
194         i_page = 'b' << 16;
195     if (i_page == 0) return;
196
197     p_vbi = (vlc_object_t *) vlc_object_find_name(pl_Get(VLCIntf), "zvbi");
198     if (p_vbi) {
199         var_SetInteger(p_vbi, "vbi-page", i_page);
200         vlc_object_release(p_vbi);
201     }
202 }
203
204 - (IBAction)lockVideosAspectRatio:(id)sender
205 {
206     [[VLCCoreInteraction sharedInstance] setAspectRatioIsLocked: ![sender state]];
207     [sender setState: [[VLCCoreInteraction sharedInstance] aspectRatioIsLocked]];
208 }
209
210 - (IBAction)addSubtitleFile:(id)sender
211 {
212     NSInteger i_returnValue = 0;
213     input_thread_t * p_input = pl_CurrentInput(VLCIntf);
214     if (!p_input)
215         return;
216
217     input_item_t *p_item = input_GetItem(p_input);
218     if (!p_item) {
219         vlc_object_release(p_input);
220         return;
221     }
222
223     char *path = input_item_GetURI(p_item);
224     if (!path)
225         path = strdup("");
226
227     NSOpenPanel * openPanel = [NSOpenPanel openPanel];
228     [openPanel setCanChooseFiles: YES];
229     [openPanel setCanChooseDirectories: NO];
230     [openPanel setAllowsMultipleSelection: YES];
231     [openPanel setAllowedFileTypes: [NSArray arrayWithObjects: @"cdg",@"@idx",@"srt",@"sub",@"utf",@"ass",@"ssa",@"aqt",@"jss",@"psb",@"rt",@"smi",@"txt",@"smil", nil]];
232     [openPanel setDirectoryURL:[NSURL fileURLWithPath:[[NSString stringWithUTF8String:path] stringByExpandingTildeInPath]]];
233     i_returnValue = [openPanel runModal];
234     free(path);
235
236     if (i_returnValue == NSOKButton) {
237         NSUInteger c = 0;
238         if (!p_input)
239             return;
240
241         c = [[openPanel URLs] count];
242
243         for (int i = 0; i < c ; i++) {
244             msg_Dbg(VLCIntf, "loading subs from %s", [[[[openPanel URLs] objectAtIndex: i] path] UTF8String]);
245             if (input_AddSubtitle(p_input, [[[[openPanel URLs] objectAtIndex: i] path] UTF8String], TRUE))
246                 msg_Warn(VLCIntf, "unable to load subtitles from '%s'",
247                          [[[[openPanel URLs] objectAtIndex: i] path] UTF8String]);
248         }
249     }
250     vlc_object_release(p_input);
251 }
252
253 - (BOOL)keyEvent:(NSEvent *)o_event
254 {
255     BOOL eventHandled = NO;
256     NSString * characters = [o_event charactersIgnoringModifiers];
257     if ([characters length] > 0) {
258         unichar key = [characters characterAtIndex: 0];
259
260         if (key) {
261             input_thread_t * p_input = pl_CurrentInput(VLCIntf);
262             if (p_input != NULL) {
263                 vout_thread_t *p_vout = input_GetVout(p_input);
264
265                 if (p_vout != NULL) {
266                     /* Escape */
267                     if (key == (unichar) 0x1b) {
268                         if (var_GetBool(p_vout, "fullscreen")) {
269                             [[VLCCoreInteraction sharedInstance] toggleFullscreen];
270                             eventHandled = YES;
271                         }
272                     }
273                     else if (key == ' ') {
274                         [self play:self];
275                         eventHandled = YES;
276                     }
277                     vlc_object_release(p_vout);
278                 }
279                 vlc_object_release(p_input);
280             }
281         }
282     }
283     return eventHandled;
284 }
285
286 - (IBAction)goToSpecificTime:(id)sender
287 {
288     if (sender == o_specificTime_cancel_btn)
289     {
290         [NSApp endSheet: o_specificTime_win];
291         [o_specificTime_win close];
292     } else if (sender == o_specificTime_ok_btn) {
293         input_thread_t * p_input = pl_CurrentInput(VLCIntf);
294         if (p_input) {
295             int64_t timeInSec = 0;
296             NSString * fieldContent = [o_specificTime_enter_fld stringValue];
297             if ([[fieldContent componentsSeparatedByString: @":"] count] > 1 &&
298                [[fieldContent componentsSeparatedByString: @":"] count] <= 3) {
299                 NSArray * ourTempArray = \
300                     [fieldContent componentsSeparatedByString: @":"];
301
302                 if ([[fieldContent componentsSeparatedByString: @":"] count] == 3) {
303                     timeInSec += ([[ourTempArray objectAtIndex: 0] intValue] * 3600); //h
304                     timeInSec += ([[ourTempArray objectAtIndex: 1] intValue] * 60); //m
305                     timeInSec += [[ourTempArray objectAtIndex: 2] intValue];        //s
306                 } else {
307                     timeInSec += ([[ourTempArray objectAtIndex: 0] intValue] * 60); //m
308                     timeInSec += [[ourTempArray objectAtIndex: 1] intValue]; //s
309                 }
310             }
311             else
312                 timeInSec = [fieldContent intValue];
313
314             input_Control(p_input, INPUT_SET_TIME, (int64_t)(timeInSec * 1000000));
315             vlc_object_release(p_input);
316         }
317
318         [NSApp endSheet: o_specificTime_win];
319         [o_specificTime_win close];
320     } else {
321         input_thread_t * p_input = pl_CurrentInput(VLCIntf);
322         if (p_input) {
323             /* we can obviously only do that if an input is available */
324             vlc_value_t pos, length;
325             var_Get(p_input, "time", &pos);
326             [o_specificTime_enter_fld setIntValue: (pos.i_time / 1000000)];
327             var_Get(p_input, "length", &length);
328             [o_specificTime_stepper setMaxValue: (length.i_time / 1000000)];
329
330             [NSApp beginSheet: o_specificTime_win modalForWindow: \
331                 [NSApp mainWindow] modalDelegate: self didEndSelector: nil \
332                 contextInfo: nil];
333             [o_specificTime_win makeKeyWindow];
334             vlc_object_release(p_input);
335         }
336     }
337 }
338
339 @end
340
341 @implementation VLCControls (NSMenuValidation)
342
343 - (BOOL)validateMenuItem:(NSMenuItem *)o_mi
344 {
345     return [[VLCMainMenu sharedInstance] validateMenuItem:o_mi];
346 }
347
348 @end