1 /*****************************************************************************
2 * VLCVideoEffectsWindowController.m: MacOS X interface module
3 *****************************************************************************
4 * Copyright (C) 2011-2015 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 "VLCVideoEffectsWindowController.h"
27 #import "VLCPopupPanelController.h"
28 #import "VLCTextfieldPanelController.h"
29 #import "VLCCoreInteraction.h"
31 @interface VLCVideoEffectsWindowController()
33 NSInteger i_old_profile_index;
38 #pragma mark Initialization
40 @implementation VLCVideoEffectsWindowController
44 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",
45 [NSArray arrayWithObject:_NS("Default")], @"VideoEffectProfileNames", nil];
46 [[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
51 self = [super initWithWindowNibName:@"VideoEffects"];
53 i_old_profile_index = -1;
55 self.popupPanel = [[VLCPopupPanelController alloc] init];
56 self.textfieldPanel = [[VLCTextfieldPanelController alloc] init];
64 [self.window setTitle: _NS("Video Effects")];
65 [self.window setExcludedFromWindowsMenu:YES];
66 [self.window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
68 [[_tabView tabViewItemAtIndex:[_tabView indexOfTabViewItemWithIdentifier:@"basic"]] setLabel:_NS("Basic")];
69 [[_tabView tabViewItemAtIndex:[_tabView indexOfTabViewItemWithIdentifier:@"crop"]] setLabel:_NS("Crop")];
70 [[_tabView tabViewItemAtIndex:[_tabView indexOfTabViewItemWithIdentifier:@"geometry"]] setLabel:_NS("Geometry")];
71 [[_tabView tabViewItemAtIndex:[_tabView indexOfTabViewItemWithIdentifier:@"color"]] setLabel:_NS("Color")];
72 [[_tabView tabViewItemAtIndex:[_tabView indexOfTabViewItemWithIdentifier:@"misc"]] setLabel:_NS("Miscellaneous")];
74 [self resetProfileSelector];
76 [_adjustCheckbox setTitle:_NS("Image Adjust")];
77 [_adjustHueLabel setStringValue:_NS("Hue")];
78 [_adjustContrastLabel setStringValue:_NS("Contrast")];
79 [_adjustBrightnessLabel setStringValue:_NS("Brightness")];
80 [_adjustBrightnessCheckbox setTitle:_NS("Brightness Threshold")];
81 [_adjustSaturationLabel setStringValue:_NS("Saturation")];
82 [_adjustGammaLabel setStringValue:_NS("Gamma")];
83 [_adjustResetButton setTitle: _NS("Reset")];
84 [_sharpenCheckbox setTitle:_NS("Sharpen")];
85 [_sharpenLabel setStringValue:_NS("Sigma")];
86 [_bandingCheckbox setTitle:_NS("Banding removal")];
87 [_bandingLabel setStringValue:_NS("Radius")];
88 [_grainCheckbox setTitle:_NS("Film Grain")];
89 [_grainLabel setStringValue:_NS("Variance")];
90 [_cropTopLabel setStringValue:_NS("Top")];
91 [_cropLeftLabel setStringValue:_NS("Left")];
92 [_cropRightLabel setStringValue:_NS("Right")];
93 [_cropBottomLabel setStringValue:_NS("Bottom")];
94 [_cropSyncTopBottomCheckbox setTitle:_NS("Synchronize top and bottom")];
95 [_cropSyncLeftRightCheckbox setTitle:_NS("Synchronize left and right")];
97 [_transformCheckbox setTitle:_NS("Transform")];
98 [_transformPopup removeAllItems];
99 [_transformPopup addItemWithTitle: _NS("Rotate by 90 degrees")];
100 [[_transformPopup lastItem] setTag: 90];
101 [_transformPopup addItemWithTitle: _NS("Rotate by 180 degrees")];
102 [[_transformPopup lastItem] setTag: 180];
103 [_transformPopup addItemWithTitle: _NS("Rotate by 270 degrees")];
104 [[_transformPopup lastItem] setTag: 270];
105 [_transformPopup addItemWithTitle: _NS("Flip horizontally")];
106 [[_transformPopup lastItem] setTag: 1];
107 [_transformPopup addItemWithTitle: _NS("Flip vertically")];
108 [[_transformPopup lastItem] setTag: 2];
109 [_zoomCheckbox setTitle:_NS("Magnification/Zoom")];
110 [_puzzleCheckbox setTitle:_NS("Puzzle game")];
111 [_puzzleRowsLabel setStringValue:_NS("Rows")];
112 [_puzzleColumnsLabel setStringValue:_NS("Columns")];
113 [_cloneCheckbox setTitle:_NS("Clone")];
114 [_cloneNumberLabel setStringValue:_NS("Number of clones")];
115 [_wallCheckbox setTitle:_NS("Wall")];
116 [_wallNumbersOfRowsLabel setStringValue:_NS("Rows")];
117 [_wallNumberOfColumnsLabel setStringValue:_NS("Columns")];
119 [_thresholdCheckbox setTitle:_NS("Color threshold")];
120 [_thresholdColorLabel setStringValue:_NS("Color")];
121 [_thresholdSaturationLabel setStringValue:_NS("Saturation")];
122 [_thresholdSimilarityLabel setStringValue:_NS("Similarity")];
123 [_sepiaCheckbox setTitle:_NS("Sepia")];
124 [_sepiaLabel setStringValue:_NS("Intensity")];
125 [_noiseCheckbox setTitle:_NS("Noise")];
126 [_gradientCheckbox setTitle:_NS("Gradient")];
127 [_gradientModeLabel setStringValue:_NS("Mode")];
128 [_gradientModePopup removeAllItems];
129 [_gradientModePopup addItemWithTitle: _NS("Gradient")];
130 [[_gradientModePopup lastItem] setTag: 1];
131 [_gradientModePopup addItemWithTitle: _NS("Edge")];
132 [[_gradientModePopup lastItem] setTag: 2];
133 [_gradientModePopup addItemWithTitle: _NS("Hough")];
134 [[_gradientModePopup lastItem] setTag: 3];
135 [_gradientColorCheckbox setTitle:_NS("Color")];
136 [_gradientCartoonCheckbox setTitle:_NS("Cartoon")];
137 [_extractCheckbox setTitle:_NS("Color extraction")];
138 [_extractLabel setStringValue:_NS("Color")];
139 [_invertCheckbox setTitle:_NS("Invert colors")];
140 [_posterizeCheckbox setTitle:_NS("Posterize")];
141 [_posterizeLabel setStringValue:_NS("Posterize level")];
142 [_blurCheckbox setTitle:_NS("Motion blur")];
143 [_blurLabel setStringValue:_NS("Factor")];
144 [_motiondetectCheckbox setTitle:_NS("Motion Detect")];
145 [_watereffectCheckbox setTitle:_NS("Water effect")];
146 [_wavesCheckbox setTitle:_NS("Waves")];
147 [_psychedelicCheckbox setTitle:_NS("Psychedelic")];
148 [_anaglyphCheckbox setTitle:_NS("Anaglyph")];
150 [_addTextCheckbox setTitle:_NS("Add text")];
151 [_addTextTextLabel setStringValue:_NS("Text")];
152 [_addTextPositionLabel setStringValue:_NS("Position")];
153 [_addTextPositionPopup removeAllItems];
154 [_addTextPositionPopup addItemWithTitle: _NS("Center")];
155 [[_addTextPositionPopup lastItem] setTag: 0];
156 [_addTextPositionPopup addItemWithTitle: _NS("Left")];
157 [[_addTextPositionPopup lastItem] setTag: 1];
158 [_addTextPositionPopup addItemWithTitle: _NS("Right")];
159 [[_addTextPositionPopup lastItem] setTag: 2];
160 [_addTextPositionPopup addItemWithTitle: _NS("Top")];
161 [[_addTextPositionPopup lastItem] setTag: 4];
162 [_addTextPositionPopup addItemWithTitle: _NS("Bottom")];
163 [[_addTextPositionPopup lastItem] setTag: 8];
164 [_addTextPositionPopup addItemWithTitle: _NS("Top-Left")];
165 [[_addTextPositionPopup lastItem] setTag: 5];
166 [_addTextPositionPopup addItemWithTitle: _NS("Top-Right")];
167 [[_addTextPositionPopup lastItem] setTag: 6];
168 [_addTextPositionPopup addItemWithTitle: _NS("Bottom-Left")];
169 [[_addTextPositionPopup lastItem] setTag: 9];
170 [_addTextPositionPopup addItemWithTitle: _NS("Bottom-Right")];
171 [[_addTextPositionPopup lastItem] setTag: 10];
172 [_addLogoCheckbox setTitle:_NS("Add logo")];
173 [_addLogoLogoLabel setStringValue:_NS("Logo")];
174 [_addLogoPositionLabel setStringValue:_NS("Position")];
175 [_addLogoPositionPopup removeAllItems];
176 [_addLogoPositionPopup addItemWithTitle: _NS("Center")];
177 [[_addLogoPositionPopup lastItem] setTag: 0];
178 [_addLogoPositionPopup addItemWithTitle: _NS("Left")];
179 [[_addLogoPositionPopup lastItem] setTag: 1];
180 [_addLogoPositionPopup addItemWithTitle: _NS("Right")];
181 [[_addLogoPositionPopup lastItem] setTag: 2];
182 [_addLogoPositionPopup addItemWithTitle: _NS("Top")];
183 [[_addLogoPositionPopup lastItem] setTag: 4];
184 [_addLogoPositionPopup addItemWithTitle: _NS("Bottom")];
185 [[_addLogoPositionPopup lastItem] setTag: 8];
186 [_addLogoPositionPopup addItemWithTitle: _NS("Top-Left")];
187 [[_addLogoPositionPopup lastItem] setTag: 5];
188 [_addLogoPositionPopup addItemWithTitle: _NS("Top-Right")];
189 [[_addLogoPositionPopup lastItem] setTag: 6];
190 [_addLogoPositionPopup addItemWithTitle: _NS("Bottom-Left")];
191 [[_addLogoPositionPopup lastItem] setTag: 9];
192 [_addLogoPositionPopup addItemWithTitle: _NS("Bottom-Right")];
193 [[_addLogoPositionPopup lastItem] setTag: 10];
194 [_addLogoTransparencyLabel setStringValue:_NS("Transparency")];
196 [_tabView selectFirstTabViewItem:self];
198 [[NSNotificationCenter defaultCenter] addObserver:self
199 selector:@selector(inputChangedEvent:)
200 name:VLCInputChangedNotification
209 [[NSNotificationCenter defaultCenter] removeObserver:self];
212 - (void)updateCocoaWindowLevel:(NSInteger)i_level
214 if (self.isWindowLoaded && [self.window isVisible] && [self.window level] != i_level)
215 [self.window setLevel: i_level];
219 #pragma mark internal functions
221 -(void)inputChangedEvent:(NSNotification *)o_notification
223 // reset crop values when input changed
224 [self setCropBottomValue:0];
225 [self setCropTopValue:0];
226 [self setCropLeftValue:0];
227 [self setCropRightValue:0];
230 - (void)resetProfileSelector
232 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
233 [_profilePopup removeAllItems];
235 NSArray *profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
236 [_profilePopup addItemsWithTitles:profileNames];
238 [[_profilePopup menu] addItem:[NSMenuItem separatorItem]];
239 [_profilePopup addItemWithTitle:_NS("Duplicate current profile...")];
240 [[_profilePopup lastItem] setTarget: self];
241 [[_profilePopup lastItem] setAction: @selector(addProfile:)];
243 if ([profileNames count] > 1) {
244 [_profilePopup addItemWithTitle:_NS("Organize profiles...")];
245 [[_profilePopup lastItem] setTarget: self];
246 [[_profilePopup lastItem] setAction: @selector(removeProfile:)];
249 [_profilePopup selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
250 [self profileSelectorAction:self];
255 intf_thread_t *p_intf = getIntf();
260 /* do we have any filter enabled? if yes, show it. */
262 psz_vfilters = config_GetPsz(p_intf, "video-filter");
264 [_adjustCheckbox setState: (NSInteger)strstr(psz_vfilters, "adjust")];
265 [_sharpenCheckbox setState: (NSInteger)strstr(psz_vfilters, "sharpen")];
266 [_bandingCheckbox setState: (NSInteger)strstr(psz_vfilters, "gradfun")];
267 [_grainCheckbox setState: (NSInteger)strstr(psz_vfilters, "grain")];
268 [_transformCheckbox setState: (NSInteger)strstr(psz_vfilters, "transform")];
269 [_zoomCheckbox setState: (NSInteger)strstr(psz_vfilters, "magnify")];
270 [_puzzleCheckbox setState: (NSInteger)strstr(psz_vfilters, "puzzle")];
271 [_thresholdCheckbox setState: (NSInteger)strstr(psz_vfilters, "colorthres")];
272 [_sepiaCheckbox setState: (NSInteger)strstr(psz_vfilters, "sepia")];
273 [_noiseCheckbox setState: (NSInteger)strstr(psz_vfilters, "noise")];
274 [_gradientCheckbox setState: (NSInteger)strstr(psz_vfilters, "gradient")];
275 [_extractCheckbox setState: (NSInteger)strstr(psz_vfilters, "extract")];
276 [_invertCheckbox setState: (NSInteger)strstr(psz_vfilters, "invert")];
277 [_posterizeCheckbox setState: (NSInteger)strstr(psz_vfilters, "posterize")];
278 [_blurCheckbox setState: (NSInteger)strstr(psz_vfilters, "motionblur")];
279 [_motiondetectCheckbox setState: (NSInteger)strstr(psz_vfilters, "motiondetect")];
280 [_watereffectCheckbox setState: (NSInteger)strstr(psz_vfilters, "ripple")];
281 [_wavesCheckbox setState: (NSInteger)strstr(psz_vfilters, "wave")];
282 [_psychedelicCheckbox setState: (NSInteger)strstr(psz_vfilters, "psychedelic")];
283 [_anaglyphCheckbox setState: (NSInteger)strstr(psz_vfilters, "anaglyph")];
286 [_adjustCheckbox setState: NSOffState];
287 [_sharpenCheckbox setState: NSOffState];
288 [_bandingCheckbox setState: NSOffState];
289 [_grainCheckbox setState: NSOffState];
290 [_transformCheckbox setState: NSOffState];
291 [_zoomCheckbox setState: NSOffState];
292 [_puzzleCheckbox setState: NSOffState];
293 [_thresholdCheckbox setState: NSOffState];
294 [_sepiaCheckbox setState: NSOffState];
295 [_noiseCheckbox setState: NSOffState];
296 [_gradientCheckbox setState: NSOffState];
297 [_extractCheckbox setState: NSOffState];
298 [_invertCheckbox setState: NSOffState];
299 [_posterizeCheckbox setState: NSOffState];
300 [_blurCheckbox setState: NSOffState];
301 [_motiondetectCheckbox setState: NSOffState];
302 [_watereffectCheckbox setState: NSOffState];
303 [_wavesCheckbox setState: NSOffState];
304 [_psychedelicCheckbox setState: NSOffState];
305 [_anaglyphCheckbox setState: NSOffState];
308 psz_vfilters = config_GetPsz(p_intf, "sub-source");
310 [_addTextCheckbox setState: (NSInteger)strstr(psz_vfilters, "marq")];
311 [_addLogoCheckbox setState: (NSInteger)strstr(psz_vfilters, "logo")];
314 [_addTextCheckbox setState: NSOffState];
315 [_addLogoCheckbox setState: NSOffState];
318 psz_vfilters = config_GetPsz(p_intf, "video-splitter");
320 [_cloneCheckbox setState: (NSInteger)strstr(psz_vfilters, "clone")];
321 [_wallCheckbox setState: (NSInteger)strstr(psz_vfilters, "wall")];
324 [_cloneCheckbox setState: NSOffState];
325 [_wallCheckbox setState: NSOffState];
328 /* fetch and show the various values */
329 [_adjustHueSlider setFloatValue: config_GetFloat(p_intf, "hue")];
330 [_adjustContrastSlider setFloatValue: config_GetFloat(p_intf, "contrast")];
331 [_adjustBrightnessSlider setFloatValue: config_GetFloat(p_intf, "brightness")];
332 [_adjustSaturationSlider setFloatValue: config_GetFloat(p_intf, "saturation")];
333 [_adjustBrightnessCheckbox setState:(config_GetInt(p_intf, "brightness-threshold") != 0 ? NSOnState : NSOffState)];
334 [_adjustGammaSlider setFloatValue: config_GetFloat(p_intf, "gamma")];
335 [_adjustBrightnessSlider setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "brightness")]];
336 [_adjustContrastSlider setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "contrast")]];
337 [_adjustGammaSlider setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "gamma")]];
338 [_adjustHueSlider setToolTip: [NSString stringWithFormat:@"%.0f", config_GetFloat(p_intf, "hue")]];
339 [_adjustSaturationSlider setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "saturation")]];
340 b_state = [_adjustCheckbox state];
342 [_adjustBrightnessSlider setEnabled: b_state];
343 [_adjustBrightnessCheckbox setEnabled: b_state];
344 [_adjustContrastSlider setEnabled: b_state];
345 [_adjustGammaSlider setEnabled: b_state];
346 [_adjustHueSlider setEnabled: b_state];
347 [_adjustSaturationSlider setEnabled: b_state];
348 [_adjustBrightnessLabel setEnabled: b_state];
349 [_adjustContrastLabel setEnabled: b_state];
350 [_adjustGammaLabel setEnabled: b_state];
351 [_adjustHueLabel setEnabled: b_state];
352 [_adjustSaturationLabel setEnabled: b_state];
353 [_adjustResetButton setEnabled: b_state];
355 [_sharpenSlider setFloatValue: config_GetFloat(p_intf, "sharpen-sigma")];
356 [_sharpenSlider setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "sharpen-sigma")]];
357 [_sharpenSlider setEnabled: [_sharpenCheckbox state]];
358 [_sharpenLabel setEnabled: [_sharpenCheckbox state]];
360 [_bandingSlider setIntValue: config_GetInt(p_intf, "gradfun-radius")];
361 [_bandingSlider setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "gradfun-radius")]];
362 [_bandingSlider setEnabled: [_bandingCheckbox state]];
363 [_bandingLabel setEnabled: [_bandingCheckbox state]];
365 [_grainSlider setFloatValue: config_GetFloat(p_intf, "grain-variance")];
366 [_grainSlider setToolTip: [NSString stringWithFormat:@"%0.3f", config_GetFloat(p_intf, "grain-variance")]];
367 [_grainSlider setEnabled: [_grainCheckbox state]];
368 [_grainLabel setEnabled: [_grainCheckbox state]];
370 [self setCropLeftValue: 0];
371 [self setCropTopValue: 0];
372 [self setCropRightValue: 0];
373 [self setCropBottomValue: 0];
374 [_cropSyncTopBottomCheckbox setState: NSOffState];
375 [_cropSyncLeftRightCheckbox setState: NSOffState];
377 tmpChar = config_GetPsz(p_intf, "transform-type");
378 tmpString = toNSStr(tmpChar);
379 if ([tmpString isEqualToString:@"hflip"])
380 [_transformPopup selectItemWithTag: 1];
381 else if ([tmpString isEqualToString:@"vflip"])
382 [_transformPopup selectItemWithTag: 2];
384 [_transformPopup selectItemWithTag:[tmpString intValue]];
386 [_transformPopup setEnabled: [_transformCheckbox state]];
388 [self setPuzzleColumnsValue: config_GetInt(p_intf, "puzzle-cols")];
389 [self setPuzzleRowsValue: config_GetInt(p_intf, "puzzle-rows")];
390 b_state = [_puzzleCheckbox state];
391 [_puzzleRowsTextField setEnabled: b_state];
392 [_puzzleRowsStepper setEnabled: b_state];
393 [_puzzleRowsLabel setEnabled: b_state];
394 [_puzzleColumnsTextField setEnabled: b_state];
395 [_puzzleColumnsStepper setEnabled: b_state];
396 [_puzzleColumnsLabel setEnabled: b_state];
398 [self setCloneValue: config_GetInt(p_intf, "clone-count")];
399 b_state = [_cloneCheckbox state];
400 [_cloneNumberLabel setEnabled: b_state];
401 [_cloneNumberTextField setEnabled: b_state];
402 [_cloneNumberStepper setEnabled: b_state];
404 b_state = [_wallCheckbox state];
405 [self setWallRowsValue: config_GetInt(p_intf, "wall-rows")];
406 [_wallNumbersOfRowsLabel setEnabled: b_state];
407 [_wallNumbersOfRowsTextField setEnabled: b_state];
408 [_wallNumbersOfRowsStepper setEnabled: b_state];
409 [self setWallColumnsValue: config_GetInt(p_intf, "wall-cols")];
410 [_wallNumberOfColumnsLabel setEnabled: b_state];
411 [_wallNumberOfColumnsTextField setEnabled: b_state];
412 [_wallNumberOfColumnsStepper setEnabled: b_state];
414 [_thresholdColorTextField setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "colorthres-color")] uppercaseString]];
415 [_thresholdSaturationSlider setIntValue: config_GetInt(p_intf, "colorthres-saturationthres")];
416 [_thresholdSaturationSlider setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-saturationthres")]];
417 [_thresholdSimilaritySlider setIntValue: config_GetInt(p_intf, "colorthres-similaritythres")];
418 [_thresholdSimilaritySlider setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "colorthres-similaritythres")]];
420 b_state = [_thresholdCheckbox state];
421 [_thresholdColorTextField setEnabled: b_state];
422 [_thresholdColorLabel setEnabled: b_state];
423 [_thresholdSaturationSlider setEnabled: b_state];
424 [_thresholdSaturationLabel setEnabled: b_state];
425 [_thresholdSimilaritySlider setEnabled: b_state];
426 [_thresholdSimilarityLabel setEnabled: b_state];
428 [self setSepiaValue: config_GetInt(p_intf, "sepia-intensity")];
429 b_state = [_sepiaCheckbox state];
430 [_sepiaTextField setEnabled: b_state];
431 [_sepiaStepper setEnabled: b_state];
432 [_sepiaLabel setEnabled: b_state];
434 tmpChar = config_GetPsz(p_intf, "gradient-mode");
435 tmpString = toNSStr(tmpChar);
436 if ([tmpString isEqualToString:@"hough"])
437 [_gradientModePopup selectItemWithTag: 3];
438 else if ([tmpString isEqualToString:@"edge"])
439 [_gradientModePopup selectItemWithTag: 2];
441 [_gradientModePopup selectItemWithTag: 1];
443 [_gradientCartoonCheckbox setState: config_GetInt(p_intf, "gradient-cartoon")];
444 [_gradientColorCheckbox setState: config_GetInt(p_intf, "gradient-type")];
445 b_state = [_gradientCheckbox state];
446 [_gradientModePopup setEnabled: b_state];
447 [_gradientModeLabel setEnabled: b_state];
448 [_gradientCartoonCheckbox setEnabled: b_state];
449 [_gradientColorCheckbox setEnabled: b_state];
451 [_extractTextField setStringValue: [[NSString stringWithFormat:@"%llx", config_GetInt(p_intf, "extract-component")] uppercaseString]];
452 [_extractTextField setEnabled: [_extractCheckbox state]];
453 [_extractLabel setEnabled: [_extractCheckbox state]];
455 [self setPosterizeValue: config_GetInt(p_intf, "posterize-level")];
456 b_state = [_posterizeCheckbox state];
457 [_posterizeTextField setEnabled: b_state];
458 [_posterizeStepper setEnabled: b_state];
459 [_posterizeLabel setEnabled: b_state];
461 [_blurSlider setIntValue: config_GetInt(p_intf, "blur-factor")];
462 [_blurSlider setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "blur-factor")]];
463 [_blurSlider setEnabled: [_blurCheckbox state]];
464 [_blurLabel setEnabled: [_blurCheckbox state]];
466 tmpChar = config_GetPsz(p_intf, "marq-marquee");
467 [_addTextTextTextField setStringValue:toNSStr(tmpChar)];
470 [_addTextPositionPopup selectItemWithTag: config_GetInt(p_intf, "marq-position")];
471 b_state = [_addTextCheckbox state];
472 [_addTextPositionPopup setEnabled: b_state];
473 [_addTextPositionLabel setEnabled: b_state];
474 [_addTextTextLabel setEnabled: b_state];
475 [_addTextTextTextField setEnabled: b_state];
477 tmpChar = config_GetPsz(p_intf, "logo-file");
478 [_addLogoLogoTextField setStringValue: toNSStr(tmpChar)];
481 [_addLogoPositionPopup selectItemWithTag: config_GetInt(p_intf, "logo-position")];
482 [_addLogoTransparencySlider setIntValue: config_GetInt(p_intf, "logo-opacity")];
483 [_addLogoTransparencySlider setToolTip: [NSString stringWithFormat:@"%lli", config_GetInt(p_intf, "logo-opacity")]];
484 b_state = [_addLogoCheckbox state];
485 [_addLogoPositionPopup setEnabled: b_state];
486 [_addLogoPositionLabel setEnabled: b_state];
487 [_addLogoLogoTextField setEnabled: b_state];
488 [_addLogoLogoLabel setEnabled: b_state];
489 [_addLogoTransparencySlider setEnabled: b_state];
490 [_addLogoTransparencyLabel setEnabled: b_state];
493 - (NSString *)generateProfileString
495 intf_thread_t *p_intf = getIntf();
496 return [NSString stringWithFormat:@"%@;%@;%@;%lli;%f;%f;%f;%f;%f;%lli;%f;%@;%lli;%lli;%lli;%lli;%lli;%lli;%@;%lli;%lli;%lli;%lli;%lli;%@;%lli;%@;%lli;%lli;%lli;%lli;%lli;%lli;%f",
497 B64EncAndFree(config_GetPsz(p_intf, "video-filter")),
498 B64EncAndFree(config_GetPsz(p_intf, "sub-source")),
499 B64EncAndFree(config_GetPsz(p_intf, "video-splitter")),
500 0LL, // former "hue" value, deprecated since 3.0.0
501 config_GetFloat(p_intf, "contrast"),
502 config_GetFloat(p_intf, "brightness"),
503 config_GetFloat(p_intf, "saturation"),
504 config_GetFloat(p_intf, "gamma"),
505 config_GetFloat(p_intf, "sharpen-sigma"),
506 config_GetInt(p_intf, "gradfun-radius"),
507 config_GetFloat(p_intf, "grain-variance"),
508 B64EncAndFree(config_GetPsz(p_intf, "transform-type")),
509 config_GetInt(p_intf, "puzzle-rows"),
510 config_GetInt(p_intf, "puzzle-cols"),
511 config_GetInt(p_intf, "colorthres-color"),
512 config_GetInt(p_intf, "colorthres-saturationthres"),
513 config_GetInt(p_intf, "colorthres-similaritythres"),
514 config_GetInt(p_intf, "sepia-intensity"),
515 B64EncAndFree(config_GetPsz(p_intf, "gradient-mode")),
516 config_GetInt(p_intf, "gradient-cartoon"),
517 config_GetInt(p_intf, "gradient-type"),
518 config_GetInt(p_intf, "extract-component"),
519 config_GetInt(p_intf, "posterize-level"),
520 config_GetInt(p_intf, "blur-factor"),
521 B64EncAndFree(config_GetPsz(p_intf, "marq-marquee")),
522 config_GetInt(p_intf, "marq-position"),
523 B64EncAndFree(config_GetPsz(p_intf, "logo-file")),
524 config_GetInt(p_intf, "logo-position"),
525 config_GetInt(p_intf, "logo-opacity"),
526 config_GetInt(p_intf, "clone-count"),
527 config_GetInt(p_intf, "wall-rows"),
528 config_GetInt(p_intf, "wall-cols"),
529 // version 2 of profile string:
530 config_GetInt(p_intf, "brightness-threshold"), // index: 32
531 // version 3 of profile string: (vlc-3.0.0)
532 config_GetFloat(p_intf, "hue") // index: 33
537 #pragma mark generic UI code
539 - (void)saveCurrentProfile
541 if (i_old_profile_index == -1)
544 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
545 /* fetch all the current settings in a uniform string */
546 NSString *newProfile = [self generateProfileString];
548 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
549 if (i_old_profile_index >= [workArray count])
552 [workArray replaceObjectAtIndex:i_old_profile_index withObject:newProfile];
553 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
554 [defaults synchronize];
557 - (IBAction)toggleWindow:(id)sender
559 if ([self.window isKeyWindow])
560 [self.window orderOut:sender];
562 [self.window setLevel: [[[VLCMain sharedInstance] voutController] currentStatusWindowLevel]];
563 [self.window makeKeyAndOrderFront:sender];
567 - (IBAction)profileSelectorAction:(id)sender
569 intf_thread_t *p_intf = getIntf();
570 [self saveCurrentProfile];
571 i_old_profile_index = [_profilePopup indexOfSelectedItem];
572 VLCCoreInteraction *vci_si = [VLCCoreInteraction sharedInstance];
574 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
575 NSUInteger selectedProfile = [_profilePopup indexOfSelectedItem];
578 NSArray *items = [[[defaults objectForKey:@"VideoEffectProfiles"] objectAtIndex:selectedProfile] componentsSeparatedByString:@";"];
580 // version 1 of profile string has 32 entries
581 if ([items count] < 32) {
582 msg_Err(p_intf, "Error in parsing profile string");
587 /* filter handling */
588 NSString *tempString = B64DecNSStr([items firstObject]);
589 vout_thread_t *p_vout = getVout();
591 /* enable the new filters */
592 config_PutPsz(p_intf, "video-filter", [tempString UTF8String]);
594 var_SetString(p_vout, "video-filter", [tempString UTF8String]);
597 tempString = B64DecNSStr([items objectAtIndex:1]);
598 /* enable another round of new filters */
599 config_PutPsz(p_intf, "sub-source", [tempString UTF8String]);
601 var_SetString(p_vout, "sub-source", [tempString UTF8String]);
605 vlc_object_release(p_vout);
608 tempString = B64DecNSStr([items objectAtIndex:2]);
609 /* enable another round of new filters */
610 char *psz_current_splitter = var_GetString(pl_Get(p_intf), "video-splitter");
611 bool b_filter_changed = ![tempString isEqualToString:toNSStr(psz_current_splitter)];
612 free(psz_current_splitter);
614 if (b_filter_changed) {
615 config_PutPsz(p_intf, "video-splitter", [tempString UTF8String]);
616 var_SetString(pl_Get(p_intf), "video-splitter", [tempString UTF8String]);
619 /* try to set filter values on-the-fly and store them appropriately */
620 // index 3 is deprecated
621 [vci_si setVideoFilterProperty:"contrast" forFilter:"adjust" float:[[items objectAtIndex:4] floatValue]];
622 [vci_si setVideoFilterProperty:"brightness" forFilter:"adjust" float:[[items objectAtIndex:5] floatValue]];
623 [vci_si setVideoFilterProperty:"saturation" forFilter:"adjust" float:[[items objectAtIndex:6] floatValue]];
624 [vci_si setVideoFilterProperty:"gamma" forFilter:"adjust" float:[[items objectAtIndex:7] floatValue]];
625 [vci_si setVideoFilterProperty:"sharpen-sigma" forFilter:"sharpen" float:[[items objectAtIndex:8] floatValue]];
626 [vci_si setVideoFilterProperty:"gradfun-radius" forFilter:"gradfun" integer:[[items objectAtIndex:9] intValue]];
627 [vci_si setVideoFilterProperty:"grain-variance" forFilter:"grain" float:[[items objectAtIndex:10] floatValue]];
628 [vci_si setVideoFilterProperty:"transform-type" forFilter:"transform" string:[B64DecNSStr([items objectAtIndex:11]) UTF8String]];
629 [vci_si setVideoFilterProperty:"puzzle-rows" forFilter:"puzzle" integer:[[items objectAtIndex:12] intValue]];
630 [vci_si setVideoFilterProperty:"puzzle-cols" forFilter:"puzzle" integer:[[items objectAtIndex:13] intValue]];
631 [vci_si setVideoFilterProperty:"colorthres-color" forFilter:"colorthres" integer:[[items objectAtIndex:14] intValue]];
632 [vci_si setVideoFilterProperty:"colorthres-saturationthres" forFilter:"colorthres" integer:[[items objectAtIndex:15] intValue]];
633 [vci_si setVideoFilterProperty:"colorthres-similaritythres" forFilter:"colorthres" integer:[[items objectAtIndex:16] intValue]];
634 [vci_si setVideoFilterProperty:"sepia-intensity" forFilter:"sepia" integer:[[items objectAtIndex:17] intValue]];
635 [vci_si setVideoFilterProperty:"gradient-mode" forFilter:"gradient" string:[B64DecNSStr([items objectAtIndex:18]) UTF8String]];
636 [vci_si setVideoFilterProperty:"gradient-cartoon" forFilter:"gradient" boolean:[[items objectAtIndex:19] intValue]];
637 [vci_si setVideoFilterProperty:"gradient-type" forFilter:"gradient" integer:[[items objectAtIndex:20] intValue]];
638 [vci_si setVideoFilterProperty:"extract-component" forFilter:"extract" integer:[[items objectAtIndex:21] intValue]];
639 [vci_si setVideoFilterProperty:"posterize-level" forFilter:"posterize" integer:[[items objectAtIndex:22] intValue]];
640 [vci_si setVideoFilterProperty:"blur-factor" forFilter:"motionblur" integer:[[items objectAtIndex:23] intValue]];
641 [vci_si setVideoFilterProperty:"marq-marquee" forFilter:"marq" string:[B64DecNSStr([items objectAtIndex:24]) UTF8String]];
642 [vci_si setVideoFilterProperty:"marq-position" forFilter:"marq" integer:[[items objectAtIndex:25] intValue]];
643 [vci_si setVideoFilterProperty:"logo-file" forFilter:"logo" string:[B64DecNSStr([items objectAtIndex:26]) UTF8String]];
644 [vci_si setVideoFilterProperty:"logo-position" forFilter:"logo" integer:[[items objectAtIndex:27] intValue]];
645 [vci_si setVideoFilterProperty:"logo-opacity" forFilter:"logo" integer:[[items objectAtIndex:28] intValue]];
646 [vci_si setVideoFilterProperty:"clone-count" forFilter:"clone" integer:[[items objectAtIndex:29] intValue]];
647 [vci_si setVideoFilterProperty:"wall-rows" forFilter:"wall" integer:[[items objectAtIndex:30] intValue]];
648 [vci_si setVideoFilterProperty:"wall-cols" forFilter:"wall" integer:[[items objectAtIndex:31] intValue]];
650 if ([items count] >= 33) { // version >=2 of profile string
651 [vci_si setVideoFilterProperty: "brightness-threshold" forFilter: "adjust" boolean: [[items objectAtIndex:32] intValue]];
655 if ([items count] >= 34) { // version >=3 of profile string
656 hueValue = [[items objectAtIndex:33] floatValue];
658 hueValue = [[items objectAtIndex:3] intValue]; // deprecated since 3.0.0
659 // convert to new scale ([0,360] --> [-180,180])
662 [vci_si setVideoFilterProperty:"hue" forFilter:"adjust" float:hueValue];
664 [defaults setInteger:selectedProfile forKey:@"VideoEffectSelectedProfile"];
665 [defaults synchronize];
670 - (void)addProfile:(id)sender
673 #pragma clang diagnostic push
674 #pragma clang diagnostic ignored "-Wpartial-availability"
675 #ifdef MAC_OS_X_VERSION_10_10
676 if (OSX_YOSEMITE_AND_HIGHER) {
677 [[_textfieldPanel window] setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
680 #pragma clang diagnostic pop
681 [_textfieldPanel setTitleString:_NS("Duplicate current profile for a new profile")];
682 [_textfieldPanel setSubTitleString:_NS("Enter a name for the new profile:")];
683 [_textfieldPanel setCancelButtonString:_NS("Cancel")];
684 [_textfieldPanel setOkButtonString:_NS("Save")];
686 __weak typeof(self) _self = self;
687 [_textfieldPanel runModalForWindow:self.window completionHandler:^(NSInteger returnCode, NSString *resultingText) {
689 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
691 if (returnCode != NSOKButton) {
692 [_profilePopup selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
696 NSArray *profileNames = [defaults objectForKey:@"VideoEffectProfileNames"];
698 // duplicate names are not allowed in the popup control
699 if ([resultingText length] == 0 || [profileNames containsObject:resultingText]) {
700 [_profilePopup selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
702 NSAlert *alert = [[NSAlert alloc] init];
703 [alert setAlertStyle:NSCriticalAlertStyle];
704 [alert setMessageText:_NS("Please enter a unique name for the new profile.")];
705 [alert setInformativeText:_NS("Multiple profiles with the same name are not allowed.")];
707 [alert beginSheetModalForWindow:_self.window
714 /* fetch all the current settings in a uniform string */
715 NSString *newProfile = [_self generateProfileString];
717 /* add string to user defaults as well as a label */
719 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfiles"]];
720 [workArray addObject:newProfile];
721 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
722 [defaults setInteger:[workArray count] - 1 forKey:@"VideoEffectSelectedProfile"];
724 workArray = [[NSMutableArray alloc] initWithArray:[defaults objectForKey:@"VideoEffectProfileNames"]];
725 [workArray addObject:resultingText];
726 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
729 [defaults synchronize];
732 [_self resetProfileSelector];
736 - (void)removeProfile:(id)sender
739 #pragma clang diagnostic push
740 #pragma clang diagnostic ignored "-Wpartial-availability"
741 #ifdef MAC_OS_X_VERSION_10_10
742 if (OSX_YOSEMITE_AND_HIGHER) {
743 [[_popupPanel window] setAppearance:[NSAppearance appearanceNamed:NSAppearanceNameVibrantDark]];
746 #pragma clang diagnostic pop
747 [_popupPanel setTitleString:_NS("Remove a preset")];
748 [_popupPanel setSubTitleString:_NS("Select the preset you would like to remove:")];
749 [_popupPanel setOkButtonString:_NS("Remove")];
750 [_popupPanel setCancelButtonString:_NS("Cancel")];
751 [_popupPanel setPopupButtonContent:[[NSUserDefaults standardUserDefaults] objectForKey:@"VideoEffectProfileNames"]];
753 __weak typeof(self) _self = self;
754 [_popupPanel runModalForWindow:self.window completionHandler:^(NSInteger returnCode, NSInteger selectedIndex) {
756 NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
758 if (returnCode != NSOKButton) {
759 [_profilePopup selectItemAtIndex:[defaults integerForKey:@"VideoEffectSelectedProfile"]];
763 /* remove selected profile from settings */
764 NSMutableArray *workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfiles"]];
765 [workArray removeObjectAtIndex:selectedIndex];
766 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfiles"];
768 workArray = [[NSMutableArray alloc] initWithArray: [defaults objectForKey:@"VideoEffectProfileNames"]];
769 [workArray removeObjectAtIndex:selectedIndex];
770 [defaults setObject:[NSArray arrayWithArray:workArray] forKey:@"VideoEffectProfileNames"];
772 if (i_old_profile_index >= selectedIndex)
773 [defaults setInteger:i_old_profile_index - 1 forKey:@"VideoEffectSelectedProfile"];
776 [defaults synchronize];
778 /* do not save deleted profile */
779 i_old_profile_index = -1;
781 [_self resetProfileSelector];
787 - (IBAction)enableAdjust:(id)sender
789 BOOL b_state = [_adjustCheckbox state];
791 [[VLCCoreInteraction sharedInstance] setVideoFilter: "adjust" on: b_state];
792 [_adjustBrightnessSlider setEnabled: b_state];
793 [_adjustBrightnessCheckbox setEnabled: b_state];
794 [_adjustBrightnessLabel setEnabled: b_state];
795 [_adjustContrastSlider setEnabled: b_state];
796 [_adjustContrastLabel setEnabled: b_state];
797 [_adjustGammaSlider setEnabled: b_state];
798 [_adjustGammaLabel setEnabled: b_state];
799 [_adjustHueSlider setEnabled: b_state];
800 [_adjustHueLabel setEnabled: b_state];
801 [_adjustSaturationSlider setEnabled: b_state];
802 [_adjustSaturationLabel setEnabled: b_state];
803 [_adjustResetButton setEnabled: b_state];
806 - (IBAction)adjustSliderChanged:(id)sender
808 if (sender == _adjustBrightnessSlider)
809 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "brightness" forFilter: "adjust" float: [_adjustBrightnessSlider floatValue]];
810 else if (sender == _adjustContrastSlider)
811 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "contrast" forFilter: "adjust" float: [_adjustContrastSlider floatValue]];
812 else if (sender == _adjustGammaSlider)
813 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gamma" forFilter: "adjust" float: [_adjustGammaSlider floatValue]];
814 else if (sender == _adjustHueSlider)
815 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "hue" forFilter: "adjust" float: [_adjustHueSlider floatValue]];
816 else if (sender == _adjustSaturationSlider)
817 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "saturation" forFilter: "adjust" float: [_adjustSaturationSlider floatValue]];
819 if (sender == _adjustHueSlider)
820 [_adjustHueSlider setToolTip: [NSString stringWithFormat:@"%.0f", [_adjustHueSlider floatValue]]];
822 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
825 - (IBAction)enableAdjustBrightnessThreshold:(id)sender
827 VLCCoreInteraction *vci_si = [VLCCoreInteraction sharedInstance];
829 if (sender == _adjustResetButton) {
830 [_adjustBrightnessSlider setFloatValue: 1.0];
831 [_adjustContrastSlider setFloatValue: 1.0];
832 [_adjustGammaSlider setFloatValue: 1.0];
833 [_adjustHueSlider setFloatValue: 0];
834 [_adjustSaturationSlider setFloatValue: 1.0];
835 [_adjustBrightnessSlider setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
836 [_adjustContrastSlider setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
837 [_adjustGammaSlider setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
838 [_adjustHueSlider setToolTip: [NSString stringWithFormat:@"%.0f", 0.0]];
839 [_adjustSaturationSlider setToolTip: [NSString stringWithFormat:@"%0.3f", 1.0]];
840 [vci_si setVideoFilterProperty: "brightness" forFilter: "adjust" float: 1.0];
841 [vci_si setVideoFilterProperty: "contrast" forFilter: "adjust" float: 1.0];
842 [vci_si setVideoFilterProperty: "gamma" forFilter: "adjust" float: 1.0];
843 [vci_si setVideoFilterProperty: "hue" forFilter: "adjust" float: 0.0];
844 [vci_si setVideoFilterProperty: "saturation" forFilter: "adjust" float: 1.0];
846 [vci_si setVideoFilterProperty: "brightness-threshold" forFilter: "adjust" boolean: [_adjustBrightnessCheckbox state]];
850 - (IBAction)enableSharpen:(id)sender
852 BOOL b_state = [_sharpenCheckbox state];
854 [[VLCCoreInteraction sharedInstance] setVideoFilter: "sharpen" on: b_state];
855 [_sharpenSlider setEnabled: b_state];
856 [_sharpenLabel setEnabled: b_state];
859 - (IBAction)sharpenSliderChanged:(id)sender
861 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "sharpen-sigma" forFilter: "sharpen" float: [sender floatValue]];
862 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
865 - (IBAction)enableBanding:(id)sender
867 BOOL b_state = [_bandingCheckbox state];
869 [[VLCCoreInteraction sharedInstance] setVideoFilter: "gradfun" on: b_state];
870 [_bandingSlider setEnabled: b_state];
871 [_bandingLabel setEnabled: b_state];
874 - (IBAction)bandingSliderChanged:(id)sender
876 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradfun-radius" forFilter: "gradfun" integer: [sender intValue]];
877 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
880 - (IBAction)enableGrain:(id)sender
882 BOOL b_state = [_grainCheckbox state];
884 [[VLCCoreInteraction sharedInstance] setVideoFilter: "grain" on: b_state];
885 [_grainSlider setEnabled: b_state];
886 [_grainLabel setEnabled: b_state];
889 - (IBAction)grainSliderChanged:(id)sender
891 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "grain-variance" forFilter: "grain" float: [sender floatValue]];
892 [sender setToolTip: [NSString stringWithFormat:@"%0.3f", [sender floatValue]]];
899 - (IBAction)cropObjectChanged:(id)sender
901 if ([_cropSyncTopBottomCheckbox state]) {
902 if (sender == _cropBottomTextField || sender == _cropBottomStepper)
903 [self setCropTopValue: [self cropBottomValue]];
905 [self setCropBottomValue: [self cropTopValue]];
907 if ([_cropSyncLeftRightCheckbox state]) {
908 if (sender == _cropRightTextField || sender == _cropRightStepper)
909 [self setCropLeftValue: [self cropRightValue]];
911 [self setCropRightValue: [self cropLeftValue]];
914 vout_thread_t *p_vout = getVout();
916 var_SetInteger(p_vout, "crop-top", [_cropTopTextField intValue]);
917 var_SetInteger(p_vout, "crop-bottom", [_cropBottomTextField intValue]);
918 var_SetInteger(p_vout, "crop-left", [_cropLeftTextField intValue]);
919 var_SetInteger(p_vout, "crop-right", [_cropRightTextField intValue]);
920 vlc_object_release(p_vout);
925 #pragma mark geometry
926 - (IBAction)enableTransform:(id)sender
928 [[VLCCoreInteraction sharedInstance] setVideoFilter: "transform" on: [_transformCheckbox state]];
929 [_transformPopup setEnabled: [_transformCheckbox state]];
932 - (IBAction)transformModifierChanged:(id)sender
934 NSInteger tag = [[_transformPopup selectedItem] tag];
935 const char *psz_string = [[NSString stringWithFormat:@"%li", tag] UTF8String];
937 psz_string = "hflip";
939 psz_string = "vflip";
941 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "transform-type" forFilter: "transform" string: psz_string];
944 - (IBAction)enableZoom:(id)sender
946 [[VLCCoreInteraction sharedInstance] setVideoFilter: "magnify" on: [_zoomCheckbox state]];
949 - (IBAction)enablePuzzle:(id)sender
951 BOOL b_state = [_puzzleCheckbox state];
953 [[VLCCoreInteraction sharedInstance] setVideoFilter: "puzzle" on: b_state];
954 [_puzzleColumnsTextField setEnabled: b_state];
955 [_puzzleColumnsStepper setEnabled: b_state];
956 [_puzzleColumnsLabel setEnabled: b_state];
957 [_puzzleRowsTextField setEnabled: b_state];
958 [_puzzleRowsStepper setEnabled: b_state];
959 [_puzzleRowsLabel setEnabled: b_state];
962 - (IBAction)puzzleModifierChanged:(id)sender
964 if (sender == _puzzleColumnsTextField || sender == _puzzleColumnsStepper)
965 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "puzzle-cols" forFilter: "puzzle" integer: [sender intValue]];
967 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "puzzle-rows" forFilter: "puzzle" integer: [sender intValue]];
970 - (IBAction)enableClone:(id)sender
972 BOOL b_state = [_cloneCheckbox state];
974 if (b_state && [_wallCheckbox state]) {
975 [_wallCheckbox setState: NSOffState];
976 [self enableWall:_wallCheckbox];
979 [[VLCCoreInteraction sharedInstance] setVideoFilter: "clone" on: b_state];
980 [_cloneNumberLabel setEnabled: b_state];
981 [_cloneNumberTextField setEnabled: b_state];
982 [_cloneNumberStepper setEnabled: b_state];
985 - (IBAction)cloneModifierChanged:(id)sender
987 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "clone-count" forFilter: "clone" integer: [_cloneNumberTextField intValue]];
990 - (IBAction)enableWall:(id)sender
992 BOOL b_state = [_wallCheckbox state];
994 if (b_state && [_cloneCheckbox state]) {
995 [_cloneCheckbox setState: NSOffState];
996 [self enableClone:_cloneCheckbox];
999 [[VLCCoreInteraction sharedInstance] setVideoFilter: "wall" on: b_state];
1000 [_wallNumberOfColumnsTextField setEnabled: b_state];
1001 [_wallNumberOfColumnsStepper setEnabled: b_state];
1002 [_wallNumberOfColumnsLabel setEnabled: b_state];
1004 [_wallNumbersOfRowsTextField setEnabled: b_state];
1005 [_wallNumbersOfRowsStepper setEnabled: b_state];
1006 [_wallNumbersOfRowsLabel setEnabled: b_state];
1009 - (IBAction)wallModifierChanged:(id)sender
1011 if (sender == _wallNumberOfColumnsTextField || sender == _wallNumberOfColumnsStepper)
1012 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "wall-cols" forFilter: "wall" integer: [sender intValue]];
1014 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "wall-rows" forFilter: "wall" integer: [sender intValue]];
1019 - (IBAction)enableThreshold:(id)sender
1021 BOOL b_state = [_thresholdCheckbox state];
1023 [[VLCCoreInteraction sharedInstance] setVideoFilter: "colorthres" on: b_state];
1024 [_thresholdColorTextField setEnabled: b_state];
1025 [_thresholdColorLabel setEnabled: b_state];
1026 [_thresholdSaturationSlider setEnabled: b_state];
1027 [_thresholdSaturationLabel setEnabled: b_state];
1028 [_thresholdSimilaritySlider setEnabled: b_state];
1029 [_thresholdSimilarityLabel setEnabled: b_state];
1032 - (IBAction)thresholdModifierChanged:(id)sender
1034 if (sender == _thresholdColorTextField)
1035 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "colorthres-color" forFilter: "colorthres" integer: [_thresholdColorTextField intValue]];
1036 else if (sender == _thresholdSaturationSlider) {
1037 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "colorthres-saturationthres" forFilter: "colorthres" integer: [_thresholdSaturationSlider intValue]];
1038 [_thresholdSaturationSlider setToolTip: [NSString stringWithFormat:@"%i", [_thresholdSaturationSlider intValue]]];
1040 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "colorthres-similaritythres" forFilter: "colorthres" integer: [_thresholdSimilaritySlider intValue]];
1041 [_thresholdSimilaritySlider setToolTip: [NSString stringWithFormat:@"%i", [_thresholdSimilaritySlider intValue]]];
1045 - (IBAction)enableSepia:(id)sender
1047 BOOL b_state = [_sepiaCheckbox state];
1049 [[VLCCoreInteraction sharedInstance] setVideoFilter: "sepia" on: b_state];
1050 [_sepiaTextField setEnabled: b_state];
1051 [_sepiaStepper setEnabled: b_state];
1052 [_sepiaLabel setEnabled: b_state];
1055 - (IBAction)sepiaModifierChanged:(id)sender
1057 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "sepia-intensity" forFilter: "sepia" integer: [_sepiaTextField intValue]];
1060 - (IBAction)enableNoise:(id)sender
1062 [[VLCCoreInteraction sharedInstance] setVideoFilter: "noise" on: [_noiseCheckbox state]];
1065 - (IBAction)enableGradient:(id)sender
1067 BOOL b_state = [_gradientCheckbox state];
1069 [[VLCCoreInteraction sharedInstance] setVideoFilter: "gradient" on: b_state];
1070 [_gradientModePopup setEnabled: b_state];
1071 [_gradientModeLabel setEnabled: b_state];
1072 [_gradientColorCheckbox setEnabled: b_state];
1073 [_gradientCartoonCheckbox setEnabled: b_state];
1076 - (IBAction)gradientModifierChanged:(id)sender
1078 if (sender == _gradientModePopup) {
1079 if ([[_gradientModePopup selectedItem] tag] == 3)
1080 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "hough"];
1081 else if ([[_gradientModePopup selectedItem] tag] == 2)
1082 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "edge"];
1084 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-mode" forFilter: "gradient" string: "gradient"];
1085 } else if (sender == _gradientColorCheckbox)
1086 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-type" forFilter: "gradient" integer: [_gradientColorCheckbox state]];
1088 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "gradient-cartoon" forFilter: "gradient" boolean: [_gradientCartoonCheckbox state]];
1091 - (IBAction)enableExtract:(id)sender
1093 BOOL b_state = [_extractCheckbox state];
1094 [[VLCCoreInteraction sharedInstance] setVideoFilter: "extract" on: b_state];
1095 [_extractTextField setEnabled: b_state];
1096 [_extractLabel setEnabled: b_state];
1099 - (IBAction)extractModifierChanged:(id)sender
1101 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "extract-component" forFilter: "extract" integer: [_extractTextField intValue]];
1104 - (IBAction)enableInvert:(id)sender
1106 [[VLCCoreInteraction sharedInstance] setVideoFilter: "invert" on: [_invertCheckbox state]];
1109 - (IBAction)enablePosterize:(id)sender
1111 BOOL b_state = [_posterizeCheckbox state];
1113 [[VLCCoreInteraction sharedInstance] setVideoFilter: "posterize" on: b_state];
1114 [_posterizeTextField setEnabled: b_state];
1115 [_posterizeStepper setEnabled: b_state];
1116 [_posterizeLabel setEnabled: b_state];
1119 - (IBAction)posterizeModifierChanged:(id)sender
1121 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "posterize-level" forFilter: "posterize" integer: [_posterizeTextField intValue]];
1124 - (IBAction)enableBlur:(id)sender
1126 BOOL b_state = [_blurCheckbox state];
1128 [[VLCCoreInteraction sharedInstance] setVideoFilter: "motionblur" on: b_state];
1129 [_blurSlider setEnabled: b_state];
1130 [_blurLabel setEnabled: b_state];
1133 - (IBAction)blurModifierChanged:(id)sender
1135 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "blur-factor" forFilter: "motionblur" integer: [sender intValue]];
1136 [sender setToolTip: [NSString stringWithFormat:@"%i", [sender intValue]]];
1139 - (IBAction)enableMotionDetect:(id)sender
1141 [[VLCCoreInteraction sharedInstance] setVideoFilter: "motiondetect" on: [_motiondetectCheckbox state]];
1144 - (IBAction)enableWaterEffect:(id)sender
1146 [[VLCCoreInteraction sharedInstance] setVideoFilter: "ripple" on: [_watereffectCheckbox state]];
1149 - (IBAction)enableWaves:(id)sender
1151 [[VLCCoreInteraction sharedInstance] setVideoFilter: "wave" on: [_wavesCheckbox state]];
1154 - (IBAction)enablePsychedelic:(id)sender
1156 [[VLCCoreInteraction sharedInstance] setVideoFilter: "psychedelic" on: [_psychedelicCheckbox state]];
1160 #pragma mark Miscellaneous
1161 - (IBAction)enableAddText:(id)sender
1163 BOOL b_state = [_addTextCheckbox state];
1164 VLCCoreInteraction *vci_si = [VLCCoreInteraction sharedInstance];
1166 [_addTextPositionPopup setEnabled: b_state];
1167 [_addTextPositionLabel setEnabled: b_state];
1168 [_addTextTextLabel setEnabled: b_state];
1169 [_addTextTextTextField setEnabled: b_state];
1170 [vci_si setVideoFilter: "marq" on: b_state];
1171 [vci_si setVideoFilterProperty: "marq-marquee" forFilter: "marq" string: [[_addTextTextTextField stringValue] UTF8String]];
1172 [vci_si setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[_addTextPositionPopup selectedItem] tag]];
1175 - (IBAction)addTextModifierChanged:(id)sender
1177 if (sender == _addTextTextTextField)
1178 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "marq-marquee" forFilter: "marq" string:[[_addTextTextTextField stringValue] UTF8String]];
1180 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "marq-position" forFilter: "marq" integer: [[_addTextPositionPopup selectedItem] tag]];
1183 - (IBAction)enableAddLogo:(id)sender
1185 BOOL b_state = [_addLogoCheckbox state];
1187 [_addLogoPositionPopup setEnabled: b_state];
1188 [_addLogoPositionLabel setEnabled: b_state];
1189 [_addLogoLogoTextField setEnabled: b_state];
1190 [_addLogoLogoLabel setEnabled: b_state];
1191 [_addLogoTransparencySlider setEnabled: b_state];
1192 [_addLogoTransparencyLabel setEnabled: b_state];
1193 [[VLCCoreInteraction sharedInstance] setVideoFilter: "logo" on: b_state];
1196 - (IBAction)addLogoModifierChanged:(id)sender
1198 if (sender == _addLogoLogoTextField)
1199 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "logo-file" forFilter: "logo" string: [[_addLogoLogoTextField stringValue] UTF8String]];
1200 else if (sender == _addLogoPositionPopup)
1201 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "logo-position" forFilter: "logo" integer: [[_addLogoPositionPopup selectedItem] tag]];
1203 [[VLCCoreInteraction sharedInstance] setVideoFilterProperty: "logo-opacity" forFilter: "logo" integer: [_addLogoTransparencySlider intValue]];
1204 [_addLogoTransparencySlider setToolTip: [NSString stringWithFormat:@"%i", [_addLogoTransparencySlider intValue]]];
1208 - (IBAction)enableAnaglyph:(id)sender
1210 [[VLCCoreInteraction sharedInstance] setVideoFilter: "anaglyph" on: [_anaglyphCheckbox state]];