1 /*****************************************************************************
2 * preferences_widgets.cpp : wxWindows plugin for vlc
3 *****************************************************************************
4 * Copyright (C) 2000-2004 VideoLAN
7 * Authors: Gildas Bazin <gbazin@netcourrier.com>
8 * Sigmund Augdal <sigmunau@idi.ntnu.no>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
28 #include <stdlib.h> /* malloc(), free() */
29 #include <errno.h> /* ENOMEM */
30 #include <string.h> /* strerror() */
38 #include "wxwindows.h"
39 #include "preferences_widgets.h"
41 /*****************************************************************************
42 * CreateConfigControl wrapper
43 *****************************************************************************/
44 ConfigControl *CreateConfigControl( vlc_object_t *p_this,
45 module_config_t *p_item, wxWindow *parent )
47 ConfigControl *p_control = NULL;
49 switch( p_item->i_type )
51 case CONFIG_ITEM_MODULE:
52 p_control = new ModuleConfigControl( p_this, p_item, parent );
55 case CONFIG_ITEM_STRING:
58 p_control = new StringConfigControl( p_this, p_item, parent );
62 p_control = new StringListConfigControl( p_this, p_item, parent );
66 case CONFIG_ITEM_FILE:
67 case CONFIG_ITEM_DIRECTORY:
68 p_control = new FileConfigControl( p_this, p_item, parent );
71 case CONFIG_ITEM_INTEGER:
74 p_control = new IntegerListConfigControl( p_this, p_item, parent );
76 else if( p_item->i_min != 0 || p_item->i_max != 0 )
78 p_control = new RangedIntConfigControl( p_this, p_item, parent );
82 p_control = new IntegerConfigControl( p_this, p_item, parent );
87 p_control = new KeyConfigControl( p_this, p_item, parent );
90 case CONFIG_ITEM_FLOAT:
91 p_control = new FloatConfigControl( p_this, p_item, parent );
94 case CONFIG_ITEM_BOOL:
95 p_control = new BoolConfigControl( p_this, p_item, parent );
105 /*****************************************************************************
106 * ConfigControl implementation
107 *****************************************************************************/
108 ConfigControl::ConfigControl( vlc_object_t *_p_this,
109 module_config_t *p_item, wxWindow *parent )
110 : wxPanel( parent ), p_this( _p_this ),
111 pf_update_callback( NULL ), p_update_data( NULL ),
112 name( wxU(p_item->psz_name) ), i_type( p_item->i_type ),
113 b_advanced( p_item->b_advanced )
116 sizer = new wxBoxSizer( wxHORIZONTAL );
119 ConfigControl::~ConfigControl()
123 wxSizer *ConfigControl::Sizer()
128 wxString ConfigControl::GetName()
133 int ConfigControl::GetType()
138 vlc_bool_t ConfigControl::IsAdvanced()
143 void ConfigControl::SetUpdateCallback( void (*p_callback)( void * ),
146 pf_update_callback = p_callback;
147 p_update_data = p_data;
150 void ConfigControl::OnUpdate( wxCommandEvent& WXUNUSED(event) )
152 if( pf_update_callback )
154 pf_update_callback( p_update_data );
158 /*****************************************************************************
159 * KeyConfigControl implementation
160 *****************************************************************************/
161 static wxString KeysList[] =
190 wxT("Mouse Wheel Up"),
191 wxT("Mouse Wheel Down"),
235 KeyConfigControl::KeyConfigControl( vlc_object_t *p_this,
236 module_config_t *p_item, wxWindow *parent )
237 : ConfigControl( p_this, p_item, parent )
239 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
240 alt = new wxCheckBox( this, -1, wxU(_("Alt")) );
241 alt->SetValue( p_item->i_value & KEY_MODIFIER_ALT );
242 ctrl = new wxCheckBox( this, -1, wxU(_("Ctrl")) );
243 ctrl->SetValue( p_item->i_value & KEY_MODIFIER_CTRL );
244 shift = new wxCheckBox( this, -1, wxU(_("Shift")) );
245 shift->SetValue( p_item->i_value & KEY_MODIFIER_SHIFT );
246 combo = new wxComboBox( this, -1, wxT(""), wxDefaultPosition,
247 wxDefaultSize, WXSIZEOF(KeysList), KeysList,
249 for( unsigned int i = 0; i < WXSIZEOF(KeysList); i++ )
251 combo->SetClientData( i, (void*)vlc_keys[i].i_key_code );
252 if( (unsigned int)vlc_keys[i].i_key_code ==
253 ( ((unsigned int)p_item->i_value) & ~KEY_MODIFIER ) )
255 combo->SetSelection( i );
256 combo->SetValue( wxU(_(vlc_keys[i].psz_key_string)) );
260 sizer->Add( label, 2, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
261 sizer->Add( alt, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
262 sizer->Add( ctrl, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
263 sizer->Add( shift, 1, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
264 sizer->Add( combo, 2, wxALIGN_CENTER_VERTICAL | wxALL | wxEXPAND, 5 );
266 this->SetSizerAndFit( sizer );
269 KeyConfigControl::~KeyConfigControl()
274 int KeyConfigControl::GetIntValue()
277 if( alt->IsChecked() )
279 result |= KEY_MODIFIER_ALT;
281 if( ctrl->IsChecked() )
283 result |= KEY_MODIFIER_CTRL;
285 if( shift->IsChecked() )
287 result |= KEY_MODIFIER_SHIFT;
289 int selected = combo->GetSelection();
292 result |= (int)combo->GetClientData( selected );
297 /*****************************************************************************
298 * ModuleConfigControl implementation
299 *****************************************************************************/
300 ModuleConfigControl::ModuleConfigControl( vlc_object_t *p_this,
301 module_config_t *p_item,
303 : ConfigControl( p_this, p_item, parent )
308 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
309 combo = new wxComboBox( this, -1, wxL2U(p_item->psz_value),
310 wxDefaultPosition, wxDefaultSize,
311 0, NULL, wxCB_READONLY | wxCB_SORT );
313 /* build a list of available modules */
314 p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
315 combo->Append( wxU(_("Default")), (void *)NULL );
316 combo->SetSelection( 0 );
317 for( int i_index = 0; i_index < p_list->i_count; i_index++ )
319 p_parser = (module_t *)p_list->p_values[i_index].p_object ;
321 if( !strcmp( p_parser->psz_capability, p_item->psz_type ) )
323 combo->Append( wxU(p_parser->psz_longname),
324 p_parser->psz_object_name );
325 if( p_item->psz_value && !strcmp(p_item->psz_value,
326 p_parser->psz_object_name) )
327 combo->SetValue( wxU(p_parser->psz_longname) );
330 vlc_list_release( p_list );
332 combo->SetToolTip( wxU(p_item->psz_longtext) );
333 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
334 sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
336 this->SetSizerAndFit( sizer );
339 ModuleConfigControl::~ModuleConfigControl()
344 wxString ModuleConfigControl::GetPszValue()
346 return wxU( (char *)combo->GetClientData( combo->GetSelection() ));
349 /*****************************************************************************
350 * StringConfigControl implementation
351 *****************************************************************************/
352 StringConfigControl::StringConfigControl( vlc_object_t *p_this,
353 module_config_t *p_item,
355 : ConfigControl( p_this, p_item, parent )
357 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
358 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
359 textctrl = new wxTextCtrl( this, -1,
360 wxL2U(p_item->psz_value),
364 textctrl->SetToolTip( wxU(p_item->psz_longtext) );
365 sizer->Add( textctrl, 1, wxALL, 5 );
367 this->SetSizerAndFit( sizer );
370 StringConfigControl::~StringConfigControl()
375 wxString StringConfigControl::GetPszValue()
377 return textctrl->GetValue();
380 BEGIN_EVENT_TABLE(StringConfigControl, wxPanel)
382 EVT_TEXT(-1, StringConfigControl::OnUpdate)
385 /*****************************************************************************
386 * StringListConfigControl implementation
387 *****************************************************************************/
388 StringListConfigControl::StringListConfigControl( vlc_object_t *p_this,
389 module_config_t *p_item,
391 : ConfigControl( p_this, p_item, parent )
393 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
394 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
395 combo = new wxComboBox( this, -1, wxT(""),
396 wxDefaultPosition, wxDefaultSize,
397 0, NULL, wxCB_READONLY );
398 UpdateCombo( p_item );
400 combo->SetToolTip( wxU(p_item->psz_longtext) );
401 sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
403 for( int i = 0; i < p_item->i_action; i++ )
406 new wxButton( this, wxID_HIGHEST+i,
407 wxU(p_item->ppsz_action_text[i]) );
408 sizer->Add( button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
412 this->SetSizerAndFit( sizer );
415 StringListConfigControl::~StringListConfigControl()
419 void StringListConfigControl::UpdateCombo( module_config_t *p_item )
421 /* build a list of available options */
422 for( int i_index = 0; i_index < p_item->i_list; i_index++ )
424 combo->Append( ( p_item->ppsz_list_text &&
425 p_item->ppsz_list_text[i_index] ) ?
426 wxU(p_item->ppsz_list_text[i_index]) :
427 wxL2U(p_item->ppsz_list[i_index]) );
428 combo->SetClientData( i_index, (void *)p_item->ppsz_list[i_index] );
429 if( ( p_item->psz_value &&
430 !strcmp( p_item->psz_value, p_item->ppsz_list[i_index] ) ) ||
431 ( !p_item->psz_value && !*p_item->ppsz_list[i_index] ) )
433 combo->SetSelection( i_index );
434 combo->SetValue( ( p_item->ppsz_list_text &&
435 p_item->ppsz_list_text[i_index] ) ?
436 wxU(p_item->ppsz_list_text[i_index]) :
437 wxL2U(p_item->ppsz_list[i_index]) );
442 BEGIN_EVENT_TABLE(StringListConfigControl, wxPanel)
444 EVT_BUTTON(-1, StringListConfigControl::OnAction)
447 EVT_TEXT(-1, StringListConfigControl::OnUpdate)
450 void StringListConfigControl::OnAction( wxCommandEvent& event )
452 int i_action = event.GetId() - wxID_HIGHEST;
454 module_config_t *p_item = config_FindConfig( p_this, GetName().mb_str() );
455 if( !p_item ) return;
457 if( i_action < 0 || i_action >= p_item->i_action ) return;
460 wxString value = GetPszValue();
461 (const char *)val.psz_string = value.mb_str();
462 p_item->ppf_action[i_action]( p_this, GetName().mb_str(), val, val, 0 );
464 if( p_item->b_dirty )
467 UpdateCombo( p_item );
468 p_item->b_dirty = VLC_FALSE;
472 wxString StringListConfigControl::GetPszValue()
474 int selected = combo->GetSelection();
477 return wxL2U((char *)combo->GetClientData( selected ));
482 /*****************************************************************************
483 * FileConfigControl implementation
484 *****************************************************************************/
485 FileConfigControl::FileConfigControl( vlc_object_t *p_this,
486 module_config_t *p_item,
488 : ConfigControl( p_this, p_item, parent )
490 directory = p_item->i_type == CONFIG_ITEM_DIRECTORY;
491 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
492 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
493 textctrl = new wxTextCtrl( this, -1,
494 wxL2U(p_item->psz_value),
498 textctrl->SetToolTip( wxU(p_item->psz_longtext) );
499 sizer->Add( textctrl, 1, wxALL, 5 );
500 browse = new wxButton( this, wxID_HIGHEST, wxU(_("Browse...")) );
501 sizer->Add( browse, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
503 this->SetSizerAndFit( sizer );
506 BEGIN_EVENT_TABLE(FileConfigControl, wxPanel)
508 EVT_BUTTON(wxID_HIGHEST, FileConfigControl::OnBrowse)
511 void FileConfigControl::OnBrowse( wxCommandEvent& event )
515 wxDirDialog dialog( this, wxU(_("Choose directory")) );
517 if( dialog.ShowModal() == wxID_OK )
519 textctrl->SetValue( dialog.GetPath() );
524 wxFileDialog dialog( this, wxU(_("Choose file")),
525 wxT(""), wxT(""), wxT("*.*"),
526 #if defined( __WXMSW__ )
532 if( dialog.ShowModal() == wxID_OK )
534 textctrl->SetValue( dialog.GetPath() );
539 FileConfigControl::~FileConfigControl()
544 wxString FileConfigControl::GetPszValue()
546 return textctrl->GetValue();
549 /*****************************************************************************
550 * IntegerConfigControl implementation
551 *****************************************************************************/
552 IntegerConfigControl::IntegerConfigControl( vlc_object_t *p_this,
553 module_config_t *p_item,
555 : ConfigControl( p_this, p_item, parent )
557 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
558 spin = new wxSpinCtrl( this, -1,
559 wxString::Format(wxT("%d"),
561 wxDefaultPosition, wxDefaultSize,
563 -10000000, 10000000, p_item->i_value);
564 spin->SetToolTip( wxU(p_item->psz_longtext) );
565 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
566 sizer->Add( spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
568 this->SetSizerAndFit( sizer );
571 IntegerConfigControl::~IntegerConfigControl()
576 int IntegerConfigControl::GetIntValue()
578 return spin->GetValue();
581 /*****************************************************************************
582 * IntegerListConfigControl implementation
583 *****************************************************************************/
584 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *p_this,
585 module_config_t *p_item,
587 : ConfigControl( p_this, p_item, parent )
589 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
590 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
591 combo = new wxComboBox( this, -1, wxT(""),
592 wxDefaultPosition, wxDefaultSize,
593 0, NULL, wxCB_READONLY );
595 UpdateCombo( p_item );
597 combo->SetToolTip( wxU(p_item->psz_longtext) );
598 sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
601 this->SetSizerAndFit( sizer );
604 IntegerListConfigControl::~IntegerListConfigControl()
608 void IntegerListConfigControl::UpdateCombo( module_config_t *p_item )
610 /* build a list of available options */
611 for( int i_index = 0; i_index < p_item->i_list; i_index++ )
613 if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
615 combo->Append( wxU(p_item->ppsz_list_text[i_index]) );
619 combo->Append( wxString::Format(wxT("%i"),
620 p_item->pi_list[i_index]) );
622 combo->SetClientData( i_index, (void *)p_item->pi_list[i_index] );
623 if( p_item->i_value == p_item->pi_list[i_index] )
625 combo->SetSelection( i_index );
626 if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
628 combo->SetValue( wxU(p_item->ppsz_list_text[i_index]) );
632 combo->SetValue( wxString::Format(wxT("%i"),
633 p_item->pi_list[i_index]) );
639 BEGIN_EVENT_TABLE(IntegerListConfigControl, wxPanel)
641 EVT_BUTTON(-1, IntegerListConfigControl::OnAction)
644 void IntegerListConfigControl::OnAction( wxCommandEvent& event )
646 int i_action = event.GetId() - wxID_HIGHEST;
648 module_config_t *p_item;
649 p_item = config_FindConfig( p_this, GetName().mb_str() );
650 if( !p_item ) return;
652 if( i_action < 0 || i_action >= p_item->i_action ) return;
655 val.i_int = GetIntValue();
656 p_item->ppf_action[i_action]( p_this, GetName().mb_str(), val, val, 0 );
658 if( p_item->b_dirty )
661 UpdateCombo( p_item );
662 p_item->b_dirty = VLC_FALSE;
666 int IntegerListConfigControl::GetIntValue()
668 int selected = combo->GetSelection();
671 return (int)combo->GetClientData( selected );
676 /*****************************************************************************
677 * RangedIntConfigControl implementation
678 *****************************************************************************/
679 RangedIntConfigControl::RangedIntConfigControl( vlc_object_t *p_this,
680 module_config_t *p_item,
682 : ConfigControl( p_this, p_item, parent )
684 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
685 slider = new wxSlider( this, -1, p_item->i_value, p_item->i_min,
686 p_item->i_max, wxDefaultPosition, wxDefaultSize,
687 wxSL_LABELS | wxSL_HORIZONTAL );
688 slider->SetToolTip( wxU(p_item->psz_longtext) );
689 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
690 sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
692 this->SetSizerAndFit( sizer );
695 RangedIntConfigControl::~RangedIntConfigControl()
700 int RangedIntConfigControl::GetIntValue()
702 return slider->GetValue();
705 /*****************************************************************************
706 * FloatConfigControl implementation
707 *****************************************************************************/
708 FloatConfigControl::FloatConfigControl( vlc_object_t *p_this,
709 module_config_t *p_item,
711 : ConfigControl( p_this, p_item, parent )
713 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
714 textctrl = new wxTextCtrl( this, -1,
715 wxString::Format(wxT("%f"),
717 wxDefaultPosition, wxDefaultSize,
718 wxTE_PROCESS_ENTER );
719 textctrl->SetToolTip( wxU(p_item->psz_longtext) );
720 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
721 sizer->Add( textctrl, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
723 this->SetSizerAndFit( sizer );
726 FloatConfigControl::~FloatConfigControl()
731 float FloatConfigControl::GetFloatValue()
734 if( (wxSscanf(textctrl->GetValue(), wxT("%f"), &f_value) == 1) )
739 /*****************************************************************************
740 * BoolConfigControl implementation
741 *****************************************************************************/
742 BoolConfigControl::BoolConfigControl( vlc_object_t *p_this,
743 module_config_t *p_item,
745 : ConfigControl( p_this, p_item, parent )
747 checkbox = new wxCheckBox( this, -1, wxU(p_item->psz_text) );
748 if( p_item->i_value ) checkbox->SetValue(TRUE);
749 checkbox->SetToolTip( wxU(p_item->psz_longtext) );
750 sizer->Add( checkbox, 0, wxALL, 5 );
752 this->SetSizerAndFit( sizer );
755 BoolConfigControl::~BoolConfigControl()
760 int BoolConfigControl::GetIntValue()
762 if( checkbox->IsChecked() )