]> git.sesse.net Git - vlc/blob - modules/gui/macosx/VideoEffects.m
macosx: fixed confusing interface behavior of the crop filter controls
[vlc] / modules / gui / macosx / VideoEffects.m
1 /*****************************************************************************
2  * VideoEffects.m: MacOS X interface module
3  *****************************************************************************
4  * Copyright (C) 2011 Felix Paul Kühne
5  * $Id$
6  *
7  * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 #import "CompatibilityFixes.h"
25 #import "intf.h"
26 #import <vlc_common.h>
27 #import "VideoEffects.h"
28
29 #pragma mark -
30 #pragma mark Initialization & Generic code
31
32 @implementation VLCVideoEffects
33 static VLCVideoEffects *_o_sharedInstance = nil;
34
35 + (VLCVideoEffects *)sharedInstance
36 {
37     return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
38 }
39
40 - (id)init
41 {
42     if (_o_sharedInstance) {
43         [self dealloc];
44     } else {
45         p_intf = VLCIntf;
46         _o_sharedInstance = [super init];
47     }
48     
49     return _o_sharedInstance;
50 }
51
52 - (IBAction)toggleWindow:(id)sender
53 {
54     if( [o_window isVisible] )
55         [o_window orderOut:sender];
56     else
57         [o_window makeKeyAndOrderFront:sender];
58 }
59
60 - (void)awakeFromNib
61 {
62     [o_window setTitle: _NS("Video Effects")];
63     [o_window setExcludedFromWindowsMenu:YES];
64     if (OSX_LION)
65         [o_window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
66
67     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"basic"]] setLabel:_NS("Basic")];
68     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"crop"]] setLabel:_NS("Crop")];
69     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"geometry"]] setLabel:_NS("Geometry")];
70     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"color"]] setLabel:_NS("Color")];
71     [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"misc"]] setLabel:_NS("Miscellaneous")];
72
73     [o_adjust_ckb setTitle:_NS("Image Adjust")];
74     [o_adjust_hue_lbl setStringValue:_NS("Hue")];
75     [o_adjust_contrast_lbl setStringValue:_NS("Contrast")];
76     [o_adjust_brightness_lbl setStringValue:_NS("Brightness")];
77     [o_adjust_brightness_ckb setTitle:_NS("Brightness Threshold")];
78     [o_adjust_saturation_lbl setStringValue:_NS("Saturation")];
79     [o_adjust_gamma_lbl setStringValue:_NS("Gamma")];
80     [o_adjust_opaque_lbl setStringValue:_NS("Opaqueness")];
81     [o_sharpen_ckb setTitle:_NS("Sharpen")];
82     [o_sharpen_lbl setStringValue:_NS("Sigma")];
83     [o_banding_ckb setTitle:_NS("Banding removal")];
84     [o_banding_lbl setStringValue:_NS("Radius")];
85     [o_grain_ckb setTitle:_NS("Film Grain")];
86     [o_grain_lbl setStringValue:_NS("Variance")];
87     [o_crop_top_lbl setStringValue:_NS("Top")];
88     [o_crop_left_lbl setStringValue:_NS("Left")];
89     [o_crop_right_lbl setStringValue:_NS("Right")];
90     [o_crop_bottom_lbl setStringValue:_NS("Bottom")];
91     [o_crop_sync_top_bottom_ckb setTitle:_NS("Synchronize top and bottom")];
92     [o_crop_sync_left_right_ckb setTitle:_NS("Synchronize left and right")];
93
94     [o_transform_ckb setTitle:_NS("Transform")];
95     [o_transform_pop removeAllItems];
96     [o_transform_pop addItemWithTitle: _NS("Rotate by 90 degrees")];
97     [[o_transform_pop lastItem] setTag: 90];
98     [o_transform_pop addItemWithTitle: _NS("Rotate by 180 degrees")];
99     [[o_transform_pop lastItem] setTag: 180];
100     [o_transform_pop addItemWithTitle: _NS("Rotate by 270 degrees")];
101     [[o_transform_pop lastItem] setTag: 270];
102     [o_transform_pop addItemWithTitle: _NS("Flip horizontally")];
103     [[o_transform_pop lastItem] setTag: 1];
104     [o_transform_pop addItemWithTitle: _NS("Flip vertically")];
105     [[o_transform_pop lastItem] setTag: 2];
106     [o_zoom_ckb setTitle:_NS("Magnification/Zoom")];
107     [o_puzzle_ckb setTitle:_NS("Puzzle game")];
108     [o_puzzle_rows_lbl setStringValue:_NS("Rows")];
109     [o_puzzle_columns_lbl setStringValue:_NS("Columns")];
110     [o_puzzle_blackslot_ckb setTitle:_NS("Black Slot")];
111
112     [o_threshold_ckb setTitle:_NS("Color threshold")];
113     [o_threshold_color_lbl setStringValue:_NS("Color")];
114     [o_threshold_saturation_lbl setStringValue:_NS("Saturation")];
115     [o_threshold_similarity_lbl setStringValue:_NS("Similarity")];
116     [o_sepia_ckb setTitle:_NS("Sepia")];
117     [o_sepia_lbl setStringValue:_NS("Intensity")];
118     [o_noise_ckb setTitle:_NS("Noise")];
119     [o_gradient_ckb setTitle:_NS("Gradient")];
120     [o_gradient_mode_lbl setStringValue:_NS("Mode")];
121     [o_gradient_mode_pop removeAllItems];
122     [o_gradient_mode_pop addItemWithTitle: _NS("Gradient")];
123     [[o_gradient_mode_pop lastItem] setTag: 1];
124     [o_gradient_mode_pop addItemWithTitle: _NS("Edge")];
125     [[o_gradient_mode_pop lastItem] setTag: 2];
126     [o_gradient_mode_pop addItemWithTitle: _NS("Hough")];
127     [[o_gradient_mode_pop lastItem] setTag: 3];
128     [o_gradient_color_ckb setTitle:_NS("Color")];
129     [o_gradient_cartoon_ckb setTitle:_NS("Cartoon")];
130     [o_extract_ckb setTitle:_NS("Color extraction")];
131     [o_extract_lbl setStringValue:_NS("Color")];
132     [o_invert_ckb setTitle:_NS("Invert colors")];
133     [o_posterize_ckb setTitle:_NS("Posterize")];
134     [o_posterize_lbl setStringValue:_NS("Posterize level")];
135     [o_blur_ckb setTitle:_NS("Motion blue")];
136     [o_blur_lbl setStringValue:_NS("Factor")];
137     [o_motiondetect_ckb setTitle:_NS("Motion Detect")];
138     [o_watereffect_ckb setTitle:_NS("Water effect")];
139     [o_waves_ckb setTitle:_NS("Waves")];
140     [o_psychedelic_ckb setTitle:_NS("Psychedelic")];
141
142     [o_clone_ckb setTitle:_NS("Image clone")];
143     [o_clone_lbl setStringValue:_NS("Number of clones")];
144     [o_addtext_ckb setTitle:_NS("Add text")];
145     [o_addtext_text_lbl setStringValue:_NS("Text")];
146     [o_addtext_pos_lbl setStringValue:_NS("Position")];
147     [o_addtext_pos_pop removeAllItems];
148     [o_addtext_pos_pop addItemWithTitle: _NS("Center")];
149     [[o_addtext_pos_pop lastItem] setTag: 0];
150     [o_addtext_pos_pop addItemWithTitle: _NS("Left")];
151     [[o_addtext_pos_pop lastItem] setTag: 1];
152     [o_addtext_pos_pop addItemWithTitle: _NS("Right")];
153     [[o_addtext_pos_pop lastItem] setTag: 2];
154     [o_addtext_pos_pop addItemWithTitle: _NS("Top")];
155     [[o_addtext_pos_pop lastItem] setTag: 4];
156     [o_addtext_pos_pop addItemWithTitle: _NS("Bottom")];
157     [[o_addtext_pos_pop lastItem] setTag: 8];
158     [o_addtext_pos_pop addItemWithTitle: _NS("Top-Left")];
159     [[o_addtext_pos_pop lastItem] setTag: 5];
160     [o_addtext_pos_pop addItemWithTitle: _NS("Top-Right")];
161     [[o_addtext_pos_pop lastItem] setTag: 6];
162     [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Left")];
163     [[o_addtext_pos_pop lastItem] setTag: 9];
164     [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Right")];
165     [[o_addtext_pos_pop lastItem] setTag: 10];
166     [o_addlogo_ckb setTitle:_NS("Add logo")];
167     [o_addlogo_logo_lbl setStringValue:_NS("Logo")];
168     [o_addlogo_top_lbl setStringValue:_NS("Top")];
169     [o_addlogo_left_lbl setStringValue:_NS("Left")];
170     [o_addlogo_transparency_lbl setStringValue:_NS("Transparency")];
171
172     [o_tableView selectFirstTabViewItem:self];
173
174     [self resetValues];
175 }
176
177 - (void)resetValues
178 {
179     NSString *tmpString;
180     char *tmpChar;
181     /* do we have any filter enabled? if yes, show it. */
182     char * psz_vfilters;
183     psz_vfilters = config_GetPsz( p_intf, "video-filter" );
184     if( psz_vfilters ) {
185         [o_adjust_ckb setState: (NSInteger)strstr( psz_vfilters, "adjust")];
186         [o_sharpen_ckb setState: (NSInteger)strstr( psz_vfilters, "sharpen")];
187         [o_banding_ckb setState: (NSInteger)strstr( psz_vfilters, "gradfun")];
188         [o_grain_ckb setState: (NSInteger)strstr( psz_vfilters, "grain")];
189         [o_transform_ckb setState: (NSInteger)strstr( psz_vfilters, "transform")];
190         [o_zoom_ckb setState: (NSInteger)strstr( psz_vfilters, "magnify")];
191         [o_puzzle_ckb setState: (NSInteger)strstr( psz_vfilters, "puzzle")];
192         [o_threshold_ckb setState: (NSInteger)strstr( psz_vfilters, "colorthres")];
193         [o_sepia_ckb setState: (NSInteger)strstr( psz_vfilters, "sepia")];
194         [o_noise_ckb setState: (NSInteger)strstr( psz_vfilters, "noise")];
195         [o_gradient_ckb setState: (NSInteger)strstr( psz_vfilters, "gradient")];
196         [o_extract_ckb setState: (NSInteger)strstr( psz_vfilters, "extract")];
197         [o_invert_ckb setState: (NSInteger)strstr( psz_vfilters, "invert")];
198         [o_posterize_ckb setState: (NSInteger)strstr( psz_vfilters, "posterize")];
199         [o_blur_ckb setState: (NSInteger)strstr( psz_vfilters, "motionblur")];
200         [o_motiondetect_ckb setState: (NSInteger)strstr( psz_vfilters, "motiondetect")];
201         [o_watereffect_ckb setState: (NSInteger)strstr( psz_vfilters, "ripple")];
202         [o_waves_ckb setState: (NSInteger)strstr( psz_vfilters, "wave")];
203         [o_psychedelic_ckb setState: (NSInteger)strstr( psz_vfilters, "psychedelic")];
204         [o_clone_ckb setState: (NSInteger)strstr( psz_vfilters, "clone")];
205         free( psz_vfilters );
206     }
207     // TODO: don't forget about o_addtext_ckb, o_addlogo_ckb, o_eraselogo_ckb
208
209     /* fetch and show the various values */
210     [o_adjust_hue_sld setIntValue: config_GetInt( p_intf, "hue" )];
211     [o_adjust_contrast_sld setFloatValue: config_GetFloat( p_intf, "contrast" )];
212     [o_adjust_brightness_sld setFloatValue: config_GetFloat( p_intf, "brightness" )];
213     [o_adjust_saturation_sld setFloatValue: config_GetFloat( p_intf, "saturation" )];
214     [o_adjust_gamma_sld setFloatValue: config_GetFloat( p_intf, "gamma" )];
215     [o_adjust_brightness_sld setEnabled: [o_adjust_ckb state]];
216     [o_adjust_brightness_ckb setEnabled: [o_adjust_ckb state]];
217     [o_adjust_contrast_sld setEnabled: [o_adjust_ckb state]];
218     [o_adjust_gamma_sld setEnabled: [o_adjust_ckb state]];
219     [o_adjust_hue_sld setEnabled: [o_adjust_ckb state]];
220     [o_adjust_saturation_sld setEnabled: [o_adjust_ckb state]];
221     [o_adjust_brightness_lbl setEnabled: [o_adjust_ckb state]];
222     [o_adjust_contrast_lbl setEnabled: [o_adjust_ckb state]];
223     [o_adjust_gamma_lbl setEnabled: [o_adjust_ckb state]];
224     [o_adjust_hue_lbl setEnabled: [o_adjust_ckb state]];
225     [o_adjust_saturation_lbl setEnabled: [o_adjust_ckb state]];
226     [o_adjust_opaque_sld setFloatValue: config_GetFloat( p_intf, "macosx-opaqueness" )];
227     [o_adjust_opaque_sld setEnabled: [o_adjust_ckb state]];
228     [o_adjust_opaque_lbl setEnabled: [o_adjust_ckb state]];
229     [o_sharpen_sld setFloatValue: config_GetFloat( p_intf, "sharpen-sigma" )];
230     [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
231     [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
232     [o_banding_sld setIntValue: config_GetInt( p_intf, "gradfun-radius" )];
233     [o_banding_sld setEnabled: [o_banding_ckb state]];
234     [o_banding_lbl setEnabled: [o_banding_ckb state]];
235     [o_grain_sld setFloatValue: config_GetFloat( p_intf, "grain-variance" )];
236     [o_grain_sld setEnabled: [o_grain_ckb state]];
237     [o_grain_lbl setEnabled: [o_grain_ckb state]];
238
239     [o_crop_top_fld setIntValue: 0];
240     [o_crop_left_fld setIntValue: 0];
241     [o_crop_right_fld setIntValue: 0];
242     [o_crop_bottom_fld setIntValue: 0];
243     [o_crop_sync_top_bottom_ckb setState: NSOffState];
244     [o_crop_sync_left_right_ckb setState: NSOffState];
245
246     tmpChar = config_GetPsz( p_intf, "transform-type" );
247     tmpString = [NSString stringWithUTF8String: tmpChar];
248     if( [tmpString isEqualToString:@"hflip"] )
249         [o_transform_pop selectItemWithTag: 1];
250     else if( [tmpString isEqualToString:@"vflip"] )
251         [o_transform_pop selectItemWithTag: 2];
252     else
253         [o_transform_pop selectItemWithTag:[tmpString intValue]];
254     FREENULL( tmpChar );
255     [o_transform_pop setEnabled: [o_transform_ckb state]];
256     [o_puzzle_rows_fld setIntValue: config_GetInt( p_intf, "puzzle-rows" )];
257     [o_puzzle_columns_fld setIntValue: config_GetInt( p_intf, "puzzle-cols" )];
258     [o_puzzle_blackslot_ckb setState: config_GetInt( p_intf, "puzzle-black-slot" )];
259     [o_puzzle_rows_fld setEnabled: [o_puzzle_ckb state]];
260     [o_puzzle_rows_lbl setEnabled: [o_puzzle_ckb state]];
261     [o_puzzle_columns_fld setEnabled: [o_puzzle_ckb state]];
262     [o_puzzle_columns_lbl setEnabled: [o_puzzle_ckb state]];
263     [o_puzzle_blackslot_ckb setEnabled: [o_puzzle_ckb state]];
264
265     [o_threshold_color_fld setStringValue: [[NSString stringWithFormat:@"%x", config_GetInt( p_intf, "colorthres-color" )] uppercaseString]];
266     [o_threshold_saturation_sld setIntValue: config_GetInt( p_intf, "colorthres-saturationthres" )];
267     [o_threshold_similarity_sld setIntValue: config_GetInt( p_intf, "colorthres-similaritythres" )];
268     [o_threshold_color_fld setEnabled: [o_threshold_ckb state]];
269     [o_threshold_color_lbl setEnabled: [o_threshold_ckb state]];
270     [o_threshold_saturation_sld setEnabled: [o_threshold_ckb state]];
271     [o_threshold_saturation_lbl setEnabled: [o_threshold_ckb state]];
272     [o_threshold_similarity_sld setEnabled: [o_threshold_ckb state]];
273     [o_threshold_similarity_lbl setEnabled: [o_threshold_ckb state]];
274     [o_sepia_fld setIntValue: config_GetInt( p_intf, "sepia-intensity" )];
275     [o_sepia_fld setEnabled: [o_sepia_ckb state]];
276     [o_sepia_lbl setEnabled: [o_sepia_ckb state]];
277     tmpChar = config_GetPsz( p_intf, "gradient-mode" );
278     tmpString = [NSString stringWithUTF8String: tmpChar];
279     if( [tmpString isEqualToString:@"hough"] )
280         [o_gradient_mode_pop selectItemWithTag: 3];
281     else if( [tmpString isEqualToString:@"edge"] )
282         [o_gradient_mode_pop selectItemWithTag: 2];
283     else
284         [o_gradient_mode_pop selectItemWithTag: 1];
285     FREENULL( tmpChar );
286     [o_gradient_cartoon_ckb setState: config_GetInt( p_intf, "gradient-cartoon" )];
287     [o_gradient_color_ckb setState: config_GetInt( p_intf, "gradient-type" )];
288     [o_gradient_mode_pop setEnabled: [o_gradient_ckb state]];
289     [o_gradient_mode_lbl setEnabled: [o_gradient_ckb state]];
290     [o_gradient_cartoon_ckb setEnabled: [o_gradient_ckb state]];
291     [o_gradient_color_ckb setEnabled: [o_gradient_ckb state]];
292     [o_extract_fld setStringValue: [[NSString stringWithFormat:@"%x", config_GetInt( p_intf, "extract-component" )] uppercaseString]];
293     [o_extract_fld setEnabled: [o_extract_ckb state]];
294     [o_extract_lbl setEnabled: [o_extract_ckb state]];
295     [o_posterize_fld setIntValue: config_GetInt( p_intf, "posterize-level" )];
296     [o_posterize_fld setEnabled: [o_posterize_ckb state]];
297     [o_posterize_lbl setEnabled: [o_posterize_ckb state]];
298     [o_blur_sld setIntValue: config_GetInt( p_intf, "blur-factor" )];
299     [o_blur_sld setEnabled: [o_blur_ckb state]];
300     [o_blur_lbl setEnabled: [o_blur_ckb state]];
301
302     [o_clone_fld setIntValue: config_GetInt( p_intf, "clone-count" )];
303     [o_clone_fld setEnabled: [o_clone_ckb state]];
304     [o_clone_lbl setEnabled: [o_clone_ckb state]];
305     tmpChar = config_GetPsz( p_intf, "marq-marquee" );
306     if( tmpChar )
307     {
308         [o_addtext_text_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
309         FREENULL( tmpChar );
310     }
311     [o_addtext_pos_pop selectItemWithTag: config_GetInt( p_intf, "marq-position" )];
312     [o_addtext_pos_pop setEnabled: [o_addtext_ckb state]];
313     [o_addtext_pos_lbl setEnabled: [o_addtext_ckb state]];
314     [o_addtext_text_lbl setEnabled: [o_addtext_ckb state]];
315     [o_addtext_text_fld setEnabled: [o_addtext_ckb state]];
316
317     tmpChar = config_GetPsz( p_intf, "logo-file" );
318     if( tmpChar )
319     {
320        [o_addlogo_logo_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
321         FREENULL( tmpChar );
322     }
323     [o_addlogo_top_fld setIntValue: config_GetInt( p_intf, "logo-x" )];
324     [o_addlogo_left_fld setIntValue: config_GetInt( p_intf, "logo-y" )];
325     [o_addlogo_transparency_sld setIntValue: config_GetInt( p_intf, "logo-opacity" )];
326     [o_addlogo_logo_fld setEnabled: [o_addlogo_ckb state]];
327     [o_addlogo_logo_lbl setEnabled: [o_addlogo_ckb state]];
328     [o_addlogo_left_fld setEnabled: [o_addlogo_ckb state]];
329     [o_addlogo_left_lbl setEnabled: [o_addlogo_ckb state]];
330     [o_addlogo_top_fld setEnabled: [o_addlogo_ckb state]];
331     [o_addlogo_top_lbl setEnabled: [o_addlogo_ckb state]];
332     [o_addlogo_transparency_sld setEnabled: [o_addlogo_ckb state]];
333     [o_addlogo_transparency_lbl setEnabled: [o_addlogo_ckb state]];
334 }
335
336 - (void)setVideoFilter: (char *)psz_name on:(BOOL)b_on
337 {
338     char *psz_tmp;
339     vout_thread_t * p_vout = getVout();
340     if( p_vout )
341         psz_tmp = var_GetNonEmptyString( p_vout, "video-filter" );
342     else
343         psz_tmp = config_GetPsz( p_intf, "video-filter" );
344
345     if( b_on )
346     {
347         if(! psz_tmp)
348             config_PutPsz( p_intf, "video-filter", psz_name );
349         else if( (NSInteger)strstr( psz_tmp, psz_name ) == NO )
350         {
351             psz_tmp = (char *)[[NSString stringWithFormat: @"%s:%s", psz_tmp, psz_name] UTF8String];
352             config_PutPsz( p_intf, "video-filter", psz_tmp );
353         }
354     } else {
355         if( psz_tmp )
356         {
357             psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@":%s",psz_name]]] UTF8String];
358             psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@"%s:",psz_name]]] UTF8String];
359             psz_tmp = (char *)[[[NSString stringWithUTF8String: psz_tmp] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithUTF8String:psz_name]]] UTF8String];
360             config_PutPsz( p_intf, "video-filter", psz_tmp );
361         }
362     }
363
364     if( p_vout ) {
365         var_SetString( p_vout, "video-filter", psz_tmp );
366         vlc_object_release( p_vout );
367     }
368 }
369
370 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter integer: (int)i_value
371 {
372     vout_thread_t *p_vout = getVout();
373     vlc_object_t *p_filter;
374
375     if( p_vout == NULL ) {
376         config_PutInt( p_intf , psz_name , i_value );
377     } else {
378         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
379
380         if(! p_filter ) {
381             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
382             vlc_object_release( p_vout );
383             return;
384         }
385         var_SetFloat( p_filter, psz_name, i_value );
386         config_PutFloat( p_intf, psz_name, i_value );
387         vlc_object_release( p_vout );
388     }
389 }
390
391 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter float: (float)f_value
392 {
393     vout_thread_t *p_vout = getVout();
394     vlc_object_t *p_filter;
395
396     if( p_vout == NULL ) {
397         config_PutFloat( p_intf , psz_name , f_value );
398     } else {
399         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
400
401         if(! p_filter ) {
402             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
403             vlc_object_release( p_vout );
404             return;
405         }
406         var_SetFloat( p_filter, psz_name, f_value );
407         config_PutFloat( p_intf, psz_name, f_value );
408         vlc_object_release( p_vout );
409     }
410 }
411
412 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter string: (char *)psz_value
413 {
414     vout_thread_t *p_vout = getVout();
415     vlc_object_t *p_filter;
416
417     if( p_vout == NULL ) {
418         config_PutPsz( p_intf, psz_name, psz_value );
419     } else {
420         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
421
422         if(! p_filter ) {
423             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
424             vlc_object_release( p_vout );
425             return;
426         }
427         var_SetString( p_filter, psz_name, psz_value );
428         config_PutPsz( p_intf, psz_name, psz_value );
429         vlc_object_release( p_vout );
430     }
431 }
432
433 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter boolean: (BOOL)b_value
434 {
435     vout_thread_t *p_vout = getVout();
436     vlc_object_t *p_filter;
437
438     if( p_vout == NULL ) {
439         config_PutInt( p_intf, psz_name, b_value );
440     } else {
441         p_filter = vlc_object_find_name( pl_Get(p_intf), psz_filter );
442
443         if(! p_filter ) {
444             msg_Err( p_intf, "we're unable to find the filter '%s'", psz_filter );
445             vlc_object_release( p_vout );
446             return;
447         }
448         var_SetBool( p_filter, psz_name, b_value );
449         config_PutInt( p_intf, psz_name, b_value );
450         vlc_object_release( p_vout );
451     }
452 }
453
454 #pragma mark -
455 #pragma mark basic
456 - (IBAction)enableAdjust:(id)sender
457 {
458     BOOL state = [o_adjust_ckb state];
459     [self setVideoFilter: "adjust" on:[o_adjust_ckb state]];
460     [o_adjust_brightness_sld setEnabled: state];
461     [o_adjust_brightness_ckb setEnabled: state];
462     [o_adjust_brightness_lbl setEnabled: state];
463     [o_adjust_contrast_sld setEnabled: state];
464     [o_adjust_contrast_lbl setEnabled: state];
465     [o_adjust_gamma_sld setEnabled: state];
466     [o_adjust_gamma_lbl setEnabled: state];
467     [o_adjust_hue_sld setEnabled: state];
468     [o_adjust_hue_lbl setEnabled: state];
469     [o_adjust_saturation_sld setEnabled: state];
470     [o_adjust_saturation_lbl setEnabled: state];
471     [o_adjust_opaque_sld setEnabled: state];
472     [o_adjust_opaque_lbl setEnabled: state];
473 }
474
475 - (IBAction)adjustSliderChanged:(id)sender
476 {
477     if( sender == o_adjust_opaque_sld ){
478         vlc_value_t val;
479         id o_tmpWindow = [NSApp keyWindow];
480         NSArray *o_windows = [NSApp orderedWindows];
481         NSEnumerator *o_enumerator = [o_windows objectEnumerator];
482         playlist_t * p_playlist = pl_Get( p_intf );
483         vout_thread_t *p_vout = getVout();
484         vout_thread_t *p_real_vout;
485
486         val.f_float = [o_adjust_opaque_sld floatValue];
487
488         if( p_vout != NULL )
489         {
490             //FIXME: update this implementation once the vout is fixed
491             #if 0
492                 p_real_vout = [VLCVoutView realVout: p_vout];
493                 var_Set( p_real_vout, "macosx-opaqueness", val );
494
495                 while ((o_tmpWindow = [o_enumerator nextObject]))
496                 {
497                     if( [[o_tmpWindow className] isEqualToString: @"VLCVoutWindow"] ||
498                        [[[VLCMain sharedInstance] embeddedList] windowContainsEmbedded: o_tmpWindow])
499                     {
500                         [o_tmpWindow setAlphaValue: val.f_float];
501                     }
502                     break;
503                 }
504             #endif
505             vlc_object_release( p_vout );
506         }
507
508         config_PutFloat( p_playlist , "macosx-opaqueness" , val.f_float );
509     } else {
510         if( sender == o_adjust_brightness_sld )
511             [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: [o_adjust_brightness_sld floatValue]];
512         else if( sender == o_adjust_contrast_sld )
513             [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: [o_adjust_contrast_sld floatValue]];
514         else if( sender == o_adjust_gamma_sld )
515             [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: [o_adjust_gamma_sld floatValue]];
516         else if( sender == o_adjust_hue_sld )
517             [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: [o_adjust_hue_sld intValue]];
518         else if( sender == o_adjust_saturation_sld )
519             [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: [o_adjust_saturation_sld floatValue]];
520     }
521 }
522
523 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
524 {
525     config_PutInt( p_intf, "brightness-threshold", [o_adjust_brightness_ckb state] );
526 }
527
528 - (IBAction)enableSharpen:(id)sender
529 {
530     [self setVideoFilter: "sharpen" on: [o_sharpen_ckb state]];
531     [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
532     [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
533 }
534
535 - (IBAction)sharpenSliderChanged:(id)sender
536 {
537     [self setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [o_sharpen_sld floatValue]];
538 }
539
540 - (IBAction)enableBanding:(id)sender
541 {
542     [self setVideoFilter: "gradfun" on: [o_banding_ckb state]];
543     [o_banding_sld setEnabled: [o_banding_ckb state]];
544     [o_banding_lbl setEnabled: [o_banding_ckb state]];
545 }
546
547 - (IBAction)bandingSliderChanged:(id)sender
548 {
549     [self setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [o_banding_sld intValue]];
550 }
551
552 - (IBAction)enableGrain:(id)sender
553 {
554     [self setVideoFilter: "grain" on: [o_grain_ckb state]];
555     [o_grain_sld setEnabled: [o_grain_ckb state]];
556     [o_grain_lbl setEnabled: [o_grain_ckb state]];
557 }
558
559 - (IBAction)grainSliderChanged:(id)sender
560 {
561     [self setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [o_grain_sld floatValue]];
562 }
563
564
565 #pragma mark -
566 #pragma mark crop
567
568 #define updateopposite( giver, taker ) \
569     if (sender == giver) \
570         [taker setIntValue: [giver intValue]]
571
572 - (IBAction)cropObjectChanged:(id)sender
573 {
574     updateopposite( o_crop_top_fld, o_crop_top_stp );
575     updateopposite( o_crop_top_stp, o_crop_top_fld );
576     updateopposite( o_crop_left_fld, o_crop_left_stp );
577     updateopposite( o_crop_left_stp, o_crop_left_fld );
578     updateopposite( o_crop_right_fld, o_crop_right_stp );
579     updateopposite( o_crop_right_stp, o_crop_right_fld );
580     updateopposite( o_crop_bottom_fld, o_crop_bottom_stp );
581     updateopposite( o_crop_bottom_stp, o_crop_bottom_fld );
582
583     if( [o_crop_sync_top_bottom_ckb state] ) {
584         if (sender == o_crop_top_fld || sender == o_crop_top_stp ) {
585             [o_crop_bottom_fld setIntValue: [o_crop_top_fld intValue]];
586             [o_crop_bottom_stp setIntValue: [o_crop_top_fld intValue]];
587         }
588         else
589         {
590             [o_crop_top_fld setIntValue: [o_crop_bottom_fld intValue]];
591             [o_crop_top_stp setIntValue: [o_crop_bottom_fld intValue]];
592         }
593     }
594     if( [o_crop_sync_left_right_ckb state] ) {
595         if (sender == o_crop_left_fld || sender == o_crop_left_stp ) {
596             [o_crop_right_fld setIntValue: [o_crop_left_fld intValue]];
597             [o_crop_right_stp setIntValue: [o_crop_left_fld intValue]];
598         }
599         else
600         {
601             [o_crop_left_fld setIntValue: [o_crop_right_fld intValue]];
602             [o_crop_left_stp setIntValue: [o_crop_right_fld intValue]];
603         }
604     }
605
606     vout_thread_t *p_vout = getVout();
607     if( p_vout ) {
608         var_SetInteger( p_vout, "crop-top", [o_crop_top_fld intValue] );
609         var_SetInteger( p_vout, "crop-bottom", [o_crop_bottom_fld intValue] );
610         var_SetInteger( p_vout, "crop-left", [o_crop_left_fld intValue] );
611         var_SetInteger( p_vout, "crop-right", [o_crop_right_fld intValue] );
612         vlc_object_release( p_vout );
613     }
614 }
615
616 #undef updateopposite
617
618 #pragma mark -
619 #pragma mark geometry
620 - (IBAction)enableTransform:(id)sender
621 {
622     [self setVideoFilter: "transform" on: [o_transform_ckb state]];
623     [o_transform_pop setEnabled: [o_transform_ckb state]];
624 }
625
626 - (IBAction)transformModifierChanged:(id)sender
627 {
628     if( [[o_transform_pop selectedItem] tag] == 1 )
629         config_PutPsz( p_intf, "transform-type", "hflip" );
630     else if( [[o_transform_pop selectedItem] tag] == 2 )
631         config_PutPsz( p_intf, "transform-type", "vflip" );
632     else
633         config_PutPsz( p_intf, "transform-type", (char *)[o_transform_pop tag] );
634 }
635
636 - (IBAction)enableZoom:(id)sender
637 {
638     [self setVideoFilter: "magnify" on: [o_zoom_ckb state]];
639 }
640
641 - (IBAction)enablePuzzle:(id)sender
642 {
643     BOOL state = [o_puzzle_ckb state];
644     [self setVideoFilter: "puzzle" on: state];
645     [o_puzzle_columns_fld setEnabled: state];
646     [o_puzzle_columns_lbl setEnabled: state];
647     [o_puzzle_rows_fld setEnabled: state];
648     [o_puzzle_rows_lbl setEnabled: state];
649     [o_puzzle_blackslot_ckb setEnabled: state];
650 }
651
652 - (IBAction)puzzleModifierChanged:(id)sender
653 {
654     if( sender == o_puzzle_blackslot_ckb )
655         [self setVideoFilterProperty: "puzzle-black-slot" forFilter: "puzzle" boolean: [o_puzzle_blackslot_ckb state]];
656     else if( sender == o_puzzle_columns_fld )
657         [self setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [o_puzzle_columns_fld intValue]];
658     else
659         [self setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [o_puzzle_rows_fld intValue]];
660 }
661
662
663 #pragma mark -
664 #pragma mark color
665 - (IBAction)enableThreshold:(id)sender
666 {
667     BOOL state = [o_threshold_ckb state];
668     [self setVideoFilter: "colorthres" on: state];
669     [o_threshold_color_fld setEnabled: state];
670     [o_threshold_color_lbl setEnabled: state];
671     [o_threshold_saturation_sld setEnabled: state];
672     [o_threshold_saturation_lbl setEnabled: state];
673     [o_threshold_similarity_sld setEnabled: state];
674     [o_threshold_similarity_lbl setEnabled: state];
675 }
676
677 - (IBAction)thresholdModifierChanged:(id)sender
678 {
679     if( sender == o_threshold_color_fld )
680         [self setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [o_threshold_color_fld intValue]];
681     else if( sender == o_threshold_saturation_sld )
682         [self setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [o_threshold_saturation_sld intValue]];
683     else
684         [self setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [o_threshold_similarity_sld intValue]];
685 }
686
687 - (IBAction)enableSepia:(id)sender
688 {
689     [self setVideoFilter: "sepia" on: [o_sepia_ckb state]];
690     [o_sepia_fld setEnabled: [o_sepia_ckb state]];
691     [o_sepia_lbl setEnabled: [o_sepia_ckb state]];
692 }
693
694 - (IBAction)sepiaModifierChanged:(id)sender
695 {
696     [self setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [o_sepia_fld intValue]];
697 }
698
699 - (IBAction)enableNoise:(id)sender
700 {
701     [self setVideoFilter: "noise" on: [o_noise_ckb state]];
702 }
703
704 - (IBAction)enableGradient:(id)sender
705 {
706     BOOL state = [o_gradient_ckb state];
707     [self setVideoFilter: "gradient" on: state];
708     [o_gradient_mode_pop setEnabled: state];
709     [o_gradient_mode_lbl setEnabled: state];
710     [o_gradient_color_ckb setEnabled: state];
711     [o_gradient_cartoon_ckb setEnabled: state];
712 }
713
714 - (IBAction)gradientModifierChanged:(id)sender
715 {
716     if( sender == o_gradient_mode_pop ) {
717         if( [[o_gradient_mode_pop selectedItem] tag] == 3 )
718             [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
719         else if( [[o_gradient_mode_pop selectedItem] tag] == 2 )
720             [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
721         else
722             [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
723     }
724     else if( sender == o_gradient_color_ckb )
725         [self setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [o_gradient_color_ckb state]];
726     else
727         [self setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [o_gradient_cartoon_ckb state]];
728 }
729
730 - (IBAction)enableExtract:(id)sender
731 {
732     [self setVideoFilter: "extract" on: [o_extract_ckb state]];
733     [o_extract_fld setEnabled: [o_extract_ckb state]];
734     [o_extract_lbl setEnabled: [o_extract_ckb state]];
735 }
736
737 - (IBAction)extractModifierChanged:(id)sender
738 {
739     [self setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [o_extract_fld intValue]];  
740 }
741
742 - (IBAction)enableInvert:(id)sender
743 {
744     [self setVideoFilter: "invert" on: [o_invert_ckb state]];
745 }
746
747 - (IBAction)enablePosterize:(id)sender
748 {
749     [self setVideoFilter: "posterize" on: [o_posterize_ckb state]];
750     [o_posterize_fld setEnabled: [o_posterize_ckb state]];
751     [o_posterize_lbl setEnabled: [o_posterize_ckb state]];
752 }
753
754 - (IBAction)posterizeModifierChanged:(id)sender
755 {
756     [self setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [o_extract_fld intValue]];
757 }
758
759 - (IBAction)enableBlur:(id)sender
760 {
761     [self setVideoFilter: "motionblur" on: [o_blur_ckb state]];
762     [o_blur_sld setEnabled: [o_blur_ckb state]];
763     [o_blur_lbl setEnabled: [o_blur_ckb state]];
764 }
765
766 - (IBAction)blurModifierChanged:(id)sender
767 {
768     [self setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [o_blur_sld intValue]];
769 }
770
771 - (IBAction)enableMotionDetect:(id)sender
772 {
773     [self setVideoFilter: "motiondetect" on: [o_motiondetect_ckb state]];
774 }
775
776 - (IBAction)enableWaterEffect:(id)sender
777 {
778     [self setVideoFilter: "ripple" on: [o_watereffect_ckb state]];
779 }
780
781 - (IBAction)enableWaves:(id)sender
782 {
783     [self setVideoFilter: "wave" on: [o_waves_ckb state]];
784 }
785
786 - (IBAction)enablePsychedelic:(id)sender
787 {
788     [self setVideoFilter: "psychedelic" on: [o_psychedelic_ckb state]];
789 }
790
791
792 #pragma mark -
793 #pragma mark Miscellaneous
794 - (IBAction)enableClone:(id)sender
795 {
796     msg_Dbg( p_intf, "not yet implemented" );
797 }
798
799 - (IBAction)cloneModifierChanged:(id)sender
800 {
801     msg_Dbg( p_intf, "not yet implemented" );
802 }
803
804 - (IBAction)enableAddText:(id)sender
805 {
806     msg_Dbg( p_intf, "not yet implemented" );
807 }
808
809 - (IBAction)addTextModifierChanged:(id)sender
810 {
811     msg_Dbg( p_intf, "not yet implemented" );
812 }
813
814 - (IBAction)enableAddLogo:(id)sender
815 {
816     msg_Dbg( p_intf, "not yet implemented" );
817 }
818
819 - (IBAction)addLogoModifierChanged:(id)sender
820 {
821     msg_Dbg( p_intf, "not yet implemented" );
822 }
823
824 @end