1 /*****************************************************************************
2 * PreferencesWindow.cpp: beos interface
3 *****************************************************************************
4 * Copyright (C) 1999, 2000, 2001 VideoLAN
5 * $Id: PreferencesWindow.cpp,v 1.15 2003/05/03 13:37:21 titer Exp $
7 * Authors: Eric Petit <titer@videolan.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
22 *****************************************************************************/
24 #include <stdlib.h> /* atoi(), strtod() */
26 #include <InterfaceKit.h>
27 #include <SupportKit.h>
32 #include "PreferencesWindow.h"
34 /*****************************************************************************
35 * StringItemWithView::StringItemWithView
36 *****************************************************************************/
37 StringItemWithView::StringItemWithView( const char * text )
40 /* We use the default constructor */
43 /*****************************************************************************
44 * ConfigView::ConfigView
45 *****************************************************************************/
46 ConfigView::ConfigView( BRect frame, const char * name,
47 uint32 resizingMode, uint32 flags )
48 : BView( frame, name, resizingMode, flags )
50 /* We use the default constructor */
53 /*****************************************************************************
54 * PreferencesWindow::PreferencesWindow
55 *****************************************************************************/
56 PreferencesWindow::PreferencesWindow( intf_thread_t * p_interface,
57 BRect frame, const char * name )
58 : BWindow( frame, name, B_FLOATING_WINDOW_LOOK, B_NORMAL_WINDOW_FEEL,
60 fConfigScroll( NULL ),
65 /* The "background" view */
66 rgb_color background = ui_color( B_PANEL_BACKGROUND_COLOR );
67 fPrefsView = new BView( Bounds(), NULL, B_FOLLOW_ALL, B_WILL_DRAW );
68 fPrefsView->SetViewColor( background );
69 AddChild( fPrefsView );
71 /* Create the preferences tree */
73 rect.InsetBy( 10, 10 );
74 rect.right = rect.left + 150;
75 fOutline = new BOutlineListView( rect, "preferences tree",
76 B_SINGLE_SELECTION_LIST,
77 B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM );
79 rect.right += B_V_SCROLL_BAR_WIDTH;
80 BScrollView * scrollview = new BScrollView( "scrollview", fOutline,
81 B_FOLLOW_LEFT | B_FOLLOW_TOP_BOTTOM,
83 fPrefsView->AddChild( scrollview );
85 /* We need to be informed if the user selects an item */
86 fOutline->SetSelectionMessage( new BMessage( PREFS_ITEM_SELECTED ) );
88 /* Create a dummy view so we can correctly place the real config views later */
90 rect.left = rect.right + 15;
91 rect.right = Bounds().right - 15;
92 fDummyView = new BView( rect, "", B_FOLLOW_ALL_SIDES, B_WILL_DRAW );
93 fPrefsView->AddChild( fDummyView );
97 - manage CONFIG_HINT_SUBCATEGORY
98 - use a pop-up for CONFIG_HINT_MODULE
99 - use BSliders for integer_with_range and float_with_range
100 - add a tab for BeOS specific configution (screenshot path, etc)
101 - add the needed LockLooper()s
102 - fix window resizing
103 - make this intuitive ! */
105 p_list = vlc_list_find( p_intf, VLC_OBJECT_MODULE, FIND_ANYWHERE );
108 msg_Warn( p_intf, "couldn't find any module !" );
113 for( int i = 0; i < p_list->i_count; i++ )
115 p_module = (module_t*) p_list->p_values[i].p_object;
117 /* If the module has no config option, ignore it */
118 module_config_t * p_item;
119 p_item = p_module->p_config;
124 if( p_item->i_type & CONFIG_ITEM )
126 } while( p_item->i_type != CONFIG_HINT_END && p_item++ );
127 if( p_item->i_type == CONFIG_HINT_END )
130 /* Build the config view for this module */
131 rect = fDummyView->Bounds();
132 rect.right -= B_V_SCROLL_BAR_WIDTH;
133 ConfigView * configView;
134 configView = new ConfigView( rect, "config view",
135 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, B_WILL_DRAW );
136 configView->SetViewColor( background );
138 rect = configView->Bounds();
139 rect.InsetBy( 10, 10 );
140 rect.bottom = rect.top + TEXT_HEIGHT;
141 BTextControl * textControl;
142 BCheckBox * checkBox;
144 /* FIXME: we use the BControl name to store the VLC variable name.
145 To know what variable type it is, I add one character at the beginning
146 of the name (see ApplyChanges()); it's not pretty, but it works. To
149 p_item = p_module->p_config;
150 bool firstItem = true;
153 switch( p_item->i_type )
155 case CONFIG_ITEM_STRING:
156 case CONFIG_ITEM_FILE:
157 case CONFIG_ITEM_MODULE:
158 case CONFIG_ITEM_DIRECTORY:
160 rect.OffsetBy( 0, 25 );
164 memset( name, 0, 128 );
165 sprintf( name, "s%s", p_item->psz_name );
166 textControl = new BTextControl( rect, name, p_item->psz_text,
168 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
169 configView->AddChild( textControl );
172 case CONFIG_ITEM_INTEGER:
174 rect.OffsetBy( 0, 25 );
178 memset( name, 0, 128 );
179 sprintf( name, "i%s", p_item->psz_name );
180 textControl = new BTextControl( rect, name, p_item->psz_text,
182 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
183 configView->AddChild( textControl );
186 case CONFIG_ITEM_FLOAT:
188 rect.OffsetBy( 0, 25 );
192 memset( name, 0, 128 );
193 sprintf( name, "f%s", p_item->psz_name );
194 textControl = new BTextControl( rect, name, p_item->psz_text,
196 B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
197 configView->AddChild( textControl );
200 case CONFIG_ITEM_BOOL:
202 rect.OffsetBy( 0,25 );
206 memset( name, 0, 128 );
207 sprintf( name, "b%s", p_item->psz_name );
208 checkBox = new BCheckBox( rect, name, p_item->psz_text,
209 new BMessage(), B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP );
210 configView->AddChild( checkBox );
214 } while( p_item->i_type != CONFIG_HINT_END && p_item++ );
216 /* Adjust the configView size */
218 configView->fRealBounds = BRect( 0, 0, configView->Bounds().Width(), rect.bottom );
219 configView->ResizeTo( configView->Bounds().Width(), configView->Bounds().Height() );
221 /* Add the item to the tree */
222 StringItemWithView * stringItem;
223 stringItem = new StringItemWithView( p_module->psz_object_name );
224 stringItem->fConfigView = configView;
225 fOutline->AddItem( stringItem );
228 vlc_list_release( p_list );
230 /* Set the correct values */
231 ApplyChanges( false );
233 /* Select the first item */
234 fOutline->Select( 0 );
236 /* Add the buttons */
239 rect.InsetBy( 10, 10 );
240 rect.left = rect.right - 80;
241 rect.top = rect.bottom - 25;
242 button = new BButton( rect, "", _("OK"), new BMessage( PREFS_OK ),
243 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
244 fPrefsView->AddChild( button );
245 rect.OffsetBy( -90, 0 );
246 button = new BButton( rect, "", _("Revert"), new BMessage( PREFS_REVERT ),
247 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
248 fPrefsView->AddChild( button );
249 rect.OffsetBy( -90, 0 );
250 button = new BButton( rect, "", _("Apply"), new BMessage( PREFS_APPLY ),
251 B_FOLLOW_RIGHT | B_FOLLOW_BOTTOM );
252 fPrefsView->AddChild( button );
258 /*****************************************************************************
259 * PreferencesWindow::~PreferencesWindow
260 *****************************************************************************/
261 PreferencesWindow::~PreferencesWindow()
265 /*****************************************************************************
266 * PreferencesWindow::QuitRequested
267 *****************************************************************************/
268 bool PreferencesWindow::QuitRequested()
275 /*****************************************************************************
276 * PreferencesWindow::MessageReceived
277 *****************************************************************************/
278 void PreferencesWindow::MessageReceived( BMessage * message )
280 switch( message->what )
282 case PREFS_ITEM_SELECTED:
287 ApplyChanges( true );
288 PostMessage( B_QUIT_REQUESTED );
292 ApplyChanges( false );
296 ApplyChanges( true );
300 BWindow::MessageReceived( message );
304 /*****************************************************************************
305 * PreferencesWindow::FrameResized
306 *****************************************************************************/
307 void PreferencesWindow::FrameResized( float width, float height )
309 BWindow::FrameResized( width, height );
313 /*****************************************************************************
314 * PreferencesWindow::Update
315 *****************************************************************************/
316 void PreferencesWindow::Update()
318 /* Get the selected item */
319 if( fOutline->CurrentSelection() < 0 )
321 StringItemWithView * selectedItem =
322 (StringItemWithView*) fOutline->ItemAt( fOutline->CurrentSelection() );
326 /* If we don't do this, the ConfigView will remember a wrong position */
327 BScrollBar * scrollBar = fConfigScroll->ScrollBar( B_VERTICAL );
328 scrollBar->SetValue( 0 );
330 /* Detach the current ConfigView, remove the BScrollView */
332 while( ( view = fConfigScroll->ChildAt( 0 ) ) )
333 fConfigScroll->RemoveChild( view );
334 fDummyView->RemoveChild( fConfigScroll );
335 delete fConfigScroll;
338 /* Create a BScrollView with the new ConfigView in it */
339 fConfigScroll = new BScrollView( "", selectedItem->fConfigView, B_FOLLOW_ALL_SIDES,
340 0, false, true, B_NO_BORDER );
341 fDummyView->AddChild( fConfigScroll );
346 /*****************************************************************************
347 * PreferencesWindow::UpdateScrollBar
348 *****************************************************************************/
349 void PreferencesWindow::UpdateScrollBar()
351 /* We have to fix the scrollbar manually because it doesn't handle
352 correctly simple BViews */
354 /* Get the current config view */
355 if( fOutline->CurrentSelection() < 0 )
357 StringItemWithView * selectedItem =
358 (StringItemWithView*) fOutline->ItemAt( fOutline->CurrentSelection() );
360 /* Fix the scrollbar */
361 BRect visible = fConfigScroll->Bounds() & selectedItem->fConfigView->fRealBounds;
362 BRect total = fConfigScroll->Bounds() | selectedItem->fConfigView->fRealBounds;
363 BScrollBar * scrollBar = fConfigScroll->ScrollBar( B_VERTICAL );
364 long max = (long)( selectedItem->fConfigView->fRealBounds.Height() -
365 fConfigScroll->Bounds().Height() );
366 if( max < 0 ) max = 0;
367 scrollBar->SetRange( 0, max );
368 scrollBar->SetProportion( visible.Height() / total.Height() );
371 /*****************************************************************************
372 * PreferencesWindow::ApplyChanges
373 * Apply changes if doIt is true, revert them otherwise
374 *****************************************************************************/
375 void PreferencesWindow::ApplyChanges( bool doIt )
377 StringItemWithView * item;
382 for( int i = 0; i < fOutline->CountItems(); i++ )
384 item = (StringItemWithView*) fOutline->ItemAt( i );
385 view = item->fConfigView;
387 for( int j = 0; j < view->CountChildren(); j++ )
389 child = view->ChildAt( j );
390 name = child->Name();
393 case 's': /* BTextControl, string variable */
395 config_PutPsz( p_intf, name + 1, ((BTextControl*)child)->Text() );
397 ((BTextControl*)child)->SetText( config_GetPsz( p_intf, name + 1 ) );
399 case 'i': /* BTextControl, int variable */
401 config_PutInt( p_intf, name + 1, atoi( ((BTextControl*)child)->Text() ) );
405 string << config_GetInt( p_intf, name + 1 );
406 ((BTextControl*)child)->SetText( string.String() );
409 case 'f': /* BTextControl, float variable */
411 config_PutFloat( p_intf, name + 1,
412 strtod( ((BTextControl*)child)->Text(), NULL ) );
416 string << config_GetFloat( p_intf, name + 1 );
417 ((BTextControl*)child)->SetText( string.String() );
420 case 'b': /* BCheckBox, bool variable */
422 config_PutInt( p_intf, name + 1, ((BCheckBox*)child)->Value() );
424 ((BCheckBox*)child)->SetValue( config_GetInt( p_intf, name + 1 ) );
431 /*****************************************************************************
432 * PreferencesWindow::ReallyQuit
433 *****************************************************************************/
434 void PreferencesWindow::ReallyQuit()