]> git.sesse.net Git - vlc/blob - modules/gui/beos/PreferencesWindow.cpp
0ea466f7da3804d80ab07d29dc37eaabcb62926d
[vlc] / modules / gui / beos / PreferencesWindow.cpp
1 /*****************************************************************************
2  * PreferencesWindow.cpp: beos interface
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Eric Petit <titer@m0k.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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24
25 #include <String.h>
26
27 #include <vlc/vlc.h>
28 #include <vlc_interface.h>
29 #include <vlc_keys.h>
30 #include <vlc_config_cat.h>
31
32 #include "PreferencesWindow.h"
33
34 #define TYPE_CATEGORY 0
35 #define TYPE_SUBCATEGORY 2
36 #define TYPE_MODULE 3
37
38 /*****************************************************************************
39  * PreferencesWindow::PreferencesWindow
40  *****************************************************************************/
41 PreferencesWindow::PreferencesWindow( intf_thread_t * _p_intf,
42                                       BRect frame, const char * name )
43     : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
44                B_NOT_ZOOMABLE )
45 {
46     p_intf   = _p_intf;
47     fCurrent = NULL;
48
49     BRect rect;
50
51     SetSizeLimits( PREFS_WINDOW_WIDTH, 2000, PREFS_WINDOW_HEIGHT, 2000 );
52
53     /* The "background" view */
54     fPrefsView = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
55     fPrefsView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
56     AddChild( fPrefsView );
57
58     /* Create a scrollable outline view for the preferences tree */
59     rect = Bounds();
60     rect.InsetBy( 10, 10 );
61     rect.right = rect.left + 150;
62     fOutline = new BOutlineListView( rect, "preferences tree",
63                                      B_SINGLE_SELECTION_LIST,
64                                      B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM );
65     BScrollView * scrollview =
66         new BScrollView( "scrollview", fOutline,
67                          B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
68                          0, false, true );
69     fPrefsView->AddChild( scrollview );
70
71     /* We need to be informed if the user selects an item */
72     fOutline->SetSelectionMessage( new BMessage( PREFS_ITEM_SELECTED ) );
73
74     /* Create a dummy, empty view so we can correctly place the real
75        config views later */
76     rect.bottom -= 40;
77     rect.left = rect.right + 15 + B_V_SCROLL_BAR_WIDTH;
78     rect.right = Bounds().right - 15;
79     fDummyView = new BView( rect, "", B_FOLLOW_ALL_SIDES, B_WILL_DRAW );
80     fDummyView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
81     fPrefsView->AddChild( fDummyView );
82
83     /* Fill the tree */
84     vlc_list_t * p_list;
85     p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
86     if( !p_list )
87     {
88         msg_Warn( p_intf, "couldn't find any module !" );
89         return;
90     }
91
92     /* Find the main module */
93     module_t * p_module = NULL;
94     module_config_t * p_item = NULL;
95     for( int i = 0; i < p_list->i_count; i++ )
96     {
97         p_module = (module_t*) p_list->p_values[i].p_object;
98
99         if( !strcmp( p_module->psz_object_name, "main" ) &&
100             ( p_item = p_module->p_config ) )
101             break;
102         else
103             p_module = NULL;
104     }
105
106     ConfigItem * catItem = NULL, * subcatItem, * otherItem;
107
108     if( p_module )
109     {
110         /* We found the main module, build the category tree */
111         for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
112         {
113             switch( p_item->i_type )
114             {
115                 case CONFIG_CATEGORY:
116                     catItem = new ConfigItem( p_intf,
117                         config_CategoryNameGet( p_item->i_value ),
118                         false,
119                         p_item->i_value,
120                         TYPE_CATEGORY,
121                         config_CategoryHelpGet( p_item->i_value ) );
122                     fOutline->AddItem( catItem );
123                     break;
124
125                 case CONFIG_SUBCATEGORY:
126                     if( catItem )
127                     {
128                         subcatItem = new ConfigItem( p_intf,
129                             config_CategoryNameGet( p_item->i_value ),
130                             false,
131                             p_item->i_value,
132                             TYPE_SUBCATEGORY,
133                             config_CategoryHelpGet( p_item->i_value ) );
134                         fOutline->AddUnder( subcatItem, catItem );
135                     }
136                     else
137                     {
138                         msg_Warn( p_intf, "subcategory without a category" );
139                     }
140                     break;
141             }
142         }
143     }
144
145     /* Now parse all others modules */
146
147     int category, subcategory, options;
148
149     for( int i = 0; i < p_list->i_count; i++ )
150     {
151         category    = -1;
152         subcategory = -1;
153         options     = 0;
154
155         p_module = (module_t*) p_list->p_values[i].p_object;
156
157         if( !strcmp( p_module->psz_object_name, "main" ) )
158             continue;
159
160         if( p_module->b_submodule ||
161             !( p_item = p_module->p_config ) )
162             continue;
163
164         for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
165         {
166             switch( p_item->i_type )
167             {
168                 case CONFIG_CATEGORY:
169                     category = p_item->i_value;
170                     break;
171                 case CONFIG_SUBCATEGORY:
172                     subcategory = p_item->i_value;
173                     break;
174                 default:
175                     if( p_item->i_type & CONFIG_ITEM )
176                         options++;
177             }
178             if( options > 0 && category >= 0 && subcategory >= 0 )
179             {
180                 break;
181             }
182         }
183
184         if( options < 1 || category < 0 || subcategory < 0 )
185             continue;
186
187         catItem = NULL;
188         for( int j = 0; j < fOutline->CountItemsUnder( NULL, true ); j++ )
189         {
190             catItem = (ConfigItem*)
191                 fOutline->ItemUnderAt( NULL, true, j );
192             if( catItem->ObjectId() == category )
193                 break;
194             else
195                 catItem = NULL;
196         }
197
198         if( !catItem )
199             continue;
200
201         subcatItem = NULL;
202         for( int j = 0; j < fOutline->CountItemsUnder( catItem, true ); j++ )
203         {
204             subcatItem = (ConfigItem*)
205                 fOutline->ItemUnderAt( catItem, true, j );
206             if( subcatItem->ObjectId() == subcategory )
207                 break;
208             else
209                 subcatItem = NULL;
210         }
211
212         if( !subcatItem )
213             subcatItem = catItem;
214
215         otherItem = new ConfigItem( p_intf,
216             p_module->psz_shortname ?
217               p_module->psz_shortname : p_module->psz_object_name,
218             p_module->b_submodule,
219             p_module->b_submodule ?
220               ((module_t *)p_module->p_parent)->i_object_id :
221               p_module->i_object_id,
222             TYPE_MODULE,
223             NULL );
224         fOutline->AddUnder( otherItem, subcatItem );
225     }
226
227     vlc_list_release( p_list );
228
229     /* Collapse the whole tree */
230     for( int i = 0; i < fOutline->FullListCountItems(); i++ )
231     {
232         otherItem = (ConfigItem *) fOutline->FullListItemAt( i );
233         fOutline->Collapse( otherItem );
234     }
235
236     /* Set the correct values */
237     Apply( false );
238
239     /* Select the first item */
240     fOutline->Select( 0 );
241
242     /* Add the buttons */
243     BButton * button;
244     rect = Bounds();
245     rect.InsetBy( 10, 10 );
246     rect.left = rect.right - 80;
247     rect.top = rect.bottom - 25;
248     button = new BButton( rect, "", _("Apply"), new BMessage( PREFS_APPLY ),
249                           B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
250     button->MakeDefault( true );
251     fPrefsView->AddChild( button );
252     rect.OffsetBy( -90, 0 );
253     button = new BButton( rect, "", _("Save"), new BMessage( PREFS_SAVE ),
254                           B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
255     fPrefsView->AddChild( button );
256     rect.OffsetBy( -90, 0 );
257     button = new BButton( rect, "", _("Defaults"),
258                           new BMessage( PREFS_DEFAULTS ),
259                           B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
260     fPrefsView->AddChild( button );
261
262     Hide();
263     Show();
264 }
265
266 /*****************************************************************************
267  * PreferencesWindow::~PreferencesWindow
268  *****************************************************************************/
269 PreferencesWindow::~PreferencesWindow()
270 {
271 }
272
273 /*****************************************************************************
274  * PreferencesWindow::QuitRequested
275  *****************************************************************************/
276 bool PreferencesWindow::QuitRequested()
277 {
278     if( !IsHidden() )
279     {
280         Hide();
281     }
282     return false;
283 }
284
285 /*****************************************************************************
286  * PreferencesWindow::MessageReceived
287  *****************************************************************************/
288 void PreferencesWindow::MessageReceived( BMessage * message )
289 {
290     switch( message->what )
291     {
292         case PREFS_ITEM_SELECTED:
293             Update();
294             break;
295
296         case PREFS_DEFAULTS:
297             config_ResetAll( p_intf );
298             config_SaveConfigFile( p_intf, NULL );
299             Apply( false );
300             break;
301
302         case PREFS_APPLY:
303             Apply( true );
304             break;
305
306         case PREFS_SAVE:
307             Apply( true );
308             config_SaveConfigFile( p_intf, NULL );
309             break;
310
311         default:
312             BWindow::MessageReceived( message );
313     }
314 }
315
316 /*****************************************************************************
317  * PreferencesWindow::FrameResized
318  *****************************************************************************/
319 void PreferencesWindow::FrameResized( float width, float height )
320 {
321     BWindow::FrameResized( width, height );
322     fCurrent->UpdateScrollBar();
323 }
324
325 /*****************************************************************************
326  * PreferencesWindow::Update
327  *****************************************************************************/
328 void PreferencesWindow::Update()
329 {
330     /* Get the selected item, if any */
331     if( fOutline->CurrentSelection() < 0 )
332         return;
333
334     /* Detach the old box if any */
335     if( fCurrent )
336     {
337         fCurrent->ResetScroll();
338         fDummyView->RemoveChild( fCurrent->Box() );
339     }
340
341     /* Add the new one... */
342     fCurrent = (ConfigItem *)
343         fOutline->ItemAt( fOutline->CurrentSelection() );
344     fDummyView->AddChild( fCurrent->Box() );
345
346     /* ...then resize it (we must resize it after it's attached or the
347        children don't get adjusted) */
348     fCurrent->Box()->ResizeTo( fDummyView->Bounds().Width(),
349                                fDummyView->Bounds().Height() );
350     fCurrent->UpdateScrollBar();
351 }
352
353 /*****************************************************************************
354  * PreferencesWindow::Apply
355  * Apply changes if doIt is true, revert them otherwise
356  *****************************************************************************/
357 void PreferencesWindow::Apply( bool doIt )
358 {
359     ConfigItem * item;
360
361     for( int i = 0; i < fOutline->FullListCountItems(); i++ )
362     {
363         item = (ConfigItem*) fOutline->FullListItemAt( i );
364         item->Apply( doIt );
365     }
366 }
367
368 /*****************************************************************************
369  * PreferencesWindow::ReallyQuit
370  *****************************************************************************/
371 void PreferencesWindow::ReallyQuit()
372 {
373     Lock();
374     Hide();
375     Quit();
376 }
377
378 /***********************************************************************
379  * ConfigItem::ConfigItem
380  ***********************************************************************
381  *
382  **********************************************************************/
383 ConfigItem::ConfigItem( intf_thread_t * _p_intf, char * name,
384                         bool subModule, int objectId,
385                         int type, char * help )
386     : BStringItem( name )
387 {
388     p_intf     = _p_intf;
389     fSubModule = subModule;
390     fObjectId  = objectId;
391     fType      = type;
392     fHelp      = strdup( help );
393
394     BRect r;
395     r = BRect( 0, 0, 100, 100 );
396     fBox = new BBox( r, NULL, B_FOLLOW_ALL );
397     fBox->SetLabel( name );
398
399     fTextView = NULL;
400     fScroll   = NULL;
401     fView     = NULL;
402
403     if( fType == TYPE_CATEGORY )
404     {
405         /* Category: we just show the help text */
406         r = fBox->Bounds();
407         r.InsetBy( 10, 10 );
408         r.top += 5;
409
410         fTextView = new VTextView( r, NULL, B_FOLLOW_ALL, B_WILL_DRAW);
411         fTextView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
412         fTextView->MakeEditable( false );
413         fTextView->MakeSelectable( false );
414         fTextView->Insert( fHelp );
415         fBox->AddChild( fTextView );
416
417         return;
418     }
419
420     vlc_list_t * p_list = NULL;
421     module_t * p_module = NULL;
422     if( fType == TYPE_MODULE )
423     {
424         p_module = (module_t *) vlc_object_get( p_intf, fObjectId );
425     }
426     else
427     {
428         if( !( p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE,
429                                        FIND_ANYWHERE ) ) )
430         {
431             return;
432         }
433         for( int i = 0; i < p_list->i_count; i++ )
434         {
435             p_module = (module_t*) p_list->p_values[i].p_object;
436
437             if( !strcmp( p_module->psz_object_name, "main" ) )
438                 break;
439             else
440                 p_module = NULL;
441         }
442     }
443
444     if( !p_module || p_module->i_object_type != VLC_OBJECT_MODULE )
445     {
446         /* Shouldn't happen */
447         return;
448     }
449
450     module_config_t * p_item;
451     p_item = fSubModule ? ((module_t *)p_module->p_parent)->p_config :
452                p_module->p_config;
453
454     if( fType == TYPE_SUBCATEGORY )
455     {
456         for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
457         {
458             if( p_item->i_type == CONFIG_SUBCATEGORY &&
459                 p_item->i_value == fObjectId )
460             {
461                 break;
462             }
463         }
464     }
465
466     r = fBox->Bounds();
467     r = BRect( 10,20,fBox->Bounds().right-B_V_SCROLL_BAR_WIDTH-10,
468                fBox->Bounds().bottom-10 );
469     fView = new BView( r, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
470                        B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE );
471     fView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
472
473     r = fView->Bounds();
474     r.InsetBy( 10,10 );
475
476     ConfigWidget * widget;
477     for( ; p_item->i_type != CONFIG_HINT_END; p_item++ )
478     {
479         if( ( p_item->i_type == CONFIG_CATEGORY ||
480               p_item->i_type == CONFIG_SUBCATEGORY ) &&
481             fType == TYPE_SUBCATEGORY &&
482             p_item->i_value != fObjectId )
483         {
484             break;
485         }
486
487         widget = new ConfigWidget( p_intf, r, p_item );
488         if( !widget->InitCheck() )
489         {
490             delete widget;
491             continue;
492         }
493         fView->AddChild( widget );
494         r.top += widget->Bounds().Height();
495     }
496
497     if( fType == TYPE_MODULE )
498     {
499         vlc_object_release( p_module );
500     }
501     else
502     {
503         vlc_list_release( p_list );
504     }
505
506     /* Create a scroll view around our fView */
507     fScroll = new BScrollView( NULL, fView, B_FOLLOW_ALL, 0, false,
508                                true, B_FANCY_BORDER );
509     fScroll->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
510     fBox->AddChild( fScroll );
511
512     /* Adjust fView's height to the size it actually needs (we do this
513        only now so the BScrollView fits the BBox) */
514     fView->ResizeTo( fView->Bounds().Width(), r.top + 10 );
515 }
516
517 /***********************************************************************
518  * ConfigItem::~ConfigItem
519  ***********************************************************************
520  *
521  **********************************************************************/
522 ConfigItem::~ConfigItem()
523 {
524     if( fHelp )
525     {
526         free( fHelp );
527     }
528 }
529
530 /*****************************************************************************
531  * ConfigItem::UpdateScrollBar
532  *****************************************************************************/
533 void ConfigItem::UpdateScrollBar()
534 {
535     /* We have to fix the scrollbar manually because it doesn't handle
536        correctly simple BViews */
537
538     if( !fScroll )
539     {
540         return;
541     }
542
543     /* Get the available BRect for display */
544     BRect display = fScroll->Bounds();
545     display.right -= B_V_SCROLL_BAR_WIDTH;
546
547     /* Fix the scrollbar */
548     BScrollBar * scrollBar;
549     BRect visible = display & fView->Bounds();
550     BRect total   = display | fView->Bounds();
551     scrollBar = fScroll->ScrollBar( B_VERTICAL );
552     long max = (long)( fView->Bounds().Height() - visible.Height() );
553     if( max < 0 ) max = 0;
554     scrollBar->SetRange( 0, max );
555     scrollBar->SetProportion( visible.Height() / total.Height() );
556     scrollBar->SetSteps( 10, 100 );
557
558     /* We have to force redraw to avoid visual bugs when resizing
559        (BeOS bug?) */
560     fScroll->Invalidate();
561     fView->Invalidate();
562 }
563
564 /*****************************************************************************
565  * ConfigItem::ResetScroll
566  *****************************************************************************/
567 void ConfigItem::ResetScroll()
568 {
569     if( !fScroll )
570     {
571         return;
572     }
573
574     fView->ScrollTo( 0, 0 );
575 }
576
577 /***********************************************************************
578  * ConfigItem::Apply
579  ***********************************************************************
580  *
581  **********************************************************************/
582 void ConfigItem::Apply( bool doIt )
583 {
584     if( !fScroll )
585     {
586         return;
587     }
588
589     /* Call ConfigWidget::Apply for every child of your fView */
590     ConfigWidget * widget;
591     for( int i = 0; i < fView->CountChildren(); i++ )
592     {
593         widget = (ConfigWidget*) fView->ChildAt( i );
594         widget->Apply( doIt );
595     }
596 }
597
598 /***********************************************************************
599  * ConfigWidget::ConfigWidget
600  ***********************************************************************
601  * Builds a view with the right controls for the given config variable.
602  *  rect: the BRect where we place ourselves. All we care is its width
603  *    and its top coordinate, since we adapt our height to take only
604  *    the place we need
605  **********************************************************************/
606 ConfigWidget::ConfigWidget( intf_thread_t * _p_intf, BRect rect,
607                             module_config_t * p_item )
608     : BView( rect, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP,
609              B_WILL_DRAW )
610 {
611     p_intf = _p_intf;
612
613     SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) );
614
615     BRect r;
616     BMenuItem * menuItem;
617     /* Skip deprecated options */
618     if( p_item->psz_current )
619     {
620         fInitOK = false;
621         return;
622     }
623
624     fInitOK = true;
625
626     fType = p_item->i_type;
627     fName = strdup( p_item->psz_name );
628
629     switch( fType )
630     {
631         case CONFIG_ITEM_MODULE:
632         case CONFIG_ITEM_MODULE_CAT:
633         case CONFIG_ITEM_MODULE_LIST_CAT:
634         case CONFIG_ITEM_STRING:
635         case CONFIG_ITEM_FILE:
636         case CONFIG_ITEM_DIRECTORY:
637         case CONFIG_ITEM_INTEGER:
638         case CONFIG_ITEM_FLOAT:
639             ResizeTo( Bounds().Width(), 25 );
640             fTextControl = new VTextControl( Bounds(), NULL,
641                 p_item->psz_text, NULL, new BMessage(),
642                 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
643             AddChild( fTextControl );
644             break;
645         case CONFIG_ITEM_KEY:
646             ResizeTo( Bounds().Width(), 25 );
647             r = Bounds();
648             r.left = r.right - 100;
649             fPopUpMenu = new BPopUpMenu( "" );
650             fMenuField = new BMenuField( r, NULL, NULL, fPopUpMenu,
651                 B_FOLLOW_RIGHT | B_FOLLOW_TOP );
652             for( unsigned i = 0;
653                  i < sizeof( vlc_keys ) / sizeof( key_descriptor_t );
654                  i++ )
655             {
656                 menuItem = new BMenuItem( vlc_keys[i].psz_key_string, NULL );
657                 fPopUpMenu->AddItem( menuItem );
658             }
659             r.right = r.left - 10; r.left = r.left - 60;
660             fShiftCheck = new BCheckBox( r, NULL, "Shift",
661                 new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP );
662             r.right = r.left - 10; r.left = r.left - 60;
663             fCtrlCheck = new BCheckBox( r, NULL, "Ctrl",
664                 new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP );
665             r.right = r.left - 10; r.left = r.left - 60;
666             fAltCheck = new BCheckBox( r, NULL, "Alt",
667                 new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP );
668             r.right = r.left - 10; r.left = 0; r.bottom -= 10;
669             fStringView = new BStringView( r, NULL, p_item->psz_text,
670                 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
671             AddChild( fStringView );
672             AddChild( fAltCheck );
673             AddChild( fCtrlCheck );
674             AddChild( fShiftCheck );
675             AddChild( fMenuField );
676             break;
677         case CONFIG_ITEM_BOOL:
678             ResizeTo( Bounds().Width(), 25 );
679             fCheckBox = new BCheckBox( Bounds(), NULL, p_item->psz_text,
680                 new BMessage(), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
681             AddChild( fCheckBox );
682             break;
683         case CONFIG_SECTION:
684             fInitOK = false;
685             break;
686         default:
687             fInitOK = false;
688     }
689 }
690
691 ConfigWidget::~ConfigWidget()
692 {
693     free( fName );
694 }
695
696 /***********************************************************************
697  * ConfigWidget::Apply
698  ***********************************************************************
699  *
700  **********************************************************************/
701 void ConfigWidget::Apply( bool doIt )
702 {
703     BMenuItem * menuItem;
704     char string[256];
705     vlc_value_t val;
706
707     switch( fType )
708     {
709         case CONFIG_ITEM_STRING:
710         case CONFIG_ITEM_FILE:
711         case CONFIG_ITEM_MODULE:
712         case CONFIG_ITEM_MODULE_CAT:
713         case CONFIG_ITEM_MODULE_LIST_CAT:
714         case CONFIG_ITEM_DIRECTORY:
715             if( doIt )
716             {
717                 config_PutPsz( p_intf, fName, fTextControl->Text() );
718             }
719             else
720             {
721                 fTextControl->SetText( config_GetPsz( p_intf, fName ) );
722             }
723             break;
724
725         case CONFIG_ITEM_INTEGER:
726             if( doIt )
727             {
728                 config_PutInt( p_intf, fName, atoi( fTextControl->Text() ) );
729             }
730             else
731             {
732                 snprintf( string, 256, "%d", config_GetInt( p_intf, fName ) );
733                 fTextControl->SetText( string );
734             }
735             break;
736
737         case CONFIG_ITEM_FLOAT:
738             if( doIt )
739             {
740                 config_PutFloat( p_intf, fName, atof( fTextControl->Text() ) );
741             }
742             else
743             {
744                 snprintf( string, 256, "%f", config_GetFloat( p_intf, fName ) );
745                 fTextControl->SetText( string );
746             }
747             break;
748
749         case CONFIG_ITEM_KEY:
750             if( doIt )
751             {
752                 menuItem = fPopUpMenu->FindMarked();
753                 if( menuItem )
754                 {
755                     val.i_int = vlc_keys[fPopUpMenu->IndexOf( menuItem )].i_key_code;
756                     if( fAltCheck->Value() )
757                     {
758                         val.i_int |= KEY_MODIFIER_ALT;
759                     }
760                     if( fCtrlCheck->Value() )
761                     {
762                         val.i_int |= KEY_MODIFIER_CTRL;
763                     }
764                     if( fShiftCheck->Value() )
765                     {
766                         val.i_int |= KEY_MODIFIER_SHIFT;
767                     }
768                     var_Set( p_intf->p_libvlc, fName, val );
769                 }
770             }
771             else
772             {
773                 val.i_int = config_GetInt( p_intf, fName );
774                 fAltCheck->SetValue( val.i_int & KEY_MODIFIER_ALT );
775                 fCtrlCheck->SetValue( val.i_int & KEY_MODIFIER_CTRL );
776                 fShiftCheck->SetValue( val.i_int & KEY_MODIFIER_SHIFT );
777         
778                 for( unsigned i = 0;
779                      i < sizeof( vlc_keys ) / sizeof( key_descriptor_t ); i++ )
780                 {
781                     if( (unsigned) vlc_keys[i].i_key_code ==
782                             ( val.i_int & ~KEY_MODIFIER ) )
783                     {
784                         menuItem = fPopUpMenu->ItemAt( i );
785                         menuItem->SetMarked( true );
786                         break;
787                     }
788                 }
789             }
790             break;
791
792         case CONFIG_ITEM_BOOL:
793             if( doIt )
794             {
795                 config_PutInt( p_intf, fName, fCheckBox->Value() );
796             }
797             else
798             {
799                 fCheckBox->SetValue( config_GetInt( p_intf, fName ) );
800             }
801             break;
802
803         default:
804             break;
805     }
806 }
807
808 VTextView::VTextView( BRect frame, const char *name,
809                       uint32 resizingMode, uint32 flags )
810     : BTextView( frame, name, BRect( 10,10,10,10 ), resizingMode, flags )
811 {
812     FrameResized( Bounds().Width(), Bounds().Height() );
813 }
814
815 void VTextView::FrameResized( float width, float height )
816 {
817     BTextView::FrameResized( width, height );
818     SetTextRect( BRect( 10,10, width-11, height-11 ) );
819 }
820
821 VTextControl::VTextControl( BRect frame, const char *name,
822                             const char *label, const char *text,
823                             BMessage * message, uint32 resizingMode )
824     : BTextControl( frame, name, label, text, message, resizingMode )
825 {
826     FrameResized( Bounds().Width(), Bounds().Height() );
827 }
828
829 void VTextControl::FrameResized( float width, float height )
830 {
831     BTextControl::FrameResized( width, height );
832     SetDivider( width / 2 );
833 }