]> git.sesse.net Git - vlc/blob - modules/gui/macosx/prefs_widgets.m
* THANKS: hungarian translator and designer of OSX intf controller added
[vlc] / modules / gui / macosx / prefs_widgets.m
1 /*****************************************************************************
2  * prefs_widgets.m: Preferences controls
3  *****************************************************************************
4  * Copyright (C) 2002-2003 VideoLAN
5  * $Id: prefs_widgets.m,v 1.1 2003/11/17 06:31:22 hartman Exp $
6  *
7  * Authors: Derk-Jan Hartman <hartman at videolan.org> 
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <string.h>
29
30 #include <vlc/vlc.h>
31 #include "vlc_keys.h"
32
33 #include "intf.h"
34 #include "prefs_widgets.h"
35
36 #define PREFS_WRAP 300
37 #define OFFSET_RIGHT 20
38 #define OFFSET_BETWEEN 10
39
40 @implementation VLCConfigControl
41
42 - (id)initWithFrame: (NSRect)frame
43 {
44     return [self initWithFrame: frame
45                     item: nil
46                     withObject: nil];
47 }
48
49 - (id)initWithFrame: (NSRect)frame
50         item: (module_config_t *)p_item
51         withObject: (vlc_object_t *)_p_this
52 {
53     self = [super initWithFrame: frame];
54
55     if( self != nil )
56     {
57         p_this = _p_this;
58         o_label = NULL;
59         psz_name = strdup( p_item->psz_name );
60         i_type = p_item->i_type;
61         b_advanced = p_item->b_advanced;
62         [self setAutoresizingMask:NSViewWidthSizable | NSViewMinYMargin ];
63     }
64     return (self);
65 }
66
67 - (void)dealloc
68 {
69     if( o_label ) [o_label release];
70     if( psz_name ) free( psz_name );
71     [super dealloc];
72 }
73
74
75 + (VLCConfigControl *)newControl: (module_config_t *)p_item withView: (NSView *)o_parent_view withObject: (vlc_object_t *)_p_this
76 {
77     VLCConfigControl *p_control = NULL;
78     NSRect frame = [o_parent_view bounds];
79     
80     switch( p_item->i_type )
81     {
82     case CONFIG_ITEM_MODULE:
83         p_control = [[ModuleConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
84         break;
85
86     case CONFIG_ITEM_STRING:
87         if( !p_item->i_list )
88         {
89             p_control = [[StringConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
90         }
91         else
92         {
93             p_control = [[StringListConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
94         }
95         break;
96         
97     case CONFIG_ITEM_FILE:
98     case CONFIG_ITEM_DIRECTORY:
99         p_control = [[FileConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
100         break;
101
102     case CONFIG_ITEM_INTEGER:
103         if( p_item->i_list )
104         {
105             p_control = [[IntegerListConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
106         }
107         else if( p_item->i_min != 0 || p_item->i_max != 0 )
108         {
109             p_control = [[RangedIntegerConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
110         }
111         else
112         {
113             p_control = [[IntegerConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
114         }
115         break;
116
117     case CONFIG_ITEM_KEY:
118         p_control = [[KeyConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
119         break;
120
121     case CONFIG_ITEM_FLOAT:
122         if( p_item->f_min != 0 || p_item->f_max != 0 )
123         {
124             p_control = [[RangedFloatConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
125         }
126         else
127         {
128             p_control = [[FloatConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
129         }
130         break;
131
132     case CONFIG_ITEM_BOOL:
133         p_control = [[BoolConfigControl alloc] initWithFrame: frame item: p_item withObject: _p_this ];
134         break;
135         
136     default:
137         break;
138     }
139     return p_control;
140 }
141
142 - (NSString *)getName
143 {
144     return [NSApp localizedString: psz_name];
145 }
146
147 - (int)getType
148 {
149     return i_type;
150 }
151
152 - (BOOL)isAdvanced
153 {
154     return b_advanced;
155 }
156
157 - (int)intValue
158 {
159     return 0;
160 }
161
162 - (float)floatValue
163 {
164     return 0;
165 }
166
167 - (char *)stringValue
168 {
169     return NULL;
170 }
171
172 @end
173
174
175 @implementation KeyConfigControl
176
177 - (id)initWithFrame: (NSRect)frame
178         item: (module_config_t *)p_item
179         withObject: (vlc_object_t *)_p_this
180 {
181     frame.size.height = 80;
182     if( self = [super initWithFrame: frame item: p_item
183                 withObject: _p_this] )
184     {
185         NSRect s_rc = frame;
186         unsigned int i;
187
188         o_matrix = [[[NSMatrix alloc] initWithFrame: s_rc mode: NSHighlightModeMatrix cellClass: [NSButtonCell class] numberOfRows:2 numberOfColumns:2] retain];
189         NSArray *o_cells = [o_matrix cells];
190         for( i = 0; i < [o_cells count]; i++ )
191         {
192             NSButtonCell *o_current_cell = [o_cells objectAtIndex:i];
193             [o_current_cell setButtonType: NSSwitchButton];
194             [o_current_cell setControlSize: NSSmallControlSize];
195             [o_matrix setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext] toWidth: PREFS_WRAP] forCell: o_current_cell];
196
197             switch( i )
198             {
199                 case 0:
200                     [o_current_cell setTitle:_NS("Command")];
201                     [o_current_cell setState: p_item->i_value & KEY_MODIFIER_COMMAND];
202                     break;
203                 case 1:
204                     [o_current_cell setTitle:_NS("Control")];
205                     [o_current_cell setState: p_item->i_value & KEY_MODIFIER_CTRL];
206                     break;
207                 case 2:
208                     [o_current_cell setTitle:_NS("Option/Alt")];
209                     [o_current_cell setState: p_item->i_value & KEY_MODIFIER_ALT];
210                     break;
211                 case 3:
212                     [o_current_cell setTitle:_NS("Shift")];
213                     [o_current_cell setState: p_item->i_value & KEY_MODIFIER_SHIFT];
214                     break;
215             }
216         }
217         [o_matrix sizeToCells];
218         [o_matrix setAutoresizingMask:NSViewMaxXMargin ];
219         [[self contentView] addSubview: o_matrix];
220
221         /* add the combo box */
222         s_rc.origin.x += [o_matrix frame].size.width + OFFSET_BETWEEN;
223         s_rc.size.height = 22;
224         s_rc.size.width = 100;
225
226         o_combo = [[[NSComboBox alloc] initWithFrame: s_rc] retain];
227         [o_combo setAutoresizingMask:NSViewMaxXMargin ];
228         [o_combo setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext] toWidth: PREFS_WRAP]];
229         
230         for( i = 0; i < sizeof(vlc_keys) / sizeof(key_descriptor_t); i++ )
231         {
232             
233             if( vlc_keys[i].psz_key_string && *vlc_keys[i].psz_key_string )
234             [o_combo addItemWithObjectValue: [NSApp localizedString:vlc_keys[i].psz_key_string]];
235         }
236         
237         [o_combo setStringValue: [NSApp localizedString:KeyToString(( ((unsigned int)p_item->i_value) & ~KEY_MODIFIER ))]];
238         [[self contentView] addSubview: o_combo];
239         
240         /* add the label */
241         s_rc.origin.y += 50;
242         
243         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
244         [o_label setDrawsBackground: NO];
245         [o_label setBordered: NO];
246         [o_label setEditable: NO];
247         [o_label setSelectable: NO];
248         if ( p_item->psz_text )
249             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
250
251         [o_label sizeToFit];
252         [[self contentView] addSubview: o_label];
253         [o_label setAutoresizingMask:NSViewMaxXMargin ];
254     }
255     return self;
256 }
257
258 - (void)dealloc
259 {
260     [o_matrix release];
261     [o_combo release];
262     [super dealloc];
263 }
264
265 - (int)getIntValue
266 {
267     unsigned int i, i_new_key = 0;
268     NSButtonCell *o_current_cell;
269     NSArray *o_cells = [o_matrix cells];
270
271     for( i = 0; i < [o_cells count]; i++ )
272     {
273         o_current_cell = [o_cells objectAtIndex:i];
274         if( [[o_current_cell title] isEqualToString:_NS("Command")] && 
275             [o_current_cell state] == NSOnState )
276         {
277             i_new_key |= KEY_MODIFIER_COMMAND;
278         }
279         if( [[o_current_cell title] isEqualToString:_NS("Control")] && 
280             [o_current_cell state] == NSOnState )
281         {
282             i_new_key |= KEY_MODIFIER_CTRL;
283         }
284         if( [[o_current_cell title] isEqualToString:_NS("Option/Alt")] && 
285             [o_current_cell state] == NSOnState )
286         {
287             i_new_key |= KEY_MODIFIER_ALT;
288         }
289         if( [[o_current_cell title] isEqualToString:_NS("Shift")] && 
290             [o_current_cell state] == NSOnState )
291         {
292             i_new_key |= KEY_MODIFIER_SHIFT;
293         }
294     }
295     i_new_key |= StringToKey([[o_combo stringValue] cString]);
296     return i_new_key;
297 }
298
299
300 @end
301
302 @implementation ModuleConfigControl
303
304 - (id)initWithFrame: (NSRect)frame
305         item: (module_config_t *)p_item
306         withObject: (vlc_object_t *)_p_this
307 {
308     frame.size.height = 20;
309     if( self = [super initWithFrame: frame item: p_item
310                 withObject: _p_this] )
311     {
312         vlc_list_t *p_list;
313         module_t *p_parser;
314         NSRect s_rc = frame;
315         int i_index;
316
317         /* add the label */
318         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
319         [o_label setDrawsBackground: NO];
320         [o_label setBordered: NO];
321         [o_label setEditable: NO];
322         [o_label setSelectable: NO];
323         if ( p_item->psz_text )
324             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
325
326         [o_label sizeToFit];
327         [[self contentView] addSubview: o_label];
328         [o_label setAutoresizingMask:NSViewMaxXMargin ];
329         
330         /* build the popup */
331         s_rc.origin.x = s_rc.size.width - 200 - OFFSET_RIGHT;
332         s_rc.size.width = 200;
333         
334         o_popup = [[[NSPopUpButton alloc] initWithFrame: s_rc] retain];
335         [[self contentView] addSubview: o_popup];
336         [o_popup setAutoresizingMask:NSViewMinXMargin ];
337
338         [o_popup setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
339         [o_popup addItemWithTitle: _NS("Default")];
340         [[o_popup lastItem] setTag: -1];
341         [o_popup selectItem: [o_popup lastItem]];
342         
343         /* build a list of available modules */
344         p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
345         for( i_index = 0; i_index < p_list->i_count; i_index++ )
346         {
347             p_parser = (module_t *)p_list->p_values[i_index].p_object ;
348
349             if( !strcmp( p_parser->psz_capability,
350                         p_item->psz_type ) )
351             {
352                 NSString *o_description = [NSApp
353                     localizedString: p_parser->psz_longname];
354                 [o_popup addItemWithTitle: o_description];
355
356                 if( p_item->psz_value &&
357                     !strcmp( p_item->psz_value, p_parser->psz_object_name ) )
358                 {
359                     [o_popup selectItem:[o_popup lastItem]];
360                 }
361             }
362         }
363         vlc_list_release( p_list );
364     }
365     return self;
366 }
367
368 - (void)dealloc
369 {
370     [o_popup release];
371     [super dealloc];
372 }
373
374 - (char *)stringValue
375 {
376     NSString *newval = [o_popup stringValue];
377     char *returnval;
378     int i_index;
379     vlc_list_t *p_list;
380     module_t *p_parser;
381     module_config_t *p_item;
382
383     p_item = config_FindConfig( p_this, psz_name );
384     p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
385     for( i_index = 0; i_index < p_list->i_count; i_index++ )
386     {
387         p_parser = (module_t *)p_list->p_values[i_index].p_object ;
388
389         if( !strcmp( p_parser->psz_capability,
390                     p_item->psz_type ) )
391         {
392             NSString *o_description = [NSApp
393                 localizedString: p_parser->psz_longname];
394             
395             if( [newval isEqualToString: o_description] )
396             {
397                 returnval = strdup(p_parser->psz_object_name);
398                 break;
399             }
400         }
401     }
402     vlc_list_release( p_list );
403     return returnval;
404 }
405
406 @end
407
408 @implementation StringConfigControl
409 - (id)initWithFrame: (NSRect)frame
410         item: (module_config_t *)p_item
411         withObject: (vlc_object_t *)_p_this
412 {
413     frame.size.height = 22;
414     if( self = [super initWithFrame: frame item: p_item
415                 withObject: _p_this] )
416     {
417         NSRect s_rc = frame;
418
419         /* add the label */
420         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
421         [o_label setDrawsBackground: NO];
422         [o_label setBordered: NO];
423         [o_label setEditable: NO];
424         [o_label setSelectable: NO];
425         if( p_item->psz_text )
426             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
427
428         [o_label sizeToFit];
429         [[self contentView] addSubview: o_label];
430         [o_label setAutoresizingMask:NSViewMaxXMargin ];
431         
432         /* build the textfield */
433         s_rc.origin.x = s_rc.size.width - 200 - OFFSET_RIGHT;
434         s_rc.size.width = 200;
435         
436         o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];
437         [o_textfield setAutoresizingMask:NSViewMinXMargin | NSViewWidthSizable ];
438
439         [o_textfield setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
440         [o_textfield setStringValue: [NSApp localizedString: p_item->psz_value]];
441         [[self contentView] addSubview: o_textfield];
442     }
443     return self;
444 }
445
446 - (void)dealloc
447 {
448     [o_textfield release];
449     [super dealloc];
450 }
451
452 - (char *)stringValue
453 {
454     return strdup( [NSApp delocalizeString:[o_textfield stringValue]] );
455 }
456
457 @end
458
459 @implementation StringListConfigControl
460
461 - (id)initWithFrame: (NSRect)frame
462         item: (module_config_t *)p_item
463         withObject: (vlc_object_t *)_p_this
464 {
465     frame.size.height = 20;
466     if( self = [super initWithFrame: frame item: p_item
467                 withObject: _p_this] )
468     {
469         NSRect s_rc = frame;
470         int i_index;
471
472         /* add the label */
473         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
474         [o_label setDrawsBackground: NO];
475         [o_label setBordered: NO];
476         [o_label setEditable: NO];
477         [o_label setSelectable: NO];
478         if( p_item->psz_text )
479             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
480
481         [o_label sizeToFit];
482         [[self contentView] addSubview: o_label];
483         [o_label setAutoresizingMask:NSViewMaxXMargin ];
484         
485         /* build the textfield */
486         s_rc.origin.x = s_rc.size.width - 200 - OFFSET_RIGHT;
487         s_rc.size.width = 200;
488         
489         o_combo = [[[NSComboBox alloc] initWithFrame: s_rc] retain];
490         [o_combo setAutoresizingMask:NSViewMinXMargin | NSViewWidthSizable ];
491
492         [o_combo setUsesDataSource:TRUE];
493         [o_combo setDataSource:self];
494         [o_combo setNumberOfVisibleItems:10];
495         for( i_index = 0; i_index < p_item->i_list; i_index++ )
496         {
497             if( p_item->psz_value && !strcmp( p_item->psz_value, p_item->ppsz_list[i_index] ) )
498             {
499                 [o_combo selectItemAtIndex: i_index];
500             }
501         }
502
503         [o_combo setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
504         [[self contentView] addSubview: o_combo];
505     }
506     return self;
507 }
508
509 - (void)dealloc
510 {
511     [o_combo release];
512     [super dealloc];
513 }
514
515 - (char *)stringValue
516 {
517     module_config_t *p_item;
518     p_item = config_FindConfig( p_this, psz_name );
519
520     if( [o_combo indexOfSelectedItem] >= 0 )
521         return strdup( p_item->ppsz_list[[o_combo indexOfSelectedItem]] );
522     else
523         return strdup( [NSApp delocalizeString: [o_combo stringValue]] );
524 }
525
526 @end
527
528 @implementation StringListConfigControl (NSComboBoxDataSource)
529
530 - (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox
531 {
532     module_config_t *p_item;
533     p_item = config_FindConfig( p_this, psz_name );
534
535     return p_item->i_list;
536 }
537
538 - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)i_index
539 {
540     module_config_t *p_item;
541     p_item = config_FindConfig( p_this, psz_name );
542
543     if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
544     {
545         return [NSApp localizedString: p_item->ppsz_list_text[i_index]];
546     } else return [NSApp localizedString: p_item->ppsz_list[i_index]];
547 }
548
549 @end
550
551 @implementation FileConfigControl
552
553 - (id)initWithFrame: (NSRect)frame
554         item: (module_config_t *)p_item
555         withObject: (vlc_object_t *)_p_this
556 {
557     frame.size.height = 49;
558     if( self = [super initWithFrame: frame item: p_item
559                 withObject: _p_this] )
560     {
561         NSRect s_rc = frame;
562         s_rc.origin.y = 29;
563         s_rc.size.height = 20;
564
565         /* is it a directory */
566         b_directory = ( [self getType] == CONFIG_ITEM_DIRECTORY ) ? YES : NO;
567
568         /* add the label */
569         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
570         [o_label setDrawsBackground: NO];
571         [o_label setBordered: NO];
572         [o_label setEditable: NO];
573         [o_label setSelectable: NO];
574         if( p_item->psz_text )
575             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
576
577         [o_label sizeToFit];
578         [o_label setAutoresizingMask:NSViewMaxXMargin ];
579         [[self contentView] addSubview: o_label];
580         
581         /* build the button */
582         s_rc.origin.y = s_rc.origin.x = 0;
583         s_rc.size.height = 22;
584
585         o_button = [[[NSButton alloc] initWithFrame: s_rc] retain];
586         [o_button setButtonType: NSMomentaryPushInButton];
587         [o_button setBezelStyle: NSRoundedBezelStyle];
588         [o_button setTitle: _NS("Browse...")];
589         [o_button sizeToFit];
590         [o_button setAutoresizingMask:NSViewMinXMargin];
591         [o_button setFrameOrigin: NSMakePoint( s_rc.size.width - 
592                     [o_button frame].size.width - OFFSET_RIGHT, s_rc.origin.y)];
593         [o_button setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
594
595         [o_button setTarget: self];
596         [o_button setAction: @selector(openFileDialog:)];
597
598         s_rc.size.height = 22;
599         s_rc.size.width = s_rc.size.width - OFFSET_BETWEEN - [o_button frame].size.width - OFFSET_RIGHT;
600         
601         o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];
602         
603         [o_textfield setStringValue: [NSApp localizedString: p_item->psz_value]];
604         [o_textfield setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
605
606         [o_textfield setAutoresizingMask:NSViewWidthSizable];
607                
608         [[self contentView] addSubview: o_textfield];
609         [[self contentView] addSubview: o_button];
610     }
611     return self;
612 }
613
614 - (void)dealloc
615 {
616     [o_textfield release];
617     [o_button release];
618     [super dealloc];
619 }
620
621 - (IBAction)openFileDialog: (id)sender
622 {
623     NSOpenPanel *o_open_panel = [NSOpenPanel openPanel];
624     
625     [o_open_panel setTitle: _NS("Select a file or directory")];
626     [o_open_panel setPrompt: _NS("Select")];
627     [o_open_panel setAllowsMultipleSelection: NO];
628     [o_open_panel setCanChooseFiles: YES];
629     [o_open_panel setCanChooseDirectories: b_advanced];
630     [o_open_panel beginSheetForDirectory:nil
631         file:nil
632         types:nil
633         modalForWindow:[sender window]
634         modalDelegate: self
635         didEndSelector: @selector(pathChosenInPanel: 
636                         withReturn:
637                         contextInfo:)
638         contextInfo: nil];
639 }
640
641 - (void)pathChosenInPanel:(NSOpenPanel *)o_sheet withReturn:(int)i_return_code contextInfo:(void  *)o_context_info
642 {
643     if( i_return_code == NSOKButton )
644     {
645         NSString *o_path = [[o_sheet filenames] objectAtIndex: 0];
646         [o_textfield setStringValue: o_path];
647     }
648 }
649
650 - (char *)stringValue
651 {
652     return strdup( [NSApp delocalizeString: [o_textfield stringValue]] );
653 }
654
655 @end
656
657 @implementation IntegerConfigControl
658 - (id)initWithFrame: (NSRect)frame
659         item: (module_config_t *)p_item
660         withObject: (vlc_object_t *)_p_this
661 {
662     frame.size.height = 22;
663     if( self = [super initWithFrame: frame item: p_item
664                 withObject: _p_this] )
665     {
666         NSRect s_rc = frame;
667
668         /* add the label */
669         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
670         [o_label setDrawsBackground: NO];
671         [o_label setBordered: NO];
672         [o_label setEditable: NO];
673         [o_label setSelectable: NO];
674         if( p_item->psz_text )
675             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
676
677         [o_label sizeToFit];
678         [[self contentView] addSubview: o_label];
679         [o_label setAutoresizingMask:NSViewMaxXMargin ];
680         
681         /* build the stepper */
682         s_rc.origin.x = s_rc.size.width - 13 - OFFSET_RIGHT;
683         
684         o_stepper = [[[NSStepper alloc] initWithFrame: s_rc] retain];
685         [o_stepper sizeToFit];
686         [o_stepper setAutoresizingMask:NSViewMinXMargin];
687
688         [o_stepper setMaxValue: 1600];
689         [o_stepper setMinValue: -1600];
690         [o_stepper setIntValue: p_item->i_value];
691         [o_stepper setTarget: self];
692         [o_stepper setAction: @selector(stepperChanged:)];
693         [o_stepper sendActionOn:NSLeftMouseUpMask|NSLeftMouseDownMask|NSLeftMouseDraggedMask];
694         [o_stepper setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
695         [[self contentView] addSubview: o_stepper];
696     
697         /* build the textfield */
698         s_rc.origin.x = s_rc.size.width - 60 - OFFSET_BETWEEN - 13 - OFFSET_RIGHT;
699         s_rc.size.width = 60;
700         
701         o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];
702         [o_textfield setAutoresizingMask:NSViewMinXMargin | NSViewWidthSizable ];
703
704         [o_textfield setIntValue: p_item->i_value];
705         [o_textfield setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
706         [o_textfield setDelegate: self];
707         [[NSNotificationCenter defaultCenter] addObserver: self
708             selector: @selector(textfieldChanged:)
709             name: NSControlTextDidChangeNotification
710             object: o_textfield];
711         [[self contentView] addSubview: o_textfield];
712     }
713     return self;
714 }
715
716 - (void)dealloc
717 {
718     [o_stepper release];
719     [o_textfield release];
720     [super dealloc];
721 }
722
723 - (IBAction)stepperChanged:(id)sender
724 {
725     [o_textfield setIntValue: [o_stepper intValue]];
726 }
727
728 - (void)textfieldChanged:(NSNotification *)o_notification
729 {
730     [o_stepper setIntValue: [o_textfield intValue]];
731 }
732
733 - (int)getIntValue
734 {
735     return [o_stepper intValue];
736 }
737
738 @end
739
740 @implementation IntegerListConfigControl
741
742 - (id)initWithFrame: (NSRect)frame
743         item: (module_config_t *)p_item
744         withObject: (vlc_object_t *)_p_this
745 {
746     frame.size.height = 20;
747     if( self = [super initWithFrame: frame item: p_item
748                 withObject: _p_this] )
749     {
750         NSRect s_rc = frame;
751         int i_index;
752
753         /* add the label */
754         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
755         [o_label setDrawsBackground: NO];
756         [o_label setBordered: NO];
757         [o_label setEditable: NO];
758         [o_label setSelectable: NO];
759         if( p_item->psz_text )
760             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
761
762         [o_label sizeToFit];
763         [[self contentView] addSubview: o_label];
764         [o_label setAutoresizingMask:NSViewMaxXMargin ];
765         
766         /* build the textfield */
767         s_rc.origin.x = s_rc.size.width - 200 - OFFSET_RIGHT;
768         s_rc.size.width = 200;
769         
770         o_combo = [[[NSComboBox alloc] initWithFrame: s_rc] retain];
771         [o_combo setAutoresizingMask:NSViewMinXMargin | NSViewWidthSizable ];
772
773         [o_combo setUsesDataSource:TRUE];
774         [o_combo setDataSource:self];
775         [o_combo setNumberOfVisibleItems:10];
776         for( i_index = 0; i_index < p_item->i_list; i_index++ )
777         {
778             if( p_item->i_value == p_item->pi_list[i_index] )
779             {
780                 [o_combo selectItemAtIndex: i_index];
781             }
782         }
783
784         [o_combo setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
785         [[self contentView] addSubview: o_combo];
786     }
787     return self;
788 }
789
790 - (void)dealloc
791 {
792     [o_combo release];
793     [super dealloc];
794 }
795
796 - (int)intValue
797 {
798     module_config_t *p_item;
799     p_item = config_FindConfig( p_this, psz_name );
800
801     if( [o_combo indexOfSelectedItem] >= 0 )
802         return p_item->pi_list[[o_combo indexOfSelectedItem]];
803     else
804         return [o_combo intValue];
805 }
806
807 @end
808
809 @implementation IntegerListConfigControl (NSComboBoxDataSource)
810
811 - (int)numberOfItemsInComboBox:(NSComboBox *)aComboBox
812 {
813     module_config_t *p_item;
814     p_item = config_FindConfig( p_this, psz_name );
815
816     return p_item->i_list;
817 }
818
819 - (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(int)i_index
820 {
821     module_config_t *p_item;
822     p_item = config_FindConfig( p_this, psz_name );
823
824     if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
825     {
826         return [NSApp localizedString: p_item->ppsz_list_text[i_index]];
827     } else return [NSString stringWithFormat: @"%i", p_item->pi_list[i_index]];
828 }
829
830 @end
831
832 @implementation RangedIntegerConfigControl
833
834 - (id)initWithFrame: (NSRect)frame
835         item: (module_config_t *)p_item
836         withObject: (vlc_object_t *)_p_this
837 {
838     frame.size.height = 50;
839     if( self = [super initWithFrame: frame item: p_item
840                 withObject: _p_this] )
841     {
842         NSRect s_rc = frame;
843         s_rc.size.height = 20;
844         s_rc.origin.y = 30;
845     
846         /* add the label */
847         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
848         [o_label setDrawsBackground: NO];
849         [o_label setBordered: NO];
850         [o_label setEditable: NO];
851         [o_label setSelectable: NO];
852         if( p_item->psz_text )
853             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
854
855         [o_label sizeToFit];
856         [[self contentView] addSubview: o_label];
857         [o_label setAutoresizingMask:NSViewMaxXMargin ];
858
859         /* build the slider */
860         /* min value textfield */
861         s_rc.origin.y = 0;
862         s_rc.origin.x = 0;
863         s_rc.size.width = 40;
864
865         o_textfield_min = [[[NSTextField alloc] initWithFrame: s_rc] retain];
866         [o_textfield_min setAutoresizingMask:NSViewMaxXMargin];
867         [o_textfield_min setDrawsBackground: NO];
868         [o_textfield_min setBordered: NO];
869         [o_textfield_min setEditable: NO];
870         [o_textfield_min setSelectable: NO];
871
872         [o_textfield_min setIntValue: p_item->i_min];
873         [o_textfield_min setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
874         [[self contentView] addSubview: o_textfield_min];
875
876         /* the slider */
877         s_rc.size.width = [[self contentView] bounds].size.width - OFFSET_RIGHT - 2*OFFSET_BETWEEN - 3*40;
878         s_rc.origin.x = 40 + OFFSET_BETWEEN;
879
880         o_slider = [[[NSStepper alloc] initWithFrame: s_rc] retain];
881         [o_slider setAutoresizingMask:NSViewWidthSizable];
882
883         [o_slider setMaxValue: p_item->i_max];
884         [o_slider setMinValue: p_item->i_min];
885         [o_slider setIntValue: p_item->i_value];
886         [o_slider setTarget: self];
887         [o_slider setAction: @selector(sliderChanged:)];
888         [o_slider sendActionOn:NSLeftMouseUpMask|NSLeftMouseDownMask|NSLeftMouseDraggedMask];
889         [o_slider setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
890         [[self contentView] addSubview: o_slider];
891         
892         /* max value textfield */
893         s_rc.size.width = 40;
894         s_rc.origin.x = [[self contentView] bounds].size.width - OFFSET_RIGHT - OFFSET_BETWEEN - 2*40;
895         
896         o_textfield_max = [[[NSTextField alloc] initWithFrame: s_rc] retain];
897         [o_textfield_max setAutoresizingMask:NSViewMinXMargin ];
898
899         [o_textfield_max setDrawsBackground: NO];
900         [o_textfield_max setBordered: NO];
901         [o_textfield_max setEditable: NO];
902         [o_textfield_max setSelectable: NO];
903
904         [o_textfield_max setIntValue: p_item->i_max];
905         [o_textfield_max setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
906         [[self contentView] addSubview: o_textfield_max];
907         
908         /* current value textfield */
909         s_rc.size.width = 40;
910         s_rc.origin.x = [[self contentView] bounds].size.width - OFFSET_RIGHT - 40;
911
912         o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];
913         [o_textfield setAutoresizingMask:NSViewMinXMargin];
914
915         [o_textfield setIntValue: p_item->i_value];
916         [o_textfield setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
917         [o_textfield setDelegate: self];
918         [[NSNotificationCenter defaultCenter] addObserver: self
919             selector: @selector(textfieldChanged:)
920             name: NSControlTextDidChangeNotification
921             object: o_textfield];
922         [[self contentView] addSubview: o_textfield];
923
924     }
925     return self;
926 }
927
928 - (void)dealloc
929 {
930     [o_textfield release];
931     [o_textfield_min release];
932     [o_textfield_max release];
933     [o_slider release];
934     [super dealloc];
935 }
936
937 - (IBAction)sliderChanged:(id)sender
938 {
939     [o_textfield setIntValue: [o_slider intValue]];
940 }
941
942 - (void)textfieldChanged:(NSNotification *)o_notification
943 {
944     [o_slider setIntValue: [o_textfield intValue]];
945 }
946
947 - (int)intValue
948 {
949     return [o_slider intValue];
950 }
951
952 @end
953
954 @implementation FloatConfigControl
955
956 - (id)initWithFrame: (NSRect)frame
957         item: (module_config_t *)p_item
958         withObject: (vlc_object_t *)_p_this
959 {
960     frame.size.height = 20;
961     if( self = [super initWithFrame: frame item: p_item
962                 withObject: _p_this] )
963     {
964         NSRect s_rc = frame;
965
966         /* add the label */
967         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
968         [o_label setDrawsBackground: NO];
969         [o_label setBordered: NO];
970         [o_label setEditable: NO];
971         [o_label setSelectable: NO];
972         if( p_item->psz_text )
973             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
974
975         [o_label sizeToFit];
976         [[self contentView] addSubview: o_label];
977         [o_label setAutoresizingMask:NSViewMaxXMargin ];
978
979         /* build the textfield */
980         s_rc.origin.x = s_rc.size.width - 60 - OFFSET_RIGHT;
981         s_rc.size.width = 60;
982         
983         o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];
984         [o_textfield setAutoresizingMask:NSViewMinXMargin | NSViewWidthSizable ];
985
986         [o_textfield setFloatValue: p_item->f_value];
987         [o_textfield setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
988         [[self contentView] addSubview: o_textfield];
989     }
990     return self;
991 }
992
993 - (void)dealloc
994 {
995     [o_textfield release];
996     [super dealloc];
997 }
998
999 - (float)floatValue
1000 {
1001     return [o_textfield floatValue];
1002 }
1003
1004 @end
1005
1006 @implementation RangedFloatConfigControl
1007
1008 - (id)initWithFrame: (NSRect)frame
1009         item: (module_config_t *)p_item
1010         withObject: (vlc_object_t *)_p_this
1011 {
1012     frame.size.height = 50;
1013     if( self = [super initWithFrame: frame item: p_item
1014                 withObject: _p_this] )
1015     {
1016         NSRect s_rc = frame;
1017         s_rc.size.height = 20;
1018         s_rc.origin.y = 30;
1019     
1020         /* add the label */
1021         o_label = [[[NSTextField alloc] initWithFrame: s_rc] retain];
1022         [o_label setDrawsBackground: NO];
1023         [o_label setBordered: NO];
1024         [o_label setEditable: NO];
1025         [o_label setSelectable: NO];
1026         if( p_item->psz_text )
1027             [o_label setStringValue: [NSApp localizedString: p_item->psz_text]];
1028
1029         [o_label sizeToFit];
1030         [[self contentView] addSubview: o_label];
1031         [o_label setAutoresizingMask:NSViewMaxXMargin ];
1032
1033         /* build the slider */
1034         /* min value textfield */
1035         s_rc.origin.y = 0;
1036         s_rc.origin.x = 0;
1037         s_rc.size.width = 40;
1038
1039         o_textfield_min = [[[NSTextField alloc] initWithFrame: s_rc] retain];
1040         [o_textfield_min setAutoresizingMask:NSViewMaxXMargin];
1041         [o_textfield_min setDrawsBackground: NO];
1042         [o_textfield_min setBordered: NO];
1043         [o_textfield_min setEditable: NO];
1044         [o_textfield_min setSelectable: NO];
1045
1046         [o_textfield_min setFloatValue: p_item->f_min];
1047         [o_textfield_min setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
1048         [[self contentView] addSubview: o_textfield_min];
1049
1050         /* the slider */
1051         s_rc.size.width = [[self contentView] bounds].size.width - OFFSET_RIGHT - 2*OFFSET_BETWEEN - 3*40;
1052         s_rc.origin.x = 40 + OFFSET_BETWEEN;
1053
1054         o_slider = [[[NSStepper alloc] initWithFrame: s_rc] retain];
1055         [o_slider setAutoresizingMask:NSViewWidthSizable];
1056
1057         [o_slider setMaxValue: p_item->f_max];
1058         [o_slider setMinValue: p_item->f_min];
1059         [o_slider setFloatValue: p_item->f_value];
1060         [o_slider setTarget: self];
1061         [o_slider setAction: @selector(sliderChanged:)];
1062         [o_slider sendActionOn:NSLeftMouseUpMask|NSLeftMouseDownMask|NSLeftMouseDraggedMask];
1063         [o_slider setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
1064         [[self contentView] addSubview: o_slider];
1065         
1066         /* max value textfield */
1067         s_rc.size.width = 40;
1068         s_rc.origin.x = [[self contentView] bounds].size.width - OFFSET_RIGHT - OFFSET_BETWEEN - 2*40;
1069         
1070         o_textfield_max = [[[NSTextField alloc] initWithFrame: s_rc] retain];
1071         [o_textfield_max setAutoresizingMask:NSViewMinXMargin ];
1072
1073         [o_textfield_max setDrawsBackground: NO];
1074         [o_textfield_max setBordered: NO];
1075         [o_textfield_max setEditable: NO];
1076         [o_textfield_max setSelectable: NO];
1077
1078         [o_textfield_max setFloatValue: p_item->f_max];
1079         [o_textfield_max setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
1080         [[self contentView] addSubview: o_textfield_max];
1081         
1082         /* current value textfield */
1083         s_rc.size.width = 40;
1084         s_rc.origin.x = [[self contentView] bounds].size.width - OFFSET_RIGHT - 40;
1085
1086         o_textfield = [[[NSTextField alloc] initWithFrame: s_rc] retain];
1087         [o_textfield setAutoresizingMask:NSViewMinXMargin];
1088
1089         [o_textfield setFloatValue: p_item->f_value];
1090         [o_textfield setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
1091         [o_textfield setDelegate: self];
1092         [[NSNotificationCenter defaultCenter] addObserver: self
1093             selector: @selector(textfieldChanged:)
1094             name: NSControlTextDidChangeNotification
1095             object: o_textfield];
1096         [[self contentView] addSubview: o_textfield];
1097
1098     }
1099     return self;
1100 }
1101
1102 - (void)dealloc
1103 {
1104     [o_textfield release];
1105     [o_textfield_min release];
1106     [o_textfield_max release];
1107     [o_slider release];
1108     [super dealloc];
1109 }
1110
1111 - (IBAction)sliderChanged:(id)sender
1112 {
1113     [o_textfield setFloatValue: [o_slider floatValue]];
1114 }
1115
1116 - (void)textfieldChanged:(NSNotification *)o_notification
1117 {
1118     [o_slider setFloatValue: [o_textfield floatValue]];
1119 }
1120
1121 - (float)floatValue
1122 {
1123     return [o_slider floatValue];
1124 }
1125
1126 @end
1127
1128
1129 @implementation BoolConfigControl
1130
1131 - (id)initWithFrame: (NSRect)frame
1132         item: (module_config_t *)p_item
1133         withObject: (vlc_object_t *)_p_this
1134 {
1135     frame.size.height = 20;
1136     if( self = [super initWithFrame: frame item: p_item
1137             withObject: _p_this] )
1138     {
1139         NSRect s_rc = frame;
1140         s_rc.size.height = 20;
1141         
1142         o_checkbox = [[[NSButton alloc] initWithFrame: s_rc] retain];
1143         [o_checkbox setButtonType: NSSwitchButton];
1144         [o_checkbox setIntValue: p_item->i_value];
1145         [o_checkbox setTitle: [NSApp localizedString: p_item->psz_text]];
1146         [o_checkbox setToolTip: [NSApp wrapString: [NSApp localizedString: p_item->psz_longtext ] toWidth: PREFS_WRAP]];
1147         [[self contentView] addSubview: o_checkbox];
1148     }
1149     return self;
1150 }
1151
1152 - (void)dealloc
1153 {
1154     [o_checkbox release];
1155     [super dealloc];
1156 }
1157
1158 - (int)intValue
1159 {
1160     [o_checkbox intValue];
1161 }
1162
1163 @end