X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fgui%2Fbeos%2FPreferencesWindow.cpp;h=248741a40d579d1515337adc36034ed612f3c478;hb=6ee1e193fd896ab9a4729fde14f009d9ce629815;hp=c9e0f04904a61061d5e4e1755164def8fceb3370;hpb=d9ddadd06b6caeea58d2e26a2ad5d56289a16d6f;p=vlc diff --git a/modules/gui/beos/PreferencesWindow.cpp b/modules/gui/beos/PreferencesWindow.cpp index c9e0f04904..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.14 2003/04/22 16:36:16 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,357 +18,247 @@ * * 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. *****************************************************************************/ -/* system headers */ -#include -#include -/* BeOS headers */ -#include -#include -#include -#include +#include -/* VLC headers */ #include -#include +#include +#include +#include -/* BeOS module headers */ -#include "VlcWrapper.h" -#include "MsgVals.h" #include "PreferencesWindow.h" -static const char* kTranslatorField = "be:translator"; -static const char* kTypeField = "be:type"; -static const char* kDefaultScreenShotPath = "/boot/home/vlc screenshot"; -static const uint32 kDefaultScreenShotFormat = 'PNG '; - -// add_translator_items -status_t -add_translator_items( BMenu* intoMenu, uint32 fromType, uint32 command ) -{ - BTranslatorRoster* roster = BTranslatorRoster::Default(); - translator_id* ids = NULL; - int32 count = 0; - - status_t err = B_NO_INIT; - if ( roster ) - err = roster->GetAllTranslators( &ids, &count ); - if ( err < B_OK ) - return err; - for ( int32 tix = 0; tix < count; tix++ ) - { - const translation_format* formats = NULL; - int32 num_formats = 0; - bool checkOutFormats = false; - err = roster->GetInputFormats( ids[tix], &formats, &num_formats ); - if ( err == B_OK ) - { - for ( int iix = 0; iix < num_formats; iix++ ) - { - if ( formats[iix].type == fromType ) - { - checkOutFormats = true; - break; - } - } - } - if ( !checkOutFormats ) - continue; - err = roster->GetOutputFormats(ids[tix], &formats, &num_formats); - if ( err == B_OK ) - { - for ( int32 oix = 0; oix < num_formats; oix++ ) - { - if ( formats[oix].type != fromType ) - { - BMessage* message = new BMessage( command ); - message->AddInt32( kTranslatorField, ids[tix] ); - message->AddInt32( kTypeField, formats[oix].type ); - intoMenu->AddItem( new BMenuItem( formats[oix].name, message ) ); - } - } - } - } - delete[] ids; - return B_OK; -} - -// get_config_string -char* -get_config_string( intf_thread_t* intf, const char* field, const char* defaultString ) -{ - char* string = config_GetPsz( intf, field ); - if ( !string ) - { - string = strdup( defaultString ); - config_PutPsz( intf, field, string ); - } - return string; -} - -// get_config_int -int32 -get_config_int( intf_thread_t* intf, const char* field, int32 defaultValue ) -{ - int32 value = config_GetInt( intf, field ); - if ( value < 0 ) - { - value = defaultValue; - config_PutInt( intf, field, value ); - } - return value; -} - -// get_config_float -float -get_config_float( intf_thread_t* intf, const char* field, float defaultValue ) -{ - float value = config_GetFloat( intf, field ); - if ( value < 0 ) - { - value = defaultValue; - config_PutFloat( intf, field, value ); - } - return value; -} - - -/***************************************************************************** - * DirectoryTextControl class - *****************************************************************************/ -class DirectoryTextControl : public BTextControl -{ - public: - DirectoryTextControl( BRect frame, const char* name, - const char* label, const char* text, - BMessage* message, - uint32 resizingMode = B_FOLLOW_LEFT | B_FOLLOW_TOP, - uint32 flags = B_WILL_DRAW | B_NAVIGABLE ); - virtual ~DirectoryTextControl(); - - virtual void MessageReceived(BMessage *msg); -}; - -DirectoryTextControl::DirectoryTextControl( BRect frame, const char* name, - const char* label, const char* text, - BMessage* message, - uint32 resizingMode, uint32 flags) - : BTextControl( frame, name, label, text, message, resizingMode, flags ) -{ -} - -DirectoryTextControl::~DirectoryTextControl() -{ -} - -/***************************************************************************** - * DirectoryTextControl::MessageReceived - *****************************************************************************/ -void -DirectoryTextControl::MessageReceived( BMessage* message ) -{ - switch ( message->what ) - { - case B_SIMPLE_DATA: - { - entry_ref ref; - if ( message->FindRef( "refs", &ref ) == B_OK ) { - BString directory; - BEntry entry; - BPath path; - if ( entry.SetTo( &ref, true ) == B_OK - && entry.IsDirectory() - && path.SetTo( &entry ) == B_OK ) - { - SetText( path.Path() ); - } - } - break; - } - default: - BTextControl::MessageReceived( message ); - break; - } -} - - +#define TYPE_CATEGORY 0 +#define TYPE_SUBCATEGORY 2 +#define TYPE_MODULE 3 /***************************************************************************** - * Preferences::PreferencesWindow + * 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_RESIZABLE ), - fDVDMenusBackup( false ), - fPostProcessingBackup( 0 ), - fBrightnessBackup( 100.0 ), - fContrastBackup( 100.0 ), - fHueBackup( 0 ), - fSaturationBackup( 100.0 ), - fScreenShotPathBackup( kDefaultScreenShotPath ), - fScreenShotFormatBackup( kDefaultScreenShotFormat ), - p_intf( p_interface ) + B_NOT_ZOOMABLE ) { + p_intf = _p_intf; + fCurrent = NULL; + BRect rect; - /* "background" view */ - rgb_color background = ui_color( B_PANEL_BACKGROUND_COLOR ); + 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( background ); + fPrefsView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); AddChild( fPrefsView ); - /* add the tabs */ + /* Create a scrollable outline view for the preferences tree */ rect = Bounds(); - rect.top += 10.0; - rect.bottom -= 45.0; - fTabView = new BTabView( rect, "preferences view" ); - fTabView->SetViewColor( background ); - - fGeneralView = new BView( fTabView->Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW ); - fGeneralView->SetViewColor( background ); - fAdjustView = new BView( fTabView->Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW ); - fAdjustView->SetViewColor( background ); - - fGeneralTab = new BTab(); - fTabView->AddTab( fGeneralView, fGeneralTab ); - fGeneralTab->SetLabel( _("General") ); - - fAdjustTab = new BTab(); - fTabView->AddTab( fAdjustView, fAdjustTab ); - fAdjustTab->SetLabel( _("Picture") ); - - /* fills the tabs */ - /* general tab */ - rect = fGeneralView->Bounds(); - rect.InsetBy( 10, 10 ); - rect.bottom = rect.top + 10; - fDvdMenusCheck = new BCheckBox( rect, "dvdmenus", _("Use DVD menus"), - new BMessage( DVDMENUS_CHECK ) ); - fGeneralView->AddChild( fDvdMenusCheck ); - - rect.top = rect.bottom + 20; - rect.bottom = rect.top + 30; - fPpSlider = new BSlider( rect, "post-processing", _("MPEG4 post-processing level"), - new BMessage( FFMPEG_UPDATE ), - 0, 6, B_TRIANGLE_THUMB, - B_FOLLOW_LEFT, B_WILL_DRAW ); - fPpSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); - fPpSlider->SetHashMarkCount( 7 ); - fPpSlider->SetLimitLabels( _("None"), _("Maximum") ); - fGeneralView->AddChild( fPpSlider ); - - - rect.top = fPpSlider->Frame().bottom + 5.0; - rect.bottom = rect.top + 15.0; - fScreenShotPathTC = new DirectoryTextControl( rect, "screenshot path", - _("Screenshot Path:"), - fScreenShotPathBackup.String(), - new BMessage( SET_FOLDER ) ); -// fScreenShotPathTC->ResizeToPreferred(); - - rect.top = fScreenShotPathTC->Frame().bottom + 5.0; - rect.bottom = rect.top + 15.0; // TODO: this will be so tricky to get right! - BMenu* translatorMenu = new BMenu( "translators" ); - add_translator_items( translatorMenu, B_TRANSLATOR_BITMAP, SET_TRANSLATOR ); - fScreenShotFormatMF = new BMenuField( rect, "translators field", - _("Screenshot Format:"), translatorMenu ); - fScreenShotFormatMF->Menu()->SetRadioMode( true ); - fScreenShotFormatMF->Menu()->SetLabelFromMarked( true ); - // this will most likely not work for BMenuFields -// fScreenShotFormatMF->ResizeToPreferred(); - - fGeneralView->AddChild( fScreenShotPathTC ); - fGeneralView->AddChild( fScreenShotFormatMF ); - - // make sure the controls labels are aligned nicely - float labelWidthM = fScreenShotFormatMF->StringWidth( fScreenShotFormatMF->Label() ) + 5.0; - float labelWidthP = fScreenShotPathTC->StringWidth( fScreenShotPathTC->Label() ) + 5.0; - if ( labelWidthM > labelWidthP ) - { - fScreenShotPathTC->SetDivider( labelWidthM ); - fScreenShotFormatMF->SetDivider( labelWidthM ); - } - else - { - fScreenShotPathTC->SetDivider( labelWidthP ); - fScreenShotFormatMF->SetDivider( labelWidthP ); - } - - /* restart message */ - rect = fGeneralView->Bounds(); - rect.bottom -= 40.0; - font_height fh; - be_plain_font->GetHeight( &fh ); - rect.top = rect.bottom - ceilf( fh.ascent + fh.descent ) - 2.0; - fRestartString = new BStringView( rect, NULL, - _("DVD-menu and MPEG4 settings take effect after playback is restarted.") ); - fRestartString->SetAlignment( B_ALIGN_CENTER ); - fGeneralView->AddChild( fRestartString ); - - - /* adjust tab */ - rect = fAdjustView->Bounds(); rect.InsetBy( 10, 10 ); - rect.bottom = rect.top + 30; - fBrightnessSlider = new BSlider( rect, "brightness", _("Brightness"), - new BMessage( ADJUST_UPDATE ), - 0, 200, B_TRIANGLE_THUMB, - B_FOLLOW_LEFT, B_WILL_DRAW ); - rect.OffsetBy( 0, 40 ); - fContrastSlider = new BSlider( rect, "contrast", _("Contrast"), - new BMessage( ADJUST_UPDATE ), - 0, 200, B_TRIANGLE_THUMB, - B_FOLLOW_LEFT, B_WILL_DRAW ); - rect.OffsetBy( 0, 40 ); - fHueSlider = new BSlider( rect, "hue", _("Hue"), - new BMessage( ADJUST_UPDATE ), - 0, 360, B_TRIANGLE_THUMB, - B_FOLLOW_LEFT, B_WILL_DRAW ); - rect.OffsetBy( 0, 40 ); - fSaturationSlider = new BSlider( rect, "saturation", _("Saturation"), - new BMessage( ADJUST_UPDATE ), - 0, 200, B_TRIANGLE_THUMB, - B_FOLLOW_LEFT, B_WILL_DRAW ); - fAdjustView->AddChild( fBrightnessSlider ); - fAdjustView->AddChild( fContrastSlider ); - fAdjustView->AddChild( fHueSlider ); - fAdjustView->AddChild( fSaturationSlider ); - - fPrefsView->AddChild( fTabView ); - - /* buttons */ - BButton *button; + 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 ); + fPrefsView->AddChild( scrollview ); + + /* We need to be informed if the user selects an item */ + fOutline->SetSelectionMessage( new BMessage( PREFS_ITEM_SELECTED ) ); + + /* 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; + fDummyView = new BView( rect, "", B_FOLLOW_ALL_SIDES, B_WILL_DRAW ); + fDummyView->SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); + fPrefsView->AddChild( fDummyView ); + + /* Fill the tree */ + vlc_list_t * p_list; + p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE ); + if( !p_list ) + { + msg_Warn( p_intf, "couldn't find any module !" ); + return; + } + + /* Find the main module */ + module_t * p_module = NULL; + 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; + + if( !strcmp( p_module->psz_object_name, "main" ) && + ( p_item = p_module->p_config ) ) + break; + else + p_module = NULL; + } + + ConfigItem * catItem = NULL, * subcatItem, * otherItem; + + if( p_module ) + { + /* We found the main module, build the category tree */ + for( ; p_item->i_type != CONFIG_HINT_END; p_item++ ) + { + 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( p_module->b_submodule || + !( p_item = p_module->p_config ) ) + continue; + + for( ; p_item->i_type != CONFIG_HINT_END; p_item++ ) + { + switch( p_item->i_type ) + { + 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; + } + } + + if( options < 1 || category < 0 || subcategory < 0 ) + continue; + + catItem = NULL; + for( int j = 0; j < fOutline->CountItemsUnder( NULL, true ); j++ ) + { + catItem = (ConfigItem*) + fOutline->ItemUnderAt( NULL, true, j ); + if( catItem->ObjectId() == category ) + break; + else + catItem = NULL; + } + + if( !catItem ) + continue; + + subcatItem = NULL; + for( int j = 0; j < fOutline->CountItemsUnder( catItem, true ); j++ ) + { + subcatItem = (ConfigItem*) + fOutline->ItemUnderAt( catItem, true, j ); + if( subcatItem->ObjectId() == subcategory ) + break; + else + subcatItem = NULL; + } + + 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 ); + + /* Collapse the whole tree */ + for( int i = 0; i < fOutline->FullListCountItems(); i++ ) + { + otherItem = (ConfigItem *) fOutline->FullListItemAt( i ); + fOutline->Collapse( otherItem ); + } + + /* Set the correct values */ + Apply( false ); + + /* Select the first item */ + fOutline->Select( 0 ); + + /* Add the buttons */ + BButton * button; rect = Bounds(); rect.InsetBy( 10, 10 ); - rect.top = rect.bottom - 25; rect.left = rect.right - 80; - button = new BButton( rect, NULL, _("OK"), new BMessage( PREFS_OK ) ); + rect.top = rect.bottom - 25; + button = new BButton( rect, "", _("Apply"), new BMessage( PREFS_APPLY ), + B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM ); + button->MakeDefault( true ); fPrefsView->AddChild( button ); - - SetDefaultButton( button ); - rect.OffsetBy( -90, 0 ); - button = new BButton( rect, NULL, _("Cancel"), new BMessage( PREFS_CANCEL ) ); + button = new BButton( rect, "", _("Save"), new BMessage( PREFS_SAVE ), + B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM ); fPrefsView->AddChild( button ); - rect.OffsetBy( -90, 0 ); - button = new BButton( rect, NULL, _("Revert"), new BMessage( PREFS_REVERT ) ); + button = new BButton( rect, "", _("Defaults"), + new BMessage( PREFS_DEFAULTS ), + B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM ); fPrefsView->AddChild( button ); - rect.left = Bounds().left + 10.0; - rect.right = rect.left + 80.0; - button = new BButton( rect, NULL, _("Defaults"), new BMessage( PREFS_DEFAULTS ) ); - fPrefsView->AddChild( button ); - - - // sync GUI to VLC - _SetToSettings(); - - // start window thread in hidden state Hide(); Show(); } @@ -383,81 +273,96 @@ PreferencesWindow::~PreferencesWindow() /***************************************************************************** * PreferencesWindow::QuitRequested *****************************************************************************/ -bool -PreferencesWindow::QuitRequested() +bool PreferencesWindow::QuitRequested() { - // work arround problem when window is closed or Ok pressed though - // the text control has focus (it will not have commited changes) - config_PutPsz( p_intf, "beos-screenshot-path", fScreenShotPathTC->Text() ); - if ( !IsHidden() ) - Hide(); - return false; + if( !IsHidden() ) + { + Hide(); + } + return false; } /***************************************************************************** * PreferencesWindow::MessageReceived *****************************************************************************/ -void PreferencesWindow::MessageReceived( BMessage * p_message ) +void PreferencesWindow::MessageReceived( BMessage * message ) { - switch ( p_message->what ) + switch( message->what ) { - case SET_TRANSLATOR: - case SET_FOLDER: - _ApplyScreenShotSettings(); - break; - case DVDMENUS_CHECK: - _ApplyDVDSettings(); - break; - case ADJUST_UPDATE: - _ApplyPictureSettings(); - break; - case FFMPEG_UPDATE: - _ApplyFFmpegSettings(); + case PREFS_ITEM_SELECTED: + Update(); break; - case PREFS_REVERT: - _RevertChanges(); - break; + case PREFS_DEFAULTS: - _SetDefaults(); - _ApplyChanges(); + config_ResetAll( p_intf ); + config_SaveConfigFile( p_intf, NULL ); + Apply( false ); break; - case PREFS_CANCEL: - _RevertChanges(); - // fall through - case PREFS_OK: - PostMessage( B_QUIT_REQUESTED ); + + case PREFS_APPLY: + Apply( true ); break; - default: - BWindow::MessageReceived( p_message ); + + case PREFS_SAVE: + Apply( true ); + config_SaveConfigFile( p_intf, NULL ); break; + + default: + BWindow::MessageReceived( message ); } } /***************************************************************************** - * PreferencesWindow::Show + * PreferencesWindow::FrameResized *****************************************************************************/ -void -PreferencesWindow::Show() +void PreferencesWindow::FrameResized( float width, float height ) { - // collect settings for backup - fDVDMenusBackup = fDvdMenusCheck->Value() == B_CONTROL_ON; - fPostProcessingBackup = fPpSlider->Value(); - fBrightnessBackup = fBrightnessSlider->Value(); - fContrastBackup = fContrastSlider->Value(); - fHueBackup = fHueSlider->Value(); - fSaturationBackup = fSaturationSlider->Value(); - fScreenShotPathBackup.SetTo( fScreenShotPathTC->Text() ); - if ( BMenuItem* item = fScreenShotFormatMF->Menu()->FindMarked() ) - { - BMessage* message = item->Message(); - if ( message && message->FindInt32( kTypeField, - (int32*)&fScreenShotFormatBackup ) != B_OK ) - fScreenShotFormatBackup = kDefaultScreenShotFormat; - } - else - fScreenShotFormatBackup = kDefaultScreenShotFormat; - - BWindow::Show(); + BWindow::FrameResized( width, height ); + fCurrent->UpdateScrollBar(); +} + +/***************************************************************************** + * PreferencesWindow::Update + *****************************************************************************/ +void PreferencesWindow::Update() +{ + /* Get the selected item, if any */ + if( fOutline->CurrentSelection() < 0 ) + return; + + /* 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 ); + } } /***************************************************************************** @@ -470,184 +375,459 @@ void PreferencesWindow::ReallyQuit() Quit(); } -void -PreferencesWindow::_SetGUI( bool dvdMenus, int32 postProcessing, - float brightness, float contrast, - int32 hue, float saturation, - const char* screenShotPath, - uint32 screenShotTranslator) +/*********************************************************************** + * ConfigItem::ConfigItem + *********************************************************************** + * + **********************************************************************/ +ConfigItem::ConfigItem( intf_thread_t * _p_intf, char * name, + bool subModule, int objectId, + int type, char * help ) + : BStringItem( name ) { - fDvdMenusCheck->SetValue( dvdMenus ); - fPpSlider->SetValue( postProcessing ); - fBrightnessSlider->SetValue( brightness ); - fContrastSlider->SetValue( contrast ); - fHueSlider->SetValue( hue ); - fSaturationSlider->SetValue( saturation ); - // mark appropriate translator item - bool found = false; - for ( int32 i = 0; BMenuItem* item = fScreenShotFormatMF->Menu()->ItemAt( i ); i++ ) - { - if ( BMessage* message = item->Message() ) - { - uint32 format; - if ( message->FindInt32( kTypeField, (int32*)&format ) == B_OK - && format == screenShotTranslator ) - { - item->SetMarked( true ); - found = true; - break; - } - } - } - if ( !found ) - { - if ( BMenuItem* item = fScreenShotFormatMF->Menu()->ItemAt( 0 ) ) - item->SetMarked( true ); - } - fScreenShotPathTC->SetText( screenShotPath ); -} + 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; -/***************************************************************************** - * PreferencesWindow::_SetDefaults - *****************************************************************************/ -void PreferencesWindow::_SetDefaults() -{ - _SetGUI( false, 0, 100.0, 100.0, 0, 100.0, - kDefaultScreenShotPath, kDefaultScreenShotFormat ); + if( !strcmp( p_module->psz_object_name, "main" ) ) + break; + else + p_module = NULL; + } + } + + 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 ); + } + + /* 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 ); } -/***************************************************************************** - * PreferencesWindow::_SetToSettings - *****************************************************************************/ -void PreferencesWindow::_SetToSettings() +/*********************************************************************** + * ConfigItem::~ConfigItem + *********************************************************************** + * + **********************************************************************/ +ConfigItem::~ConfigItem() { - char* path = get_config_string( p_intf, "beos-screenshot-path", kDefaultScreenShotPath ); - - p_intf->p_sys->b_dvdmenus = get_config_int( p_intf, "beos-use-dvd-menus", false ); - - _SetGUI( p_intf->p_sys->b_dvdmenus, - get_config_int( p_intf, "ffmpeg-pp-q", 0 ), - 100 * get_config_float( p_intf, "brightness", 1.0 ), - 100 * get_config_float( p_intf, "contrast", 1.0 ), - get_config_int( p_intf, "hue", 0 ), - 100 * get_config_float( p_intf, "saturation", 1.0 ), - path, - get_config_int( p_intf, "beos-screenshot-format", - kDefaultScreenShotFormat ) ); - free( path ); + if( fHelp ) + { + free( fHelp ); + } } /***************************************************************************** - * PreferencesWindow::_RevertChanges + * ConfigItem::UpdateScrollBar *****************************************************************************/ -void -PreferencesWindow::_RevertChanges() +void ConfigItem::UpdateScrollBar() { - _SetGUI( fDVDMenusBackup, - fPostProcessingBackup, - fBrightnessBackup, - fContrastBackup, - fHueBackup, - fSaturationBackup, - fScreenShotPathBackup.String(), - fScreenShotFormatBackup ); - - _ApplyChanges(); + /* We have to fix the scrollbar manually because it doesn't handle + correctly simple BViews */ + + if( !fScroll ) + { + return; + } + + /* Get the available BRect for display */ + BRect display = fScroll->Bounds(); + display.right -= B_V_SCROLL_BAR_WIDTH; + + /* Fix the scrollbar */ + BScrollBar * scrollBar; + 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 + * ConfigItem::ResetScroll *****************************************************************************/ -void PreferencesWindow::_ApplyChanges() +void ConfigItem::ResetScroll() { - _ApplyScreenShotSettings(); - _ApplyPictureSettings(); - _ApplyFFmpegSettings(); - _ApplyDVDSettings(); + if( !fScroll ) + { + return; + } + + fView->ScrollTo( 0, 0 ); } -/***************************************************************************** - * PreferencesWindow::_ApplyScreenShotSettings - *****************************************************************************/ -void -PreferencesWindow::_ApplyScreenShotSettings() +/*********************************************************************** + * ConfigItem::Apply + *********************************************************************** + * + **********************************************************************/ +void ConfigItem::Apply( bool doIt ) { - // screen shot settings - uint32 translator = kDefaultScreenShotFormat; - if ( BMenuItem* item = fScreenShotFormatMF->Menu()->FindMarked() ) - { - BMessage* message = item->Message(); - if ( message && message->FindInt32( kTypeField, (int32*)&translator ) != B_OK ) - translator = kDefaultScreenShotFormat; - } - config_PutInt( p_intf, "beos-screenshot-format", translator ); - config_PutPsz( p_intf, "beos-screenshot-path", fScreenShotPathTC->Text() ); + 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::_ApplyPictureSettings - *****************************************************************************/ -void -PreferencesWindow::_ApplyPictureSettings() +/*********************************************************************** + * 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 ) { - VlcWrapper* p_wrapper = p_intf->p_sys->p_wrapper; - - // picture adjustment settings - config_PutFloat( p_intf, "brightness", - (float)fBrightnessSlider->Value() / 100 ); - config_PutFloat( p_intf, "contrast", - (float)fContrastSlider->Value() / 100 ); - config_PutInt( p_intf, "hue", fHueSlider->Value() ); - config_PutFloat( p_intf, "saturation", - (float)fSaturationSlider->Value() / 100 ); - - // take care of changing "filters on the fly" - if( config_GetFloat( p_intf, "brightness" ) != 1 || - config_GetFloat( p_intf, "contrast" ) != 1 || - config_GetInt( p_intf, "hue" ) != 0 || - config_GetFloat( p_intf, "saturation" ) != 1 ) + p_intf = _p_intf; + + SetViewColor( ui_color( B_PANEL_BACKGROUND_COLOR ) ); + + BRect r; + BMenuItem * menuItem; + /* Skip deprecated options */ + if( p_item->psz_current ) { - char* string = config_GetPsz( p_intf, "filter" ); - if( !string || strcmp( string, "adjust" ) ) - { - config_PutPsz( p_intf, "filter", "adjust" ); - p_wrapper->FilterChange(); - } - if ( string ) - free( string ); + fInitOK = false; + return; } - else + + fInitOK = true; + + fType = p_item->i_type; + fName = strdup( p_item->psz_name ); + + switch( fType ) { - char* string = config_GetPsz( p_intf, "filter" ); - if ( string ) - { - config_PutPsz( p_intf, "filter", NULL ); - p_wrapper->FilterChange(); - free( string ); - } + 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::_ApplyFFmpegSettings - *****************************************************************************/ -void -PreferencesWindow::_ApplyFFmpegSettings() +ConfigWidget::~ConfigWidget() { - // ffmpeg post processing - config_PutInt( p_intf, "ffmpeg-pp-q", fPpSlider->Value() ); + free( fName ); } -/***************************************************************************** - * PreferencesWindow::_ApplyDVDSettings - *****************************************************************************/ -void -PreferencesWindow::_ApplyDVDSettings() +/*********************************************************************** + * ConfigWidget::Apply + *********************************************************************** + * + **********************************************************************/ +void ConfigWidget::Apply( bool doIt ) { - // dvd menus - bool dvdMenus = fDvdMenusCheck->Value() == B_CONTROL_ON; - p_intf->p_sys->b_dvdmenus = dvdMenus; - config_PutInt( p_intf, "beos-use-dvd-menus", dvdMenus ); + BMenuItem * menuItem; + char string[256]; + vlc_value_t val; + + switch( fType ) + { + 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; + + 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 ) + { + val.i_int = vlc_keys[fPopUpMenu->IndexOf( menuItem )].i_key_code; + if( fAltCheck->Value() ) + { + val.i_int |= KEY_MODIFIER_ALT; + } + if( fCtrlCheck->Value() ) + { + val.i_int |= KEY_MODIFIER_CTRL; + } + if( fShiftCheck->Value() ) + { + val.i_int |= KEY_MODIFIER_SHIFT; + } + var_Set( p_intf->p_libvlc, fName, val ); + } + } + 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++ ) + { + if( (unsigned) vlc_keys[i].i_key_code == + ( val.i_int & ~KEY_MODIFIER ) ) + { + menuItem = fPopUpMenu->ItemAt( i ); + menuItem->SetMarked( true ); + break; + } + } + } + break; + + case CONFIG_ITEM_BOOL: + if( doIt ) + { + config_PutInt( p_intf, fName, fCheckBox->Value() ); + } + else + { + fCheckBox->SetValue( config_GetInt( p_intf, fName ) ); + } + break; + + default: + 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() ); +} + +void VTextView::FrameResized( float width, float height ) +{ + BTextView::FrameResized( width, height ); + SetTextRect( BRect( 10,10, width-11, height-11 ) ); +} + +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 ); +}