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 <vlc_strings.h>
30 #import "VideoEffects.h"
31 #import "SharedDialogs.h"
33 @interface VLCVideoEffects (Internal)
34 - (void)resetProfileSelector;
38 #pragma mark Initialization
40 @implementation VLCVideoEffects
41 static VLCVideoEffects *_o_sharedInstance = nil;
43 @synthesize cropLeftValue, cropTopValue, cropRightValue, cropBottomValue;
44 @synthesize puzzleRowsValue, puzzleColumnsValue;
45 @synthesize wallRowsValue, wallColumnsValue;
46 @synthesize cloneValue;
47 @synthesize sepiaValue;
48 @synthesize posterizeValue;
50 + (VLCVideoEffects *)sharedInstance
52 return _o_sharedInstance ? _o_sharedInstance : [[self alloc] init];
57 NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:[NSArray arrayWithObject:@";;;0;1.000000;1.000000;1.000000;1.000000;0.050000;16;2.000000;OTA=;4;4;0;16711680;20;15;120;Z3JhZGllbnQ=;1;0;16711680;6;80;VkxD;-1;;-1;255;2;3;3"], @"VideoEffectProfiles", [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_puzzle_blackslot_ckb setTitle:_NS("Black Slot")];
127 [o_clone_ckb setTitle:_NS("Clone")];
128 [o_clone_number_lbl setStringValue:_NS("Number of clones")];
129 [o_wall_ckb setTitle:_NS("Wall")];
130 [o_wall_numofrows_lbl setStringValue:_NS("Rows")];
131 [o_wall_numofcols_lbl setStringValue:_NS("Columns")];
133 [o_threshold_ckb setTitle:_NS("Color threshold")];
134 [o_threshold_color_lbl setStringValue:_NS("Color")];
135 [o_threshold_saturation_lbl setStringValue:_NS("Saturation")];
136 [o_threshold_similarity_lbl setStringValue:_NS("Similarity")];
137 [o_sepia_ckb setTitle:_NS("Sepia")];
138 [o_sepia_lbl setStringValue:_NS("Intensity")];
139 [o_noise_ckb setTitle:_NS("Noise")];
140 [o_gradient_ckb setTitle:_NS("Gradient")];
141 [o_gradient_mode_lbl setStringValue:_NS("Mode")];
142 [o_gradient_mode_pop removeAllItems];
143 [o_gradient_mode_pop addItemWithTitle: _NS("Gradient")];
144 [[o_gradient_mode_pop lastItem] setTag: 1];
145 [o_gradient_mode_pop addItemWithTitle: _NS("Edge")];
146 [[o_gradient_mode_pop lastItem] setTag: 2];
147 [o_gradient_mode_pop addItemWithTitle: _NS("Hough")];
148 [[o_gradient_mode_pop lastItem] setTag: 3];
149 [o_gradient_color_ckb setTitle:_NS("Color")];
150 [o_gradient_cartoon_ckb setTitle:_NS("Cartoon")];
151 [o_extract_ckb setTitle:_NS("Color extraction")];
152 [o_extract_lbl setStringValue:_NS("Color")];
153 [o_invert_ckb setTitle:_NS("Invert colors")];
154 [o_posterize_ckb setTitle:_NS("Posterize")];
155 [o_posterize_lbl setStringValue:_NS("Posterize level")];
156 [o_blur_ckb setTitle:_NS("Motion blur")];
157 [o_blur_lbl setStringValue:_NS("Factor")];
158 [o_motiondetect_ckb setTitle:_NS("Motion Detect")];
159 [o_watereffect_ckb setTitle:_NS("Water effect")];
160 [o_waves_ckb setTitle:_NS("Waves")];
161 [o_psychedelic_ckb setTitle:_NS("Psychedelic")];
162 [o_anaglyph_ckb setTitle:_NS("Anaglyph 3D")];
164 [o_addtext_ckb setTitle:_NS("Add text")];
165 [o_addtext_text_lbl setStringValue:_NS("Text")];
166 [o_addtext_pos_lbl setStringValue:_NS("Position")];
167 [o_addtext_pos_pop removeAllItems];
168 [o_addtext_pos_pop addItemWithTitle: _NS("Center")];
169 [[o_addtext_pos_pop lastItem] setTag: 0];
170 [o_addtext_pos_pop addItemWithTitle: _NS("Left")];
171 [[o_addtext_pos_pop lastItem] setTag: 1];
172 [o_addtext_pos_pop addItemWithTitle: _NS("Right")];
173 [[o_addtext_pos_pop lastItem] setTag: 2];
174 [o_addtext_pos_pop addItemWithTitle: _NS("Top")];
175 [[o_addtext_pos_pop lastItem] setTag: 4];
176 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom")];
177 [[o_addtext_pos_pop lastItem] setTag: 8];
178 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Left")];
179 [[o_addtext_pos_pop lastItem] setTag: 5];
180 [o_addtext_pos_pop addItemWithTitle: _NS("Top-Right")];
181 [[o_addtext_pos_pop lastItem] setTag: 6];
182 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Left")];
183 [[o_addtext_pos_pop lastItem] setTag: 9];
184 [o_addtext_pos_pop addItemWithTitle: _NS("Bottom-Right")];
185 [[o_addtext_pos_pop lastItem] setTag: 10];
186 [o_addlogo_ckb setTitle:_NS("Add logo")];
187 [o_addlogo_logo_lbl setStringValue:_NS("Logo")];
188 [o_addlogo_pos_lbl setStringValue:_NS("Position")];
189 [o_addlogo_pos_pop removeAllItems];
190 [o_addlogo_pos_pop addItemWithTitle: _NS("Center")];
191 [[o_addlogo_pos_pop lastItem] setTag: 0];
192 [o_addlogo_pos_pop addItemWithTitle: _NS("Left")];
193 [[o_addlogo_pos_pop lastItem] setTag: 1];
194 [o_addlogo_pos_pop addItemWithTitle: _NS("Right")];
195 [[o_addlogo_pos_pop lastItem] setTag: 2];
196 [o_addlogo_pos_pop addItemWithTitle: _NS("Top")];
197 [[o_addlogo_pos_pop lastItem] setTag: 4];
198 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom")];
199 [[o_addlogo_pos_pop lastItem] setTag: 8];
200 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Left")];
201 [[o_addlogo_pos_pop lastItem] setTag: 5];
202 [o_addlogo_pos_pop addItemWithTitle: _NS("Top-Right")];
203 [[o_addlogo_pos_pop lastItem] setTag: 6];
204 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Left")];
205 [[o_addlogo_pos_pop lastItem] setTag: 9];
206 [o_addlogo_pos_pop addItemWithTitle: _NS("Bottom-Right")];
207 [[o_addlogo_pos_pop lastItem] setTag: 10];
208 [o_addlogo_transparency_lbl setStringValue:_NS("Transparency")];
210 [o_tableView selectFirstTabViewItem:self];
215 - (void)updateCocoaWindowLevel:(NSInteger)i_level
217 if (o_window && [o_window isVisible] && [o_window level] != i_level)
218 [o_window setLevel: i_level];
222 #pragma mark internal functions
223 - (void)resetProfileSelector
225 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
226 [o_profile_pop removeAllItems];
228 NSArray * profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
229 [o_profile_pop addItemsWithTitles:profileNames];
231 [[o_profile_pop menu] addItem:[NSMenuItem separatorItem]];
232 [o_profile_pop addItemWithTitle:_NS("Duplicate current profile...")];
233 [[o_profile_pop lastItem] setTarget: self];
234 [[o_profile_pop lastItem] setAction: @selector(addProfile:)];
236 if ([profileNames count] > 1) {
237 [o_profile_pop addItemWithTitle:_NS("Organize profiles...")];
238 [[o_profile_pop lastItem] setTarget: self];
239 [[o_profile_pop lastItem] setAction: @selector(removeProfile:)];
242 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
243 [self profileSelectorAction:self];
252 /* do we have any filter enabled? if yes, show it. */
254 psz_vfilters = config_GetPsz(p_intf, "video-filter");
256 [o_adjust_ckb setState: (NSInteger)strstr(psz_vfilters, "adjust")];
257 [o_sharpen_ckb setState: (NSInteger)strstr(psz_vfilters, "sharpen")];
258 [o_banding_ckb setState: (NSInteger)strstr(psz_vfilters, "gradfun")];
259 [o_grain_ckb setState: (NSInteger)strstr(psz_vfilters, "grain")];
260 [o_transform_ckb setState: (NSInteger)strstr(psz_vfilters, "transform")];
261 [o_zoom_ckb setState: (NSInteger)strstr(psz_vfilters, "magnify")];
262 [o_puzzle_ckb setState: (NSInteger)strstr(psz_vfilters, "puzzle")];
263 [o_threshold_ckb setState: (NSInteger)strstr(psz_vfilters, "colorthres")];
264 [o_sepia_ckb setState: (NSInteger)strstr(psz_vfilters, "sepia")];
265 [o_noise_ckb setState: (NSInteger)strstr(psz_vfilters, "noise")];
266 [o_gradient_ckb setState: (NSInteger)strstr(psz_vfilters, "gradient")];
267 [o_extract_ckb setState: (NSInteger)strstr(psz_vfilters, "extract")];
268 [o_invert_ckb setState: (NSInteger)strstr(psz_vfilters, "invert")];
269 [o_posterize_ckb setState: (NSInteger)strstr(psz_vfilters, "posterize")];
270 [o_blur_ckb setState: (NSInteger)strstr(psz_vfilters, "motionblur")];
271 [o_motiondetect_ckb setState: (NSInteger)strstr(psz_vfilters, "motiondetect")];
272 [o_watereffect_ckb setState: (NSInteger)strstr(psz_vfilters, "ripple")];
273 [o_waves_ckb setState: (NSInteger)strstr(psz_vfilters, "wave")];
274 [o_psychedelic_ckb setState: (NSInteger)strstr(psz_vfilters, "psychedelic")];
275 [o_anaglyph_ckb setState: (NSInteger)strstr(psz_vfilters, "anaglyph")];
278 [o_adjust_ckb setState: NSOffState];
279 [o_sharpen_ckb setState: NSOffState];
280 [o_banding_ckb setState: NSOffState];
281 [o_grain_ckb setState: NSOffState];
282 [o_transform_ckb setState: NSOffState];
283 [o_zoom_ckb setState: NSOffState];
284 [o_puzzle_ckb setState: NSOffState];
285 [o_threshold_ckb setState: NSOffState];
286 [o_sepia_ckb setState: NSOffState];
287 [o_noise_ckb setState: NSOffState];
288 [o_gradient_ckb setState: NSOffState];
289 [o_extract_ckb setState: NSOffState];
290 [o_invert_ckb setState: NSOffState];
291 [o_posterize_ckb setState: NSOffState];
292 [o_blur_ckb setState: NSOffState];
293 [o_motiondetect_ckb setState: NSOffState];
294 [o_watereffect_ckb setState: NSOffState];
295 [o_waves_ckb setState: NSOffState];
296 [o_psychedelic_ckb setState: NSOffState];
297 [o_anaglyph_ckb setState: NSOffState];
300 psz_vfilters = config_GetPsz(p_intf, "sub-source");
302 [o_addtext_ckb setState: (NSInteger)strstr(psz_vfilters, "marq")];
303 [o_addlogo_ckb setState: (NSInteger)strstr(psz_vfilters, "logo")];
306 [o_addtext_ckb setState: NSOffState];
307 [o_addlogo_ckb setState: NSOffState];
310 psz_vfilters = config_GetPsz(p_intf, "video-splitter");
312 [o_clone_ckb setState: (NSInteger)strstr(psz_vfilters, "clone")];
313 [o_wall_ckb setState: (NSInteger)strstr(psz_vfilters, "wall")];
316 [o_clone_ckb setState: NSOffState];
317 [o_wall_ckb setState: NSOffState];
320 /* fetch and show the various values */
321 [o_adjust_hue_sld setIntValue: config_GetInt(p_intf, "hue")];
322 [o_adjust_contrast_sld setFloatValue: config_GetFloat(p_intf, "contrast")];
323 [o_adjust_brightness_sld setFloatValue: config_GetFloat(p_intf, "brightness")];
324 [o_adjust_saturation_sld setFloatValue: config_GetFloat(p_intf, "saturation")];
325 [o_adjust_gamma_sld setFloatValue: config_GetFloat(p_intf, "gamma")];
326 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "brightness")]];
327 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "contrast")]];
328 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "gamma")]];
329 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "hue")]];
330 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "saturation")]];
331 b_state = [o_adjust_ckb state];
332 [o_adjust_brightness_sld setEnabled: b_state];
333 [o_adjust_brightness_ckb setEnabled: b_state];
334 [o_adjust_contrast_sld setEnabled: b_state];
335 [o_adjust_gamma_sld setEnabled: b_state];
336 [o_adjust_hue_sld setEnabled: b_state];
337 [o_adjust_saturation_sld setEnabled: b_state];
338 [o_adjust_brightness_lbl setEnabled: b_state];
339 [o_adjust_contrast_lbl setEnabled: b_state];
340 [o_adjust_gamma_lbl setEnabled: b_state];
341 [o_adjust_hue_lbl setEnabled: b_state];
342 [o_adjust_saturation_lbl setEnabled: b_state];
343 [o_adjust_reset_btn setEnabled: b_state];
345 [o_sharpen_sld setFloatValue: config_GetFloat(p_intf, "sharpen-sigma")];
346 [o_sharpen_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "sharpen-sigma")]];
347 [o_sharpen_sld setEnabled: [o_sharpen_ckb state]];
348 [o_sharpen_lbl setEnabled: [o_sharpen_ckb state]];
350 [o_banding_sld setIntValue: config_GetInt(p_intf, "gradfun-radius")];
351 [o_banding_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "gradfun-radius")]];
352 [o_banding_sld setEnabled: [o_banding_ckb state]];
353 [o_banding_lbl setEnabled: [o_banding_ckb state]];
355 [o_grain_sld setFloatValue: config_GetFloat(p_intf, "grain-variance")];
356 [o_grain_sld setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "grain-variance")]];
357 [o_grain_sld setEnabled: [o_grain_ckb state]];
358 [o_grain_lbl setEnabled: [o_grain_ckb state]];
360 [self setCropLeftValue: 0];
361 [self setCropTopValue: 0];
362 [self setCropRightValue: 0];
363 [self setCropBottomValue: 0];
364 [o_crop_sync_top_bottom_ckb setState: NSOffState];
365 [o_crop_sync_left_right_ckb setState: NSOffState];
367 tmpChar = config_GetPsz(p_intf, "transform-type");
368 tmpString = [NSString stringWithUTF8String: tmpChar];
369 if ([tmpString isEqualToString:@"hflip"])
370 [o_transform_pop selectItemWithTag: 1];
371 else if ([tmpString isEqualToString:@"vflip"])
372 [o_transform_pop selectItemWithTag: 2];
374 [o_transform_pop selectItemWithTag:[tmpString intValue]];
376 [o_transform_pop setEnabled: [o_transform_ckb state]];
378 [self setPuzzleColumnsValue: config_GetInt(p_intf, "puzzle-cols")];
379 [self setPuzzleRowsValue: config_GetInt(p_intf, "puzzle-rows")];
380 [o_puzzle_blackslot_ckb setState: config_GetInt(p_intf, "puzzle-black-slot")];
381 b_state = [o_puzzle_ckb state];
382 [o_puzzle_rows_fld setEnabled: b_state];
383 [o_puzzle_rows_stp setEnabled: b_state];
384 [o_puzzle_rows_lbl setEnabled: b_state];
385 [o_puzzle_columns_fld setEnabled: b_state];
386 [o_puzzle_columns_stp setEnabled: b_state];
387 [o_puzzle_columns_lbl setEnabled: b_state];
388 [o_puzzle_blackslot_ckb setEnabled: b_state];
390 [self setCloneValue: config_GetInt(p_intf, "clone-count")];
391 b_state = [o_clone_ckb state];
392 [o_clone_number_lbl setEnabled: b_state];
393 [o_clone_number_fld setEnabled: b_state];
394 [o_clone_number_stp setEnabled: b_state];
396 b_state = [o_wall_ckb state];
397 [self setWallRowsValue: config_GetInt(p_intf, "wall-rows")];
398 [o_wall_numofrows_lbl setEnabled: b_state];
399 [o_wall_numofrows_fld setEnabled: b_state];
400 [o_wall_numofrows_stp setEnabled: b_state];
401 [self setWallColumnsValue: config_GetInt(p_intf, "wall-cols")];
402 [o_wall_numofcols_lbl setEnabled: b_state];
403 [o_wall_numofcols_fld setEnabled: b_state];
404 [o_wall_numofcols_stp setEnabled: b_state];
406 [o_threshold_color_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "colorthres-color")] uppercaseString]];
407 [o_threshold_saturation_sld setIntValue: config_GetInt(p_intf, "colorthres-saturationthres")];
408 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-saturationthres")]];
409 [o_threshold_similarity_sld setIntValue: config_GetInt(p_intf, "colorthres-similaritythres")];
410 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-similaritythres")]];
412 b_state = [o_threshold_ckb state];
413 [o_threshold_color_fld setEnabled: b_state];
414 [o_threshold_color_lbl setEnabled: b_state];
415 [o_threshold_saturation_sld setEnabled: b_state];
416 [o_threshold_saturation_lbl setEnabled: b_state];
417 [o_threshold_similarity_sld setEnabled: b_state];
418 [o_threshold_similarity_lbl setEnabled: b_state];
420 [self setSepiaValue: config_GetInt(p_intf, "sepia-intensity")];
421 b_state = [o_sepia_ckb state];
422 [o_sepia_fld setEnabled: b_state];
423 [o_sepia_stp setEnabled: b_state];
424 [o_sepia_lbl setEnabled: b_state];
426 tmpChar = config_GetPsz(p_intf, "gradient-mode");
427 tmpString = [NSString stringWithUTF8String: tmpChar];
428 if ([tmpString isEqualToString:@"hough"])
429 [o_gradient_mode_pop selectItemWithTag: 3];
430 else if ([tmpString isEqualToString:@"edge"])
431 [o_gradient_mode_pop selectItemWithTag: 2];
433 [o_gradient_mode_pop selectItemWithTag: 1];
435 [o_gradient_cartoon_ckb setState: config_GetInt(p_intf, "gradient-cartoon")];
436 [o_gradient_color_ckb setState: config_GetInt(p_intf, "gradient-type")];
437 b_state = [o_gradient_ckb state];
438 [o_gradient_mode_pop setEnabled: b_state];
439 [o_gradient_mode_lbl setEnabled: b_state];
440 [o_gradient_cartoon_ckb setEnabled: b_state];
441 [o_gradient_color_ckb setEnabled: b_state];
443 [o_extract_fld setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "extract-component")] uppercaseString]];
444 [o_extract_fld setEnabled: [o_extract_ckb state]];
445 [o_extract_lbl setEnabled: [o_extract_ckb state]];
447 [self setPosterizeValue: config_GetInt(p_intf, "posterize-level")];
448 b_state = [o_posterize_ckb state];
449 [o_posterize_fld setEnabled: b_state];
450 [o_posterize_stp setEnabled: b_state];
451 [o_posterize_lbl setEnabled: b_state];
453 [o_blur_sld setIntValue: config_GetInt(p_intf, "blur-factor")];
454 [o_blur_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "blur-factor")]];
455 [o_blur_sld setEnabled: [o_blur_ckb state]];
456 [o_blur_lbl setEnabled: [o_blur_ckb state]];
458 tmpChar = config_GetPsz(p_intf, "marq-marquee");
460 [o_addtext_text_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
463 [o_addtext_text_fld setStringValue: @""];
464 [o_addtext_pos_pop selectItemWithTag: config_GetInt(p_intf, "marq-position")];
465 b_state = [o_addtext_ckb state];
466 [o_addtext_pos_pop setEnabled: b_state];
467 [o_addtext_pos_lbl setEnabled: b_state];
468 [o_addtext_text_lbl setEnabled: b_state];
469 [o_addtext_text_fld setEnabled: b_state];
471 tmpChar = config_GetPsz(p_intf, "logo-file");
473 [o_addlogo_logo_fld setStringValue: [NSString stringWithUTF8String: tmpChar]];
476 [o_addlogo_logo_fld setStringValue: @""];
477 [o_addlogo_pos_pop selectItemWithTag: config_GetInt(p_intf, "logo-position")];
478 [o_addlogo_transparency_sld setIntValue: config_GetInt(p_intf, "logo-opacity")];
479 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "logo-opacity")]];
480 b_state = [o_addlogo_ckb state];
481 [o_addlogo_pos_pop setEnabled: b_state];
482 [o_addlogo_pos_lbl setEnabled: b_state];
483 [o_addlogo_logo_fld setEnabled: b_state];
484 [o_addlogo_logo_lbl setEnabled: b_state];
485 [o_addlogo_transparency_sld setEnabled: b_state];
486 [o_addlogo_transparency_lbl setEnabled: b_state];
489 - (void)setVideoFilter: (char *)psz_name on:(BOOL)b_on
491 char *psz_string, *psz_parser;
492 const char *psz_filter_type;
494 module_t *p_obj = module_find(psz_name);
496 msg_Err(p_intf, "Unable to find filter module \"%s\".", psz_name);
499 msg_Dbg(p_intf, "will set filter '%s'", psz_name);
501 if (module_provides(p_obj, "video splitter")) {
502 psz_filter_type = "video-splitter";
503 } else if (module_provides(p_obj, "video filter2")) {
504 psz_filter_type = "video-filter";
505 } else if (module_provides(p_obj, "sub source")) {
506 psz_filter_type = "sub-source";
507 } else if (module_provides(p_obj, "sub filter")) {
508 psz_filter_type = "sub-filter";
510 msg_Err(p_intf, "Unknown video filter type.");
514 psz_string = config_GetPsz(p_intf, psz_filter_type);
518 psz_string = psz_name;
519 else if (strstr(psz_string, psz_name) == NULL)
520 psz_string = (char *)[[NSString stringWithFormat: @"%s:%s", psz_string, psz_name] UTF8String];
525 psz_parser = strstr(psz_string, psz_name);
527 if (*(psz_parser + strlen(psz_name)) == ':') {
528 memmove(psz_parser, psz_parser + strlen(psz_name) + 1,
529 strlen(psz_parser + strlen(psz_name) + 1) + 1);
534 /* Remove trailing : : */
535 if (strlen(psz_string) > 0 && *(psz_string + strlen(psz_string) -1) == ':')
536 *(psz_string + strlen(psz_string) -1) = '\0';
542 config_PutPsz(p_intf, psz_filter_type, psz_string);
544 /* Try to set on the fly */
545 if (!strcmp(psz_filter_type, "video-splitter")) {
546 playlist_t *p_playlist = pl_Get(p_intf);
547 var_SetString(p_playlist, psz_filter_type, psz_string);
549 vout_thread_t *p_vout = getVout();
551 var_SetString(p_vout, psz_filter_type, psz_string);
552 vlc_object_release(p_vout);
557 - (void)restartFilterIfNeeded: (char *)psz_filter option: (char *)psz_name
559 vout_thread_t *p_vout = getVout();
564 vlc_object_release(p_vout);
566 vlc_object_t *p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
569 i_type = var_Type(p_filter, psz_name);
571 i_type = config_GetType(p_intf, psz_name);
573 if (!(i_type & VLC_VAR_ISCOMMAND)) {
574 msg_Warn(p_intf, "Brute-restarting filter '%s', because the last changed option isn't a command", psz_name);
575 [self setVideoFilter: psz_filter on: NO];
576 [self setVideoFilter: psz_filter on: YES];
578 msg_Dbg(p_intf, "restart not needed");
580 vlc_object_release(p_filter);
584 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter integer: (int)i_value
586 vout_thread_t *p_vout = getVout();
587 vlc_object_t *p_filter;
589 config_PutInt(p_intf, psz_name, i_value);
592 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
595 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
596 vlc_object_release(p_vout);
599 var_SetInteger(p_filter, psz_name, i_value);
600 vlc_object_release(p_vout);
601 vlc_object_release(p_filter);
603 [self restartFilterIfNeeded: psz_filter option: psz_name];
607 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter float: (float)f_value
609 vout_thread_t *p_vout = getVout();
610 vlc_object_t *p_filter;
612 config_PutFloat(p_intf, psz_name, f_value);
615 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
618 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
619 vlc_object_release(p_vout);
622 var_SetFloat(p_filter, psz_name, f_value);
623 vlc_object_release(p_vout);
624 vlc_object_release(p_filter);
626 [self restartFilterIfNeeded: psz_filter option: psz_name];
630 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter string: (char *)psz_value
632 vout_thread_t *p_vout = getVout();
633 vlc_object_t *p_filter;
635 config_PutPsz(p_intf, psz_name, EnsureUTF8(psz_value));
638 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
641 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
642 vlc_object_release(p_vout);
645 var_SetString(p_filter, psz_name, EnsureUTF8(psz_value));
646 vlc_object_release(p_vout);
647 vlc_object_release(p_filter);
649 [self restartFilterIfNeeded: psz_filter option: psz_name];
653 - (void)setVideoFilterProperty: (char *)psz_name forFilter: (char *)psz_filter boolean: (BOOL)b_value
655 vout_thread_t *p_vout = getVout();
656 vlc_object_t *p_filter;
658 config_PutInt(p_intf, psz_name, b_value);
661 p_filter = vlc_object_find_name(pl_Get(p_intf), psz_filter);
664 msg_Warn(p_intf, "filter '%s' isn't enabled", psz_filter);
665 vlc_object_release(p_vout);
668 var_SetBool(p_filter, psz_name, b_value);
669 vlc_object_release(p_vout);
670 vlc_object_release(p_filter);
674 - (NSString *)generateProfileString
676 return [NSString stringWithFormat:@"%s;%s;%s;%lli;%f;%f;%f;%f;%f;%lli;%f;%s;%lli;%lli;%lli;%lli;%lli;%lli;%lli;%s;%lli;%lli;%lli;%lli;%lli;%s;%lli;%s;%lli;%lli;%lli;%lli;%lli",
677 vlc_b64_encode(config_GetPsz(p_intf, "video-filter")),
678 vlc_b64_encode(config_GetPsz(p_intf, "sub-source")),
679 vlc_b64_encode(config_GetPsz(p_intf, "video-splitter")),
680 config_GetInt(p_intf, "hue"),
681 config_GetFloat(p_intf, "contrast"),
682 config_GetFloat(p_intf, "brightness"),
683 config_GetFloat(p_intf, "saturation"),
684 config_GetFloat(p_intf, "gamma"),
685 config_GetFloat(p_intf, "sharpen-sigma"),
686 config_GetInt(p_intf, "gradfun-radius"),
687 config_GetFloat(p_intf, "grain-variance"),
688 vlc_b64_encode(config_GetPsz(p_intf, "transform-type")),
689 config_GetInt(p_intf, "puzzle-rows"),
690 config_GetInt(p_intf, "puzzle-cols"),
691 config_GetInt(p_intf, "puzzle-black-slot"),
692 config_GetInt(p_intf, "colorthres-color"),
693 config_GetInt(p_intf, "colorthres-saturationthres"),
694 config_GetInt(p_intf, "colorthres-similaritythres"),
695 config_GetInt(p_intf, "sepia-intensity"),
696 vlc_b64_encode(config_GetPsz(p_intf, "gradient-mode")),
697 config_GetInt(p_intf, "gradient-cartoon"),
698 config_GetInt(p_intf, "gradient-type"),
699 config_GetInt(p_intf, "extract-component"),
700 config_GetInt(p_intf, "posterize-level"),
701 config_GetInt(p_intf, "blur-factor"),
702 vlc_b64_encode(config_GetPsz(p_intf, "marq-marquee")),
703 config_GetInt(p_intf, "marq-position"),
704 vlc_b64_encode(config_GetPsz(p_intf, "logo-file")),
705 config_GetInt(p_intf, "logo-position"),
706 config_GetInt(p_intf, "logo-opacity"),
707 config_GetInt(p_intf, "clone-count"),
708 config_GetInt(p_intf, "wall-rows"),
709 config_GetInt(p_intf, "wall-cols")
714 #pragma mark generic UI code
716 - (void)saveCurrentProfile
718 if (i_old_profile_index == -1)
721 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
722 /* fetch all the current settings in a uniform string */
723 NSString *newProfile = [self generateProfileString];
725 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
726 if (i_old_profile_index >= [workArray count])
729 [workArray replaceObjectAtIndex:i_old_profile_index withObject:newProfile];
730 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
732 [defaults synchronize];
735 - (IBAction)toggleWindow:(id)sender
737 if ([o_window isVisible])
738 [o_window orderOut:sender];
740 [o_window setLevel: [[[VLCMain sharedInstance] voutController] currentWindowLevel]];
741 [o_window makeKeyAndOrderFront:sender];
745 - (IBAction)profileSelectorAction:(id)sender
747 [self saveCurrentProfile];
748 i_old_profile_index = [o_profile_pop indexOfSelectedItem];
750 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
751 NSUInteger selectedProfile = [o_profile_pop indexOfSelectedItem];
753 /* disable all current video filters, if a vout is available */
754 vout_thread_t *p_vout = getVout();
756 var_SetString(p_vout, "video-filter", "");
757 var_SetString(p_vout, "sub-source", "");
758 var_SetString(p_vout, "video-splitter", "");
759 vlc_object_release(p_vout);
763 NSArray *items = [[[defaults objectForKey:@"VideoEffectProfiles"] objectAtIndex:selectedProfile] componentsSeparatedByString:@";"];
765 /* filter handling */
766 NSString *tempString = [NSString stringWithFormat:@"%s", vlc_b64_decode([[items objectAtIndex:0] UTF8String])];
769 /* enable the new filters */
770 if ([tempString length] > 0) {
771 tempArray = [tempString componentsSeparatedByString:@":"];
772 count = [tempArray count];
773 for (NSUInteger x = 0; x < count; x++)
774 [self setVideoFilter:(char *)[[tempArray objectAtIndex:x] UTF8String] on:YES];
776 config_PutPsz(p_intf, "video-filter", [tempString UTF8String]);
778 tempString = [NSString stringWithFormat:@"%s", vlc_b64_decode([[items objectAtIndex:1] UTF8String])];
779 /* enable another round of new filters */
780 if ([tempString length] > 0) {
781 tempArray = [tempString componentsSeparatedByString:@":"];
782 count = [tempArray count];
783 for (NSUInteger x = 0; x < count; x++)
784 [self setVideoFilter:(char *)[[tempArray objectAtIndex:x] UTF8String] on:YES];
786 config_PutPsz(p_intf,"sub-source", [tempString UTF8String]);
788 tempString = [NSString stringWithFormat:@"%s", vlc_b64_decode([[items objectAtIndex:2] UTF8String])];
789 /* enable another round of new filters */
790 if ([tempString length] > 0) {
791 tempArray = [tempString componentsSeparatedByString:@":"];
792 count = [tempArray count];
793 for (NSUInteger x = 0; x < count; x++)
794 [self setVideoFilter:(char *)[[tempArray objectAtIndex:x] UTF8String] on:YES];
796 config_PutPsz(p_intf,"video-splitter", [tempString UTF8String]);
798 /* try to set filter values on-the-fly and store them appropriately */
799 [self setVideoFilterProperty:"hue" forFilter:"adjust" integer:[[items objectAtIndex:3] intValue]];
800 [self setVideoFilterProperty:"contrast" forFilter:"adjust" float:[[items objectAtIndex:4] floatValue]];
801 [self setVideoFilterProperty:"brightness" forFilter:"adjust" float:[[items objectAtIndex:5] floatValue]];
802 [self setVideoFilterProperty:"saturation" forFilter:"adjust" float:[[items objectAtIndex:6] floatValue]];
803 [self setVideoFilterProperty:"gamma" forFilter:"adjust" float:[[items objectAtIndex:7] floatValue]];
804 [self setVideoFilterProperty:"sharpen-sigma" forFilter:"sharpen" float:[[items objectAtIndex:8] floatValue]];
805 [self setVideoFilterProperty:"gradfun-radius" forFilter:"gradfun" integer:[[items objectAtIndex:9] intValue]];
806 [self setVideoFilterProperty:"grain-variance" forFilter:"grain" float:[[items objectAtIndex:10] floatValue]];
807 [self setVideoFilterProperty:"transform-type" forFilter:"transform" string:vlc_b64_decode([[items objectAtIndex:11] UTF8String])];
808 [self setVideoFilterProperty:"puzzle-rows" forFilter:"puzzle" integer:[[items objectAtIndex:12] intValue]];
809 [self setVideoFilterProperty:"puzzle-cols" forFilter:"puzzle" integer:[[items objectAtIndex:13] intValue]];
810 [self setVideoFilterProperty:"puzzle-black-slot" forFilter:"puzzle" boolean:[[items objectAtIndex:14] intValue]];
811 [self setVideoFilterProperty:"colorthres-color" forFilter:"colorthres" integer:[[items objectAtIndex:15] intValue]];
812 [self setVideoFilterProperty:"colorthres-saturationthres" forFilter:"colorthres" integer:[[items objectAtIndex:16] intValue]];
813 [self setVideoFilterProperty:"colorthres-similaritythres" forFilter:"colorthres" integer:[[items objectAtIndex:17] intValue]];
814 [self setVideoFilterProperty:"sepia-intensity" forFilter:"sepia" integer:[[items objectAtIndex:18] intValue]];
815 [self setVideoFilterProperty:"gradient-mode" forFilter:"gradient" string:vlc_b64_decode([[items objectAtIndex:19] UTF8String])];
816 [self setVideoFilterProperty:"gradient-cartoon" forFilter:"gradient" integer:[[items objectAtIndex:20] intValue]];
817 [self setVideoFilterProperty:"gradient-type" forFilter:"gradient" integer:[[items objectAtIndex:21] intValue]];
818 [self setVideoFilterProperty:"extract-component" forFilter:"extract" integer:[[items objectAtIndex:22] intValue]];
819 [self setVideoFilterProperty:"posterize-level" forFilter:"posterize" integer:[[items objectAtIndex:23] intValue]];
820 [self setVideoFilterProperty:"blur-factor" forFilter:"motionblur" integer:[[items objectAtIndex:24] intValue]];
821 [self setVideoFilterProperty:"marq-marquee" forFilter:"marq" string:vlc_b64_decode([[items objectAtIndex:25] UTF8String])];
822 [self setVideoFilterProperty:"marq-position" forFilter:"marq" integer:[[items objectAtIndex:26] intValue]];
823 [self setVideoFilterProperty:"logo-file" forFilter:"logo" string:vlc_b64_decode([[items objectAtIndex:27] UTF8String])];
824 [self setVideoFilterProperty:"logo-position" forFilter:"logo" integer:[[items objectAtIndex:28] intValue]];
825 [self setVideoFilterProperty:"logo-opacity" forFilter:"logo" integer:[[items objectAtIndex:29] intValue]];
826 [self setVideoFilterProperty:"clone-count" forFilter:"clone" integer:[[items objectAtIndex:30] intValue]];
827 [self setVideoFilterProperty:"wall-rows" forFilter:"wall" integer:[[items objectAtIndex:31] intValue]];
828 [self setVideoFilterProperty:"wall-cols" forFilter:"wall" integer:[[items objectAtIndex:32] intValue]];
830 [defaults setInteger:selectedProfile forKey:@"VideoEffectSelectedProfile"];
831 [defaults synchronize];
836 - (IBAction)addProfile:(id)sender
839 VLCEnterTextPanel * panel = [VLCEnterTextPanel sharedInstance];
840 [panel setTitle: _NS("Duplicate current profile for a new profile")];
841 [panel setSubTitle: _NS("Enter a name for the new profile:")];
842 [panel setCancelButtonLabel: _NS("Cancel")];
843 [panel setOKButtonLabel: _NS("Save")];
844 [panel setTarget:self];
846 [panel runModalForWindow:o_window];
849 - (void)panel:(VLCEnterTextPanel *)panel returnValue:(NSUInteger)value text:(NSString *)text
851 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
853 if (value != NSOKButton) {
854 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
858 NSArray *profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
860 // duplicate names are not allowed in the popup control
861 if ([text length] == 0 || [profileNames containsObject:text]) {
862 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
864 NSAlert *alert = [[[NSAlert alloc] init] autorelease];
865 [alert setAlertStyle:NSCriticalAlertStyle];
866 [alert setMessageText:_NS("Please enter a unique name for the new profile.")];
867 [alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
869 [alert beginSheetModalForWindow:o_window
876 /* fetch all the current settings in a uniform string */
877 NSString *newProfile = [self generateProfileString];
879 /* add string to user defaults as well as a label */
881 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
882 [workArray addObject:newProfile];
883 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
884 [defaults setInteger:[workArray count] - 1 forKey:@"VideoEffectSelectedProfile"];
887 workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfileNames"]];
888 [workArray addObject:text];
889 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
893 [defaults synchronize];
896 [self resetProfileSelector];
899 - (IBAction)removeProfile:(id)sender
902 VLCSelectItemInPopupPanel * panel = [VLCSelectItemInPopupPanel sharedInstance];
903 [panel setTitle:_NS("Remove a preset")];
904 [panel setSubTitle:_NS("Select the preset you would like to remove:")];
905 [panel setOKButtonLabel:_NS("Remove")];
906 [panel setCancelButtonLabel:_NS("Cancel")];
907 [panel setPopupButtonContent:[[NSUserDefaults standardUserDefaults] objectForKey:@"VideoEffectProfileNames"]];
908 [panel setTarget:self];
910 [panel runModalForWindow:o_window];
913 - (void)panel:(VLCSelectItemInPopupPanel *)panel returnValue:(NSUInteger)value item:(NSUInteger)item
915 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
917 if (value != NSOKButton) {
918 [o_profile_pop selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
922 /* remove selected profile from settings */
923 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfiles"]];
924 [workArray removeObjectAtIndex:item];
925 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
928 workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfileNames"]];
929 [workArray removeObjectAtIndex:item];
930 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
933 if (i_old_profile_index >= item)
934 [defaults setInteger:i_old_profile_index - 1 forKey:@"VideoEffectSelectedProfile"];
937 [defaults synchronize];
939 /* do not save deleted profile */
940 i_old_profile_index = -1;
942 [self resetProfileSelector];
947 - (IBAction)enableAdjust:(id)sender
949 BOOL b_state = [o_adjust_ckb state];
951 [self setVideoFilter: "adjust" on: b_state];
952 [o_adjust_brightness_sld setEnabled: b_state];
953 [o_adjust_brightness_ckb setEnabled: b_state];
954 [o_adjust_brightness_lbl setEnabled: b_state];
955 [o_adjust_contrast_sld setEnabled: b_state];
956 [o_adjust_contrast_lbl setEnabled: b_state];
957 [o_adjust_gamma_sld setEnabled: b_state];
958 [o_adjust_gamma_lbl setEnabled: b_state];
959 [o_adjust_hue_sld setEnabled: b_state];
960 [o_adjust_hue_lbl setEnabled: b_state];
961 [o_adjust_saturation_sld setEnabled: b_state];
962 [o_adjust_saturation_lbl setEnabled: b_state];
963 [o_adjust_reset_btn setEnabled: b_state];
966 - (IBAction)adjustSliderChanged:(id)sender
968 if (sender == o_adjust_brightness_sld)
969 [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: [o_adjust_brightness_sld floatValue]];
970 else if (sender == o_adjust_contrast_sld)
971 [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: [o_adjust_contrast_sld floatValue]];
972 else if (sender == o_adjust_gamma_sld)
973 [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: [o_adjust_gamma_sld floatValue]];
974 else if (sender == o_adjust_hue_sld)
975 [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: [o_adjust_hue_sld intValue]];
976 else if (sender == o_adjust_saturation_sld)
977 [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: [o_adjust_saturation_sld floatValue]];
979 if (sender == o_adjust_hue_sld)
980 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", [o_adjust_hue_sld intValue]]];
982 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
985 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
987 if (sender == o_adjust_reset_btn) {
988 [o_adjust_brightness_sld setFloatValue: 1.0];
989 [o_adjust_contrast_sld setFloatValue: 1.0];
990 [o_adjust_gamma_sld setFloatValue: 1.0];
991 [o_adjust_hue_sld setIntValue: 0];
992 [o_adjust_saturation_sld setFloatValue: 1.0];
993 [o_adjust_brightness_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
994 [o_adjust_contrast_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
995 [o_adjust_gamma_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
996 [o_adjust_hue_sld setToolTip: [NSString stringWithFormat:@"%i", 0]];
997 [o_adjust_saturation_sld setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
998 [self setVideoFilterProperty: "brightness" forFilter: "adjust" float: 1.0];
999 [self setVideoFilterProperty: "contrast" forFilter: "adjust" float: 1.0];
1000 [self setVideoFilterProperty: "gamma" forFilter: "adjust" float: 1.0];
1001 [self setVideoFilterProperty: "hue" forFilter: "adjust" integer: 0.0];
1002 [self setVideoFilterProperty: "saturation" forFilter: "adjust" float: 1.0];
1004 config_PutInt(p_intf, "brightness-threshold", [o_adjust_brightness_ckb state]);
1007 - (IBAction)enableSharpen:(id)sender
1009 BOOL b_state = [o_sharpen_ckb state];
1011 [self setVideoFilter: "sharpen" on: b_state];
1012 [o_sharpen_sld setEnabled: b_state];
1013 [o_sharpen_lbl setEnabled: b_state];
1016 - (IBAction)sharpenSliderChanged:(id)sender
1018 [self setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [sender floatValue]];
1019 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
1022 - (IBAction)enableBanding:(id)sender
1024 BOOL b_state = [o_banding_ckb state];
1026 [self setVideoFilter: "gradfun" on: b_state];
1027 [o_banding_sld setEnabled: b_state];
1028 [o_banding_lbl setEnabled: b_state];
1031 - (IBAction)bandingSliderChanged:(id)sender
1033 [self setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [sender intValue]];
1034 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
1037 - (IBAction)enableGrain:(id)sender
1039 BOOL b_state = [o_grain_ckb state];
1041 [self setVideoFilter: "grain" on: b_state];
1042 [o_grain_sld setEnabled: b_state];
1043 [o_grain_lbl setEnabled: b_state];
1046 - (IBAction)grainSliderChanged:(id)sender
1048 [self setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [sender floatValue]];
1049 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
1056 - (IBAction)cropObjectChanged:(id)sender
1058 if ([o_crop_sync_top_bottom_ckb state]) {
1059 if (sender == o_crop_bottom_fld || sender == o_crop_bottom_stp)
1060 [self setCropTopValue: [self cropBottomValue]];
1062 [self setCropBottomValue: [self cropTopValue]];
1064 if ([o_crop_sync_left_right_ckb state]) {
1065 if (sender == o_crop_right_fld || sender == o_crop_right_stp)
1066 [self setCropLeftValue: [self cropRightValue]];
1068 [self setCropRightValue: [self cropLeftValue]];
1071 vout_thread_t *p_vout = getVout();
1073 var_SetInteger(p_vout, "crop-top", [o_crop_top_fld intValue]);
1074 var_SetInteger(p_vout, "crop-bottom", [o_crop_bottom_fld intValue]);
1075 var_SetInteger(p_vout, "crop-left", [o_crop_left_fld intValue]);
1076 var_SetInteger(p_vout, "crop-right", [o_crop_right_fld intValue]);
1077 vlc_object_release(p_vout);
1082 #pragma mark geometry
1083 - (IBAction)enableTransform:(id)sender
1085 [self setVideoFilter: "transform" on: [o_transform_ckb state]];
1086 [o_transform_pop setEnabled: [o_transform_ckb state]];
1089 - (IBAction)transformModifierChanged:(id)sender
1091 NSInteger tag = [[o_transform_pop selectedItem] tag];
1092 char *psz_string = (char *)[[NSString stringWithFormat:@"%li", tag] UTF8String];
1094 psz_string = (char *)"hflip";
1096 psz_string = (char *)"vflip";
1098 [self setVideoFilterProperty: "transform-type" forFilter: "transform" string: psz_string];
1101 - (IBAction)enableZoom:(id)sender
1103 [self setVideoFilter: "magnify" on: [o_zoom_ckb state]];
1106 - (IBAction)enablePuzzle:(id)sender
1108 BOOL b_state = [o_puzzle_ckb state];
1110 [self setVideoFilter: "puzzle" on: b_state];
1111 [o_puzzle_columns_fld setEnabled: b_state];
1112 [o_puzzle_columns_stp setEnabled: b_state];
1113 [o_puzzle_columns_lbl setEnabled: b_state];
1114 [o_puzzle_rows_fld setEnabled: b_state];
1115 [o_puzzle_rows_stp setEnabled: b_state];
1116 [o_puzzle_rows_lbl setEnabled: b_state];
1117 [o_puzzle_blackslot_ckb setEnabled: b_state];
1120 - (IBAction)puzzleModifierChanged:(id)sender
1122 if (sender == o_puzzle_blackslot_ckb)
1123 [self setVideoFilterProperty: "puzzle-black-slot" forFilter: "puzzle" boolean: [o_puzzle_blackslot_ckb state]];
1124 else if (sender == o_puzzle_columns_fld || sender == o_puzzle_columns_stp)
1125 [self setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [sender intValue]];
1127 [self setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [sender intValue]];
1130 - (IBAction)enableClone:(id)sender
1132 BOOL b_state = [o_clone_ckb state];
1134 if (b_state && [o_wall_ckb state]) {
1135 [o_wall_ckb setState: NSOffState];
1136 [self enableWall: o_wall_ckb];
1139 [self setVideoFilter: "clone" on: b_state];
1140 [o_clone_number_lbl setEnabled: b_state];
1141 [o_clone_number_fld setEnabled: b_state];
1142 [o_clone_number_stp setEnabled: b_state];
1145 - (IBAction)cloneModifierChanged:(id)sender
1147 [self setVideoFilterProperty: "clone-count" forFilter: "clone" integer: [o_clone_number_fld intValue]];
1150 - (IBAction)enableWall:(id)sender
1152 BOOL b_state = [o_wall_ckb state];
1154 if (b_state && [o_clone_ckb state]) {
1155 [o_clone_ckb setState: NSOffState];
1156 [self enableClone: o_clone_ckb];
1159 [self setVideoFilter: "wall" on: b_state];
1160 [o_wall_numofcols_fld setEnabled: b_state];
1161 [o_wall_numofcols_stp setEnabled: b_state];
1162 [o_wall_numofcols_lbl setEnabled: b_state];
1164 [o_wall_numofrows_fld setEnabled: b_state];
1165 [o_wall_numofrows_stp setEnabled: b_state];
1166 [o_wall_numofrows_lbl setEnabled: b_state];
1169 - (IBAction)wallModifierChanged:(id)sender
1171 if (sender == o_wall_numofcols_fld || sender == o_wall_numofcols_stp)
1172 [self setVideoFilterProperty: "wall-cols" forFilter: "wall" integer: [sender intValue]];
1174 [self setVideoFilterProperty: "wall-rows" forFilter: "wall" integer: [sender intValue]];
1179 - (IBAction)enableThreshold:(id)sender
1181 BOOL b_state = [o_threshold_ckb state];
1183 [self setVideoFilter: "colorthres" on: b_state];
1184 [o_threshold_color_fld setEnabled: b_state];
1185 [o_threshold_color_lbl setEnabled: b_state];
1186 [o_threshold_saturation_sld setEnabled: b_state];
1187 [o_threshold_saturation_lbl setEnabled: b_state];
1188 [o_threshold_similarity_sld setEnabled: b_state];
1189 [o_threshold_similarity_lbl setEnabled: b_state];
1192 - (IBAction)thresholdModifierChanged:(id)sender
1194 if (sender == o_threshold_color_fld)
1195 [self setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [o_threshold_color_fld intValue]];
1196 else if (sender == o_threshold_saturation_sld) {
1197 [self setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [o_threshold_saturation_sld intValue]];
1198 [o_threshold_saturation_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_saturation_sld intValue]]];
1200 [self setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [o_threshold_similarity_sld intValue]];
1201 [o_threshold_similarity_sld setToolTip: [NSString stringWithFormat:@"%i", [o_threshold_similarity_sld intValue]]];
1205 - (IBAction)enableSepia:(id)sender
1207 BOOL b_state = [o_sepia_ckb state];
1209 [self setVideoFilter: "sepia" on: b_state];
1210 [o_sepia_fld setEnabled: b_state];
1211 [o_sepia_stp setEnabled: b_state];
1212 [o_sepia_lbl setEnabled: b_state];
1215 - (IBAction)sepiaModifierChanged:(id)sender
1217 [self setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [o_sepia_fld intValue]];
1220 - (IBAction)enableNoise:(id)sender
1222 [self setVideoFilter: "noise" on: [o_noise_ckb state]];
1225 - (IBAction)enableGradient:(id)sender
1227 BOOL b_state = [o_gradient_ckb state];
1229 [self setVideoFilter: "gradient" on: b_state];
1230 [o_gradient_mode_pop setEnabled: b_state];
1231 [o_gradient_mode_lbl setEnabled: b_state];
1232 [o_gradient_color_ckb setEnabled: b_state];
1233 [o_gradient_cartoon_ckb setEnabled: b_state];
1236 - (IBAction)gradientModifierChanged:(id)sender
1238 if (sender == o_gradient_mode_pop) {
1239 if ([[o_gradient_mode_pop selectedItem] tag] == 3)
1240 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
1241 else if ([[o_gradient_mode_pop selectedItem] tag] == 2)
1242 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
1244 [self setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
1245 } else if (sender == o_gradient_color_ckb)
1246 [self setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [o_gradient_color_ckb state]];
1248 [self setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [o_gradient_cartoon_ckb state]];
1251 - (IBAction)enableExtract:(id)sender
1253 BOOL b_state = [o_extract_ckb state];
1254 [self setVideoFilter: "extract" on: b_state];
1255 [o_extract_fld setEnabled: b_state];
1256 [o_extract_lbl setEnabled: b_state];
1259 - (IBAction)extractModifierChanged:(id)sender
1261 [self setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [o_extract_fld intValue]];
1264 - (IBAction)enableInvert:(id)sender
1266 [self setVideoFilter: "invert" on: [o_invert_ckb state]];
1269 - (IBAction)enablePosterize:(id)sender
1271 BOOL b_state = [o_posterize_ckb state];
1273 [self setVideoFilter: "posterize" on: b_state];
1274 [o_posterize_fld setEnabled: b_state];
1275 [o_posterize_stp setEnabled: b_state];
1276 [o_posterize_lbl setEnabled: b_state];
1279 - (IBAction)posterizeModifierChanged:(id)sender
1281 [self setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [o_posterize_fld intValue]];
1284 - (IBAction)enableBlur:(id)sender
1286 BOOL b_state = [o_blur_ckb state];
1288 [self setVideoFilter: "motionblur" on: b_state];
1289 [o_blur_sld setEnabled: b_state];
1290 [o_blur_lbl setEnabled: b_state];
1293 - (IBAction)blurModifierChanged:(id)sender
1295 [self setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [sender intValue]];
1296 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
1299 - (IBAction)enableMotionDetect:(id)sender
1301 [self setVideoFilter: "motiondetect" on: [o_motiondetect_ckb state]];
1304 - (IBAction)enableWaterEffect:(id)sender
1306 [self setVideoFilter: "ripple" on: [o_watereffect_ckb state]];
1309 - (IBAction)enableWaves:(id)sender
1311 [self setVideoFilter: "wave" on: [o_waves_ckb state]];
1314 - (IBAction)enablePsychedelic:(id)sender
1316 [self setVideoFilter: "psychedelic" on: [o_psychedelic_ckb state]];
1320 #pragma mark Miscellaneous
1321 - (IBAction)enableAddText:(id)sender
1323 BOOL b_state = [o_addtext_ckb state];
1325 [o_addtext_pos_pop setEnabled: b_state];
1326 [o_addtext_pos_lbl setEnabled: b_state];
1327 [o_addtext_text_lbl setEnabled: b_state];
1328 [o_addtext_text_fld setEnabled: b_state];
1329 [self setVideoFilter: "marq" on: b_state];
1330 [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
1331 [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
1334 - (IBAction)addTextModifierChanged:(id)sender
1336 if (sender == o_addtext_text_fld)
1337 [self setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: (char *)[[o_addtext_text_fld stringValue] UTF8String]];
1339 [self setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[o_addtext_pos_pop selectedItem] tag]];
1342 - (IBAction)enableAddLogo:(id)sender
1344 BOOL b_state = [o_addlogo_ckb state];
1346 [o_addlogo_pos_pop setEnabled: b_state];
1347 [o_addlogo_pos_lbl setEnabled: b_state];
1348 [o_addlogo_logo_fld setEnabled: b_state];
1349 [o_addlogo_logo_lbl setEnabled: b_state];
1350 [o_addlogo_transparency_sld setEnabled: b_state];
1351 [o_addlogo_transparency_lbl setEnabled: b_state];
1352 [self setVideoFilter: "logo" on: b_state];
1355 - (IBAction)addLogoModifierChanged:(id)sender
1357 if (sender == o_addlogo_logo_fld)
1358 [self setVideoFilterProperty: "logo-file" forFilter: "logo" string: (char *)[[o_addlogo_logo_fld stringValue] UTF8String]];
1359 else if (sender == o_addlogo_pos_pop)
1360 [self setVideoFilterProperty: "logo-position" forFilter: "logo" integer: [[o_addlogo_pos_pop selectedItem] tag]];
1362 [self setVideoFilterProperty: "logo-opacity" forFilter: "logo" integer: [o_addlogo_transparency_sld intValue]];
1363 [o_addlogo_transparency_sld setToolTip: [NSString stringWithFormat:@"%i", [o_addlogo_transparency_sld intValue]]];
1367 - (IBAction)enableAnaglyph:(id)sender
1369 [self setVideoFilter: "anaglyph" on: [o_anaglyph_ckb state]];