1 /*****************************************************************************
2 * VideoEffects.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2011-2012 Felix Paul Kühne
7 * Authors: Felix Paul Kühne <fkuehne -at- videolan -dot- org>
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.
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.
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 *****************************************************************************/
24 #import "CompatibilityFixes.h"
26 #import "VideoEffects.h"
27 #import "SharedDialogs.h"
28 #import "CoreInteraction.h"
30 @interface VLCVideoEffects (Internal)
31 - (void)resetProfileSelector;
35 #pragma mark Initialization
37 @implementation VLCVideoEffects
38 static VLCVideoEffects *_o_sharedInstance = nil;
40 @synthesize cropLeftValue, cropTopValue, cropRightValue, cropBottomValue;
41 @synthesize puzzleRowsValue, puzzleColumnsValue;
42 @synthesize wallRowsValue, wallColumnsValue;
43 @synthesize cloneValue;
44 @synthesize sepiaValue;
45 @synthesize posterizeValue;
47 + (VLCVideoEffects *)sharedInstance
49 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
54 NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:@";;;0;1.000000;1.000000;1.000000;1.000000;0.050000;16;2.000000;OTA=;4;4;16711680;20;15;120;Z3JhZGllbnQ=;1;0;16711680;6;80;VkxD;-1;;-1;255;2;3;3"], @"VideoEffectProfiles",
55 [NSArray arrayWithObject:_NS("Default")], @"VideoEffectProfileNames", nil];
56 [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
61 if (_o_sharedInstance)
65 i_old_profile_index = -1;
66 _o_sharedInstance = [super init];
69 return _o_sharedInstance;
74 [o_window setTitle: _NS("Video Effects")];
75 [o_window setExcludedFromWindowsMenu:YES];
76 if (!OSX_SNOW_LEOPARD)
77 [o_window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
79 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"basic"]] setLabel:_NS("Basic")];
80 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"crop"]] setLabel:_NS("Crop")];
81 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"geometry"]] setLabel:_NS("Geometry")];
82 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"color"]] setLabel:_NS("Color")];
83 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"misc"]] setLabel:_NS("Miscellaneous")];
85 [self resetProfileSelector];
87 [o_adjust_ckb setTitle:_NS("Image Adjust")];
88 [o_adjust_hue_lbl setStringValue:_NS("Hue")];
89 [o_adjust_contrast_lbl setStringValue:_NS("Contrast")];
90 [o_adjust_brightness_lbl setStringValue:_NS("Brightness")];
91 [o_adjust_brightness_ckb setTitle:_NS("Brightness Threshold")];
92 [o_adjust_saturation_lbl setStringValue:_NS("Saturation")];
93 [o_adjust_gamma_lbl setStringValue:_NS("Gamma")];
94 [o_adjust_reset_btn setTitle: _NS("Reset")];
95 [o_sharpen_ckb setTitle:_NS("Sharpen")];
96 [o_sharpen_lbl setStringValue:_NS("Sigma")];
97 [o_banding_ckb setTitle:_NS("Banding removal")];
98 [o_banding_lbl setStringValue:_NS("Radius")];
99 [o_grain_ckb setTitle:_NS("Film Grain")];
100 [o_grain_lbl setStringValue:_NS("Variance")];
101 [o_crop_top_lbl setStringValue:_NS("Top")];
102 [o_crop_left_lbl setStringValue:_NS("Left")];
103 [o_crop_right_lbl setStringValue:_NS("Right")];
104 [o_crop_bottom_lbl setStringValue:_NS("Bottom")];
105 [o_crop_sync_top_bottom_ckb setTitle:_NS("Synchronize top and bottom")];
106 [o_crop_sync_left_right_ckb setTitle:_NS("Synchronize left and right")];
108 [o_transform_ckb setTitle:_NS("Transform")];
109 [o_transform_pop removeAllItems];
110 [o_transform_pop addItemWithTitle: _NS("Rotate by 90 degrees")];
111 [[o_transform_pop lastItem] setTag: 90];
112 [o_transform_pop addItemWithTitle: _NS("Rotate by 180 degrees")];
113 [[o_transform_pop lastItem] setTag: 180];
114 [o_transform_pop addItemWithTitle: _NS("Rotate by 270 degrees")];
115 [[o_transform_pop lastItem] setTag: 270];
116 [o_transform_pop addItemWithTitle: _NS("Flip horizontally")];
117 [[o_transform_pop lastItem] setTag: 1];
118 [o_transform_pop addItemWithTitle: _NS("Flip vertically")];
119 [[o_transform_pop lastItem] setTag: 2];
120 [o_zoom_ckb setTitle:_NS("Magnification/Zoom")];
121 [o_puzzle_ckb setTitle:_NS("Puzzle game")];
122 [o_puzzle_rows_lbl setStringValue:_NS("Rows")];
123 [o_puzzle_columns_lbl setStringValue:_NS("Columns")];
124 [o_clone_ckb setTitle:_NS("Clone")];
125 [o_clone_number_lbl setStringValue:_NS("Number of clones")];
126 [o_wall_ckb setTitle:_NS("Wall")];
127 [o_wall_numofrows_lbl setStringValue:_NS("Rows")];
128 [o_wall_numofcols_lbl setStringValue:_NS("Columns")];
130 [o_threshold_ckb setTitle:_NS("Color threshold")];
131 [o_threshold_color_lbl setStringValue:_NS("Color")];
132 [o_threshold_saturation_lbl setStringValue:_NS("Saturation")];
133 [o_threshold_similarity_lbl setStringValue:_NS("Similarity")];
134 [o_sepia_ckb setTitle:_NS("Sepia")];
135 [o_sepia_lbl setStringValue:_NS("Intensity")];
136 [o_noise_ckb setTitle:_NS("Noise")];
137 [o_gradient_ckb setTitle:_NS("Gradient")];
138 [o_gradient_mode_lbl setStringValue:_NS("Mode")];
139 [o_gradient_mode_pop removeAllItems];
140 [o_gradient_mode_pop addItemWithTitle: _NS("Gradient")];
141 [[o_gradient_mode_pop lastItem] setTag: 1];
142 [o_gradient_mode_pop addItemWithTitle: _NS("Edge")];
143 [[o_gradient_mode_pop lastItem] setTag: 2];
144 [o_gradient_mode_pop addItemWithTitle: _NS("Hough")];
145 [[o_gradient_mode_pop lastItem] setTag: 3];
146 [o_gradient_color_ckb setTitle:_NS("Color")];
147 [o_gradient_cartoon_ckb setTitle:_NS("Cartoon")];
148 [o_extract_ckb setTitle:_NS("Color extraction")];
149 [o_extract_lbl setStringValue:_NS("Color")];
150 [o_invert_ckb setTitle:_NS("Invert colors")];
151 [o_posterize_ckb setTitle:_NS("Posterize")];
152 [o_posterize_lbl setStringValue:_NS("Posterize level")];
153 [o_blur_ckb setTitle:_NS("Motion blur")];
154 [o_blur_lbl setStringValue:_NS("Factor")];
155 [o_motiondetect_ckb setTitle:_NS("Motion Detect")];
156 [o_watereffect_ckb setTitle:_NS("Water effect")];
157 [o_waves_ckb setTitle:_NS("Waves")];
158 [o_psychedelic_ckb setTitle:_NS("Psychedelic")];
159 [o_anaglyph_ckb setTitle:_NS("Anaglyph")];
161 [o_addtext_ckb setTitle:_NS("Add text")];
162 [o_addtext_text_lbl setStringValue:_NS("Text")];
163 [o_addtext_pos_lbl setStringValue:_NS("Position")];
164 [o_addtext_pos_pop removeAllItems];
165 [o_addtext_pos_pop addItemWithTitle: _NS("Center")];
166 [[o_addtext_pos_pop lastItem] setTag: 0];
167 [o_addtext_pos_pop addItemWithTitle: _NS("Left")];
168 [[o_addtext_pos_pop lastItem] setTag: 1];
169 [o_addtext_pos_pop addItemWithTitle: _NS("Right")];
170 [[o_addtext_pos_pop lastItem] setTag: 2];
171 [o_addtext_pos_pop addItemWithTitle: _NS("Top")];
172 [[o_addtext_pos_pop lastItem] setTag: 4];
173 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom")];
174 [[o_addtext_pos_pop lastItem] setTag: 8];
175 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Left")];
176 [[o_addtext_pos_pop lastItem] setTag: 5];
177 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Right")];
178 [[o_addtext_pos_pop lastItem] setTag: 6];
179 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Left")];
180 [[o_addtext_pos_pop lastItem] setTag: 9];
181 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Right")];
182 [[o_addtext_pos_pop lastItem] setTag: 10];
183 [o_addlogo_ckb setTitle:_NS("Add logo")];
184 [o_addlogo_logo_lbl setStringValue:_NS("Logo")];
185 [o_addlogo_pos_lbl setStringValue:_NS("Position")];
186 [o_addlogo_pos_pop removeAllItems];
187 [o_addlogo_pos_pop addItemWithTitle: _NS("Center")];
188 [[o_addlogo_pos_pop lastItem] setTag: 0];
189 [o_addlogo_pos_pop addItemWithTitle: _NS("Left")];
190 [[o_addlogo_pos_pop lastItem] setTag: 1];
191 [o_addlogo_pos_pop addItemWithTitle: _NS("Right")];
192 [[o_addlogo_pos_pop lastItem] setTag: 2];
193 [o_addlogo_pos_pop addItemWithTitle: _NS("Top")];
194 [[o_addlogo_pos_pop lastItem] setTag: 4];
195 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom")];
196 [[o_addlogo_pos_pop lastItem] setTag: 8];
197 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Left")];
198 [[o_addlogo_pos_pop lastItem] setTag: 5];
199 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Right")];
200 [[o_addlogo_pos_pop lastItem] setTag: 6];
201 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Left")];
202 [[o_addlogo_pos_pop lastItem] setTag: 9];
203 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Right")];
204 [[o_addlogo_pos_pop lastItem] setTag: 10];
205 [o_addlogo_transparency_lbl setStringValue:_NS("Transparency")];
207 [o_tableView selectFirstTabViewItem:self];
209 [[NSNotificationCenter defaultCenter] addObserver:self
210 selector:@selector(inputChangedEvent:)
211 name:VLCInputChangedNotification
220 [[NSNotificationCenter defaultCenter] removeObserver:self];
225 - (void)updateCocoaWindowLevel:(NSInteger)i_level
227 if (o_window && [o_window isVisible] && [o_window level] != i_level)
228 [o_window setLevel: i_level];
232 #pragma mark internal functions
234 -(void)inputChangedEvent:(NSNotification *)o_notification
236 // reset crop values when input changed
237 [self setCropBottomValue:0];
238 [self setCropTopValue:0];
239 [self setCropLeftValue:0];
240 [self setCropRightValue:0];
243 - (void)resetProfileSelector
245 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
246 [o_profile_pop removeAllItems];
248 NSArray * profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
249 [o_profile_pop addItemsWithTitles:profileNames];
251 [[o_profile_pop menu] addItem:[NSMenuItem separatorItem]];
252 [o_profile_pop addItemWithTitle:_NS("Duplicate current profile...")];
253 [[o_profile_pop lastItem] setTarget: self];
254 [[o_profile_pop lastItem] setAction: @selector(addProfile:)];
256 if ([profileNames count] > 1) {
257 [o_profile_pop addItemWithTitle:_NS("Organize profiles...")];
258 [[o_profile_pop lastItem] setTarget: self];
259 [[o_profile_pop lastItem] setAction: @selector(removeProfile:)];
262 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
263 [self profileSelectorAction:self];
272 /* do we have any filter enabled? if yes, show it. */
274 psz_vfilters = config_GetPsz(p_intf, "video-filter");
276 [o_adjust_ckb setState: (NSInteger)strstr(psz_vfilters, "adjust")];
277 [o_sharpen_ckb setState: (NSInteger)strstr(psz_vfilters, "sharpen")];
278 [o_banding_ckb setState: (NSInteger)strstr(psz_vfilters, "gradfun")];
279 [o_grain_ckb setState: (NSInteger)strstr(psz_vfilters, "grain")];
280 [o_transform_ckb setState: (NSInteger)strstr(psz_vfilters, "transform")];
281 [o_zoom_ckb setState: (NSInteger)strstr(psz_vfilters, "magnify")];
282 [o_puzzle_ckb setState: (NSInteger)strstr(psz_vfilters, "puzzle")];
283 [o_threshold_ckb setState: (NSInteger)strstr(psz_vfilters, "colorthres")];
284 [o_sepia_ckb setState: (NSInteger)strstr(psz_vfilters, "sepia")];
285 [o_noise_ckb setState: (NSInteger)strstr(psz_vfilters, "noise")];
286 [o_gradient_ckb setState: (NSInteger)strstr(psz_vfilters, "gradient")];
287 [o_extract_ckb setState: (NSInteger)strstr(psz_vfilters, "extract")];
288 [o_invert_ckb setState: (NSInteger)strstr(psz_vfilters, "invert")];
289 [o_posterize_ckb setState: (NSInteger)strstr(psz_vfilters, "posterize")];
290 [o_blur_ckb setState: (NSInteger)strstr(psz_vfilters, "motionblur")];
291 [o_motiondetect_ckb setState: (NSInteger)strstr(psz_vfilters, "motiondetect")];
292 [o_watereffect_ckb setState: (NSInteger)strstr(psz_vfilters, "ripple")];
293 [o_waves_ckb setState: (NSInteger)strstr(psz_vfilters, "wave")];
294 [o_psychedelic_ckb setState: (NSInteger)strstr(psz_vfilters, "psychedelic")];
295 [o_anaglyph_ckb setState: (NSInteger)strstr(psz_vfilters, "anaglyph")];
298 [o_adjust_ckb setState: NSOffState];
299 [o_sharpen_ckb setState: NSOffState];
300 [o_banding_ckb setState: NSOffState];
301 [o_grain_ckb setState: NSOffState];
302 [o_transform_ckb setState: NSOffState];
303 [o_zoom_ckb setState: NSOffState];
304 [o_puzzle_ckb setState: NSOffState];
305 [o_threshold_ckb setState: NSOffState];
306 [o_sepia_ckb setState: NSOffState];
307 [o_noise_ckb setState: NSOffState];
308 [o_gradient_ckb setState: NSOffState];
309 [o_extract_ckb setState: NSOffState];
310 [o_invert_ckb setState: NSOffState];
311 [o_posterize_ckb setState: NSOffState];
312 [o_blur_ckb setState: NSOffState];
313 [o_motiondetect_ckb setState: NSOffState];
314 [o_watereffect_ckb setState: NSOffState];
315 [o_waves_ckb setState: NSOffState];
316 [o_psychedelic_ckb setState: NSOffState];
317 [o_anaglyph_ckb setState: NSOffState];
320 psz_vfilters = config_GetPsz(p_intf, "sub-source");
322 [o_addtext_ckb setState: (NSInteger)strstr(psz_vfilters, "marq")];
323 [o_addlogo_ckb setState: (NSInteger)strstr(psz_vfilters, "logo")];
326 [o_addtext_ckb setState: NSOffState];
327 [o_addlogo_ckb setState: NSOffState];
330 psz_vfilters = config_GetPsz(p_intf, "video-splitter");
332 [o_clone_ckb setState: (NSInteger)strstr(psz_vfilters, "clone")];
333 [o_wall_ckb setState: (NSInteger)strstr(psz_vfilters, "wall")];
336 [o_clone_ckb setState: NSOffState];
337 [o_wall_ckb setState: NSOffState];
340 /* fetch and show the various values */
341 [o_adjust_hue_sld setFloatValue: config_GetFloat(p_intf, "hue")];
342 [o_adjust_contrast_sld setFloatValue: config_GetFloat(p_intf, "contrast")];
343 [o_adjust_brightness_sld setFloatValue: config_GetFloat(p_intf, "brightness")];
344 [o_adjust_saturation_sld setFloatValue: config_GetFloat(p_intf, "saturation")];
345 [o_adjust_brightness_ckb setState:(config_GetInt(p_intf, "brightness-threshold") != 0 ? NSOnState : NSOffState)];
346 [o_adjust_gamma_sld setFloatValue: config_GetFloat(p_intf, "gamma")];
347 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "brightness")]];
348 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "contrast")]];
349 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "gamma")]];
350 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%.0f", config_GetFloat(p_intf, "hue")]];
351 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "saturation")]];
352 b_state = [o_adjust_ckb state];
353 [o_adjust_brightness_sld setEnabled: b_state];
354 [o_adjust_brightness_ckb setEnabled: b_state];
355 [o_adjust_contrast_sld setEnabled: b_state];
356 [o_adjust_gamma_sld setEnabled: b_state];
357 [o_adjust_hue_sld setEnabled: b_state];
358 [o_adjust_saturation_sld setEnabled: b_state];
359 [o_adjust_brightness_lbl setEnabled: b_state];
360 [o_adjust_contrast_lbl setEnabled: b_state];
361 [o_adjust_gamma_lbl setEnabled: b_state];
362 [o_adjust_hue_lbl setEnabled: b_state];
363 [o_adjust_saturation_lbl setEnabled: b_state];
364 [o_adjust_reset_btn setEnabled: b_state];
366 [o_sharpen_sld setFloatValue: config_GetFloat(p_intf, "sharpen-sigma")];
367 [o_sharpen_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "sharpen-sigma")]];
368 [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
369 [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
371 [o_banding_sld setIntValue: config_GetInt(p_intf, "gradfun-radius")];
372 [o_banding_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "gradfun-radius")]];
373 [o_banding_sld setEnabled: [o_banding_ckb state]];
374 [o_banding_lbl setEnabled: [o_banding_ckb state]];
376 [o_grain_sld setFloatValue: config_GetFloat(p_intf, "grain-variance")];
377 [o_grain_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "grain-variance")]];
378 [o_grain_sld setEnabled: [o_grain_ckb state]];
379 [o_grain_lbl setEnabled: [o_grain_ckb state]];
381 [self setCropLeftValue: 0];
382 [self setCropTopValue: 0];
383 [self setCropRightValue: 0];
384 [self setCropBottomValue: 0];
385 [o_crop_sync_top_bottom_ckb setState: NSOffState];
386 [o_crop_sync_left_right_ckb setState: NSOffState];
388 tmpChar = config_GetPsz(p_intf, "transform-type");
389 tmpString = [NSString stringWithUTF8String:tmpChar];
390 if ([tmpString isEqualToString:@"hflip"])
391 [o_transform_pop selectItemWithTag: 1];
392 else if ([tmpString isEqualToString:@"vflip"])
393 [o_transform_pop selectItemWithTag: 2];
395 [o_transform_pop selectItemWithTag:[tmpString intValue]];
397 [o_transform_pop setEnabled: [o_transform_ckb state]];
399 [self setPuzzleColumnsValue: config_GetInt(p_intf, "puzzle-cols")];
400 [self setPuzzleRowsValue: config_GetInt(p_intf, "puzzle-rows")];
401 b_state = [o_puzzle_ckb state];
402 [o_puzzle_rows_fld setEnabled: b_state];
403 [o_puzzle_rows_stp setEnabled: b_state];
404 [o_puzzle_rows_lbl setEnabled: b_state];
405 [o_puzzle_columns_fld setEnabled: b_state];
406 [o_puzzle_columns_stp setEnabled: b_state];
407 [o_puzzle_columns_lbl setEnabled: b_state];
409 [self setCloneValue: config_GetInt(p_intf, "clone-count")];
410 b_state = [o_clone_ckb state];
411 [o_clone_number_lbl setEnabled: b_state];
412 [o_clone_number_fld setEnabled: b_state];
413 [o_clone_number_stp setEnabled: b_state];
415 b_state = [o_wall_ckb state];
416 [self setWallRowsValue: config_GetInt(p_intf, "wall-rows")];
417 [o_wall_numofrows_lbl setEnabled: b_state];
418 [o_wall_numofrows_fld setEnabled: b_state];
419 [o_wall_numofrows_stp setEnabled: b_state];
420 [self setWallColumnsValue: config_GetInt(p_intf, "wall-cols")];
421 [o_wall_numofcols_lbl setEnabled: b_state];
422 [o_wall_numofcols_fld setEnabled: b_state];
423 [o_wall_numofcols_stp setEnabled: b_state];
425 [o_threshold_color_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "colorthres-color")] uppercaseString]];
426 [o_threshold_saturation_sld setIntValue: config_GetInt(p_intf, "colorthres-saturationthres")];
427 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-saturationthres")]];
428 [o_threshold_similarity_sld setIntValue: config_GetInt(p_intf, "colorthres-similaritythres")];
429 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-similaritythres")]];
431 b_state = [o_threshold_ckb state];
432 [o_threshold_color_fld setEnabled: b_state];
433 [o_threshold_color_lbl setEnabled: b_state];
434 [o_threshold_saturation_sld setEnabled: b_state];
435 [o_threshold_saturation_lbl setEnabled: b_state];
436 [o_threshold_similarity_sld setEnabled: b_state];
437 [o_threshold_similarity_lbl setEnabled: b_state];
439 [self setSepiaValue: config_GetInt(p_intf, "sepia-intensity")];
440 b_state = [o_sepia_ckb state];
441 [o_sepia_fld setEnabled: b_state];
442 [o_sepia_stp setEnabled: b_state];
443 [o_sepia_lbl setEnabled: b_state];
445 tmpChar = config_GetPsz(p_intf, "gradient-mode");
446 tmpString = [NSString stringWithUTF8String:tmpChar];
447 if ([tmpString isEqualToString:@"hough"])
448 [o_gradient_mode_pop selectItemWithTag: 3];
449 else if ([tmpString isEqualToString:@"edge"])
450 [o_gradient_mode_pop selectItemWithTag: 2];
452 [o_gradient_mode_pop selectItemWithTag: 1];
454 [o_gradient_cartoon_ckb setState: config_GetInt(p_intf, "gradient-cartoon")];
455 [o_gradient_color_ckb setState: config_GetInt(p_intf, "gradient-type")];
456 b_state = [o_gradient_ckb state];
457 [o_gradient_mode_pop setEnabled: b_state];
458 [o_gradient_mode_lbl setEnabled: b_state];
459 [o_gradient_cartoon_ckb setEnabled: b_state];
460 [o_gradient_color_ckb setEnabled: b_state];
462 [o_extract_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "extract-component")] uppercaseString]];
463 [o_extract_fld setEnabled: [o_extract_ckb state]];
464 [o_extract_lbl setEnabled: [o_extract_ckb state]];
466 [self setPosterizeValue: config_GetInt(p_intf, "posterize-level")];
467 b_state = [o_posterize_ckb state];
468 [o_posterize_fld setEnabled: b_state];
469 [o_posterize_stp setEnabled: b_state];
470 [o_posterize_lbl setEnabled: b_state];
472 [o_blur_sld setIntValue: config_GetInt(p_intf, "blur-factor")];
473 [o_blur_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "blur-factor")]];
474 [o_blur_sld setEnabled: [o_blur_ckb state]];
475 [o_blur_lbl setEnabled: [o_blur_ckb state]];
477 tmpChar = config_GetPsz(p_intf, "marq-marquee");
479 [o_addtext_text_fld setStringValue: [NSString stringWithUTF8String:tmpChar]];
482 [o_addtext_text_fld setStringValue: @""];
483 [o_addtext_pos_pop selectItemWithTag: config_GetInt(p_intf, "marq-position")];
484 b_state = [o_addtext_ckb state];
485 [o_addtext_pos_pop setEnabled: b_state];
486 [o_addtext_pos_lbl setEnabled: b_state];
487 [o_addtext_text_lbl setEnabled: b_state];
488 [o_addtext_text_fld setEnabled: b_state];
490 tmpChar = config_GetPsz(p_intf, "logo-file");
492 [o_addlogo_logo_fld setStringValue: [NSString stringWithUTF8String:tmpChar]];
495 [o_addlogo_logo_fld setStringValue: @""];
496 [o_addlogo_pos_pop selectItemWithTag: config_GetInt(p_intf, "logo-position")];
497 [o_addlogo_transparency_sld setIntValue: config_GetInt(p_intf, "logo-opacity")];
498 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "logo-opacity")]];
499 b_state = [o_addlogo_ckb state];
500 [o_addlogo_pos_pop setEnabled: b_state];
501 [o_addlogo_pos_lbl setEnabled: b_state];
502 [o_addlogo_logo_fld setEnabled: b_state];
503 [o_addlogo_logo_lbl setEnabled: b_state];
504 [o_addlogo_transparency_sld setEnabled: b_state];
505 [o_addlogo_transparency_lbl setEnabled: b_state];
508 - (NSString *)generateProfileString
510 return [NSString stringWithFormat:@"%@;%@;%@;%lli;%f;%f;%f;%f;%f;%lli;%f;%@;%lli;%lli;%lli;%lli;%lli;%lli;%@;%lli;%lli;%lli;%lli;%lli;%@;%lli;%@;%lli;%lli;%lli;%lli;%lli;%lli;%f",
511 B64EncAndFree(config_GetPsz(p_intf, "video-filter")),
512 B64EncAndFree(config_GetPsz(p_intf, "sub-source")),
513 B64EncAndFree(config_GetPsz(p_intf, "video-splitter")),
514 0LL, // former "hue" value, deprecated since 3.0.0
515 config_GetFloat(p_intf, "contrast"),
516 config_GetFloat(p_intf, "brightness"),
517 config_GetFloat(p_intf, "saturation"),
518 config_GetFloat(p_intf, "gamma"),
519 config_GetFloat(p_intf, "sharpen-sigma"),
520 config_GetInt(p_intf, "gradfun-radius"),
521 config_GetFloat(p_intf, "grain-variance"),
522 B64EncAndFree(config_GetPsz(p_intf, "transform-type")),
523 config_GetInt(p_intf, "puzzle-rows"),
524 config_GetInt(p_intf, "puzzle-cols"),
525 config_GetInt(p_intf, "colorthres-color"),
526 config_GetInt(p_intf, "colorthres-saturationthres"),
527 config_GetInt(p_intf, "colorthres-similaritythres"),
528 config_GetInt(p_intf, "sepia-intensity"),
529 B64EncAndFree(config_GetPsz(p_intf, "gradient-mode")),
530 config_GetInt(p_intf, "gradient-cartoon"),
531 config_GetInt(p_intf, "gradient-type"),
532 config_GetInt(p_intf, "extract-component"),
533 config_GetInt(p_intf, "posterize-level"),
534 config_GetInt(p_intf, "blur-factor"),
535 B64EncAndFree(config_GetPsz(p_intf, "marq-marquee")),
536 config_GetInt(p_intf, "marq-position"),
537 B64EncAndFree(config_GetPsz(p_intf, "logo-file")),
538 config_GetInt(p_intf, "logo-position"),
539 config_GetInt(p_intf, "logo-opacity"),
540 config_GetInt(p_intf, "clone-count"),
541 config_GetInt(p_intf, "wall-rows"),
542 config_GetInt(p_intf, "wall-cols"),
543 // version 2 of profile string:
544 config_GetInt(p_intf, "brightness-threshold"), // index: 32
545 // version 3 of profile string: (vlc-3.0.0)
546 config_GetFloat(p_intf, "hue") // index: 33
551 #pragma mark generic UI code
553 - (void)saveCurrentProfile
555 if (i_old_profile_index == -1)
558 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
559 /* fetch all the current settings in a uniform string */
560 NSString *newProfile = [self generateProfileString];
562 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
563 if (i_old_profile_index >= [workArray count])
566 [workArray replaceObjectAtIndex:i_old_profile_index withObject:newProfile];
567 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
569 [defaults synchronize];
572 - (IBAction)toggleWindow:(id)sender
574 if ([o_window isKeyWindow])
575 [o_window orderOut:sender];
577 [o_window setLevel: [[[VLCMain sharedInstance] voutController] currentStatusWindowLevel]];
578 [o_window makeKeyAndOrderFront:sender];
582 - (IBAction)profileSelectorAction:(id)sender
584 [self saveCurrentProfile];
585 i_old_profile_index = [o_profile_pop indexOfSelectedItem];
586 VLCCoreInteraction *vci_si = [VLCCoreInteraction sharedInstance];
588 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
589 NSUInteger selectedProfile = [o_profile_pop indexOfSelectedItem];
592 NSArray *items = [[[defaults objectForKey:@"VideoEffectProfiles"] objectAtIndex:selectedProfile] componentsSeparatedByString:@";"];
594 // version 1 of profile string has 32 entries
595 if ([items count] < 32) {
596 msg_Err(p_intf, "Error in parsing profile string");
601 /* filter handling */
602 NSString *tempString = B64DecNSStr([items objectAtIndex:0]);
603 vout_thread_t *p_vout = getVout();
605 /* enable the new filters */
606 config_PutPsz(p_intf, "video-filter", [tempString UTF8String]);
608 var_SetString(p_vout, "video-filter", [tempString UTF8String]);
611 tempString = B64DecNSStr([items objectAtIndex:1]);
612 /* enable another round of new filters */
613 config_PutPsz(p_intf, "sub-source", [tempString UTF8String]);
615 var_SetString(p_vout, "sub-source", [tempString UTF8String]);
619 vlc_object_release(p_vout);
622 tempString = B64DecNSStr([items objectAtIndex:2]);
623 /* enable another round of new filters */
624 char *psz_current_splitter = var_GetString(pl_Get(p_intf), "video-splitter");
625 bool b_filter_changed = ![tempString isEqualToString:toNSStr(psz_current_splitter)];
626 free(psz_current_splitter);
628 if (b_filter_changed) {
629 config_PutPsz(p_intf, "video-splitter", [tempString UTF8String]);
630 var_SetString(pl_Get(p_intf), "video-splitter", [tempString UTF8String]);
633 /* try to set filter values on-the-fly and store them appropriately */
634 // index 3 is deprecated
635 [vci_si setVideoFilterProperty:"contrast" forFilter:"adjust" float:[[items objectAtIndex:4] floatValue]];
636 [vci_si setVideoFilterProperty:"brightness" forFilter:"adjust" float:[[items objectAtIndex:5] floatValue]];
637 [vci_si setVideoFilterProperty:"saturation" forFilter:"adjust" float:[[items objectAtIndex:6] floatValue]];
638 [vci_si setVideoFilterProperty:"gamma" forFilter:"adjust" float:[[items objectAtIndex:7] floatValue]];
639 [vci_si setVideoFilterProperty:"sharpen-sigma" forFilter:"sharpen" float:[[items objectAtIndex:8] floatValue]];
640 [vci_si setVideoFilterProperty:"gradfun-radius" forFilter:"gradfun" integer:[[items objectAtIndex:9] intValue]];
641 [vci_si setVideoFilterProperty:"grain-variance" forFilter:"grain" float:[[items objectAtIndex:10] floatValue]];
642 [vci_si setVideoFilterProperty:"transform-type" forFilter:"transform" string:[B64DecNSStr([items objectAtIndex:11]) UTF8String]];
643 [vci_si setVideoFilterProperty:"puzzle-rows" forFilter:"puzzle" integer:[[items objectAtIndex:12] intValue]];
644 [vci_si setVideoFilterProperty:"puzzle-cols" forFilter:"puzzle" integer:[[items objectAtIndex:13] intValue]];
645 [vci_si setVideoFilterProperty:"colorthres-color" forFilter:"colorthres" integer:[[items objectAtIndex:14] intValue]];
646 [vci_si setVideoFilterProperty:"colorthres-saturationthres" forFilter:"colorthres" integer:[[items objectAtIndex:15] intValue]];
647 [vci_si setVideoFilterProperty:"colorthres-similaritythres" forFilter:"colorthres" integer:[[items objectAtIndex:16] intValue]];
648 [vci_si setVideoFilterProperty:"sepia-intensity" forFilter:"sepia" integer:[[items objectAtIndex:17] intValue]];
649 [vci_si setVideoFilterProperty:"gradient-mode" forFilter:"gradient" string:[B64DecNSStr([items objectAtIndex:18]) UTF8String]];
650 [vci_si setVideoFilterProperty:"gradient-cartoon" forFilter:"gradient" boolean:[[items objectAtIndex:19] intValue]];
651 [vci_si setVideoFilterProperty:"gradient-type" forFilter:"gradient" integer:[[items objectAtIndex:20] intValue]];
652 [vci_si setVideoFilterProperty:"extract-component" forFilter:"extract" integer:[[items objectAtIndex:21] intValue]];
653 [vci_si setVideoFilterProperty:"posterize-level" forFilter:"posterize" integer:[[items objectAtIndex:22] intValue]];
654 [vci_si setVideoFilterProperty:"blur-factor" forFilter:"motionblur" integer:[[items objectAtIndex:23] intValue]];
655 [vci_si setVideoFilterProperty:"marq-marquee" forFilter:"marq" string:[B64DecNSStr([items objectAtIndex:24]) UTF8String]];
656 [vci_si setVideoFilterProperty:"marq-position" forFilter:"marq" integer:[[items objectAtIndex:25] intValue]];
657 [vci_si setVideoFilterProperty:"logo-file" forFilter:"logo" string:[B64DecNSStr([items objectAtIndex:26]) UTF8String]];
658 [vci_si setVideoFilterProperty:"logo-position" forFilter:"logo" integer:[[items objectAtIndex:27] intValue]];
659 [vci_si setVideoFilterProperty:"logo-opacity" forFilter:"logo" integer:[[items objectAtIndex:28] intValue]];
660 [vci_si setVideoFilterProperty:"clone-count" forFilter:"clone" integer:[[items objectAtIndex:29] intValue]];
661 [vci_si setVideoFilterProperty:"wall-rows" forFilter:"wall" integer:[[items objectAtIndex:30] intValue]];
662 [vci_si setVideoFilterProperty:"wall-cols" forFilter:"wall" integer:[[items objectAtIndex:31] intValue]];
664 if ([items count] >= 33) { // version >=2 of profile string
665 [vci_si setVideoFilterProperty: "brightness-threshold" forFilter: "adjust" boolean: [[items objectAtIndex:32] intValue]];
669 if ([items count] >= 34) { // version >=3 of profile string
670 hueValue = [[items objectAtIndex:33] floatValue];
672 hueValue = [[items objectAtIndex:3] intValue]; // deprecated since 3.0.0
673 // convert to new scale ([0,360] --> [-180,180])
676 [vci_si setVideoFilterProperty:"hue" forFilter:"adjust" float:hueValue];
678 [defaults setInteger:selectedProfile forKey:@"VideoEffectSelectedProfile"];
679 [defaults synchronize];
684 - (IBAction)addProfile:(id)sender
687 VLCEnterTextPanel * panel = [VLCEnterTextPanel sharedInstance];
688 [panel setTitle: _NS("Duplicate current profile for a new profile")];
689 [panel setSubTitle: _NS("Enter a name for the new profile:")];
690 [panel setCancelButtonLabel: _NS("Cancel")];
691 [panel setOKButtonLabel: _NS("Save")];
692 [panel setTarget:self];
694 [panel runModalForWindow:o_window];
697 - (void)panel:(VLCEnterTextPanel *)panel returnValue:(NSUInteger)value text:(NSString *)text
699 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
701 if (value != NSOKButton) {
702 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
706 NSArray *profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
708 // duplicate names are not allowed in the popup control
709 if ([text length] == 0 || [profileNames containsObject:text]) {
710 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
712 NSAlert *alert = [[[NSAlert alloc] init] autorelease];
713 [alert setAlertStyle:NSCriticalAlertStyle];
714 [alert setMessageText:_NS("Please enter a unique name for the new profile.")];
715 [alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
717 [alert beginSheetModalForWindow:o_window
724 /* fetch all the current settings in a uniform string */
725 NSString *newProfile = [self generateProfileString];
727 /* add string to user defaults as well as a label */
729 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
730 [workArray addObject:newProfile];
731 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
732 [defaults setInteger:[workArray count] - 1 forKey:@"VideoEffectSelectedProfile"];
735 workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfileNames"]];
736 [workArray addObject:text];
737 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
741 [defaults synchronize];
744 [self resetProfileSelector];
747 - (IBAction)removeProfile:(id)sender
750 VLCSelectItemInPopupPanel * panel = [VLCSelectItemInPopupPanel sharedInstance];
751 [panel setTitle:_NS("Remove a preset")];
752 [panel setSubTitle:_NS("Select the preset you would like to remove:")];
753 [panel setOKButtonLabel:_NS("Remove")];
754 [panel setCancelButtonLabel:_NS("Cancel")];
755 [panel setPopupButtonContent:[[NSUserDefaults standardUserDefaults] objectForKey:@"VideoEffectProfileNames"]];
756 [panel setTarget:self];
758 [panel runModalForWindow:o_window];
761 - (void)panel:(VLCSelectItemInPopupPanel *)panel returnValue:(NSUInteger)value item:(NSUInteger)item
763 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
765 if (value != NSOKButton) {
766 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
770 /* remove selected profile from settings */
771 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfiles"]];
772 [workArray removeObjectAtIndex:item];
773 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
776 workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfileNames"]];
777 [workArray removeObjectAtIndex:item];
778 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
781 if (i_old_profile_index >= item)
782 [defaults setInteger:i_old_profile_index - 1 forKey:@"VideoEffectSelectedProfile"];
785 [defaults synchronize];
787 /* do not save deleted profile */
788 i_old_profile_index = -1;
790 [self resetProfileSelector];
795 - (IBAction)enableAdjust:(id)sender
797 BOOL b_state = [o_adjust_ckb state];
799 [[VLCCoreInteraction sharedInstance] setVideoFilter: "adjust" on: b_state];
800 [o_adjust_brightness_sld setEnabled: b_state];
801 [o_adjust_brightness_ckb setEnabled: b_state];
802 [o_adjust_brightness_lbl setEnabled: b_state];
803 [o_adjust_contrast_sld setEnabled: b_state];
804 [o_adjust_contrast_lbl setEnabled: b_state];
805 [o_adjust_gamma_sld setEnabled: b_state];
806 [o_adjust_gamma_lbl setEnabled: b_state];
807 [o_adjust_hue_sld setEnabled: b_state];
808 [o_adjust_hue_lbl setEnabled: b_state];
809 [o_adjust_saturation_sld setEnabled: b_state];
810 [o_adjust_saturation_lbl setEnabled: b_state];
811 [o_adjust_reset_btn setEnabled: b_state];
814 - (IBAction)adjustSliderChanged:(id)sender
816 if (sender == o_adjust_brightness_sld)
817 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "brightness" forFilter: "adjust" float: [o_adjust_brightness_sld floatValue]];
818 else if (sender == o_adjust_contrast_sld)
819 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "contrast" forFilter: "adjust" float: [o_adjust_contrast_sld floatValue]];
820 else if (sender == o_adjust_gamma_sld)
821 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gamma" forFilter: "adjust" float: [o_adjust_gamma_sld floatValue]];
822 else if (sender == o_adjust_hue_sld)
823 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "hue" forFilter: "adjust" float: [o_adjust_hue_sld floatValue]];
824 else if (sender == o_adjust_saturation_sld)
825 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "saturation" forFilter: "adjust" float: [o_adjust_saturation_sld floatValue]];
827 if (sender == o_adjust_hue_sld)
828 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%.0f", [o_adjust_hue_sld floatValue]]];
830 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
833 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
835 VLCCoreInteraction *vci_si = [VLCCoreInteraction sharedInstance];
837 if (sender == o_adjust_reset_btn) {
838 [o_adjust_brightness_sld setFloatValue: 1.0];
839 [o_adjust_contrast_sld setFloatValue: 1.0];
840 [o_adjust_gamma_sld setFloatValue: 1.0];
841 [o_adjust_hue_sld setFloatValue: 0];
842 [o_adjust_saturation_sld setFloatValue: 1.0];
843 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
844 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
845 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
846 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%.0f", 0.0]];
847 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
848 [vci_si setVideoFilterProperty: "brightness" forFilter: "adjust" float: 1.0];
849 [vci_si setVideoFilterProperty: "contrast" forFilter: "adjust" float: 1.0];
850 [vci_si setVideoFilterProperty: "gamma" forFilter: "adjust" float: 1.0];
851 [vci_si setVideoFilterProperty: "hue" forFilter: "adjust" float: 0.0];
852 [vci_si setVideoFilterProperty: "saturation" forFilter: "adjust" float: 1.0];
854 [vci_si setVideoFilterProperty: "brightness-threshold" forFilter: "adjust" boolean: [o_adjust_brightness_ckb state]];
858 - (IBAction)enableSharpen:(id)sender
860 BOOL b_state = [o_sharpen_ckb state];
862 [[VLCCoreInteraction sharedInstance] setVideoFilter: "sharpen" on: b_state];
863 [o_sharpen_sld setEnabled: b_state];
864 [o_sharpen_lbl setEnabled: b_state];
867 - (IBAction)sharpenSliderChanged:(id)sender
869 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [sender floatValue]];
870 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
873 - (IBAction)enableBanding:(id)sender
875 BOOL b_state = [o_banding_ckb state];
877 [[VLCCoreInteraction sharedInstance] setVideoFilter: "gradfun" on: b_state];
878 [o_banding_sld setEnabled: b_state];
879 [o_banding_lbl setEnabled: b_state];
882 - (IBAction)bandingSliderChanged:(id)sender
884 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [sender intValue]];
885 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
888 - (IBAction)enableGrain:(id)sender
890 BOOL b_state = [o_grain_ckb state];
892 [[VLCCoreInteraction sharedInstance] setVideoFilter: "grain" on: b_state];
893 [o_grain_sld setEnabled: b_state];
894 [o_grain_lbl setEnabled: b_state];
897 - (IBAction)grainSliderChanged:(id)sender
899 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [sender floatValue]];
900 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
907 - (IBAction)cropObjectChanged:(id)sender
909 if ([o_crop_sync_top_bottom_ckb state]) {
910 if (sender == o_crop_bottom_fld || sender == o_crop_bottom_stp)
911 [self setCropTopValue: [self cropBottomValue]];
913 [self setCropBottomValue: [self cropTopValue]];
915 if ([o_crop_sync_left_right_ckb state]) {
916 if (sender == o_crop_right_fld || sender == o_crop_right_stp)
917 [self setCropLeftValue: [self cropRightValue]];
919 [self setCropRightValue: [self cropLeftValue]];
922 vout_thread_t *p_vout = getVout();
924 var_SetInteger(p_vout, "crop-top", [o_crop_top_fld intValue]);
925 var_SetInteger(p_vout, "crop-bottom", [o_crop_bottom_fld intValue]);
926 var_SetInteger(p_vout, "crop-left", [o_crop_left_fld intValue]);
927 var_SetInteger(p_vout, "crop-right", [o_crop_right_fld intValue]);
928 vlc_object_release(p_vout);
933 #pragma mark geometry
934 - (IBAction)enableTransform:(id)sender
936 [[VLCCoreInteraction sharedInstance] setVideoFilter: "transform" on: [o_transform_ckb state]];
937 [o_transform_pop setEnabled: [o_transform_ckb state]];
940 - (IBAction)transformModifierChanged:(id)sender
942 NSInteger tag = [[o_transform_pop selectedItem] tag];
943 const char *psz_string = [[NSString stringWithFormat:@"%li", tag] UTF8String];
945 psz_string = "hflip";
947 psz_string = "vflip";
949 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "transform-type" forFilter: "transform" string: psz_string];
952 - (IBAction)enableZoom:(id)sender
954 [[VLCCoreInteraction sharedInstance] setVideoFilter: "magnify" on: [o_zoom_ckb state]];
957 - (IBAction)enablePuzzle:(id)sender
959 BOOL b_state = [o_puzzle_ckb state];
961 [[VLCCoreInteraction sharedInstance] setVideoFilter: "puzzle" on: b_state];
962 [o_puzzle_columns_fld setEnabled: b_state];
963 [o_puzzle_columns_stp setEnabled: b_state];
964 [o_puzzle_columns_lbl setEnabled: b_state];
965 [o_puzzle_rows_fld setEnabled: b_state];
966 [o_puzzle_rows_stp setEnabled: b_state];
967 [o_puzzle_rows_lbl setEnabled: b_state];
970 - (IBAction)puzzleModifierChanged:(id)sender
972 if (sender == o_puzzle_columns_fld || sender == o_puzzle_columns_stp)
973 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [sender intValue]];
975 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [sender intValue]];
978 - (IBAction)enableClone:(id)sender
980 BOOL b_state = [o_clone_ckb state];
982 if (b_state && [o_wall_ckb state]) {
983 [o_wall_ckb setState: NSOffState];
984 [self enableWall: o_wall_ckb];
987 [[VLCCoreInteraction sharedInstance] setVideoFilter: "clone" on: b_state];
988 [o_clone_number_lbl setEnabled: b_state];
989 [o_clone_number_fld setEnabled: b_state];
990 [o_clone_number_stp setEnabled: b_state];
993 - (IBAction)cloneModifierChanged:(id)sender
995 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "clone-count" forFilter: "clone" integer: [o_clone_number_fld intValue]];
998 - (IBAction)enableWall:(id)sender
1000 BOOL b_state = [o_wall_ckb state];
1002 if (b_state && [o_clone_ckb state]) {
1003 [o_clone_ckb setState: NSOffState];
1004 [self enableClone: o_clone_ckb];
1007 [[VLCCoreInteraction sharedInstance] setVideoFilter: "wall" on: b_state];
1008 [o_wall_numofcols_fld setEnabled: b_state];
1009 [o_wall_numofcols_stp setEnabled: b_state];
1010 [o_wall_numofcols_lbl setEnabled: b_state];
1012 [o_wall_numofrows_fld setEnabled: b_state];
1013 [o_wall_numofrows_stp setEnabled: b_state];
1014 [o_wall_numofrows_lbl setEnabled: b_state];
1017 - (IBAction)wallModifierChanged:(id)sender
1019 if (sender == o_wall_numofcols_fld || sender == o_wall_numofcols_stp)
1020 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "wall-cols" forFilter: "wall" integer: [sender intValue]];
1022 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "wall-rows" forFilter: "wall" integer: [sender intValue]];
1027 - (IBAction)enableThreshold:(id)sender
1029 BOOL b_state = [o_threshold_ckb state];
1031 [[VLCCoreInteraction sharedInstance] setVideoFilter: "colorthres" on: b_state];
1032 [o_threshold_color_fld setEnabled: b_state];
1033 [o_threshold_color_lbl setEnabled: b_state];
1034 [o_threshold_saturation_sld setEnabled: b_state];
1035 [o_threshold_saturation_lbl setEnabled: b_state];
1036 [o_threshold_similarity_sld setEnabled: b_state];
1037 [o_threshold_similarity_lbl setEnabled: b_state];
1040 - (IBAction)thresholdModifierChanged:(id)sender
1042 if (sender == o_threshold_color_fld)
1043 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [o_threshold_color_fld intValue]];
1044 else if (sender == o_threshold_saturation_sld) {
1045 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [o_threshold_saturation_sld intValue]];
1046 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_saturation_sld intValue]]];
1048 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [o_threshold_similarity_sld intValue]];
1049 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_similarity_sld intValue]]];
1053 - (IBAction)enableSepia:(id)sender
1055 BOOL b_state = [o_sepia_ckb state];
1057 [[VLCCoreInteraction sharedInstance] setVideoFilter: "sepia" on: b_state];
1058 [o_sepia_fld setEnabled: b_state];
1059 [o_sepia_stp setEnabled: b_state];
1060 [o_sepia_lbl setEnabled: b_state];
1063 - (IBAction)sepiaModifierChanged:(id)sender
1065 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [o_sepia_fld intValue]];
1068 - (IBAction)enableNoise:(id)sender
1070 [[VLCCoreInteraction sharedInstance] setVideoFilter: "noise" on: [o_noise_ckb state]];
1073 - (IBAction)enableGradient:(id)sender
1075 BOOL b_state = [o_gradient_ckb state];
1077 [[VLCCoreInteraction sharedInstance] setVideoFilter: "gradient" on: b_state];
1078 [o_gradient_mode_pop setEnabled: b_state];
1079 [o_gradient_mode_lbl setEnabled: b_state];
1080 [o_gradient_color_ckb setEnabled: b_state];
1081 [o_gradient_cartoon_ckb setEnabled: b_state];
1084 - (IBAction)gradientModifierChanged:(id)sender
1086 if (sender == o_gradient_mode_pop) {
1087 if ([[o_gradient_mode_pop selectedItem] tag] == 3)
1088 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
1089 else if ([[o_gradient_mode_pop selectedItem] tag] == 2)
1090 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
1092 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
1093 } else if (sender == o_gradient_color_ckb)
1094 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [o_gradient_color_ckb state]];
1096 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [o_gradient_cartoon_ckb state]];
1099 - (IBAction)enableExtract:(id)sender
1101 BOOL b_state = [o_extract_ckb state];
1102 [[VLCCoreInteraction sharedInstance] setVideoFilter: "extract" on: b_state];
1103 [o_extract_fld setEnabled: b_state];
1104 [o_extract_lbl setEnabled: b_state];
1107 - (IBAction)extractModifierChanged:(id)sender
1109 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [o_extract_fld intValue]];
1112 - (IBAction)enableInvert:(id)sender
1114 [[VLCCoreInteraction sharedInstance] setVideoFilter: "invert" on: [o_invert_ckb state]];
1117 - (IBAction)enablePosterize:(id)sender
1119 BOOL b_state = [o_posterize_ckb state];
1121 [[VLCCoreInteraction sharedInstance] setVideoFilter: "posterize" on: b_state];
1122 [o_posterize_fld setEnabled: b_state];
1123 [o_posterize_stp setEnabled: b_state];
1124 [o_posterize_lbl setEnabled: b_state];
1127 - (IBAction)posterizeModifierChanged:(id)sender
1129 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [o_posterize_fld intValue]];
1132 - (IBAction)enableBlur:(id)sender
1134 BOOL b_state = [o_blur_ckb state];
1136 [[VLCCoreInteraction sharedInstance] setVideoFilter: "motionblur" on: b_state];
1137 [o_blur_sld setEnabled: b_state];
1138 [o_blur_lbl setEnabled: b_state];
1141 - (IBAction)blurModifierChanged:(id)sender
1143 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [sender intValue]];
1144 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
1147 - (IBAction)enableMotionDetect:(id)sender
1149 [[VLCCoreInteraction sharedInstance] setVideoFilter: "motiondetect" on: [o_motiondetect_ckb state]];
1152 - (IBAction)enableWaterEffect:(id)sender
1154 [[VLCCoreInteraction sharedInstance] setVideoFilter: "ripple" on: [o_watereffect_ckb state]];
1157 - (IBAction)enableWaves:(id)sender
1159 [[VLCCoreInteraction sharedInstance] setVideoFilter: "wave" on: [o_waves_ckb state]];
1162 - (IBAction)enablePsychedelic:(id)sender
1164 [[VLCCoreInteraction sharedInstance] setVideoFilter: "psychedelic" on: [o_psychedelic_ckb state]];
1168 #pragma mark Miscellaneous
1169 - (IBAction)enableAddText:(id)sender
1171 BOOL b_state = [o_addtext_ckb state];
1172 VLCCoreInteraction *vci_si = [VLCCoreInteraction sharedInstance];
1174 [o_addtext_pos_pop setEnabled: b_state];
1175 [o_addtext_pos_lbl setEnabled: b_state];
1176 [o_addtext_text_lbl setEnabled: b_state];
1177 [o_addtext_text_fld setEnabled: b_state];
1178 [vci_si setVideoFilter: "marq" on: b_state];
1179 [vci_si setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: [[o_addtext_text_fld stringValue] UTF8String]];
1180 [vci_si setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
1183 - (IBAction)addTextModifierChanged:(id)sender
1185 if (sender == o_addtext_text_fld)
1186 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "marq-marquee" forFilter: "marq" string:[[o_addtext_text_fld stringValue] UTF8String]];
1188 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
1191 - (IBAction)enableAddLogo:(id)sender
1193 BOOL b_state = [o_addlogo_ckb state];
1195 [o_addlogo_pos_pop setEnabled: b_state];
1196 [o_addlogo_pos_lbl setEnabled: b_state];
1197 [o_addlogo_logo_fld setEnabled: b_state];
1198 [o_addlogo_logo_lbl setEnabled: b_state];
1199 [o_addlogo_transparency_sld setEnabled: b_state];
1200 [o_addlogo_transparency_lbl setEnabled: b_state];
1201 [[VLCCoreInteraction sharedInstance] setVideoFilter: "logo" on: b_state];
1204 - (IBAction)addLogoModifierChanged:(id)sender
1206 if (sender == o_addlogo_logo_fld)
1207 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "logo-file" forFilter: "logo" string: [[o_addlogo_logo_fld stringValue] UTF8String]];
1208 else if (sender == o_addlogo_pos_pop)
1209 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "logo-position" forFilter: "logo" integer: [[o_addlogo_pos_pop selectedItem] tag]];
1211 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "logo-opacity" forFilter: "logo" integer: [o_addlogo_transparency_sld intValue]];
1212 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%i", [o_addlogo_transparency_sld intValue]]];
1216 - (IBAction)enableAnaglyph:(id)sender
1218 [[VLCCoreInteraction sharedInstance] setVideoFilter: "anaglyph" on: [o_anaglyph_ckb state]];