X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fbeos%2FPreferencesWindow.cpp;h=248741a40d579d1515337adc36034ed612f3c478;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=44a496046a98d1999e917647671894080eb1e8a1;hpb=d59b2b177ad378ad8893c291a130614ad03413e9;p=vlc diff --git a/modules/gui/beos/PreferencesWindow.cpp b/modules/gui/beos/PreferencesWindow.cpp index 44a496046a..248741a40d 100644 --- a/modules/gui/beos/PreferencesWindow.cpp +++ b/modules/gui/beos/PreferencesWindow.cpp @@ -1,10 +1,10 @@ /***************************************************************************** * PreferencesWindow.cpp: beos interface ***************************************************************************** - * Copyright (C) 1999, 2000, 2001 VideoLAN - * $Id: PreferencesWindow.cpp,v 1.24 2003/05/25 17:21:36 titer Exp $ + * Copyright (C) 1999, 2000, 2001 the VideoLAN team + * $Id$ * - * Authors: Eric Petit + * Authors: Eric Petit * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,72 +18,61 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ -#include /* atoi(), strtod() */ + +#include #include -#include +#include +#include +#include #include "PreferencesWindow.h" -/* TODO: - - add the needed LockLooper()s - - fix horizontal window resizing */ - -/* We use this function to order the items of the BOutlineView */ -int compare_func( const BListItem * _first, const BListItem * _second ) -{ - StringItemWithView * first = (StringItemWithView*) _first; - StringItemWithView * second = (StringItemWithView*) _second; - - /* The Modules tree at last */ - if( !strcmp( first->Text(), _( "Modules" ) ) ) - return 1; - if( !strcmp( second->Text(), _( "Modules" ) ) ) - return -1; - - /* alphabetic order */ - return( strcmp( first->Text(), second->Text() ) ); -} +#define TYPE_CATEGORY 0 +#define TYPE_SUBCATEGORY 2 +#define TYPE_MODULE 3 /***************************************************************************** * PreferencesWindow::PreferencesWindow *****************************************************************************/ -PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface, +PreferencesWindow::PreferencesWindow( intf_thread_t * _p_intf, BRect frame, const char * name ) : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL, - B_NOT_ZOOMABLE | B_NOT_H_RESIZABLE ), - fConfigScroll( NULL ), - p_intf( p_interface ) + B_NOT_ZOOMABLE ) { - SetSizeLimits( PREFS_WINDOW_WIDTH, PREFS_WINDOW_WIDTH, - 200, 2000 ); + p_intf = _p_intf; + fCurrent = NULL; BRect rect; + SetSizeLimits( PREFS_WINDOW_WIDTH, 2000, PREFS_WINDOW_HEIGHT, 2000 ); + /* The "background" view */ fPrefsView = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW ); fPrefsView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); AddChild( fPrefsView ); - /* Create the preferences tree */ + /* Create a scrollable outline view for the preferences tree */ rect = Bounds(); rect.InsetBy( 10, 10 ); rect.right = rect.left + 150; fOutline = new BOutlineListView( rect, "preferences tree", B_SINGLE_SELECTION_LIST, B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM ); - BScrollView * scrollview = new BScrollView( "scrollview", fOutline, - B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, - 0, false, true ); + BScrollView * scrollview = + new BScrollView( "scrollview", fOutline, + B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM, + 0, false, true ); fPrefsView->AddChild( scrollview ); /* We need to be informed if the user selects an item */ fOutline->SetSelectionMessage( new BMessage( PREFS_ITEM_SELECTED ) ); - /* Create a dummy view so we can correctly place the real config views later */ + /* Create a dummy, empty view so we can correctly place the real + config views later */ rect.bottom -= 40; rect.left = rect.right + 15 + B_V_SCROLL_BAR_WIDTH; rect.right = Bounds().right - 15; @@ -91,11 +80,6 @@ PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface, fDummyView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); fPrefsView->AddChild( fDummyView ); - /* Add a category for modules configuration */ - StringItemWithView * modulesItem; - modulesItem = new StringItemWithView( _("Modules") ); - fOutline->AddItem( modulesItem ); - /* Fill the tree */ vlc_list_t * p_list; p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE ); @@ -105,9 +89,9 @@ PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface, return; } - /* First, handle the main module */ + /* Find the main module */ module_t * p_module = NULL; - module_config_t * p_item; + module_config_t * p_item = NULL; for( int i = 0; i < p_list->i_count; i++ ) { p_module = (module_t*) p_list->p_values[i].p_object; @@ -119,91 +103,138 @@ PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface, p_module = NULL; } + ConfigItem * catItem = NULL, * subcatItem, * otherItem; + if( p_module ) { - /* We found the main module */ - while( p_item->i_type == CONFIG_HINT_CATEGORY ) + /* We found the main module, build the category tree */ + for( ; p_item->i_type != CONFIG_HINT_END; p_item++ ) { - StringItemWithView * stringItem; - stringItem = new StringItemWithView( p_item->psz_text ); - p_item++; - BuildConfigView( stringItem, &p_item, true ); - fOutline->AddItem( stringItem ); + switch( p_item->i_type ) + { + case CONFIG_CATEGORY: + catItem = new ConfigItem( p_intf, + config_CategoryNameGet( p_item->i_value ), + false, + p_item->i_value, + TYPE_CATEGORY, + config_CategoryHelpGet( p_item->i_value ) ); + fOutline->AddItem( catItem ); + break; + + case CONFIG_SUBCATEGORY: + if( catItem ) + { + subcatItem = new ConfigItem( p_intf, + config_CategoryNameGet( p_item->i_value ), + false, + p_item->i_value, + TYPE_SUBCATEGORY, + config_CategoryHelpGet( p_item->i_value ) ); + fOutline->AddUnder( subcatItem, catItem ); + } + else + { + msg_Warn( p_intf, "subcategory without a category" ); + } + break; + } } } + /* Now parse all others modules */ + + int category, subcategory, options; + for( int i = 0; i < p_list->i_count; i++ ) { + category = -1; + subcategory = -1; + options = 0; + p_module = (module_t*) p_list->p_values[i].p_object; if( !strcmp( p_module->psz_object_name, "main" ) ) continue; - /* If the module has no config option, ignore it */ - p_item = p_module->p_config; - if( !p_item ) - continue; - do { - if( p_item->i_type & CONFIG_ITEM ) - break; - } while( p_item->i_type != CONFIG_HINT_END && p_item++ ); - if( p_item->i_type == CONFIG_HINT_END ) + if( p_module->b_submodule || + !( p_item = p_module->p_config ) ) continue; - /* Create the capability tree if it doesn't already exist */ - char * psz_capability; - psz_capability = p_module->psz_capability; - if( !psz_capability || !*psz_capability ) + for( ; p_item->i_type != CONFIG_HINT_END; p_item++ ) { - /* Empty capability ? Let's look at the submodules */ - module_t * p_submodule; - for( int j = 0; j < p_module->i_children; j++ ) + switch( p_item->i_type ) { - p_submodule = (module_t*)p_module->pp_children[ j ]; - if( p_submodule->psz_capability && *p_submodule->psz_capability ) - { - psz_capability = p_submodule->psz_capability; + case CONFIG_CATEGORY: + category = p_item->i_value; break; - } + case CONFIG_SUBCATEGORY: + subcategory = p_item->i_value; + break; + default: + if( p_item->i_type & CONFIG_ITEM ) + options++; + } + if( options > 0 && category >= 0 && subcategory >= 0 ) + { + break; } } - StringItemWithView * capabilityItem; - capabilityItem = NULL; - for( int j = 0; j < fOutline->CountItemsUnder( modulesItem, true ); j++ ) + if( options < 1 || category < 0 || subcategory < 0 ) + continue; + + catItem = NULL; + for( int j = 0; j < fOutline->CountItemsUnder( NULL, true ); j++ ) { - if( !strcmp( ((StringItemWithView*) - fOutline->ItemUnderAt( modulesItem, true, j ))->Text(), - psz_capability ) ) - { - capabilityItem = (StringItemWithView*) - fOutline->ItemUnderAt( modulesItem, true, j ); + catItem = (ConfigItem*) + fOutline->ItemUnderAt( NULL, true, j ); + if( catItem->ObjectId() == category ) break; - } + else + catItem = NULL; } - if( !capabilityItem ) + + if( !catItem ) + continue; + + subcatItem = NULL; + for( int j = 0; j < fOutline->CountItemsUnder( catItem, true ); j++ ) { - capabilityItem = new StringItemWithView( psz_capability ); - fOutline->AddUnder( capabilityItem, modulesItem ); + subcatItem = (ConfigItem*) + fOutline->ItemUnderAt( catItem, true, j ); + if( subcatItem->ObjectId() == subcategory ) + break; + else + subcatItem = NULL; } - /* Now add the item ! */ - StringItemWithView * stringItem; - stringItem = new StringItemWithView( p_module->psz_object_name ); - BuildConfigView( stringItem, &p_item, false ); - fOutline->AddUnder( stringItem, capabilityItem ); + if( !subcatItem ) + subcatItem = catItem; + + otherItem = new ConfigItem( p_intf, + p_module->psz_shortname ? + p_module->psz_shortname : p_module->psz_object_name, + p_module->b_submodule, + p_module->b_submodule ? + ((module_t *)p_module->p_parent)->i_object_id : + p_module->i_object_id, + TYPE_MODULE, + NULL ); + fOutline->AddUnder( otherItem, subcatItem ); } vlc_list_release( p_list ); - /* Set the correct values */ - ApplyChanges( false ); + /* Collapse the whole tree */ + for( int i = 0; i < fOutline->FullListCountItems(); i++ ) + { + otherItem = (ConfigItem *) fOutline->FullListItemAt( i ); + fOutline->Collapse( otherItem ); + } - /* Sort items, collapse the tree */ - fOutline->FullListSortItems( compare_func ); - fOutline->Collapse( modulesItem ); - for( int i = 0; i < fOutline->CountItemsUnder( modulesItem, true ); i++ ) - fOutline->Collapse( fOutline->ItemUnderAt( modulesItem, true, i ) ); + /* Set the correct values */ + Apply( false ); /* Select the first item */ fOutline->Select( 0 ); @@ -223,7 +254,8 @@ PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface, B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM ); fPrefsView->AddChild( button ); rect.OffsetBy( -90, 0 ); - button = new BButton( rect, "", _("Defaults"), new BMessage( PREFS_DEFAULTS ), + button = new BButton( rect, "", _("Defaults"), + new BMessage( PREFS_DEFAULTS ), B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM ); fPrefsView->AddChild( button ); @@ -244,8 +276,10 @@ PreferencesWindow::~PreferencesWindow() bool PreferencesWindow::QuitRequested() { if( !IsHidden() ) + { Hide(); - return false; + } + return false; } /***************************************************************************** @@ -261,15 +295,17 @@ void PreferencesWindow::MessageReceived( BMessage * message ) case PREFS_DEFAULTS: config_ResetAll( p_intf ); - ApplyChanges( false ); + config_SaveConfigFile( p_intf, NULL ); + Apply( false ); break; case PREFS_APPLY: - ApplyChanges( true ); + Apply( true ); break; case PREFS_SAVE: - SaveChanges(); + Apply( true ); + config_SaveConfigFile( p_intf, NULL ); break; default: @@ -283,8 +319,7 @@ void PreferencesWindow::MessageReceived( BMessage * message ) void PreferencesWindow::FrameResized( float width, float height ) { BWindow::FrameResized( width, height ); - - UpdateScrollBar(); + fCurrent->UpdateScrollBar(); } /***************************************************************************** @@ -295,342 +330,504 @@ void PreferencesWindow::Update() /* Get the selected item, if any */ if( fOutline->CurrentSelection() < 0 ) return; - fCurrent = (StringItemWithView*) + + /* Detach the old box if any */ + if( fCurrent ) + { + fCurrent->ResetScroll(); + fDummyView->RemoveChild( fCurrent->Box() ); + } + + /* Add the new one... */ + fCurrent = (ConfigItem *) fOutline->ItemAt( fOutline->CurrentSelection() ); + fDummyView->AddChild( fCurrent->Box() ); + + /* ...then resize it (we must resize it after it's attached or the + children don't get adjusted) */ + fCurrent->Box()->ResizeTo( fDummyView->Bounds().Width(), + fDummyView->Bounds().Height() ); + fCurrent->UpdateScrollBar(); +} + +/***************************************************************************** + * PreferencesWindow::Apply + * Apply changes if doIt is true, revert them otherwise + *****************************************************************************/ +void PreferencesWindow::Apply( bool doIt ) +{ + ConfigItem * item; + + for( int i = 0; i < fOutline->FullListCountItems(); i++ ) + { + item = (ConfigItem*) fOutline->FullListItemAt( i ); + item->Apply( doIt ); + } +} + +/***************************************************************************** + * PreferencesWindow::ReallyQuit + *****************************************************************************/ +void PreferencesWindow::ReallyQuit() +{ + Lock(); + Hide(); + Quit(); +} + +/*********************************************************************** + * ConfigItem::ConfigItem + *********************************************************************** + * + **********************************************************************/ +ConfigItem::ConfigItem( intf_thread_t * _p_intf, char * name, + bool subModule, int objectId, + int type, char * help ) + : BStringItem( name ) +{ + p_intf = _p_intf; + fSubModule = subModule; + fObjectId = objectId; + fType = type; + fHelp = strdup( help ); + + BRect r; + r = BRect( 0, 0, 100, 100 ); + fBox = new BBox( r, NULL, B_FOLLOW_ALL ); + fBox->SetLabel( name ); + + fTextView = NULL; + fScroll = NULL; + fView = NULL; + + if( fType == TYPE_CATEGORY ) + { + /* Category: we just show the help text */ + r = fBox->Bounds(); + r.InsetBy( 10, 10 ); + r.top += 5; + + fTextView = new VTextView( r, NULL, B_FOLLOW_ALL, B_WILL_DRAW); + fTextView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); + fTextView->MakeEditable( false ); + fTextView->MakeSelectable( false ); + fTextView->Insert( fHelp ); + fBox->AddChild( fTextView ); + + return; + } + + vlc_list_t * p_list = NULL; + module_t * p_module = NULL; + if( fType == TYPE_MODULE ) + { + p_module = (module_t *) vlc_object_get( p_intf, fObjectId ); + } + else + { + if( !( p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, + FIND_ANYWHERE ) ) ) + { + return; + } + for( int i = 0; i < p_list->i_count; i++ ) + { + p_module = (module_t*) p_list->p_values[i].p_object; + + if( !strcmp( p_module->psz_object_name, "main" ) ) + break; + else + p_module = NULL; + } + } - if( !fCurrent->fConfigBox ) - /* This is a category */ + if( !p_module || p_module->i_object_type != VLC_OBJECT_MODULE ) + { + /* Shouldn't happen */ return; + } + + module_config_t * p_item; + p_item = fSubModule ? ((module_t *)p_module->p_parent)->p_config : + p_module->p_config; + + if( fType == TYPE_SUBCATEGORY ) + { + for( ; p_item->i_type != CONFIG_HINT_END; p_item++ ) + { + if( p_item->i_type == CONFIG_SUBCATEGORY && + p_item->i_value == fObjectId ) + { + break; + } + } + } + + r = fBox->Bounds(); + r = BRect( 10,20,fBox->Bounds().right-B_V_SCROLL_BAR_WIDTH-10, + fBox->Bounds().bottom-10 ); + fView = new BView( r, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, + B_WILL_DRAW | B_FULL_UPDATE_ON_RESIZE ); + fView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); + + r = fView->Bounds(); + r.InsetBy( 10,10 ); + + ConfigWidget * widget; + for( ; p_item->i_type != CONFIG_HINT_END; p_item++ ) + { + if( ( p_item->i_type == CONFIG_CATEGORY || + p_item->i_type == CONFIG_SUBCATEGORY ) && + fType == TYPE_SUBCATEGORY && + p_item->i_value != fObjectId ) + { + break; + } + + widget = new ConfigWidget( p_intf, r, p_item ); + if( !widget->InitCheck() ) + { + delete widget; + continue; + } + fView->AddChild( widget ); + r.top += widget->Bounds().Height(); + } + + if( fType == TYPE_MODULE ) + { + vlc_object_release( p_module ); + } + else + { + vlc_list_release( p_list ); + } - /* Detach the old item */ - if( fDummyView->CountChildren() > 0 ) - fDummyView->RemoveChild( fDummyView->ChildAt( 0 ) ); - - /* Resize and show the new config box */ - fCurrent->fConfigBox->ResizeTo( fDummyView->Bounds().Width(), - fDummyView->Bounds().Height() ); - fDummyView->AddChild( fCurrent->fConfigBox ); - - /* Force redrawing of its children */ - BRect rect = fCurrent->fConfigBox->Bounds(); - rect.InsetBy( 10,10 ); - rect.top += 10; - fCurrent->fConfigScroll->ResizeTo( rect.Width(), rect.Height() ); - fCurrent->fConfigScroll->Draw( fCurrent->fConfigScroll->Bounds() ); - - UpdateScrollBar(); + /* Create a scroll view around our fView */ + fScroll = new BScrollView( NULL, fView, B_FOLLOW_ALL, 0, false, + true, B_FANCY_BORDER ); + fScroll->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); + fBox->AddChild( fScroll ); + + /* Adjust fView's height to the size it actually needs (we do this + only now so the BScrollView fits the BBox) */ + fView->ResizeTo( fView->Bounds().Width(), r.top + 10 ); } +/*********************************************************************** + * ConfigItem::~ConfigItem + *********************************************************************** + * + **********************************************************************/ +ConfigItem::~ConfigItem() +{ + if( fHelp ) + { + free( fHelp ); + } +} /***************************************************************************** - * PreferencesWindow::UpdateScrollBar + * ConfigItem::UpdateScrollBar *****************************************************************************/ -void PreferencesWindow::UpdateScrollBar() +void ConfigItem::UpdateScrollBar() { /* We have to fix the scrollbar manually because it doesn't handle correctly simple BViews */ - - if( !fCurrent ) + + if( !fScroll ) + { return; + } /* Get the available BRect for display */ - BRect display = fCurrent->fConfigScroll->Bounds(); + BRect display = fScroll->Bounds(); display.right -= B_V_SCROLL_BAR_WIDTH; /* Fix the scrollbar */ BScrollBar * scrollBar; - long max; - BRect visible = display & fCurrent->fConfigView->Bounds(); - BRect total = display | fCurrent->fConfigView->Bounds(); - scrollBar = fCurrent->fConfigScroll->ScrollBar( B_VERTICAL ); - max = (long)( fCurrent->fConfigView->Bounds().Height() - visible.Height() ); + BRect visible = display & fView->Bounds(); + BRect total = display | fView->Bounds(); + scrollBar = fScroll->ScrollBar( B_VERTICAL ); + long max = (long)( fView->Bounds().Height() - visible.Height() ); if( max < 0 ) max = 0; scrollBar->SetRange( 0, max ); scrollBar->SetProportion( visible.Height() / total.Height() ); scrollBar->SetSteps( 10, 100 ); + + /* We have to force redraw to avoid visual bugs when resizing + (BeOS bug?) */ + fScroll->Invalidate(); + fView->Invalidate(); } /***************************************************************************** - * PreferencesWindow::ApplyChanges - * Apply changes if doIt is true, revert them otherwise + * ConfigItem::ResetScroll *****************************************************************************/ -void PreferencesWindow::ApplyChanges( bool doIt ) +void ConfigItem::ResetScroll() { - StringItemWithView * item; - BView * view; - BView * child; - const char * name; - BString string; - for( int i = 0; i < fOutline->CountItems(); i++ ) + if( !fScroll ) { - item = (StringItemWithView*) fOutline->ItemAt( i ); - view = item->fConfigView; + return; + } - if( !view ) - /* This is a category */ - continue; + fView->ScrollTo( 0, 0 ); +} - for( int j = 0; j < view->CountChildren(); j++ ) - { - child = view->ChildAt( j ); - name = child->Name(); - if( !strcmp( name, "ConfigTextControl" ) ) - { - ConfigTextControl * textControl; - textControl = (ConfigTextControl*) child; - switch( textControl->fConfigType ) - { - case CONFIG_ITEM_STRING: - if( doIt ) - config_PutPsz( p_intf, textControl->fConfigName, textControl->Text() ); - else - textControl->SetText( config_GetPsz( p_intf, textControl->fConfigName ) ); - break; - case CONFIG_ITEM_INTEGER: - if( doIt ) - config_PutInt( p_intf, textControl->fConfigName, atoi( textControl->Text() ) ); - else - { - string = ""; - string << config_GetInt( p_intf, textControl->fConfigName ); - textControl->SetText( string.String() ); - } - break; - case CONFIG_ITEM_FLOAT: - if( doIt ) - config_PutFloat( p_intf, textControl->fConfigName, - strtod( textControl->Text(), NULL ) ); - else - { - string = ""; - string << config_GetFloat( p_intf, textControl->fConfigName ); - textControl->SetText( string.String() ); - } - break; - } - } - else if( !strcmp( name, "ConfigCheckBox" ) ) - { - ConfigCheckBox * checkBox; - checkBox = (ConfigCheckBox*) child; - if( doIt ) - config_PutInt( p_intf, checkBox->fConfigName, checkBox->Value() ); - else - checkBox->SetValue( config_GetInt( p_intf, checkBox->fConfigName ) ); - } - else if( !strcmp( name, "ConfigMenuField" ) ) - { - ConfigMenuField * menuField; - menuField = (ConfigMenuField*) child; - BMenu * menu; - BMenuItem * menuItem; - menu = menuField->Menu(); - if( doIt ) - { - menuItem = menu->FindMarked(); - if( menuItem ) - config_PutPsz( p_intf, menuField->fConfigName, menuItem->Label() ); - } - else - { - char * value; - value = config_GetPsz( p_intf, menuField->fConfigName ); - if( !value ) value = ""; - for( int k = 0; k < menu->CountItems(); k++ ) - { - menuItem = menu->ItemAt( k ); - if( !strcmp( value, menuItem->Label() ) ) - { - menuItem->SetMarked( true ); - break; - } - } - } - } - else if( !strcmp( name, "ConfigSlider" ) ) - { - ConfigSlider * slider; - slider = (ConfigSlider*) child; - - switch( slider->fConfigType ) - { - case CONFIG_ITEM_INTEGER: - if( doIt ) - config_PutInt( p_intf, slider->fConfigName, - slider->Value() ); - else - slider->SetValue( config_GetInt( p_intf, - slider->fConfigName ) ); - break; - - case CONFIG_ITEM_FLOAT: - if( doIt ) - config_PutFloat( p_intf, slider->fConfigName, - (float)slider->Value() / 100.0 ); - else - slider->SetValue( config_GetFloat( p_intf, - slider->fConfigName ) * 100.0 ); - break; - } - } - } +/*********************************************************************** + * ConfigItem::Apply + *********************************************************************** + * + **********************************************************************/ +void ConfigItem::Apply( bool doIt ) +{ + if( !fScroll ) + { + return; + } + + /* Call ConfigWidget::Apply for every child of your fView */ + ConfigWidget * widget; + for( int i = 0; i < fView->CountChildren(); i++ ) + { + widget = (ConfigWidget*) fView->ChildAt( i ); + widget->Apply( doIt ); } } -/***************************************************************************** - * PreferencesWindow::SaveChanges - *****************************************************************************/ -void PreferencesWindow::SaveChanges() +/*********************************************************************** + * ConfigWidget::ConfigWidget + *********************************************************************** + * Builds a view with the right controls for the given config variable. + * rect: the BRect where we place ourselves. All we care is its width + * and its top coordinate, since we adapt our height to take only + * the place we need + **********************************************************************/ +ConfigWidget::ConfigWidget( intf_thread_t * _p_intf, BRect rect, + module_config_t * p_item ) + : BView( rect, NULL, B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, + B_WILL_DRAW ) { - ApplyChanges( true ); - config_SaveConfigFile( p_intf, NULL ); + p_intf = _p_intf; + + SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); + + BRect r; + BMenuItem * menuItem; + /* Skip deprecated options */ + if( p_item->psz_current ) + { + fInitOK = false; + return; + } + + fInitOK = true; + + fType = p_item->i_type; + fName = strdup( p_item->psz_name ); + + switch( fType ) + { + case CONFIG_ITEM_MODULE: + case CONFIG_ITEM_MODULE_CAT: + case CONFIG_ITEM_MODULE_LIST_CAT: + case CONFIG_ITEM_STRING: + case CONFIG_ITEM_FILE: + case CONFIG_ITEM_DIRECTORY: + case CONFIG_ITEM_INTEGER: + case CONFIG_ITEM_FLOAT: + ResizeTo( Bounds().Width(), 25 ); + fTextControl = new VTextControl( Bounds(), NULL, + p_item->psz_text, NULL, new BMessage(), + B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP ); + AddChild( fTextControl ); + break; + case CONFIG_ITEM_KEY: + ResizeTo( Bounds().Width(), 25 ); + r = Bounds(); + r.left = r.right - 100; + fPopUpMenu = new BPopUpMenu( "" ); + fMenuField = new BMenuField( r, NULL, NULL, fPopUpMenu, + B_FOLLOW_RIGHT | B_FOLLOW_TOP ); + for( unsigned i = 0; + i < sizeof( vlc_keys ) / sizeof( key_descriptor_t ); + i++ ) + { + menuItem = new BMenuItem( vlc_keys[i].psz_key_string, NULL ); + fPopUpMenu->AddItem( menuItem ); + } + r.right = r.left - 10; r.left = r.left - 60; + fShiftCheck = new BCheckBox( r, NULL, "Shift", + new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP ); + r.right = r.left - 10; r.left = r.left - 60; + fCtrlCheck = new BCheckBox( r, NULL, "Ctrl", + new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP ); + r.right = r.left - 10; r.left = r.left - 60; + fAltCheck = new BCheckBox( r, NULL, "Alt", + new BMessage(), B_FOLLOW_RIGHT | B_FOLLOW_TOP ); + r.right = r.left - 10; r.left = 0; r.bottom -= 10; + fStringView = new BStringView( r, NULL, p_item->psz_text, + B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP ); + AddChild( fStringView ); + AddChild( fAltCheck ); + AddChild( fCtrlCheck ); + AddChild( fShiftCheck ); + AddChild( fMenuField ); + break; + case CONFIG_ITEM_BOOL: + ResizeTo( Bounds().Width(), 25 ); + fCheckBox = new BCheckBox( Bounds(), NULL, p_item->psz_text, + new BMessage(), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP ); + AddChild( fCheckBox ); + break; + case CONFIG_SECTION: + fInitOK = false; + break; + default: + fInitOK = false; + } } -/***************************************************************************** - * PreferencesWindow::ReallyQuit - *****************************************************************************/ -void PreferencesWindow::ReallyQuit() +ConfigWidget::~ConfigWidget() { - Lock(); - Hide(); - Quit(); + free( fName ); } -/***************************************************************************** - * PreferencesWindow::BuildConfigView - *****************************************************************************/ -void PreferencesWindow::BuildConfigView( StringItemWithView * stringItem, - module_config_t ** pp_item, - bool stop_after_category ) +/*********************************************************************** + * ConfigWidget::Apply + *********************************************************************** + * + **********************************************************************/ +void ConfigWidget::Apply( bool doIt ) { - /* Build the BBox */ - BRect rect = fDummyView->Bounds(); - stringItem->fConfigBox = new BBox( rect, "config box", B_FOLLOW_ALL ); - stringItem->fConfigBox->SetLabel( stringItem->fText ); - - /* Build the BView */ - rect = stringItem->fConfigBox->Bounds(); - rect.InsetBy( 10,10 ); - rect.top += 10; - rect.right -= B_V_SCROLL_BAR_WIDTH + 5; - stringItem->fConfigView = new BView( rect, "config view", - B_FOLLOW_NONE, B_WILL_DRAW ); - stringItem->fConfigView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); - - /* Add all the settings options */ - rect = stringItem->fConfigView->Bounds(); - rect.InsetBy( 10, 10 ); - ConfigTextControl * textControl; - ConfigCheckBox * checkBox; - ConfigMenuField * menuField; - ConfigSlider * slider; - BPopUpMenu * popUp; + BMenuItem * menuItem; + char string[256]; + vlc_value_t val; - for( ; (*pp_item)->i_type != CONFIG_HINT_END; (*pp_item)++ ) + switch( fType ) { - if( stop_after_category && (*pp_item)->i_type == CONFIG_HINT_CATEGORY ) + case CONFIG_ITEM_STRING: + case CONFIG_ITEM_FILE: + case CONFIG_ITEM_MODULE: + case CONFIG_ITEM_MODULE_CAT: + case CONFIG_ITEM_MODULE_LIST_CAT: + case CONFIG_ITEM_DIRECTORY: + if( doIt ) + { + config_PutPsz( p_intf, fName, fTextControl->Text() ); + } + else + { + fTextControl->SetText( config_GetPsz( p_intf, fName ) ); + } break; - - /* Discard a few options */ - if( (*pp_item)->psz_name && - ( !strcmp( (*pp_item)->psz_name, "volume" ) || - !strcmp( (*pp_item)->psz_name, "saved-volume" ) || - !strcmp( (*pp_item)->psz_name, "advanced" ) ) ) - continue; - switch( (*pp_item)->i_type ) - { - case CONFIG_ITEM_STRING: - case CONFIG_ITEM_FILE: - case CONFIG_ITEM_MODULE: - case CONFIG_ITEM_DIRECTORY: - if( (*pp_item)->ppsz_list && (*pp_item)->ppsz_list[0] ) + case CONFIG_ITEM_INTEGER: + if( doIt ) + { + config_PutInt( p_intf, fName, atoi( fTextControl->Text() ) ); + } + else + { + snprintf( string, 256, "%d", config_GetInt( p_intf, fName ) ); + fTextControl->SetText( string ); + } + break; + + case CONFIG_ITEM_FLOAT: + if( doIt ) + { + config_PutFloat( p_intf, fName, atof( fTextControl->Text() ) ); + } + else + { + snprintf( string, 256, "%f", config_GetFloat( p_intf, fName ) ); + fTextControl->SetText( string ); + } + break; + + case CONFIG_ITEM_KEY: + if( doIt ) + { + menuItem = fPopUpMenu->FindMarked(); + if( menuItem ) { - rect.bottom = rect.top + 20; - popUp = new BPopUpMenu( "" ); - menuField = new ConfigMenuField( rect, (*pp_item)->psz_text, - popUp, (*pp_item)->psz_name ); - BMenuItem * menuItem; - for( int i = 0; (*pp_item)->ppsz_list[i]; i++ ) + val.i_int = vlc_keys[fPopUpMenu->IndexOf( menuItem )].i_key_code; + if( fAltCheck->Value() ) + { + val.i_int |= KEY_MODIFIER_ALT; + } + if( fCtrlCheck->Value() ) { - menuItem = new BMenuItem( (*pp_item)->ppsz_list[i], new BMessage() ); - popUp->AddItem( menuItem ); + val.i_int |= KEY_MODIFIER_CTRL; } - stringItem->fConfigView->AddChild( menuField ); - rect.top = rect.bottom + 10; + if( fShiftCheck->Value() ) + { + val.i_int |= KEY_MODIFIER_SHIFT; + } + var_Set( p_intf->p_libvlc, fName, val ); } - else + } + else + { + val.i_int = config_GetInt( p_intf, fName ); + fAltCheck->SetValue( val.i_int & KEY_MODIFIER_ALT ); + fCtrlCheck->SetValue( val.i_int & KEY_MODIFIER_CTRL ); + fShiftCheck->SetValue( val.i_int & KEY_MODIFIER_SHIFT ); + + for( unsigned i = 0; + i < sizeof( vlc_keys ) / sizeof( key_descriptor_t ); i++ ) { - rect.bottom = rect.top + 20; - textControl = new ConfigTextControl( rect, (*pp_item)->psz_text, - CONFIG_ITEM_STRING, (*pp_item)->psz_name ); - stringItem->fConfigView->AddChild( textControl ); - rect.top = rect.bottom + 10; + if( (unsigned) vlc_keys[i].i_key_code == + ( val.i_int & ~KEY_MODIFIER ) ) + { + menuItem = fPopUpMenu->ItemAt( i ); + menuItem->SetMarked( true ); + break; + } } - break; + } + break; - case CONFIG_ITEM_INTEGER: + case CONFIG_ITEM_BOOL: + if( doIt ) + { + config_PutInt( p_intf, fName, fCheckBox->Value() ); + } + else + { + fCheckBox->SetValue( config_GetInt( p_intf, fName ) ); + } + break; - if( (*pp_item)->i_min == (*pp_item)->i_max ) - { - rect.bottom = rect.top + 20; - textControl = new ConfigTextControl( rect, (*pp_item)->psz_text, - CONFIG_ITEM_INTEGER, - (*pp_item)->psz_name ); - stringItem->fConfigView->AddChild( textControl ); - rect.top = rect.bottom + 10; - } - else - { - rect.bottom = rect.top + 30; - slider = new ConfigSlider( rect, (*pp_item)->psz_text, - CONFIG_ITEM_INTEGER, (*pp_item)->i_min, - (*pp_item)->i_max, (*pp_item)->psz_name ); - stringItem->fConfigView->AddChild( slider ); - rect.top = rect.bottom + 10; - } - break; + default: + break; + } +} - case CONFIG_ITEM_FLOAT: - if( (*pp_item)->f_min == (*pp_item)->f_max ) - { - rect.bottom = rect.top + 20; - textControl = new ConfigTextControl( rect, (*pp_item)->psz_text, - CONFIG_ITEM_FLOAT, (*pp_item)->psz_name ); - stringItem->fConfigView->AddChild( textControl ); - rect.top = rect.bottom + 10; - } - else - { - rect.bottom = rect.top + 30; - slider = new ConfigSlider( rect, (*pp_item)->psz_text, - CONFIG_ITEM_FLOAT, 100 * (*pp_item)->f_min, - 100 * (*pp_item)->f_max, (*pp_item)->psz_name ); - stringItem->fConfigView->AddChild( slider ); - rect.top = rect.bottom + 10; - } - break; +VTextView::VTextView( BRect frame, const char *name, + uint32 resizingMode, uint32 flags ) + : BTextView( frame, name, BRect( 10,10,10,10 ), resizingMode, flags ) +{ + FrameResized( Bounds().Width(), Bounds().Height() ); +} - case CONFIG_ITEM_BOOL: - rect.bottom = rect.top + 20; - checkBox = new ConfigCheckBox( rect, (*pp_item)->psz_text, - (*pp_item)->psz_name ); - stringItem->fConfigView->AddChild( checkBox ); - rect.top = rect.bottom + 10; - break; - } - } +void VTextView::FrameResized( float width, float height ) +{ + BTextView::FrameResized( width, height ); + SetTextRect( BRect( 10,10, width-11, height-11 ) ); +} - /* Put the BView into a BScrollView */ - - stringItem->fConfigScroll = - new BScrollView( "config scroll", stringItem->fConfigView, - B_FOLLOW_ALL, 0, false, true, B_FANCY_BORDER ); - stringItem->fConfigScroll->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); - stringItem->fConfigBox->AddChild( stringItem->fConfigScroll ); - - /* Adjust the configView size */ - stringItem->fConfigView->ResizeTo( - stringItem->fConfigView->Bounds().Width(), rect.top ); +VTextControl::VTextControl( BRect frame, const char *name, + const char *label, const char *text, + BMessage * message, uint32 resizingMode ) + : BTextControl( frame, name, label, text, message, resizingMode ) +{ + FrameResized( Bounds().Width(), Bounds().Height() ); } +void VTextControl::FrameResized( float width, float height ) +{ + BTextControl::FrameResized( width, height ); + SetDivider( width / 2 ); +}