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 <vlc_common.h>
27 #import <vlc_modules.h>
28 #import <vlc_charset.h>
29 #import "VideoEffects.h"
30 #import "SharedDialogs.h"
32 @interface VLCVideoEffects (Internal)
33 - (void)resetProfileSelector;
37 #pragma mark Initialization
39 @implementation VLCVideoEffects
40 static VLCVideoEffects *_o_sharedInstance = nil;
42 @synthesize cropLeftValue, cropTopValue, cropRightValue, cropBottomValue;
43 @synthesize puzzleRowsValue, puzzleColumnsValue;
44 @synthesize wallRowsValue, wallColumnsValue;
45 @synthesize cloneValue;
46 @synthesize sepiaValue;
47 @synthesize posterizeValue;
49 + (VLCVideoEffects *)sharedInstance
51 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
56 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",
57 [NSArray arrayWithObject:_NS("Default")], @"VideoEffectProfileNames", nil];
58 [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
63 if (_o_sharedInstance)
67 i_old_profile_index = -1;
68 _o_sharedInstance = [super init];
71 return _o_sharedInstance;
76 [o_window setTitle: _NS("Video Effects")];
77 [o_window setExcludedFromWindowsMenu:YES];
78 if (!OSX_SNOW_LEOPARD)
79 [o_window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
81 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"basic"]] setLabel:_NS("Basic")];
82 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"crop"]] setLabel:_NS("Crop")];
83 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"geometry"]] setLabel:_NS("Geometry")];
84 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"color"]] setLabel:_NS("Color")];
85 [[o_tableView tabViewItemAtIndex:[o_tableView indexOfTabViewItemWithIdentifier:@"misc"]] setLabel:_NS("Miscellaneous")];
87 [self resetProfileSelector];
89 [o_adjust_ckb setTitle:_NS("Image Adjust")];
90 [o_adjust_hue_lbl setStringValue:_NS("Hue")];
91 [o_adjust_contrast_lbl setStringValue:_NS("Contrast")];
92 [o_adjust_brightness_lbl setStringValue:_NS("Brightness")];
93 [o_adjust_brightness_ckb setTitle:_NS("Brightness Threshold")];
94 [o_adjust_saturation_lbl setStringValue:_NS("Saturation")];
95 [o_adjust_gamma_lbl setStringValue:_NS("Gamma")];
96 [o_adjust_reset_btn setTitle: _NS("Reset")];
97 [o_sharpen_ckb setTitle:_NS("Sharpen")];
98 [o_sharpen_lbl setStringValue:_NS("Sigma")];
99 [o_banding_ckb setTitle:_NS("Banding removal")];
100 [o_banding_lbl setStringValue:_NS("Radius")];
101 [o_grain_ckb setTitle:_NS("Film Grain")];
102 [o_grain_lbl setStringValue:_NS("Variance")];
103 [o_crop_top_lbl setStringValue:_NS("Top")];
104 [o_crop_left_lbl setStringValue:_NS("Left")];
105 [o_crop_right_lbl setStringValue:_NS("Right")];
106 [o_crop_bottom_lbl setStringValue:_NS("Bottom")];
107 [o_crop_sync_top_bottom_ckb setTitle:_NS("Synchronize top and bottom")];
108 [o_crop_sync_left_right_ckb setTitle:_NS("Synchronize left and right")];
110 [o_transform_ckb setTitle:_NS("Transform")];
111 [o_transform_pop removeAllItems];
112 [o_transform_pop addItemWithTitle: _NS("Rotate by 90 degrees")];
113 [[o_transform_pop lastItem] setTag: 90];
114 [o_transform_pop addItemWithTitle: _NS("Rotate by 180 degrees")];
115 [[o_transform_pop lastItem] setTag: 180];
116 [o_transform_pop addItemWithTitle: _NS("Rotate by 270 degrees")];
117 [[o_transform_pop lastItem] setTag: 270];
118 [o_transform_pop addItemWithTitle: _NS("Flip horizontally")];
119 [[o_transform_pop lastItem] setTag: 1];
120 [o_transform_pop addItemWithTitle: _NS("Flip vertically")];
121 [[o_transform_pop lastItem] setTag: 2];
122 [o_zoom_ckb setTitle:_NS("Magnification/Zoom")];
123 [o_puzzle_ckb setTitle:_NS("Puzzle game")];
124 [o_puzzle_rows_lbl setStringValue:_NS("Rows")];
125 [o_puzzle_columns_lbl setStringValue:_NS("Columns")];
126 [o_clone_ckb setTitle:_NS("Clone")];
127 [o_clone_number_lbl setStringValue:_NS("Number of clones")];
128 [o_wall_ckb setTitle:_NS("Wall")];
129 [o_wall_numofrows_lbl setStringValue:_NS("Rows")];
130 [o_wall_numofcols_lbl setStringValue:_NS("Columns")];
132 [o_threshold_ckb setTitle:_NS("Color threshold")];
133 [o_threshold_color_lbl setStringValue:_NS("Color")];
134 [o_threshold_saturation_lbl setStringValue:_NS("Saturation")];
135 [o_threshold_similarity_lbl setStringValue:_NS("Similarity")];
136 [o_sepia_ckb setTitle:_NS("Sepia")];
137 [o_sepia_lbl setStringValue:_NS("Intensity")];
138 [o_noise_ckb setTitle:_NS("Noise")];
139 [o_gradient_ckb setTitle:_NS("Gradient")];
140 [o_gradient_mode_lbl setStringValue:_NS("Mode")];
141 [o_gradient_mode_pop removeAllItems];
142 [o_gradient_mode_pop addItemWithTitle: _NS("Gradient")];
143 [[o_gradient_mode_pop lastItem] setTag: 1];
144 [o_gradient_mode_pop addItemWithTitle: _NS("Edge")];
145 [[o_gradient_mode_pop lastItem] setTag: 2];
146 [o_gradient_mode_pop addItemWithTitle: _NS("Hough")];
147 [[o_gradient_mode_pop lastItem] setTag: 3];
148 [o_gradient_color_ckb setTitle:_NS("Color")];
149 [o_gradient_cartoon_ckb setTitle:_NS("Cartoon")];
150 [o_extract_ckb setTitle:_NS("Color extraction")];
151 [o_extract_lbl setStringValue:_NS("Color")];
152 [o_invert_ckb setTitle:_NS("Invert colors")];
153 [o_posterize_ckb setTitle:_NS("Posterize")];
154 [o_posterize_lbl setStringValue:_NS("Posterize level")];
155 [o_blur_ckb setTitle:_NS("Motion blur")];
156 [o_blur_lbl setStringValue:_NS("Factor")];
157 [o_motiondetect_ckb setTitle:_NS("Motion Detect")];
158 [o_watereffect_ckb setTitle:_NS("Water effect")];
159 [o_waves_ckb setTitle:_NS("Waves")];
160 [o_psychedelic_ckb setTitle:_NS("Psychedelic")];
161 [o_anaglyph_ckb setTitle:_NS("Anaglyph")];
163 [o_addtext_ckb setTitle:_NS("Add text")];
164 [o_addtext_text_lbl setStringValue:_NS("Text")];
165 [o_addtext_pos_lbl setStringValue:_NS("Position")];
166 [o_addtext_pos_pop removeAllItems];
167 [o_addtext_pos_pop addItemWithTitle: _NS("Center")];
168 [[o_addtext_pos_pop lastItem] setTag: 0];
169 [o_addtext_pos_pop addItemWithTitle: _NS("Left")];
170 [[o_addtext_pos_pop lastItem] setTag: 1];
171 [o_addtext_pos_pop addItemWithTitle: _NS("Right")];
172 [[o_addtext_pos_pop lastItem] setTag: 2];
173 [o_addtext_pos_pop addItemWithTitle: _NS("Top")];
174 [[o_addtext_pos_pop lastItem] setTag: 4];
175 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom")];
176 [[o_addtext_pos_pop lastItem] setTag: 8];
177 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Left")];
178 [[o_addtext_pos_pop lastItem] setTag: 5];
179 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Right")];
180 [[o_addtext_pos_pop lastItem] setTag: 6];
181 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Left")];
182 [[o_addtext_pos_pop lastItem] setTag: 9];
183 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Right")];
184 [[o_addtext_pos_pop lastItem] setTag: 10];
185 [o_addlogo_ckb setTitle:_NS("Add logo")];
186 [o_addlogo_logo_lbl setStringValue:_NS("Logo")];
187 [o_addlogo_pos_lbl setStringValue:_NS("Position")];
188 [o_addlogo_pos_pop removeAllItems];
189 [o_addlogo_pos_pop addItemWithTitle: _NS("Center")];
190 [[o_addlogo_pos_pop lastItem] setTag: 0];
191 [o_addlogo_pos_pop addItemWithTitle: _NS("Left")];
192 [[o_addlogo_pos_pop lastItem] setTag: 1];
193 [o_addlogo_pos_pop addItemWithTitle: _NS("Right")];
194 [[o_addlogo_pos_pop lastItem] setTag: 2];
195 [o_addlogo_pos_pop addItemWithTitle: _NS("Top")];
196 [[o_addlogo_pos_pop lastItem] setTag: 4];
197 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom")];
198 [[o_addlogo_pos_pop lastItem] setTag: 8];
199 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Left")];
200 [[o_addlogo_pos_pop lastItem] setTag: 5];
201 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Right")];
202 [[o_addlogo_pos_pop lastItem] setTag: 6];
203 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Left")];
204 [[o_addlogo_pos_pop lastItem] setTag: 9];
205 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Right")];
206 [[o_addlogo_pos_pop lastItem] setTag: 10];
207 [o_addlogo_transparency_lbl setStringValue:_NS("Transparency")];
209 [o_tableView selectFirstTabViewItem:self];
214 - (void)updateCocoaWindowLevel:(NSInteger)i_level
216 if (o_window && [o_window isVisible] && [o_window level] != i_level)
217 [o_window setLevel: i_level];
221 #pragma mark internal functions
222 - (void)resetProfileSelector
224 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
225 [o_profile_pop removeAllItems];
227 NSArray * profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
228 [o_profile_pop addItemsWithTitles:profileNames];
230 [[o_profile_pop menu] addItem:[NSMenuItem separatorItem]];
231 [o_profile_pop addItemWithTitle:_NS("Duplicate current profile...")];
232 [[o_profile_pop lastItem] setTarget: self];
233 [[o_profile_pop lastItem] setAction: @selector(addProfile:)];
235 if ([profileNames count] > 1) {
236 [o_profile_pop addItemWithTitle:_NS("Organize profiles...")];
237 [[o_profile_pop lastItem] setTarget: self];
238 [[o_profile_pop lastItem] setAction: @selector(removeProfile:)];
241 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
242 [self profileSelectorAction:self];
251 /* do we have any filter enabled? if yes, show it. */
253 psz_vfilters = config_GetPsz(p_intf, "video-filter");
255 [o_adjust_ckb setState: (NSInteger)strstr(psz_vfilters, "adjust")];
256 [o_sharpen_ckb setState: (NSInteger)strstr(psz_vfilters, "sharpen")];
257 [o_banding_ckb setState: (NSInteger)strstr(psz_vfilters, "gradfun")];
258 [o_grain_ckb setState: (NSInteger)strstr(psz_vfilters, "grain")];
259 [o_transform_ckb setState: (NSInteger)strstr(psz_vfilters, "transform")];
260 [o_zoom_ckb setState: (NSInteger)strstr(psz_vfilters, "magnify")];
261 [o_puzzle_ckb setState: (NSInteger)strstr(psz_vfilters, "puzzle")];
262 [o_threshold_ckb setState: (NSInteger)strstr(psz_vfilters, "colorthres")];
263 [o_sepia_ckb setState: (NSInteger)strstr(psz_vfilters, "sepia")];
264 [o_noise_ckb setState: (NSInteger)strstr(psz_vfilters, "noise")];
265 [o_gradient_ckb setState: (NSInteger)strstr(psz_vfilters, "gradient")];
266 [o_extract_ckb setState: (NSInteger)strstr(psz_vfilters, "extract")];
267 [o_invert_ckb setState: (NSInteger)strstr(psz_vfilters, "invert")];
268 [o_posterize_ckb setState: (NSInteger)strstr(psz_vfilters, "posterize")];
269 [o_blur_ckb setState: (NSInteger)strstr(psz_vfilters, "motionblur")];
270 [o_motiondetect_ckb setState: (NSInteger)strstr(psz_vfilters, "motiondetect")];
271 [o_watereffect_ckb setState: (NSInteger)strstr(psz_vfilters, "ripple")];
272 [o_waves_ckb setState: (NSInteger)strstr(psz_vfilters, "wave")];
273 [o_psychedelic_ckb setState: (NSInteger)strstr(psz_vfilters, "psychedelic")];
274 [o_anaglyph_ckb setState: (NSInteger)strstr(psz_vfilters, "anaglyph")];
277 [o_adjust_ckb setState: NSOffState];
278 [o_sharpen_ckb setState: NSOffState];
279 [o_banding_ckb setState: NSOffState];
280 [o_grain_ckb setState: NSOffState];
281 [o_transform_ckb setState: NSOffState];
282 [o_zoom_ckb setState: NSOffState];
283 [o_puzzle_ckb setState: NSOffState];
284 [o_threshold_ckb setState: NSOffState];
285 [o_sepia_ckb setState: NSOffState];
286 [o_noise_ckb setState: NSOffState];
287 [o_gradient_ckb setState: NSOffState];
288 [o_extract_ckb setState: NSOffState];
289 [o_invert_ckb setState: NSOffState];
290 [o_posterize_ckb setState: NSOffState];
291 [o_blur_ckb setState: NSOffState];
292 [o_motiondetect_ckb setState: NSOffState];
293 [o_watereffect_ckb setState: NSOffState];
294 [o_waves_ckb setState: NSOffState];
295 [o_psychedelic_ckb setState: NSOffState];
296 [o_anaglyph_ckb setState: NSOffState];
299 psz_vfilters = config_GetPsz(p_intf, "sub-source");
301 [o_addtext_ckb setState: (NSInteger)strstr(psz_vfilters, "marq")];
302 [o_addlogo_ckb setState: (NSInteger)strstr(psz_vfilters, "logo")];
305 [o_addtext_ckb setState: NSOffState];
306 [o_addlogo_ckb setState: NSOffState];
309 psz_vfilters = config_GetPsz(p_intf, "video-splitter");
311 [o_clone_ckb setState: (NSInteger)strstr(psz_vfilters, "clone")];
312 [o_wall_ckb setState: (NSInteger)strstr(psz_vfilters, "wall")];
315 [o_clone_ckb setState: NSOffState];
316 [o_wall_ckb setState: NSOffState];
319 /* fetch and show the various values */
320 [o_adjust_hue_sld setIntValue: config_GetInt(p_intf, "hue")];
321 [o_adjust_contrast_sld setFloatValue: config_GetFloat(p_intf, "contrast")];
322 [o_adjust_brightness_sld setFloatValue: config_GetFloat(p_intf, "brightness")];
323 [o_adjust_saturation_sld setFloatValue: config_GetFloat(p_intf, "saturation")];
324 [o_adjust_gamma_sld setFloatValue: config_GetFloat(p_intf, "gamma")];
325 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "brightness")]];
326 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "contrast")]];
327 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "gamma")]];
328 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "hue")]];
329 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "saturation")]];
330 b_state = [o_adjust_ckb state];
331 [o_adjust_brightness_sld setEnabled: b_state];
332 [o_adjust_brightness_ckb setEnabled: b_state];
333 [o_adjust_contrast_sld setEnabled: b_state];
334 [o_adjust_gamma_sld setEnabled: b_state];
335 [o_adjust_hue_sld setEnabled: b_state];
336 [o_adjust_saturation_sld setEnabled: b_state];
337 [o_adjust_brightness_lbl setEnabled: b_state];
338 [o_adjust_contrast_lbl setEnabled: b_state];
339 [o_adjust_gamma_lbl setEnabled: b_state];
340 [o_adjust_hue_lbl setEnabled: b_state];
341 [o_adjust_saturation_lbl setEnabled: b_state];
342 [o_adjust_reset_btn setEnabled: b_state];
344 [o_sharpen_sld setFloatValue: config_GetFloat(p_intf, "sharpen-sigma")];
345 [o_sharpen_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "sharpen-sigma")]];
346 [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
347 [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
349 [o_banding_sld setIntValue: config_GetInt(p_intf, "gradfun-radius")];
350 [o_banding_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "gradfun-radius")]];
351 [o_banding_sld setEnabled: [o_banding_ckb state]];
352 [o_banding_lbl setEnabled: [o_banding_ckb state]];
354 [o_grain_sld setFloatValue: config_GetFloat(p_intf, "grain-variance")];
355 [o_grain_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "grain-variance")]];
356 [o_grain_sld setEnabled: [o_grain_ckb state]];
357 [o_grain_lbl setEnabled: [o_grain_ckb state]];
359 [self setCropLeftValue: 0];
360 [self setCropTopValue: 0];
361 [self setCropRightValue: 0];
362 [self setCropBottomValue: 0];
363 [o_crop_sync_top_bottom_ckb setState: NSOffState];
364 [o_crop_sync_left_right_ckb setState: NSOffState];
366 tmpChar = config_GetPsz(p_intf, "transform-type");
367 tmpString = [NSString stringWithUTF8String:tmpChar];
368 if ([tmpString isEqualToString:@"hflip"])
369 [o_transform_pop selectItemWithTag: 1];
370 else if ([tmpString isEqualToString:@"vflip"])
371 [o_transform_pop selectItemWithTag: 2];
373 [o_transform_pop selectItemWithTag:[tmpString intValue]];
375 [o_transform_pop setEnabled: [o_transform_ckb state]];
377 [self setPuzzleColumnsValue: config_GetInt(p_intf, "puzzle-cols")];
378 [self setPuzzleRowsValue: config_GetInt(p_intf, "puzzle-rows")];
379 b_state = [o_puzzle_ckb state];
380 [o_puzzle_rows_fld setEnabled: b_state];
381 [o_puzzle_rows_stp setEnabled: b_state];
382 [o_puzzle_rows_lbl setEnabled: b_state];
383 [o_puzzle_columns_fld setEnabled: b_state];
384 [o_puzzle_columns_stp setEnabled: b_state];
385 [o_puzzle_columns_lbl setEnabled: b_state];
387 [self setCloneValue: config_GetInt(p_intf, "clone-count")];
388 b_state = [o_clone_ckb state];
389 [o_clone_number_lbl setEnabled: b_state];
390 [o_clone_number_fld setEnabled: b_state];
391 [o_clone_number_stp setEnabled: b_state];
393 b_state = [o_wall_ckb state];
394 [self setWallRowsValue: config_GetInt(p_intf, "wall-rows")];
395 [o_wall_numofrows_lbl setEnabled: b_state];
396 [o_wall_numofrows_fld setEnabled: b_state];
397 [o_wall_numofrows_stp setEnabled: b_state];
398 [self setWallColumnsValue: config_GetInt(p_intf, "wall-cols")];
399 [o_wall_numofcols_lbl setEnabled: b_state];
400 [o_wall_numofcols_fld setEnabled: b_state];
401 [o_wall_numofcols_stp setEnabled: b_state];
403 [o_threshold_color_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "colorthres-color")] uppercaseString]];
404 [o_threshold_saturation_sld setIntValue: config_GetInt(p_intf, "colorthres-saturationthres")];
405 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-saturationthres")]];
406 [o_threshold_similarity_sld setIntValue: config_GetInt(p_intf, "colorthres-similaritythres")];
407 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-similaritythres")]];
409 b_state = [o_threshold_ckb state];
410 [o_threshold_color_fld setEnabled: b_state];
411 [o_threshold_color_lbl setEnabled: b_state];
412 [o_threshold_saturation_sld setEnabled: b_state];
413 [o_threshold_saturation_lbl setEnabled: b_state];
414 [o_threshold_similarity_sld setEnabled: b_state];
415 [o_threshold_similarity_lbl setEnabled: b_state];
417 [self setSepiaValue: config_GetInt(p_intf, "sepia-intensity")];
418 b_state = [o_sepia_ckb state];
419 [o_sepia_fld setEnabled: b_state];
420 [o_sepia_stp setEnabled: b_state];
421 [o_sepia_lbl setEnabled: b_state];
423 tmpChar = config_GetPsz(p_intf, "gradient-mode");
424 tmpString = [NSString stringWithUTF8String:tmpChar];
425 if ([tmpString isEqualToString:@"hough"])
426 [o_gradient_mode_pop selectItemWithTag: 3];
427 else if ([tmpString isEqualToString:@"edge"])
428 [o_gradient_mode_pop selectItemWithTag: 2];
430 [o_gradient_mode_pop selectItemWithTag: 1];
432 [o_gradient_cartoon_ckb setState: config_GetInt(p_intf, "gradient-cartoon")];
433 [o_gradient_color_ckb setState: config_GetInt(p_intf, "gradient-type")];
434 b_state = [o_gradient_ckb state];
435 [o_gradient_mode_pop setEnabled: b_state];
436 [o_gradient_mode_lbl setEnabled: b_state];
437 [o_gradient_cartoon_ckb setEnabled: b_state];
438 [o_gradient_color_ckb setEnabled: b_state];
440 [o_extract_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "extract-component")] uppercaseString]];
441 [o_extract_fld setEnabled: [o_extract_ckb state]];
442 [o_extract_lbl setEnabled: [o_extract_ckb state]];
444 [self setPosterizeValue: config_GetInt(p_intf, "posterize-level")];
445 b_state = [o_posterize_ckb state];
446 [o_posterize_fld setEnabled: b_state];
447 [o_posterize_stp setEnabled: b_state];
448 [o_posterize_lbl setEnabled: b_state];
450 [o_blur_sld setIntValue: config_GetInt(p_intf, "blur-factor")];
451 [o_blur_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "blur-factor")]];
452 [o_blur_sld setEnabled: [o_blur_ckb state]];
453 [o_blur_lbl setEnabled: [o_blur_ckb state]];
455 tmpChar = config_GetPsz(p_intf, "marq-marquee");
457 [o_addtext_text_fld setStringValue: [NSString stringWithUTF8String:tmpChar]];
460 [o_addtext_text_fld setStringValue: @""];
461 [o_addtext_pos_pop selectItemWithTag: config_GetInt(p_intf, "marq-position")];
462 b_state = [o_addtext_ckb state];
463 [o_addtext_pos_pop setEnabled: b_state];
464 [o_addtext_pos_lbl setEnabled: b_state];
465 [o_addtext_text_lbl setEnabled: b_state];
466 [o_addtext_text_fld setEnabled: b_state];
468 tmpChar = config_GetPsz(p_intf, "logo-file");
470 [o_addlogo_logo_fld setStringValue: [NSString stringWithUTF8String:tmpChar]];
473 [o_addlogo_logo_fld setStringValue: @""];
474 [o_addlogo_pos_pop selectItemWithTag: config_GetInt(p_intf, "logo-position")];
475 [o_addlogo_transparency_sld setIntValue: config_GetInt(p_intf, "logo-opacity")];
476 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "logo-opacity")]];
477 b_state = [o_addlogo_ckb state];
478 [o_addlogo_pos_pop setEnabled: b_state];
479 [o_addlogo_pos_lbl setEnabled: b_state];
480 [o_addlogo_logo_fld setEnabled: b_state];
481 [o_addlogo_logo_lbl setEnabled: b_state];
482 [o_addlogo_transparency_sld setEnabled: b_state];
483 [o_addlogo_transparency_lbl setEnabled: b_state];
486 - (const char *)getFilterType:(char *)psz_name
488 module_t *p_obj = module_find(psz_name);
493 if (module_provides(p_obj, "video splitter")) {
494 return "video-splitter";
495 } else if (module_provides(p_obj, "video filter2")) {
496 return "video-filter";
497 } else if (module_provides(p_obj, "sub source")) {
499 } else if (module_provides(p_obj, "sub filter")) {
502 msg_Err(p_intf, "Unknown video filter type.");
507 - (void)setVideoFilter: (char *)psz_name on:(BOOL)b_on
509 char *psz_string, *psz_parser;
511 const char *psz_filter_type = [self getFilterType:psz_name];
512 if (!psz_filter_type) {
513 msg_Err(p_intf, "Unable to find filter module \"%s\".", psz_name);
517 msg_Dbg(p_intf, "will set filter '%s'", psz_name);
520 psz_string = config_GetPsz(p_intf, psz_filter_type);
525 psz_string = strdup(psz_name);
526 } else if (strstr(psz_string, psz_name) == NULL) {
528 psz_string = strdup([[NSString stringWithFormat: @"%s:%s", psz_string, psz_name] UTF8String]);
534 psz_parser = strstr(psz_string, psz_name);
536 if (*(psz_parser + strlen(psz_name)) == ':') {
537 memmove(psz_parser, psz_parser + strlen(psz_name) + 1,
538 strlen(psz_parser + strlen(psz_name) + 1) + 1);
543 /* Remove trailing : : */
544 if (strlen(psz_string) > 0 && *(psz_string + strlen(psz_string) -1) == ':')
545 *(psz_string + strlen(psz_string) -1) = '\0';
551 config_PutPsz(p_intf, psz_filter_type, psz_string);
553 /* Try to set on the fly */
554 if (!strcmp(psz_filter_type, "video-splitter")) {
555 playlist_t *p_playlist = pl_Get(p_intf);
556 var_SetString(p_playlist, psz_filter_type, psz_string);
558 vout_thread_t *p_vout = getVout();
560 var_SetString(p_vout, psz_filter_type, psz_string);
561 vlc_object_release(p_vout);
568 - (void)restartFilterIfNeeded: (char *)psz_filter option: (char *)psz_name
570 vout_thread_t *p_vout = getVout();
575 vlc_object_release(p_vout);
577 vlc_object_t *p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
580 /* we cannot rely on the p_filter existence.
581 This filter might be just
582 disabled, but the object still exists. Therefore, the string
583 is checked, additionally.
585 const char *psz_filter_type = [self getFilterType:psz_filter];
586 if (!psz_filter_type) {
587 msg_Err(p_intf, "Unable to find filter module \"%s\".", psz_name);
591 char *psz_string = config_GetPsz(p_intf, psz_filter_type);
595 if (strstr(psz_string, psz_filter) == NULL) {
602 i_type = var_Type(p_filter, psz_name);
604 i_type = config_GetType(p_intf, psz_name);
606 if (!(i_type & VLC_VAR_ISCOMMAND)) {
607 msg_Warn(p_intf, "Brute-restarting filter '%s', because the last changed option isn't a command", psz_name);
609 [self setVideoFilter: psz_filter on: NO];
610 [self setVideoFilter: psz_filter on: YES];
612 msg_Dbg(p_intf, "restart not needed");
615 vlc_object_release(p_filter);
619 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter integer: (int)i_value
621 vout_thread_t *p_vout = getVout();
622 vlc_object_t *p_filter;
624 config_PutInt(p_intf, psz_name, i_value);
627 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
630 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
631 vlc_object_release(p_vout);
634 var_SetInteger(p_filter, psz_name, i_value);
635 vlc_object_release(p_vout);
636 vlc_object_release(p_filter);
638 [self restartFilterIfNeeded: psz_filter option: psz_name];
642 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter float: (float)f_value
644 vout_thread_t *p_vout = getVout();
645 vlc_object_t *p_filter;
647 config_PutFloat(p_intf, psz_name, f_value);
650 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
653 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
654 vlc_object_release(p_vout);
657 var_SetFloat(p_filter, psz_name, f_value);
658 vlc_object_release(p_vout);
659 vlc_object_release(p_filter);
661 [self restartFilterIfNeeded: psz_filter option: psz_name];
665 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter string: (const char *)psz_value
667 char *psz_new_value = strdup(psz_value);
668 vout_thread_t *p_vout = getVout();
669 vlc_object_t *p_filter;
671 config_PutPsz(p_intf, psz_name, EnsureUTF8(psz_new_value));
674 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
677 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
678 vlc_object_release(p_vout);
681 var_SetString(p_filter, psz_name, EnsureUTF8(psz_new_value));
682 vlc_object_release(p_vout);
683 vlc_object_release(p_filter);
685 [self restartFilterIfNeeded: psz_filter option: psz_name];
691 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter boolean: (BOOL)b_value
693 vout_thread_t *p_vout = getVout();
694 vlc_object_t *p_filter;
696 config_PutInt(p_intf, psz_name, b_value);
699 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
702 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
703 vlc_object_release(p_vout);
706 var_SetBool(p_filter, psz_name, b_value);
707 vlc_object_release(p_vout);
708 vlc_object_release(p_filter);
712 - (NSString *)generateProfileString
714 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",
715 B64EncAndFree(config_GetPsz(p_intf, "video-filter")),
716 B64EncAndFree(config_GetPsz(p_intf, "sub-source")),
717 B64EncAndFree(config_GetPsz(p_intf, "video-splitter")),
718 config_GetInt(p_intf, "hue"),
719 config_GetFloat(p_intf, "contrast"),
720 config_GetFloat(p_intf, "brightness"),
721 config_GetFloat(p_intf, "saturation"),
722 config_GetFloat(p_intf, "gamma"),
723 config_GetFloat(p_intf, "sharpen-sigma"),
724 config_GetInt(p_intf, "gradfun-radius"),
725 config_GetFloat(p_intf, "grain-variance"),
726 B64EncAndFree(config_GetPsz(p_intf, "transform-type")),
727 config_GetInt(p_intf, "puzzle-rows"),
728 config_GetInt(p_intf, "puzzle-cols"),
729 config_GetInt(p_intf, "colorthres-color"),
730 config_GetInt(p_intf, "colorthres-saturationthres"),
731 config_GetInt(p_intf, "colorthres-similaritythres"),
732 config_GetInt(p_intf, "sepia-intensity"),
733 B64EncAndFree(config_GetPsz(p_intf, "gradient-mode")),
734 config_GetInt(p_intf, "gradient-cartoon"),
735 config_GetInt(p_intf, "gradient-type"),
736 config_GetInt(p_intf, "extract-component"),
737 config_GetInt(p_intf, "posterize-level"),
738 config_GetInt(p_intf, "blur-factor"),
739 B64EncAndFree(config_GetPsz(p_intf, "marq-marquee")),
740 config_GetInt(p_intf, "marq-position"),
741 B64EncAndFree(config_GetPsz(p_intf, "logo-file")),
742 config_GetInt(p_intf, "logo-position"),
743 config_GetInt(p_intf, "logo-opacity"),
744 config_GetInt(p_intf, "clone-count"),
745 config_GetInt(p_intf, "wall-rows"),
746 config_GetInt(p_intf, "wall-cols")
751 #pragma mark generic UI code
753 - (void)saveCurrentProfile
755 if (i_old_profile_index == -1)
758 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
759 /* fetch all the current settings in a uniform string */
760 NSString *newProfile = [self generateProfileString];
762 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
763 if (i_old_profile_index >= [workArray count])
766 [workArray replaceObjectAtIndex:i_old_profile_index withObject:newProfile];
767 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
769 [defaults synchronize];
772 - (IBAction)toggleWindow:(id)sender
774 if ([o_window isVisible])
775 [o_window orderOut:sender];
777 [o_window setLevel: [[[VLCMain sharedInstance] voutController] currentWindowLevel]];
778 [o_window makeKeyAndOrderFront:sender];
782 - (IBAction)profileSelectorAction:(id)sender
784 [self saveCurrentProfile];
785 i_old_profile_index = [o_profile_pop indexOfSelectedItem];
787 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
788 NSUInteger selectedProfile = [o_profile_pop indexOfSelectedItem];
790 /* disable all current video filters, if a vout is available */
791 vout_thread_t *p_vout = getVout();
793 var_SetString(p_vout, "video-filter", "");
794 var_SetString(p_vout, "sub-source", "");
795 var_SetString(p_vout, "video-splitter", "");
796 vlc_object_release(p_vout);
800 NSArray *items = [[[defaults objectForKey:@"VideoEffectProfiles"] objectAtIndex:selectedProfile] componentsSeparatedByString:@";"];
802 /* filter handling */
803 NSString *tempString = B64DecNSStr([items objectAtIndex:0]);
807 /* enable the new filters */
808 config_PutPsz(p_intf, "video-filter", "");
809 if ([tempString length] > 0) {
810 tempArray = [tempString componentsSeparatedByString:@":"];
811 count = [tempArray count];
812 for (NSUInteger x = 0; x < count; x++)
813 [self setVideoFilter:(char *)[[tempArray objectAtIndex:x] UTF8String] on:YES];
816 tempString = B64DecNSStr([items objectAtIndex:1]);
817 /* enable another round of new filters */
818 config_PutPsz(p_intf,"sub-source", "");
819 if ([tempString length] > 0) {
820 tempArray = [tempString componentsSeparatedByString:@":"];
821 count = [tempArray count];
822 for (NSUInteger x = 0; x < count; x++)
823 [self setVideoFilter:(char *)[[tempArray objectAtIndex:x] UTF8String] on:YES];
826 tempString = B64DecNSStr([items objectAtIndex:2]);
827 /* enable another round of new filters */
828 config_PutPsz(p_intf,"video-splitter", "");
829 if ([tempString length] > 0) {
830 tempArray = [tempString componentsSeparatedByString:@":"];
831 count = [tempArray count];
832 for (NSUInteger x = 0; x < count; x++)
833 [self setVideoFilter:(char *)[[tempArray objectAtIndex:x] UTF8String] on:YES];
836 /* try to set filter values on-the-fly and store them appropriately */
837 [self setVideoFilterProperty:"hue" forFilter:"adjust" integer:[[items objectAtIndex:3] intValue]];
838 [self setVideoFilterProperty:"contrast" forFilter:"adjust" float:[[items objectAtIndex:4] floatValue]];
839 [self setVideoFilterProperty:"brightness" forFilter:"adjust" float:[[items objectAtIndex:5] floatValue]];
840 [self setVideoFilterProperty:"saturation" forFilter:"adjust" float:[[items objectAtIndex:6] floatValue]];
841 [self setVideoFilterProperty:"gamma" forFilter:"adjust" float:[[items objectAtIndex:7] floatValue]];
842 [self setVideoFilterProperty:"sharpen-sigma" forFilter:"sharpen" float:[[items objectAtIndex:8] floatValue]];
843 [self setVideoFilterProperty:"gradfun-radius" forFilter:"gradfun" integer:[[items objectAtIndex:9] intValue]];
844 [self setVideoFilterProperty:"grain-variance" forFilter:"grain" float:[[items objectAtIndex:10] floatValue]];
845 [self setVideoFilterProperty:"transform-type" forFilter:"transform" string:[B64DecNSStr([items objectAtIndex:11]) UTF8String]];
846 [self setVideoFilterProperty:"puzzle-rows" forFilter:"puzzle" integer:[[items objectAtIndex:12] intValue]];
847 [self setVideoFilterProperty:"puzzle-cols" forFilter:"puzzle" integer:[[items objectAtIndex:13] intValue]];
848 [self setVideoFilterProperty:"colorthres-color" forFilter:"colorthres" integer:[[items objectAtIndex:14] intValue]];
849 [self setVideoFilterProperty:"colorthres-saturationthres" forFilter:"colorthres" integer:[[items objectAtIndex:15] intValue]];
850 [self setVideoFilterProperty:"colorthres-similaritythres" forFilter:"colorthres" integer:[[items objectAtIndex:16] intValue]];
851 [self setVideoFilterProperty:"sepia-intensity" forFilter:"sepia" integer:[[items objectAtIndex:17] intValue]];
852 [self setVideoFilterProperty:"gradient-mode" forFilter:"gradient" string:[B64DecNSStr([items objectAtIndex:18]) UTF8String]];
853 [self setVideoFilterProperty:"gradient-cartoon" forFilter:"gradient" integer:[[items objectAtIndex:19] intValue]];
854 [self setVideoFilterProperty:"gradient-type" forFilter:"gradient" integer:[[items objectAtIndex:20] intValue]];
855 [self setVideoFilterProperty:"extract-component" forFilter:"extract" integer:[[items objectAtIndex:21] intValue]];
856 [self setVideoFilterProperty:"posterize-level" forFilter:"posterize" integer:[[items objectAtIndex:22] intValue]];
857 [self setVideoFilterProperty:"blur-factor" forFilter:"motionblur" integer:[[items objectAtIndex:23] intValue]];
858 [self setVideoFilterProperty:"marq-marquee" forFilter:"marq" string:[B64DecNSStr([items objectAtIndex:24]) UTF8String]];
859 [self setVideoFilterProperty:"marq-position" forFilter:"marq" integer:[[items objectAtIndex:25] intValue]];
860 [self setVideoFilterProperty:"logo-file" forFilter:"logo" string:[B64DecNSStr([items objectAtIndex:26]) UTF8String]];
861 [self setVideoFilterProperty:"logo-position" forFilter:"logo" integer:[[items objectAtIndex:27] intValue]];
862 [self setVideoFilterProperty:"logo-opacity" forFilter:"logo" integer:[[items objectAtIndex:28] intValue]];
863 [self setVideoFilterProperty:"clone-count" forFilter:"clone" integer:[[items objectAtIndex:29] intValue]];
864 [self setVideoFilterProperty:"wall-rows" forFilter:"wall" integer:[[items objectAtIndex:30] intValue]];
865 [self setVideoFilterProperty:"wall-cols" forFilter:"wall" integer:[[items objectAtIndex:31] intValue]];
867 [defaults setInteger:selectedProfile forKey:@"VideoEffectSelectedProfile"];
868 [defaults synchronize];
873 - (IBAction)addProfile:(id)sender
876 VLCEnterTextPanel * panel = [VLCEnterTextPanel sharedInstance];
877 [panel setTitle: _NS("Duplicate current profile for a new profile")];
878 [panel setSubTitle: _NS("Enter a name for the new profile:")];
879 [panel setCancelButtonLabel: _NS("Cancel")];
880 [panel setOKButtonLabel: _NS("Save")];
881 [panel setTarget:self];
883 [panel runModalForWindow:o_window];
886 - (void)panel:(VLCEnterTextPanel *)panel returnValue:(NSUInteger)value text:(NSString *)text
888 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
890 if (value != NSOKButton) {
891 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
895 NSArray *profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
897 // duplicate names are not allowed in the popup control
898 if ([text length] == 0 || [profileNames containsObject:text]) {
899 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
901 NSAlert *alert = [[[NSAlert alloc] init] autorelease];
902 [alert setAlertStyle:NSCriticalAlertStyle];
903 [alert setMessageText:_NS("Please enter a unique name for the new profile.")];
904 [alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
906 [alert beginSheetModalForWindow:o_window
913 /* fetch all the current settings in a uniform string */
914 NSString *newProfile = [self generateProfileString];
916 /* add string to user defaults as well as a label */
918 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
919 [workArray addObject:newProfile];
920 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
921 [defaults setInteger:[workArray count] - 1 forKey:@"VideoEffectSelectedProfile"];
924 workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfileNames"]];
925 [workArray addObject:text];
926 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
930 [defaults synchronize];
933 [self resetProfileSelector];
936 - (IBAction)removeProfile:(id)sender
939 VLCSelectItemInPopupPanel * panel = [VLCSelectItemInPopupPanel sharedInstance];
940 [panel setTitle:_NS("Remove a preset")];
941 [panel setSubTitle:_NS("Select the preset you would like to remove:")];
942 [panel setOKButtonLabel:_NS("Remove")];
943 [panel setCancelButtonLabel:_NS("Cancel")];
944 [panel setPopupButtonContent:[[NSUserDefaults standardUserDefaults] objectForKey:@"VideoEffectProfileNames"]];
945 [panel setTarget:self];
947 [panel runModalForWindow:o_window];
950 - (void)panel:(VLCSelectItemInPopupPanel *)panel returnValue:(NSUInteger)value item:(NSUInteger)item
952 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
954 if (value != NSOKButton) {
955 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
959 /* remove selected profile from settings */
960 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfiles"]];
961 [workArray removeObjectAtIndex:item];
962 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
965 workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfileNames"]];
966 [workArray removeObjectAtIndex:item];
967 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
970 if (i_old_profile_index >= item)
971 [defaults setInteger:i_old_profile_index - 1 forKey:@"VideoEffectSelectedProfile"];
974 [defaults synchronize];
976 /* do not save deleted profile */
977 i_old_profile_index = -1;
979 [self resetProfileSelector];
984 - (IBAction)enableAdjust:(id)sender
986 BOOL b_state = [o_adjust_ckb state];
988 [self setVideoFilter: "adjust" on: b_state];
989 [o_adjust_brightness_sld setEnabled: b_state];
990 [o_adjust_brightness_ckb setEnabled: b_state];
991 [o_adjust_brightness_lbl setEnabled: b_state];
992 [o_adjust_contrast_sld setEnabled: b_state];
993 [o_adjust_contrast_lbl setEnabled: b_state];
994 [o_adjust_gamma_sld setEnabled: b_state];
995 [o_adjust_gamma_lbl setEnabled: b_state];
996 [o_adjust_hue_sld setEnabled: b_state];
997 [o_adjust_hue_lbl setEnabled: b_state];
998 [o_adjust_saturation_sld setEnabled: b_state];
999 [o_adjust_saturation_lbl setEnabled: b_state];
1000 [o_adjust_reset_btn setEnabled: b_state];
1003 - (IBAction)adjustSliderChanged:(id)sender
1005 if (sender == o_adjust_brightness_sld)
1006 [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: [o_adjust_brightness_sld floatValue]];
1007 else if (sender == o_adjust_contrast_sld)
1008 [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: [o_adjust_contrast_sld floatValue]];
1009 else if (sender == o_adjust_gamma_sld)
1010 [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: [o_adjust_gamma_sld floatValue]];
1011 else if (sender == o_adjust_hue_sld)
1012 [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: [o_adjust_hue_sld intValue]];
1013 else if (sender == o_adjust_saturation_sld)
1014 [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: [o_adjust_saturation_sld floatValue]];
1016 if (sender == o_adjust_hue_sld)
1017 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", [o_adjust_hue_sld intValue]]];
1019 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
1022 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
1024 if (sender == o_adjust_reset_btn) {
1025 [o_adjust_brightness_sld setFloatValue: 1.0];
1026 [o_adjust_contrast_sld setFloatValue: 1.0];
1027 [o_adjust_gamma_sld setFloatValue: 1.0];
1028 [o_adjust_hue_sld setIntValue: 0];
1029 [o_adjust_saturation_sld setFloatValue: 1.0];
1030 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
1031 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
1032 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
1033 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", 0]];
1034 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
1035 [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: 1.0];
1036 [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: 1.0];
1037 [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: 1.0];
1038 [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: 0.0];
1039 [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: 1.0];
1041 config_PutInt(p_intf, "brightness-threshold", [o_adjust_brightness_ckb state]);
1044 - (IBAction)enableSharpen:(id)sender
1046 BOOL b_state = [o_sharpen_ckb state];
1048 [self setVideoFilter: "sharpen" on: b_state];
1049 [o_sharpen_sld setEnabled: b_state];
1050 [o_sharpen_lbl setEnabled: b_state];
1053 - (IBAction)sharpenSliderChanged:(id)sender
1055 [self setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [sender floatValue]];
1056 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
1059 - (IBAction)enableBanding:(id)sender
1061 BOOL b_state = [o_banding_ckb state];
1063 [self setVideoFilter: "gradfun" on: b_state];
1064 [o_banding_sld setEnabled: b_state];
1065 [o_banding_lbl setEnabled: b_state];
1068 - (IBAction)bandingSliderChanged:(id)sender
1070 [self setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [sender intValue]];
1071 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
1074 - (IBAction)enableGrain:(id)sender
1076 BOOL b_state = [o_grain_ckb state];
1078 [self setVideoFilter: "grain" on: b_state];
1079 [o_grain_sld setEnabled: b_state];
1080 [o_grain_lbl setEnabled: b_state];
1083 - (IBAction)grainSliderChanged:(id)sender
1085 [self setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [sender floatValue]];
1086 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
1093 - (IBAction)cropObjectChanged:(id)sender
1095 if ([o_crop_sync_top_bottom_ckb state]) {
1096 if (sender == o_crop_bottom_fld || sender == o_crop_bottom_stp)
1097 [self setCropTopValue: [self cropBottomValue]];
1099 [self setCropBottomValue: [self cropTopValue]];
1101 if ([o_crop_sync_left_right_ckb state]) {
1102 if (sender == o_crop_right_fld || sender == o_crop_right_stp)
1103 [self setCropLeftValue: [self cropRightValue]];
1105 [self setCropRightValue: [self cropLeftValue]];
1108 vout_thread_t *p_vout = getVout();
1110 var_SetInteger(p_vout, "crop-top", [o_crop_top_fld intValue]);
1111 var_SetInteger(p_vout, "crop-bottom", [o_crop_bottom_fld intValue]);
1112 var_SetInteger(p_vout, "crop-left", [o_crop_left_fld intValue]);
1113 var_SetInteger(p_vout, "crop-right", [o_crop_right_fld intValue]);
1114 vlc_object_release(p_vout);
1119 #pragma mark geometry
1120 - (IBAction)enableTransform:(id)sender
1122 [self setVideoFilter: "transform" on: [o_transform_ckb state]];
1123 [o_transform_pop setEnabled: [o_transform_ckb state]];
1126 - (IBAction)transformModifierChanged:(id)sender
1128 NSInteger tag = [[o_transform_pop selectedItem] tag];
1129 const char *psz_string = [[NSString stringWithFormat:@"%li", tag] UTF8String];
1131 psz_string = "hflip";
1133 psz_string = "vflip";
1135 [self setVideoFilterProperty: "transform-type" forFilter: "transform" string: psz_string];
1138 - (IBAction)enableZoom:(id)sender
1140 [self setVideoFilter: "magnify" on: [o_zoom_ckb state]];
1143 - (IBAction)enablePuzzle:(id)sender
1145 BOOL b_state = [o_puzzle_ckb state];
1147 [self setVideoFilter: "puzzle" on: b_state];
1148 [o_puzzle_columns_fld setEnabled: b_state];
1149 [o_puzzle_columns_stp setEnabled: b_state];
1150 [o_puzzle_columns_lbl setEnabled: b_state];
1151 [o_puzzle_rows_fld setEnabled: b_state];
1152 [o_puzzle_rows_stp setEnabled: b_state];
1153 [o_puzzle_rows_lbl setEnabled: b_state];
1156 - (IBAction)puzzleModifierChanged:(id)sender
1158 if (sender == o_puzzle_columns_fld || sender == o_puzzle_columns_stp)
1159 [self setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [sender intValue]];
1161 [self setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [sender intValue]];
1164 - (IBAction)enableClone:(id)sender
1166 BOOL b_state = [o_clone_ckb state];
1168 if (b_state && [o_wall_ckb state]) {
1169 [o_wall_ckb setState: NSOffState];
1170 [self enableWall: o_wall_ckb];
1173 [self setVideoFilter: "clone" on: b_state];
1174 [o_clone_number_lbl setEnabled: b_state];
1175 [o_clone_number_fld setEnabled: b_state];
1176 [o_clone_number_stp setEnabled: b_state];
1179 - (IBAction)cloneModifierChanged:(id)sender
1181 [self setVideoFilterProperty: "clone-count" forFilter: "clone" integer: [o_clone_number_fld intValue]];
1184 - (IBAction)enableWall:(id)sender
1186 BOOL b_state = [o_wall_ckb state];
1188 if (b_state && [o_clone_ckb state]) {
1189 [o_clone_ckb setState: NSOffState];
1190 [self enableClone: o_clone_ckb];
1193 [self setVideoFilter: "wall" on: b_state];
1194 [o_wall_numofcols_fld setEnabled: b_state];
1195 [o_wall_numofcols_stp setEnabled: b_state];
1196 [o_wall_numofcols_lbl setEnabled: b_state];
1198 [o_wall_numofrows_fld setEnabled: b_state];
1199 [o_wall_numofrows_stp setEnabled: b_state];
1200 [o_wall_numofrows_lbl setEnabled: b_state];
1203 - (IBAction)wallModifierChanged:(id)sender
1205 if (sender == o_wall_numofcols_fld || sender == o_wall_numofcols_stp)
1206 [self setVideoFilterProperty: "wall-cols" forFilter: "wall" integer: [sender intValue]];
1208 [self setVideoFilterProperty: "wall-rows" forFilter: "wall" integer: [sender intValue]];
1213 - (IBAction)enableThreshold:(id)sender
1215 BOOL b_state = [o_threshold_ckb state];
1217 [self setVideoFilter: "colorthres" on: b_state];
1218 [o_threshold_color_fld setEnabled: b_state];
1219 [o_threshold_color_lbl setEnabled: b_state];
1220 [o_threshold_saturation_sld setEnabled: b_state];
1221 [o_threshold_saturation_lbl setEnabled: b_state];
1222 [o_threshold_similarity_sld setEnabled: b_state];
1223 [o_threshold_similarity_lbl setEnabled: b_state];
1226 - (IBAction)thresholdModifierChanged:(id)sender
1228 if (sender == o_threshold_color_fld)
1229 [self setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [o_threshold_color_fld intValue]];
1230 else if (sender == o_threshold_saturation_sld) {
1231 [self setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [o_threshold_saturation_sld intValue]];
1232 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_saturation_sld intValue]]];
1234 [self setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [o_threshold_similarity_sld intValue]];
1235 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_similarity_sld intValue]]];
1239 - (IBAction)enableSepia:(id)sender
1241 BOOL b_state = [o_sepia_ckb state];
1243 [self setVideoFilter: "sepia" on: b_state];
1244 [o_sepia_fld setEnabled: b_state];
1245 [o_sepia_stp setEnabled: b_state];
1246 [o_sepia_lbl setEnabled: b_state];
1249 - (IBAction)sepiaModifierChanged:(id)sender
1251 [self setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [o_sepia_fld intValue]];
1254 - (IBAction)enableNoise:(id)sender
1256 [self setVideoFilter: "noise" on: [o_noise_ckb state]];
1259 - (IBAction)enableGradient:(id)sender
1261 BOOL b_state = [o_gradient_ckb state];
1263 [self setVideoFilter: "gradient" on: b_state];
1264 [o_gradient_mode_pop setEnabled: b_state];
1265 [o_gradient_mode_lbl setEnabled: b_state];
1266 [o_gradient_color_ckb setEnabled: b_state];
1267 [o_gradient_cartoon_ckb setEnabled: b_state];
1270 - (IBAction)gradientModifierChanged:(id)sender
1272 if (sender == o_gradient_mode_pop) {
1273 if ([[o_gradient_mode_pop selectedItem] tag] == 3)
1274 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
1275 else if ([[o_gradient_mode_pop selectedItem] tag] == 2)
1276 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
1278 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
1279 } else if (sender == o_gradient_color_ckb)
1280 [self setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [o_gradient_color_ckb state]];
1282 [self setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [o_gradient_cartoon_ckb state]];
1285 - (IBAction)enableExtract:(id)sender
1287 BOOL b_state = [o_extract_ckb state];
1288 [self setVideoFilter: "extract" on: b_state];
1289 [o_extract_fld setEnabled: b_state];
1290 [o_extract_lbl setEnabled: b_state];
1293 - (IBAction)extractModifierChanged:(id)sender
1295 [self setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [o_extract_fld intValue]];
1298 - (IBAction)enableInvert:(id)sender
1300 [self setVideoFilter: "invert" on: [o_invert_ckb state]];
1303 - (IBAction)enablePosterize:(id)sender
1305 BOOL b_state = [o_posterize_ckb state];
1307 [self setVideoFilter: "posterize" on: b_state];
1308 [o_posterize_fld setEnabled: b_state];
1309 [o_posterize_stp setEnabled: b_state];
1310 [o_posterize_lbl setEnabled: b_state];
1313 - (IBAction)posterizeModifierChanged:(id)sender
1315 [self setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [o_posterize_fld intValue]];
1318 - (IBAction)enableBlur:(id)sender
1320 BOOL b_state = [o_blur_ckb state];
1322 [self setVideoFilter: "motionblur" on: b_state];
1323 [o_blur_sld setEnabled: b_state];
1324 [o_blur_lbl setEnabled: b_state];
1327 - (IBAction)blurModifierChanged:(id)sender
1329 [self setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [sender intValue]];
1330 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
1333 - (IBAction)enableMotionDetect:(id)sender
1335 [self setVideoFilter: "motiondetect" on: [o_motiondetect_ckb state]];
1338 - (IBAction)enableWaterEffect:(id)sender
1340 [self setVideoFilter: "ripple" on: [o_watereffect_ckb state]];
1343 - (IBAction)enableWaves:(id)sender
1345 [self setVideoFilter: "wave" on: [o_waves_ckb state]];
1348 - (IBAction)enablePsychedelic:(id)sender
1350 [self setVideoFilter: "psychedelic" on: [o_psychedelic_ckb state]];
1354 #pragma mark Miscellaneous
1355 - (IBAction)enableAddText:(id)sender
1357 BOOL b_state = [o_addtext_ckb state];
1359 [o_addtext_pos_pop setEnabled: b_state];
1360 [o_addtext_pos_lbl setEnabled: b_state];
1361 [o_addtext_text_lbl setEnabled: b_state];
1362 [o_addtext_text_fld setEnabled: b_state];
1363 [self setVideoFilter: "marq" on: b_state];
1364 [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
1365 [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
1368 - (IBAction)addTextModifierChanged:(id)sender
1370 if (sender == o_addtext_text_fld)
1371 [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
1373 [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
1376 - (IBAction)enableAddLogo:(id)sender
1378 BOOL b_state = [o_addlogo_ckb state];
1380 [o_addlogo_pos_pop setEnabled: b_state];
1381 [o_addlogo_pos_lbl setEnabled: b_state];
1382 [o_addlogo_logo_fld setEnabled: b_state];
1383 [o_addlogo_logo_lbl setEnabled: b_state];
1384 [o_addlogo_transparency_sld setEnabled: b_state];
1385 [o_addlogo_transparency_lbl setEnabled: b_state];
1386 [self setVideoFilter: "logo" on: b_state];
1389 - (IBAction)addLogoModifierChanged:(id)sender
1391 if (sender == o_addlogo_logo_fld)
1392 [self setVideoFilterProperty: "logo-file" forFilter: "logo" string: (char *)[[o_addlogo_logo_fld stringValue] UTF8String]];
1393 else if (sender == o_addlogo_pos_pop)
1394 [self setVideoFilterProperty: "logo-position" forFilter: "logo" integer: [[o_addlogo_pos_pop selectedItem] tag]];
1396 [self setVideoFilterProperty: "logo-opacity" forFilter: "logo" integer: [o_addlogo_transparency_sld intValue]];
1397 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%i", [o_addlogo_transparency_sld intValue]]];
1401 - (IBAction)enableAnaglyph:(id)sender
1403 [self setVideoFilter: "anaglyph" on: [o_anaglyph_ckb state]];