/*****************************************************************************
* PreferencesWindow.cpp: beos interface
*****************************************************************************
- * Copyright (C) 1999, 2000, 2001 VideoLAN
- * $Id: PreferencesWindow.cpp,v 1.15 2003/05/03 13:37:21 titer Exp $
+ * Copyright (C) 1999, 2000, 2001 the VideoLAN team
+ * $Id$
*
- * Authors: Eric Petit <titer@videolan.org>
+ * Authors: Eric Petit <titer@m0k.org>
*
* 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
*
* 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 <stdlib.h> /* atoi(), strtod() */
-#include <InterfaceKit.h>
-#include <SupportKit.h>
+#include <String.h>
#include <vlc/vlc.h>
-#include <vlc/intf.h>
+#include <vlc_interface.h>
+#include <vlc_keys.h>
+#include <vlc_config_cat.h>
#include "PreferencesWindow.h"
-/*****************************************************************************
- * StringItemWithView::StringItemWithView
- *****************************************************************************/
-StringItemWithView::StringItemWithView( const char * text )
- : BStringItem( text )
-{
- /* We use the default constructor */
-}
-
-/*****************************************************************************
- * ConfigView::ConfigView
- *****************************************************************************/
-ConfigView::ConfigView( BRect frame, const char * name,
- uint32 resizingMode, uint32 flags )
- : BView( frame, name, resizingMode, flags )
-{
- /* We use the default constructor */
-}
+#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 ),
- fConfigScroll( NULL ),
- p_intf( p_interface )
+ B_NOT_ZOOMABLE )
{
+ p_intf = _p_intf;
+ fCurrent = NULL;
+
BRect rect;
+ SetSizeLimits( PREFS_WINDOW_WIDTH, 2000, PREFS_WINDOW_HEIGHT, 2000 );
+
/* The "background" view */
- rgb_color background = ui_color( B_PANEL_BACKGROUND_COLOR );
fPrefsView = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
- fPrefsView->SetViewColor( background );
+ 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 );
-
- rect.right += B_V_SCROLL_BAR_WIDTH;
- 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;
+ 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 */
- /* TODO:
- - manage CONFIG_HINT_SUBCATEGORY
- - use a pop-up for CONFIG_HINT_MODULE
- - use BSliders for integer_with_range and float_with_range
- - add a tab for BeOS specific configution (screenshot path, etc)
- - add the needed LockLooper()s
- - fix window resizing
- - make this intuitive ! */
vlc_list_t * p_list;
p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
if( !p_list )
return;
}
- module_t * p_module;
+ /* 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 the module has no config option, ignore it */
- module_config_t * p_item;
- 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 )
- continue;
-
- /* Build the config view for this module */
- rect = fDummyView->Bounds();
- rect.right -= B_V_SCROLL_BAR_WIDTH;
- ConfigView * configView;
- configView = new ConfigView( rect, "config view",
- B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, B_WILL_DRAW );
- configView->SetViewColor( background );
-
- rect = configView->Bounds();
- rect.InsetBy( 10, 10 );
- rect.bottom = rect.top + TEXT_HEIGHT;
- BTextControl * textControl;
- BCheckBox * checkBox;
-
- /* FIXME: we use the BControl name to store the VLC variable name.
- To know what variable type it is, I add one character at the beginning
- of the name (see ApplyChanges()); it's not pretty, but it works. To
- be cleaned later. */
- char name[128];
- p_item = p_module->p_config;
- bool firstItem = true;
- do
+
+ 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_ITEM_STRING:
- case CONFIG_ITEM_FILE:
- case CONFIG_ITEM_MODULE:
- case CONFIG_ITEM_DIRECTORY:
- if( !firstItem )
- rect.OffsetBy( 0, 25 );
- else
- firstItem = false;
-
- memset( name, 0, 128 );
- sprintf( name, "s%s", p_item->psz_name );
- textControl = new BTextControl( rect, name, p_item->psz_text,
- "", new BMessage(),
- B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
- configView->AddChild( textControl );
+ 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_ITEM_INTEGER:
- if( !firstItem )
- rect.OffsetBy( 0, 25 );
+ 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
- firstItem = false;
-
- memset( name, 0, 128 );
- sprintf( name, "i%s", p_item->psz_name );
- textControl = new BTextControl( rect, name, p_item->psz_text,
- "", new BMessage(),
- B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
- configView->AddChild( textControl );
+ {
+ msg_Warn( p_intf, "subcategory without a category" );
+ }
break;
+ }
+ }
+ }
- case CONFIG_ITEM_FLOAT:
- if( !firstItem )
- rect.OffsetBy( 0, 25 );
- else
- firstItem = false;
-
- memset( name, 0, 128 );
- sprintf( name, "f%s", p_item->psz_name );
- textControl = new BTextControl( rect, name, p_item->psz_text,
- "", new BMessage(),
- B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
- configView->AddChild( textControl );
+ /* 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_ITEM_BOOL:
- if( !firstItem )
- rect.OffsetBy( 0,25 );
- else
- firstItem = false;
-
- memset( name, 0, 128 );
- sprintf( name, "b%s", p_item->psz_name );
- checkBox = new BCheckBox( rect, name, p_item->psz_text,
- new BMessage(), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
- configView->AddChild( checkBox );
+ 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;
- } while( p_item->i_type != CONFIG_HINT_END && p_item++ );
-
- /* Adjust the configView size */
- rect.bottom += 10;
- configView->fRealBounds = BRect( 0, 0, configView->Bounds().Width(), rect.bottom );
- configView->ResizeTo( configView->Bounds().Width(), configView->Bounds().Height() );
-
- /* Add the item to the tree */
- StringItemWithView * stringItem;
- stringItem = new StringItemWithView( p_module->psz_object_name );
- stringItem->fConfigView = configView;
- fOutline->AddItem( stringItem );
+ 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 */
- ApplyChanges( false );
-
+ Apply( false );
+
/* Select the first item */
fOutline->Select( 0 );
-
+
/* Add the buttons */
BButton * button;
rect = Bounds();
rect.InsetBy( 10, 10 );
rect.left = rect.right - 80;
rect.top = rect.bottom - 25;
- button = new BButton( rect, "", _("OK"), new BMessage( PREFS_OK ),
+ button = new BButton( rect, "", _("Apply"), new BMessage( PREFS_APPLY ),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
+ button->MakeDefault( true );
fPrefsView->AddChild( button );
rect.OffsetBy( -90, 0 );
- button = new BButton( rect, "", _("Revert"), new BMessage( PREFS_REVERT ),
+ 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, "", _("Apply"), new BMessage( PREFS_APPLY ),
+ button = new BButton( rect, "", _("Defaults"),
+ new BMessage( PREFS_DEFAULTS ),
B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
fPrefsView->AddChild( button );
-
+
Hide();
Show();
}
bool PreferencesWindow::QuitRequested()
{
if( !IsHidden() )
+ {
Hide();
- return false;
+ }
+ return false;
}
/*****************************************************************************
case PREFS_ITEM_SELECTED:
Update();
break;
-
- case PREFS_OK:
- ApplyChanges( true );
- PostMessage( B_QUIT_REQUESTED );
- break;
-
- case PREFS_REVERT:
- ApplyChanges( false );
+
+ case PREFS_DEFAULTS:
+ config_ResetAll( p_intf );
+ config_SaveConfigFile( p_intf, NULL );
+ Apply( false );
break;
-
+
case PREFS_APPLY:
- ApplyChanges( true );
+ Apply( true );
+ break;
+
+ case PREFS_SAVE:
+ Apply( true );
+ config_SaveConfigFile( p_intf, NULL );
break;
default:
void PreferencesWindow::FrameResized( float width, float height )
{
BWindow::FrameResized( width, height );
- UpdateScrollBar();
+ fCurrent->UpdateScrollBar();
}
/*****************************************************************************
*****************************************************************************/
void PreferencesWindow::Update()
{
- /* Get the selected item */
+ /* Get the selected item, if any */
if( fOutline->CurrentSelection() < 0 )
return;
- StringItemWithView * selectedItem =
- (StringItemWithView*) fOutline->ItemAt( fOutline->CurrentSelection() );
- if( fConfigScroll )
+ /* 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( !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 )
{
- /* If we don't do this, the ConfigView will remember a wrong position */
- BScrollBar * scrollBar = fConfigScroll->ScrollBar( B_VERTICAL );
- scrollBar->SetValue( 0 );
-
- /* Detach the current ConfigView, remove the BScrollView */
- BView * view;
- while( ( view = fConfigScroll->ChildAt( 0 ) ) )
- fConfigScroll->RemoveChild( view );
- fDummyView->RemoveChild( fConfigScroll );
- delete fConfigScroll;
+ vlc_object_release( p_module );
}
-
- /* Create a BScrollView with the new ConfigView in it */
- fConfigScroll = new BScrollView( "", selectedItem->fConfigView, B_FOLLOW_ALL_SIDES,
- 0, false, true, B_NO_BORDER );
- fDummyView->AddChild( fConfigScroll );
- UpdateScrollBar();
+ 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 );
}
+/***********************************************************************
+ * 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 */
-
- /* Get the current config view */
- if( fOutline->CurrentSelection() < 0 )
+
+ if( !fScroll )
+ {
return;
- StringItemWithView * selectedItem =
- (StringItemWithView*) fOutline->ItemAt( fOutline->CurrentSelection() );
-
+ }
+
+ /* Get the available BRect for display */
+ BRect display = fScroll->Bounds();
+ display.right -= B_V_SCROLL_BAR_WIDTH;
+
/* Fix the scrollbar */
- BRect visible = fConfigScroll->Bounds() & selectedItem->fConfigView->fRealBounds;
- BRect total = fConfigScroll->Bounds() | selectedItem->fConfigView->fRealBounds;
- BScrollBar * scrollBar = fConfigScroll->ScrollBar( B_VERTICAL );
- long max = (long)( selectedItem->fConfigView->fRealBounds.Height() -
- fConfigScroll->Bounds().Height() );
+ 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
- * Apply changes if doIt is true, revert them otherwise
+ * ConfigItem::ResetScroll
*****************************************************************************/
-void PreferencesWindow::ApplyChanges( bool doIt )
+void ConfigItem::ResetScroll()
{
- StringItemWithView * item;
- ConfigView * 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;
-
- for( int j = 0; j < view->CountChildren(); j++ )
- {
- child = view->ChildAt( j );
- name = child->Name();
- switch( *name )
+ return;
+ }
+
+ fView->ScrollTo( 0, 0 );
+}
+
+/***********************************************************************
+ * 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 );
+ }
+}
+
+/***********************************************************************
+ * 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 )
+{
+ 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++ )
{
- case 's': /* BTextControl, string variable */
- if( doIt )
- config_PutPsz( p_intf, name + 1, ((BTextControl*)child)->Text() );
- else
- ((BTextControl*)child)->SetText( config_GetPsz( p_intf, name + 1 ) );
- break;
- case 'i': /* BTextControl, int variable */
- if( doIt )
- config_PutInt( p_intf, name + 1, atoi( ((BTextControl*)child)->Text() ) );
- else
+ 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;
+ }
+}
+
+ConfigWidget::~ConfigWidget()
+{
+ free( fName );
+}
+
+/***********************************************************************
+ * ConfigWidget::Apply
+ ***********************************************************************
+ *
+ **********************************************************************/
+void ConfigWidget::Apply( bool doIt )
+{
+ 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() )
{
- string = "";
- string << config_GetInt( p_intf, name + 1 );
- ((BTextControl*)child)->SetText( string.String() );
+ val.i_int |= KEY_MODIFIER_ALT;
}
- break;
- case 'f': /* BTextControl, float variable */
- if( doIt )
- config_PutFloat( p_intf, name + 1,
- strtod( ((BTextControl*)child)->Text(), NULL ) );
- else
+ if( fCtrlCheck->Value() )
{
- string = "";
- string << config_GetFloat( p_intf, name + 1 );
- ((BTextControl*)child)->SetText( string.String() );
+ val.i_int |= KEY_MODIFIER_CTRL;
}
- break;
- case 'b': /* BCheckBox, bool variable */
- if( doIt )
- config_PutInt( p_intf, name + 1, ((BCheckBox*)child)->Value() );
- else
- ((BCheckBox*)child)->SetValue( config_GetInt( p_intf, name + 1 ) );
- break;
+ 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;
}
}
-/*****************************************************************************
- * PreferencesWindow::ReallyQuit
- *****************************************************************************/
-void PreferencesWindow::ReallyQuit()
+VTextView::VTextView( BRect frame, const char *name,
+ uint32 resizingMode, uint32 flags )
+ : BTextView( frame, name, BRect( 10,10,10,10 ), resizingMode, flags )
{
- Lock();
- Hide();
- Quit();
+ 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 );
}