1 /*****************************************************************************
2 * preferences_widgets.cpp : WinCE gui plugin for VLC
3 *****************************************************************************
4 * Copyright (C) 2000-2004 VideoLAN
7 * Authors: Marodon Cedric <cedric_marodon@yahoo.fr>
8 * Gildas Bazin <gbazin@videolan.org>
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 <string.h> /* strerror() */
41 #include "preferences_widgets.h"
43 /*****************************************************************************
44 * CreateConfigControl wrapper
45 *****************************************************************************/
46 ConfigControl *CreateConfigControl( vlc_object_t *p_this,
47 module_config_t *p_item,
48 HWND parent, HINSTANCE hInst,
51 ConfigControl *p_control = NULL;
53 switch( p_item->i_type )
55 case CONFIG_ITEM_MODULE:
56 p_control = new ModuleConfigControl( p_this, p_item, parent, hInst, py_pos );
59 case CONFIG_ITEM_STRING:
62 p_control = new StringConfigControl( p_this, p_item, parent, hInst, py_pos );
66 p_control = new StringListConfigControl( p_this, p_item, parent, hInst, py_pos );
70 case CONFIG_ITEM_FILE:
71 case CONFIG_ITEM_DIRECTORY:
72 p_control = new FileConfigControl( p_this, p_item, parent, hInst, py_pos );
75 case CONFIG_ITEM_INTEGER:
78 p_control = new IntegerListConfigControl( p_this, p_item, parent, hInst, py_pos );
80 else if( p_item->i_min != 0 || p_item->i_max != 0 )
82 p_control = new RangedIntConfigControl( p_this, p_item, parent, hInst, py_pos );
86 p_control = new IntegerConfigControl( p_this, p_item, parent, hInst, py_pos );
91 p_control = new KeyConfigControl( p_this, p_item, parent, hInst, py_pos );
94 case CONFIG_ITEM_FLOAT:
95 p_control = new FloatConfigControl( p_this, p_item, parent, hInst, py_pos );
98 case CONFIG_ITEM_BOOL:
99 p_control = new BoolConfigControl( p_this, p_item, parent, hInst, py_pos );
109 /*****************************************************************************
110 * ConfigControl implementation
111 *****************************************************************************/
112 ConfigControl::ConfigControl( vlc_object_t *_p_this,
113 module_config_t *p_item,
114 HWND parent, HINSTANCE hInst )
115 : p_this( _p_this ), pf_update_callback( NULL ), p_update_data( NULL ),
116 parent( parent ), name( p_item->psz_name ), i_type( p_item->i_type ),
117 b_advanced( p_item->b_advanced )
120 /*sizer = new wxBoxSizer( wxHORIZONTAL );*/
123 ConfigControl::~ConfigControl()
127 /*wxSizer *ConfigControl::Sizer()
132 char *ConfigControl::GetName()
137 int ConfigControl::GetType()
142 vlc_bool_t ConfigControl::IsAdvanced()
147 void ConfigControl::SetUpdateCallback( void (*p_callback)( void * ),
150 pf_update_callback = p_callback;
151 p_update_data = p_data;
154 void ConfigControl::OnUpdate( UINT event )
156 if( pf_update_callback )
158 pf_update_callback( p_update_data );
162 /*****************************************************************************
163 * KeyConfigControl implementation
164 *****************************************************************************/
165 string *KeyConfigControl::m_keysList = NULL;
167 KeyConfigControl::KeyConfigControl( vlc_object_t *p_this,
168 module_config_t *p_item,
169 HWND parent, HINSTANCE hInst,
171 : ConfigControl( p_this, p_item, parent, hInst )
173 // Number of keys descriptions
174 unsigned int i_keys = sizeof(vlc_keys)/sizeof(key_descriptor_t);
176 // Init the keys decriptions array
177 if( m_keysList == NULL )
179 m_keysList = new string[i_keys];
180 for( unsigned int i = 0; i < i_keys; i++ )
182 m_keysList[i] = vlc_keys[i].psz_key_string;
186 label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
187 WS_CHILD | WS_VISIBLE | SS_LEFT, 5, *py_pos, 200, 15,
188 parent, NULL, hInst, NULL );
192 alt = CreateWindow( _T("BUTTON"), _T("Alt"),
193 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
194 20, *py_pos, 15, 15, parent, NULL, hInst, NULL );
195 Button_SetCheck( alt, p_item->i_value & KEY_MODIFIER_ALT ? BST_CHECKED :
198 alt_label = CreateWindow( _T("STATIC"), _T("Alt"),
199 WS_CHILD | WS_VISIBLE | SS_LEFT, 20 + 15 + 5, *py_pos, 30, 15,
200 parent, NULL, hInst, NULL );
202 ctrl = CreateWindow( _T("BUTTON"), _T("Ctrl"),
203 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
204 20 + 15 + 5 + 30 + 5, *py_pos, 15, 15,
205 parent, NULL, hInst, NULL );
206 Button_SetCheck( ctrl, p_item->i_value & KEY_MODIFIER_CTRL ? BST_CHECKED :
209 ctrl_label = CreateWindow( _T("STATIC"), _T("Ctrl"),
210 WS_CHILD | WS_VISIBLE | SS_LEFT,
211 20 + 15 + 5 + 30 + 5 + 15 + 5, *py_pos, 30, 15,
212 parent, NULL, hInst, NULL );
214 shift = CreateWindow( _T("BUTTON"), _T("Shift"),
215 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
216 20 + 15 + 5 + 2*(30 + 5) + 15 + 5, *py_pos, 15, 15,
217 parent, NULL, hInst, NULL );
218 Button_SetCheck( shift, p_item->i_value & KEY_MODIFIER_SHIFT ?
219 BST_CHECKED : BST_UNCHECKED );
221 shift_label = CreateWindow( _T("STATIC"), _T("Shift"),
222 WS_CHILD | WS_VISIBLE | SS_LEFT,
223 20 + 15 + 5 + 2*(30 + 5) + 2*(15 + 5), *py_pos, 30, 15,
224 parent, NULL, hInst, NULL );
228 combo = CreateWindow( _T("COMBOBOX"), _T(""),
229 WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL | CBS_DROPDOWNLIST |
230 CBS_SORT | WS_VSCROLL, 20, *py_pos, 130, 5*15 + 6,
231 parent, NULL, hInst, NULL );
235 for( unsigned int i = 0; i < i_keys ; i++ )
237 ComboBox_AddString( combo, _FROMMB(m_keysList[i].c_str()) );
238 ComboBox_SetItemData( combo, i, (void*)vlc_keys[i].i_key_code );
239 if( (unsigned int)vlc_keys[i].i_key_code ==
240 ( ((unsigned int)p_item->i_value) & ~KEY_MODIFIER ) )
242 ComboBox_SetCurSel( combo, i );
243 ComboBox_SetText( combo, _FROMMB(m_keysList[i].c_str()) );
248 KeyConfigControl::~KeyConfigControl()
257 int KeyConfigControl::GetIntValue()
260 if( Button_GetCheck( alt ) )
262 result |= KEY_MODIFIER_ALT;
264 if( Button_GetCheck( ctrl ) )
266 result |= KEY_MODIFIER_CTRL;
268 if( Button_GetCheck( shift ) )
270 result |= KEY_MODIFIER_SHIFT;
272 int selected = ComboBox_GetCurSel( combo );
275 result |= (int)ComboBox_GetItemData( combo, selected );
280 /*****************************************************************************
281 * ModuleConfigControl implementation
282 *****************************************************************************/
283 ModuleConfigControl::ModuleConfigControl( vlc_object_t *p_this,
284 module_config_t *p_item,
285 HWND parent, HINSTANCE hInst,
287 : ConfigControl( p_this, p_item, parent, hInst )
292 label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
293 WS_CHILD | WS_VISIBLE | SS_LEFT,
295 parent, NULL, hInst, NULL );
299 combo = CreateWindow( _T("COMBOBOX"), _T(""),
300 WS_CHILD | WS_VISIBLE | CBS_AUTOHSCROLL |
301 CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL,
302 20, *py_pos, 180, 5*15 + 6,
303 parent, NULL, hInst, NULL);
307 /* build a list of available modules */
308 p_list = vlc_list_find( p_this, VLC_OBJECT_MODULE, FIND_ANYWHERE );
309 ComboBox_AddString( combo, _T("Default") );
310 ComboBox_SetItemData( combo, 0, (void *)NULL );
311 ComboBox_SetCurSel( combo, 0 );
312 //ComboBox_SetText( combo, _T("Default") );
313 for( int i_index = 0; i_index < p_list->i_count; i_index++ )
315 p_parser = (module_t *)p_list->p_values[i_index].p_object ;
317 if( !strcmp( p_parser->psz_capability, p_item->psz_type ) )
319 ComboBox_AddString( combo, _FROMMB(p_parser->psz_longname) );
320 ComboBox_SetItemData( combo, i_index,
321 (void*)p_parser->psz_object_name );
322 if( p_item->psz_value && !strcmp(p_item->psz_value,
323 p_parser->psz_object_name) )
325 ComboBox_SetCurSel( combo, i_index );
326 //ComboBox_SetText( combo, _FROMMB(p_parser->psz_longname) );
330 vlc_list_release( p_list );
333 ModuleConfigControl::~ModuleConfigControl()
338 char *ModuleConfigControl::GetPszValue()
340 int selected = ComboBox_GetCurSel( combo );
342 return (char *)ComboBox_GetItemData( combo, selected );
346 /*****************************************************************************
347 * StringConfigControl implementation
348 *****************************************************************************/
349 StringConfigControl::StringConfigControl( vlc_object_t *p_this,
350 module_config_t *p_item,
351 HWND parent, HINSTANCE hInst,
353 : ConfigControl( p_this, p_item, parent, hInst )
355 label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
356 WS_CHILD | WS_VISIBLE | SS_LEFT,
358 parent, NULL, hInst, NULL );
362 textctrl = CreateWindow( _T("EDIT"), p_item->psz_value ?
363 _FROMMB(p_item->psz_value) : _T(""),
364 WS_CHILD | WS_VISIBLE | WS_BORDER | SS_LEFT |
365 ES_AUTOHSCROLL, 20, *py_pos - 3, 180, 15 + 3,
366 parent, NULL, hInst, NULL );
371 StringConfigControl::~StringConfigControl()
376 char *StringConfigControl::GetPszValue()
382 i_size = Edit_GetTextLength( textctrl );
383 psz_string = (TCHAR *)malloc( (i_size + 1) * sizeof(TCHAR) );
384 Edit_GetText( textctrl, psz_string, i_size + 1 );
385 psz_result = strdup( _TOMB(psz_string) );
391 /*****************************************************************************
392 * StringListConfigControl implementation
393 *****************************************************************************/
394 StringListConfigControl::StringListConfigControl( vlc_object_t *p_this,
395 module_config_t *p_item,
396 HWND parent, HINSTANCE hInst,
398 : ConfigControl( p_this, p_item, parent, hInst )
400 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
401 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
402 combo = new wxComboBox( this, -1, wxT(""),
403 wxDefaultPosition, wxDefaultSize,
404 0, NULL, wxCB_READONLY );
405 UpdateCombo( p_item );
407 combo->SetToolTip( wxU(p_item->psz_longtext) );
408 sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
410 for( int i = 0; i < p_item->i_action; i++ )
413 new wxButton( this, wxID_HIGHEST+i,
414 wxU(p_item->ppsz_action_text[i]) );
415 sizer->Add( button, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
419 this->SetSizerAndFit( sizer );
422 StringListConfigControl::~StringListConfigControl()
426 void StringListConfigControl::UpdateCombo( module_config_t *p_item )
428 /* build a list of available options */
429 for( int i_index = 0; i_index < p_item->i_list; i_index++ )
431 combo->Append( ( p_item->ppsz_list_text &&
432 p_item->ppsz_list_text[i_index] ) ?
433 wxU(p_item->ppsz_list_text[i_index]) :
434 wxL2U(p_item->ppsz_list[i_index]) );
435 combo->SetClientData( i_index, (void *)p_item->ppsz_list[i_index] );
436 if( ( p_item->psz_value &&
437 !strcmp( p_item->psz_value, p_item->ppsz_list[i_index] ) ) ||
438 ( !p_item->psz_value && !*p_item->ppsz_list[i_index] ) )
440 combo->SetSelection( i_index );
441 combo->SetValue( ( p_item->ppsz_list_text &&
442 p_item->ppsz_list_text[i_index] ) ?
443 wxU(p_item->ppsz_list_text[i_index]) :
444 wxL2U(p_item->ppsz_list[i_index]) );
449 BEGIN_EVENT_TABLE(StringListConfigControl, wxPanel)
451 EVT_BUTTON(-1, StringListConfigControl::OnAction)
454 EVT__T(-1, StringListConfigControl::OnUpdate)
457 void StringListConfigControl::OnAction( wxCommandEvent& event )
459 int i_action = event.GetId() - wxID_HIGHEST;
461 module_config_t *p_item = config_FindConfig( p_this, GetName().mb_str() );
462 if( !p_item ) return;
464 if( i_action < 0 || i_action >= p_item->i_action ) return;
467 wxString value = GetPszValue();
468 (const char *)val.psz_string = value.mb_str();
469 p_item->ppf_action[i_action]( p_this, GetName().mb_str(), val, val, 0 );
471 if( p_item->b_dirty )
474 UpdateCombo( p_item );
475 p_item->b_dirty = VLC_FALSE;
479 wxString StringListConfigControl::GetPszValue()
481 int selected = combo->GetSelection();
484 return wxL2U((char *)combo->GetClientData( selected ));
489 /*****************************************************************************
490 * FileConfigControl implementation
491 *****************************************************************************/
492 FileConfigControl::FileConfigControl( vlc_object_t *p_this,
493 module_config_t *p_item,
494 HWND parent, HINSTANCE hInst,
496 : ConfigControl( p_this, p_item, parent, hInst )
498 directory = p_item->i_type == CONFIG_ITEM_DIRECTORY;
499 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
500 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
501 textctrl = new wxTextCtrl( this, -1,
502 wxL2U(p_item->psz_value),
506 textctrl->SetToolTip( wxU(p_item->psz_longtext) );
507 sizer->Add( textctrl, 1, wxALL, 5 );
508 browse = new wxButton( this, wxID_HIGHEST, wxU(_("Browse...")) );
509 sizer->Add( browse, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
511 this->SetSizerAndFit( sizer );
514 BEGIN_EVENT_TABLE(FileConfigControl, wxPanel)
516 EVT_BUTTON(wxID_HIGHEST, FileConfigControl::OnBrowse)
519 void FileConfigControl::OnBrowse( wxCommandEvent& event )
523 wxDirDialog dialog( this, wxU(_("Choose directory")) );
525 if( dialog.ShowModal() == wxID_OK )
527 textctrl->SetValue( dialog.GetPath() );
532 wxFileDialog dialog( this, wxU(_("Choose file")),
533 wxT(""), wxT(""), wxT("*.*"),
534 #if defined( __WXMSW__ )
540 if( dialog.ShowModal() == wxID_OK )
542 textctrl->SetValue( dialog.GetPath() );
547 FileConfigControl::~FileConfigControl()
552 wxString FileConfigControl::GetPszValue()
554 return textctrl->GetValue();
557 /*****************************************************************************
558 * IntegerConfigControl implementation
559 *****************************************************************************/
560 IntegerConfigControl::IntegerConfigControl( vlc_object_t *p_this,
561 module_config_t *p_item,
562 HWND parent, HINSTANCE hInst,
564 : ConfigControl( p_this, p_item, parent, hInst )
566 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
567 spin = new wxSpinCtrl( this, -1,
568 wxString::Format(wxT("%d"),
570 wxDefaultPosition, wxDefaultSize,
572 -10000000, 10000000, p_item->i_value);
573 spin->SetToolTip( wxU(p_item->psz_longtext) );
574 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
575 sizer->Add( spin, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
577 this->SetSizerAndFit( sizer );
580 IntegerConfigControl::~IntegerConfigControl()
585 int IntegerConfigControl::GetIntValue()
587 return spin->GetValue();
590 /*****************************************************************************
591 * IntegerListConfigControl implementation
592 *****************************************************************************/
593 IntegerListConfigControl::IntegerListConfigControl( vlc_object_t *p_this,
594 module_config_t *p_item,
598 : ConfigControl( p_this, p_item, parent, hInst )
600 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
601 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
602 combo = new wxComboBox( this, -1, wxT(""),
603 wxDefaultPosition, wxDefaultSize,
604 0, NULL, wxCB_READONLY );
606 UpdateCombo( p_item );
608 combo->SetToolTip( wxU(p_item->psz_longtext) );
609 sizer->Add( combo, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
612 this->SetSizerAndFit( sizer );
615 IntegerListConfigControl::~IntegerListConfigControl()
619 void IntegerListConfigControl::UpdateCombo( module_config_t *p_item )
621 /* build a list of available options */
622 for( int i_index = 0; i_index < p_item->i_list; i_index++ )
624 if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
626 combo->Append( wxU(p_item->ppsz_list_text[i_index]) );
630 combo->Append( wxString::Format(wxT("%i"),
631 p_item->pi_list[i_index]) );
633 combo->SetClientData( i_index, (void *)p_item->pi_list[i_index] );
634 if( p_item->i_value == p_item->pi_list[i_index] )
636 combo->SetSelection( i_index );
637 if( p_item->ppsz_list_text && p_item->ppsz_list_text[i_index] )
639 combo->SetValue( wxU(p_item->ppsz_list_text[i_index]) );
643 combo->SetValue( wxString::Format(wxT("%i"),
644 p_item->pi_list[i_index]) );
650 BEGIN_EVENT_TABLE(IntegerListConfigControl, wxPanel)
652 EVT_BUTTON(-1, IntegerListConfigControl::OnAction)
655 void IntegerListConfigControl::OnAction( wxCommandEvent& event )
657 int i_action = event.GetId() - wxID_HIGHEST;
659 module_config_t *p_item;
660 p_item = config_FindConfig( p_this, GetName().mb_str() );
661 if( !p_item ) return;
663 if( i_action < 0 || i_action >= p_item->i_action ) return;
666 val.i_int = GetIntValue();
667 p_item->ppf_action[i_action]( p_this, GetName().mb_str(), val, val, 0 );
669 if( p_item->b_dirty )
672 UpdateCombo( p_item );
673 p_item->b_dirty = VLC_FALSE;
677 int IntegerListConfigControl::GetIntValue()
679 int selected = combo->GetSelection();
682 return (int)combo->GetClientData( selected );
687 /*****************************************************************************
688 * RangedIntConfigControl implementation
689 *****************************************************************************/
690 RangedIntConfigControl::RangedIntConfigControl( vlc_object_t *p_this,
691 module_config_t *p_item,
692 HWND parent, HINSTANCE hInst,
694 : ConfigControl( p_this, p_item, parent, hInst )
696 label = new wxStaticText(this, -1, wxU(p_item->psz_text));
697 slider = new wxSlider( this, -1, p_item->i_value, p_item->i_min,
698 p_item->i_max, wxDefaultPosition, wxDefaultSize,
699 wxSL_LABELS | wxSL_HORIZONTAL );
700 slider->SetToolTip( wxU(p_item->psz_longtext) );
701 sizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
702 sizer->Add( slider, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
704 this->SetSizerAndFit( sizer );
707 RangedIntConfigControl::~RangedIntConfigControl()
712 int RangedIntConfigControl::GetIntValue()
714 return slider->GetValue();
718 /*****************************************************************************
719 * FloatConfigControl implementation
720 *****************************************************************************/
721 FloatConfigControl::FloatConfigControl( vlc_object_t *p_this,
722 module_config_t *p_item,
723 HWND parent, HINSTANCE hInst,
725 : ConfigControl( p_this, p_item, parent, hInst )
727 label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
728 WS_CHILD | WS_VISIBLE | SS_LEFT,
730 parent, NULL, hInst, NULL );
734 TCHAR psz_string[100];
735 _stprintf( psz_string, _T("%f"), p_item->f_value );
736 textctrl = CreateWindow( _T("EDIT"), psz_string,
737 WS_CHILD | WS_VISIBLE | WS_BORDER | SS_RIGHT | ES_AUTOHSCROLL,
738 20, *py_pos - 3, 70, 15 + 3, parent, NULL, hInst, NULL );
743 FloatConfigControl::~FloatConfigControl()
748 float FloatConfigControl::GetFloatValue()
752 int i_size = Edit_GetTextLength( textctrl );
753 TCHAR *psz_string = (TCHAR *)malloc( (i_size + 1) * sizeof(TCHAR) );
754 Edit_GetText( textctrl, psz_string, i_size + 1 );
756 if( _tscanf( psz_string, _T("%f"), &f_value ) == 1 )
766 /*****************************************************************************
767 * BoolConfigControl implementation
768 *****************************************************************************/
769 BoolConfigControl::BoolConfigControl( vlc_object_t *p_this,
770 module_config_t *p_item, HWND parent,
771 HINSTANCE hInst, int * py_pos )
772 : ConfigControl( p_this, p_item, parent, hInst )
774 checkbox = CreateWindow( _T("BUTTON"), _T(""),
775 WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
777 parent, NULL, hInst, NULL );
778 Button_SetCheck( checkbox, p_item->i_value ? BST_CHECKED : BST_UNCHECKED );
780 checkbox_label = CreateWindow( _T("STATIC"), _FROMMB(p_item->psz_text),
781 WS_CHILD | WS_VISIBLE | SS_LEFT,
782 5 + 15 + 5, *py_pos, 180, 15,
783 parent, NULL, hInst, NULL );
788 BoolConfigControl::~BoolConfigControl()
793 int BoolConfigControl::GetIntValue()
795 if( Button_GetCheck( checkbox ) ) return 1;