]> git.sesse.net Git - vlc/blob - modules/gui/wxwidgets/extrapanel.cpp
Merge branch 'master' of git@git.videolan.org:vlc
[vlc] / modules / gui / wxwidgets / extrapanel.cpp
1 /*****************************************************************************
2  * extrapanel.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004, 2003 the VideoLAN team
5  * $Id$
6  *
7  * Authors: ClĂ©ment Stenac <zorglub@videolan.org>
8  *
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.
13  *
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.
18  *
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., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <vlc/vlc.h>
32 #include <vlc_aout.h>
33 #include <vlc_vout.h>
34 #include <vlc_interface.h>
35
36 #include <math.h>
37
38 #include "extrapanel.hpp"
39
40 /*****************************************************************************
41  * Local class declarations.
42  *****************************************************************************/
43
44 #define SMOOTH_TIP N_( "Controls the blending of equalizer bands. The higher" \
45             " this value is, the more correlated their movement will be." )
46
47 static int IntfBandsCallback( vlc_object_t *, char const *,
48                               vlc_value_t, vlc_value_t, void * );
49 static int IntfPreampCallback( vlc_object_t *, char const *,
50                                vlc_value_t, vlc_value_t, void * );
51 static void ChangeFiltersString( intf_thread_t *, aout_instance_t *,
52                                  char *, bool );
53 static void ChangeVFiltersString( intf_thread_t *, char *, bool );
54
55
56 /* IDs for the controls and the menu commands */
57 enum
58 {
59     Notebook_Event,
60
61     Adjust_Event,
62     RestoreDefaults_Event,
63
64     Hue_Event,
65     Contrast_Event,
66     Brightness_Event,
67     Saturation_Event,
68     Gamma_Event,
69     Ratio_Event,
70
71     FiltersInfo_Event,
72
73     Filter0_Event, Filter1_Event, Filter2_Event, Filter3_Event, Filter4_Event,
74     Filter5_Event, Filter6_Event, Filter7_Event, Filter8_Event, Filter9_Event,
75
76     EqEnable_Event,
77     Eq2Pass_Event,
78     EqRestore_Event,
79
80     Smooth_Event,
81
82     Preamp_Event,
83
84     Band0_Event,Band1_Event,Band2_Event,Band3_Event,Band4_Event,
85     Band5_Event,Band6_Event,Band7_Event,Band8_Event,Band9_Event,
86
87     NormVol_Event, NVSlider_Event, HeadPhone_Event
88 };
89
90 BEGIN_EVENT_TABLE( ExtraPanel, wxPanel )
91     EVT_IDLE( ExtraPanel::OnIdle )
92
93     /* Equalizer */
94     EVT_CHECKBOX( EqEnable_Event, ExtraPanel::OnEnableEqualizer )
95     EVT_CHECKBOX( Eq2Pass_Event, ExtraPanel::OnEq2Pass )
96     EVT_BUTTON( EqRestore_Event, ExtraPanel::OnEqRestore )
97
98     EVT_COMMAND_SCROLL( Preamp_Event, ExtraPanel::OnPreamp )
99     EVT_COMMAND_SCROLL( Smooth_Event, ExtraPanel::OnEqSmooth )
100
101     EVT_COMMAND_SCROLL(Band0_Event, ExtraPanel::OnChangeEqualizer)
102     EVT_COMMAND_SCROLL(Band1_Event, ExtraPanel::OnChangeEqualizer)
103     EVT_COMMAND_SCROLL(Band2_Event, ExtraPanel::OnChangeEqualizer)
104     EVT_COMMAND_SCROLL(Band3_Event, ExtraPanel::OnChangeEqualizer)
105     EVT_COMMAND_SCROLL(Band4_Event, ExtraPanel::OnChangeEqualizer)
106     EVT_COMMAND_SCROLL(Band5_Event, ExtraPanel::OnChangeEqualizer)
107     EVT_COMMAND_SCROLL(Band6_Event, ExtraPanel::OnChangeEqualizer)
108     EVT_COMMAND_SCROLL(Band7_Event, ExtraPanel::OnChangeEqualizer)
109     EVT_COMMAND_SCROLL(Band8_Event, ExtraPanel::OnChangeEqualizer)
110     EVT_COMMAND_SCROLL(Band9_Event, ExtraPanel::OnChangeEqualizer)
111
112     /* Video */
113     EVT_CHECKBOX( Adjust_Event, ExtraPanel::OnEnableAdjust )
114     EVT_BUTTON( RestoreDefaults_Event, ExtraPanel::OnRestoreDefaults )
115
116     EVT_COMMAND_SCROLL(Hue_Event, ExtraPanel::OnAdjustUpdate)
117     EVT_COMMAND_SCROLL(Contrast_Event, ExtraPanel::OnAdjustUpdate)
118     EVT_COMMAND_SCROLL(Brightness_Event, ExtraPanel::OnAdjustUpdate)
119     EVT_COMMAND_SCROLL(Saturation_Event, ExtraPanel::OnAdjustUpdate)
120     EVT_COMMAND_SCROLL(Gamma_Event, ExtraPanel::OnAdjustUpdate)
121
122     EVT_BUTTON( FiltersInfo_Event, ExtraPanel::OnFiltersInfo )
123
124     EVT_CHECKBOX( Filter0_Event, ExtraPanel::OnSelectFilter )
125     EVT_CHECKBOX( Filter1_Event, ExtraPanel::OnSelectFilter )
126     EVT_CHECKBOX( Filter2_Event, ExtraPanel::OnSelectFilter )
127     EVT_CHECKBOX( Filter3_Event, ExtraPanel::OnSelectFilter )
128     EVT_CHECKBOX( Filter4_Event, ExtraPanel::OnSelectFilter )
129     EVT_CHECKBOX( Filter5_Event, ExtraPanel::OnSelectFilter )
130     EVT_CHECKBOX( Filter6_Event, ExtraPanel::OnSelectFilter )
131     EVT_CHECKBOX( Filter7_Event, ExtraPanel::OnSelectFilter )
132     EVT_CHECKBOX( Filter8_Event, ExtraPanel::OnSelectFilter )
133     EVT_CHECKBOX( Filter9_Event, ExtraPanel::OnSelectFilter )
134
135     /* Audio */
136     EVT_CHECKBOX( NormVol_Event, ExtraPanel::OnNormvol )
137     EVT_CHECKBOX( HeadPhone_Event, ExtraPanel::OnHeadphone )
138
139     EVT_COMMAND_SCROLL( NVSlider_Event, ExtraPanel::OnNormvolSlider )
140
141 END_EVENT_TABLE()
142
143 struct filter {
144     char *psz_filter;
145     char *psz_name;
146     char *psz_help;
147 };
148
149 static const struct filter vfilters[] =
150 {
151     { "clone", N_("Image clone"), N_("Creates several clones of the image") },
152     { "distort", N_("Distortion"), N_("Adds distortion effects") },
153     { "invert", N_("Image inversion") , N_("Inverts the colors of the image") },
154     { "motionblur", N_("Blurring"), N_("Adds motion blurring to the image") },
155     { "transform",  N_("Transformation"), N_("Rotates or flips the image") },
156     { "magnify",  N_("Magnify"), N_("Magnifies part of the image") },
157     { "puzzle",  N_("Puzzle"), N_("Turns the image into a puzzle") },
158     { NULL, NULL, NULL } /* Do not remove this line */
159 };
160
161 /*****************************************************************************
162  * Constructor.
163  *****************************************************************************/
164 ExtraPanel::ExtraPanel( intf_thread_t *_p_intf, wxWindow *_p_parent ):
165         wxPanel( _p_parent , -1, wxDefaultPosition, wxDefaultSize )
166 {
167
168     p_intf = _p_intf;
169     p_parent = _p_parent;
170     SetAutoLayout( TRUE );
171
172     wxBoxSizer *extra_sizer = new wxBoxSizer( wxHORIZONTAL );
173
174     notebook = new wxNotebook( this, Notebook_Event );
175
176 #if (!wxCHECK_VERSION(2,5,2))
177     wxNotebookSizer *notebook_sizer = new wxNotebookSizer( notebook );
178 #endif
179
180     notebook->AddPage( VideoPanel( notebook ), wxU(_("Video")) );
181     notebook->AddPage( EqzPanel( notebook ), wxU(_("Equalizer")) );
182     notebook->AddPage( AudioPanel( notebook ), wxU(_("Audio")) );
183
184 #if (!wxCHECK_VERSION(2,5,2))
185     extra_sizer->Add( notebook_sizer, 1, wxEXPAND, 0 );
186 #else
187     extra_sizer->Add( notebook, 1, wxEXPAND, 0 );
188 #endif
189
190     SetSizerAndFit( extra_sizer );
191     extra_sizer->Layout();
192 }
193
194 ExtraPanel::~ExtraPanel()
195 {
196 }
197
198 /* Video Panel constructor */
199 wxPanel *ExtraPanel::VideoPanel( wxWindow *parent )
200 {
201     char *psz_filters;
202
203     wxPanel *panel = new wxPanel( parent, -1 );
204     wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
205
206     /* Create static box to surround the adjust controls */
207     wxStaticBox *adjust_box =
208            new wxStaticBox( panel, -1, wxU(_("Image adjustment" )) );
209     wxStaticBoxSizer *adjust_sizer =
210         new wxStaticBoxSizer( adjust_box, wxVERTICAL );
211     adjust_sizer->SetMinSize( -1, 50 );
212
213     /* Create flex grid */
214     wxFlexGridSizer *adjust_gridsizer =
215         new wxFlexGridSizer( 6, 2, 0, 0);
216     adjust_gridsizer->AddGrowableCol(1);
217
218     /* Create the adjust button */
219     wxCheckBox * adjust_check = new wxCheckBox( panel, Adjust_Event,
220                                                  wxU(_("Enable")));
221
222     /* Create the restore to defaults button */
223     restoredefaults_button =
224         new wxButton( panel, RestoreDefaults_Event,
225         wxU(_("Restore Defaults")), wxDefaultPosition);
226
227     wxStaticText *hue_text = new wxStaticText( panel, -1,
228                                        wxU(_("Hue")) );
229     hue_slider = new wxSlider ( panel, Hue_Event, 0, 0,
230                                 360, wxDefaultPosition, wxDefaultSize );
231
232     wxStaticText *contrast_text = new wxStaticText( panel, -1,
233                                        wxU(_("Contrast")) );
234     contrast_slider = new wxSlider ( panel, Contrast_Event, 0, 0,
235                                 200, wxDefaultPosition, wxDefaultSize);
236
237     wxStaticText *brightness_text = new wxStaticText( panel, -1,
238                                        wxU(_("Brightness")) );
239     brightness_slider = new wxSlider ( panel, Brightness_Event, 0, 0,
240                            200, wxDefaultPosition, wxDefaultSize) ;
241
242     wxStaticText *saturation_text = new wxStaticText( panel, -1,
243                                           wxU(_("Saturation")) );
244     saturation_slider = new wxSlider ( panel, Saturation_Event, 0, 0,
245                            300, wxDefaultPosition, wxDefaultSize );
246
247     wxStaticText *gamma_text = new wxStaticText( panel, -1,
248                                           wxU(_("Gamma")) );
249     gamma_slider = new wxSlider ( panel, Gamma_Event, 0, 0,
250                            100, wxDefaultPosition, wxDefaultSize );
251
252     adjust_gridsizer->Add( adjust_check, 1, wxEXPAND|wxALL, 2 );
253     adjust_gridsizer->Add( restoredefaults_button, 1, wxEXPAND|wxALL, 2 );
254     adjust_gridsizer->Add( hue_text, 1, wxEXPAND|wxALL, 2 );
255     adjust_gridsizer->Add( hue_slider, 1, wxEXPAND|wxALL, 2 );
256     adjust_gridsizer->Add( contrast_text, 1, wxEXPAND|wxALL, 2 );
257     adjust_gridsizer->Add( contrast_slider, 1, wxEXPAND|wxALL, 2 );
258     adjust_gridsizer->Add( brightness_text, 1, wxEXPAND|wxALL, 2 );
259     adjust_gridsizer->Add( brightness_slider, 1, wxEXPAND|wxALL, 2 );
260     adjust_gridsizer->Add( saturation_text, 1, wxEXPAND|wxALL, 2 );
261     adjust_gridsizer->Add( saturation_slider, 1, wxEXPAND|wxALL, 2 );
262     adjust_gridsizer->Add( gamma_text, 1, wxEXPAND|wxALL, 2 );
263     adjust_gridsizer->Add( gamma_slider, 1, wxEXPAND|wxALL, 2 );
264
265     adjust_sizer->Add( adjust_gridsizer, 1, wxEXPAND|wxALL, 2);
266
267     panel_sizer->Add( adjust_sizer , 1, wxTOP, 2 );
268
269 #if 0
270     /* Create sizer to surround the other controls */
271     wxBoxSizer *other_sizer = new wxBoxSizer( wxVERTICAL );
272
273     wxStaticBox *video_box =
274             new wxStaticBox( panel, -1, wxU(_("Video Options")) );
275     /* Create the sizer for the frame */
276     wxStaticBoxSizer *video_sizer =
277        new wxStaticBoxSizer( video_box, wxVERTICAL );
278     video_sizer->SetMinSize( -1, 50 );
279
280     static const wxString ratio_array[] =
281     {
282         wxT("4:3"),
283         wxT("16:9"),
284     };
285
286     wxBoxSizer *ratio_sizer = new wxBoxSizer( wxHORIZONTAL );
287     wxStaticText *ratio_text = new wxStaticText( panel, -1,
288                                           wxU(_("Aspect Ratio")) );
289
290     ratio_combo = new wxComboBox( panel, Ratio_Event, wxT(""),
291                                   wxDefaultPosition, wxSize( 80 , -1),
292                                   WXSIZEOF(ratio_array), ratio_array,
293                                   0 );
294
295     ratio_sizer->Add( ratio_text, 0, wxALL, 2 );
296     ratio_sizer->Add( ratio_combo, 0, wxALL, 2 );
297     ratio_sizer->Layout();
298
299     video_sizer->Add( ratio_sizer  , 0 , wxALL , 2 );
300     video_sizer->Layout();
301 #endif
302
303     wxStaticBox *filter_box =
304                   new wxStaticBox( panel, -1, wxU(_("Video filters")) );
305     wxStaticBoxSizer *filter_sizer =
306                    new wxStaticBoxSizer( filter_box, wxHORIZONTAL );
307
308     wxBoxSizer *t_col_sizer = new wxBoxSizer( wxVERTICAL );
309
310
311     for( int i = 0 ; vfilters[i].psz_filter != NULL ; i++ )
312     {
313         wxCheckBox *box = new wxCheckBox( panel, Filter0_Event + i,
314                                           wxU( _( vfilters[i].psz_name ) ) );
315         t_col_sizer->Add( box, 0, wxALL, 2 );
316         box->SetToolTip( wxU( _( vfilters[i].psz_help ) ) );
317     }
318
319     filter_sizer->Add( t_col_sizer );
320     filter_sizer->Add( new wxButton( panel, FiltersInfo_Event,
321                             wxU(_("More Info" ) ) ), 0, wxALL, 4 );
322 #if 0
323     other_sizer->Add( video_sizer, 0, wxALL | wxEXPAND , 0);
324     other_sizer->Add( filter_sizer, 0, wxALL | wxEXPAND , 0);
325     other_sizer->Layout();
326     panel_sizer->Add(other_sizer , 1 );
327 #endif
328
329     panel_sizer->Add( filter_sizer, 1, wxTOP|wxLEFT, 2 );
330
331     panel->SetSizerAndFit( panel_sizer );
332
333     /* Layout the whole panel */
334     panel_sizer->Layout();
335
336     panel_sizer->SetSizeHints( panel );
337
338     /* Write down initial values */
339     psz_filters = config_GetPsz( p_intf, "vout-filter" );
340     if( psz_filters && strstr( psz_filters, "adjust" ) )
341     {
342         adjust_check->SetValue( 1 );
343         restoredefaults_button->Enable();
344         saturation_slider->Enable();
345         contrast_slider->Enable();
346         brightness_slider->Enable();
347         hue_slider->Enable();
348         gamma_slider->Enable();
349     }
350     else
351     {
352         adjust_check->SetValue( 0 );
353         restoredefaults_button->Disable();
354         saturation_slider->Disable();
355         contrast_slider->Disable();
356         brightness_slider->Disable();
357         hue_slider->Disable();
358         gamma_slider->Disable();
359     }
360     free( psz_filters );
361
362     int i_value = config_GetInt( p_intf, "hue" );
363     if( i_value > 0 && i_value < 360 )
364         hue_slider->SetValue( i_value );
365     float f_value;
366     f_value = config_GetFloat( p_intf, "saturation" );
367     if( f_value > 0 && f_value < 5 )
368         saturation_slider->SetValue( (int)(100 * f_value) );
369     f_value = config_GetFloat( p_intf, "contrast" );
370     if( f_value > 0 && f_value < 4 )
371         contrast_slider->SetValue( (int)(100 * f_value) );
372     f_value = config_GetFloat( p_intf, "brightness" );
373     if( f_value > 0 && f_value < 2 )
374         brightness_slider->SetValue( (int)(100 * f_value) );
375     f_value = config_GetFloat( p_intf, "gamma" );
376     if( f_value > 0 && f_value < 10 )
377         gamma_slider->SetValue( (int)(10 * f_value) );
378
379     b_update = false;
380
381     return panel;
382 }
383
384 /* Audio panel constructor */
385 wxPanel *ExtraPanel::AudioPanel( wxWindow *parent )
386 {
387     char *psz_filters;
388
389     wxPanel *panel = new wxPanel( parent, -1 );
390     wxBoxSizer *panel_sizer = new wxBoxSizer( wxHORIZONTAL );
391
392     /* Create static box to surround the adjust controls */
393     wxStaticBox *filter_box =
394            new wxStaticBox( panel, -1, wxU(_("Audio filters")) );
395     wxStaticBoxSizer *filter_sizer =
396         new wxStaticBoxSizer( filter_box, wxVERTICAL );
397     filter_sizer->SetMinSize( -1, 50 );
398
399     wxCheckBox * headphone_check = new wxCheckBox( panel, HeadPhone_Event,
400                                     wxU(_("Headphone virtualization")));
401     headphone_check->SetToolTip( wxU(_("Imitates the effect of "
402              "surround sound when using headphones." ) ) );
403
404     wxCheckBox * normvol_check = new wxCheckBox( panel, NormVol_Event,
405                                     wxU(_("Volume normalization")));
406     normvol_check->SetToolTip( wxU(_("Prevents the audio output "
407                          "level from going over a predefined value." ) ) );
408
409     wxStaticText *normvol_label = new wxStaticText( panel, -1,
410                                    wxU( _("Maximum level") ) );
411
412     wxSlider *normvol_slider = new wxSlider ( panel, NVSlider_Event, 20, 5,
413                            100, wxDefaultPosition, wxSize( 100, -1 ) );
414
415     filter_sizer->Add( headphone_check, 0, wxALL, 4 );
416     filter_sizer->Add( normvol_check, 0, wxALL, 4 );
417     filter_sizer->Add( normvol_label, 0, wxALL, 4 );
418     filter_sizer->Add( normvol_slider, 0, wxALL, 4 );
419
420     panel_sizer->Add( filter_sizer, 1, wxTOP, 2 );
421     panel->SetSizerAndFit( panel_sizer );
422     panel_sizer->Layout();
423     panel_sizer->SetSizeHints( panel );
424
425     /* Write down initial values */
426     psz_filters = config_GetPsz( p_intf, "audio-filter" );
427     if( psz_filters )
428     {
429         headphone_check->SetValue( strstr( psz_filters, "headphone" ) );
430         normvol_check->SetValue( strstr( psz_filters, "normvol" ) );
431         free( psz_filters );
432     }
433     else
434     {
435         headphone_check->SetValue( 0 );
436         normvol_check->SetValue( 0 );
437     }
438
439     return panel;
440 }
441
442
443 static const wxString band_frequencies[] =
444 {
445     wxT(" 60 Hz"),
446     wxT("170 Hz"),
447     wxT("310 Hz"),
448     wxT("600 Hz"),
449     wxT(" 1 kHz"),
450     wxT(" 3 kHz"),
451     wxT(" 6 kHz"),
452     wxT("12 kHz"),
453     wxT("14 kHz"),
454     wxT("16 kHz")
455 };
456
457 /* Equalizer Panel constructor */
458 wxPanel *ExtraPanel::EqzPanel( wxWindow *parent )
459 {
460     wxPanel *panel = new wxPanel( parent, -1 );
461     wxBoxSizer *panel_sizer = new wxBoxSizer( wxVERTICAL );
462
463     /* Create static box to surround the adjust controls */
464     wxBoxSizer *top_sizer =
465         new wxBoxSizer( wxHORIZONTAL );
466
467     /* Create the enable button */
468     eq_chkbox =  new wxCheckBox( panel, EqEnable_Event,
469                             wxU(_("Enable") ) );
470     eq_chkbox->SetToolTip( wxU(_("Enable the equalizer. You can either "
471     "manually adjust the bands or use a preset (Audio Menu->Equalizer)." ) ) );
472     top_sizer->Add( eq_chkbox, 0, wxALL, 2 );
473
474     eq_2p_chkbox =  new wxCheckBox( panel, Eq2Pass_Event,
475                             wxU(_("2 Pass") ) );
476
477     eq_2p_chkbox->SetToolTip( wxU(_("Apply the equalizer twice. "
478                "The resulting effect will be sharper.") ) );
479
480     top_sizer->Add( eq_2p_chkbox, 0, wxALL, 2 );
481
482     top_sizer->Add( 0, 0, 1, wxALL, 2 );
483
484     eq_restoredefaults_button = new wxButton( panel, EqRestore_Event,
485                                   wxU( _("Restore Defaults") ) );
486     top_sizer->Add( eq_restoredefaults_button, 0, wxALL, 2 );
487     top_sizer->Add( 0, 0, 1, wxALL, 2 );
488
489     smooth_text = new wxStaticText( panel, -1, wxU( _("Smooth :") ));
490     smooth_text->SetToolTip( wxU( _(SMOOTH_TIP) ) );
491     top_sizer->Add( smooth_text, 0, wxALL, 2 );
492
493     smooth_slider =new wxSlider( panel, Smooth_Event, 0, 0, 10 ,
494                     wxDefaultPosition, wxSize( 100, -1 ) );
495     smooth_slider->SetToolTip( wxU( _(SMOOTH_TIP) ) );
496     top_sizer->Add( smooth_slider, 0, wxALL, 2 );
497     i_smooth = 0;
498
499     /* Create flex grid */
500     wxFlexGridSizer *eq_gridsizer =
501         new wxFlexGridSizer( 2, 12, 0, 0);
502     eq_gridsizer->AddGrowableRow( 0 );
503     eq_gridsizer->AddGrowableCol( 1 );
504
505     preamp_slider = new wxSlider( panel, Preamp_Event, 80, 0, 400,
506                     wxDefaultPosition, wxSize( -1 , 90 ) , wxSL_VERTICAL );
507     eq_gridsizer->Add( preamp_slider, 1, wxEXPAND|wxALL, 2 );
508
509     eq_gridsizer->Add( 0, 0, 1, wxALL, 2 );
510
511     for( int i = 0 ; i < 10 ; i++ )
512     {
513         band_sliders[i] = new wxSlider( panel, Band0_Event + i, 200, 0, 400,
514                     wxDefaultPosition, wxSize( -1 , 90 ) , wxSL_VERTICAL );
515
516         i_values[i] = 200;
517         eq_gridsizer->Add( band_sliders[i], 1, wxEXPAND|wxALL, 2 );
518     }
519
520     preamp_text = new wxStaticText( panel, -1, wxU( _("Preamp\n12.0dB") ) );
521     wxFont font= preamp_text->GetFont();
522     font.SetPointSize(7);
523     preamp_text->SetFont( font );
524     eq_gridsizer->Add( preamp_text, wxALL, 2 );
525
526     eq_gridsizer->Add( 0, 0, 1 );
527
528     for( int i = 0 ; i < 10 ; i++ )
529     {
530         band_texts[i] = new wxStaticText( panel, -1,
531                                 band_frequencies[i] + wxU("\n0.0dB" ) ) ;
532         eq_gridsizer->Add( band_texts[i], 1, wxEXPAND|wxALL, 2 );
533         wxFont font= band_texts[i]->GetFont();
534         font.SetPointSize(7);
535         band_texts[i]->SetFont( font );
536     }
537
538     panel_sizer->Add( top_sizer , 0 , wxTOP | wxEXPAND, 5 );
539     panel_sizer->Add( eq_gridsizer , 0 , wxEXPAND, 0 );
540
541     panel->SetSizer( panel_sizer );
542
543     panel_sizer->Layout();
544
545     panel_sizer->SetSizeHints( panel );
546
547     CheckAout();
548
549     aout_instance_t *p_aout = (aout_instance_t *)vlc_object_find(p_intf,
550                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
551     char *psz_af;
552     if( p_aout )
553     {
554         psz_af = var_GetNonEmptyString( p_aout, "audio-filter" );
555         if( var_GetBool( p_aout, "equalizer-2pass" ) )
556             eq_2p_chkbox->SetValue( true );
557         vlc_object_release( p_aout );
558     }
559     else
560     {
561         psz_af = config_GetPsz( p_intf, "audio-filter" );
562         if( config_GetInt( p_intf, "equalizer-2pass" ) )
563             eq_2p_chkbox->SetValue( true );
564     }
565     if( psz_af != NULL && strstr( psz_af, "equalizer" ) )
566     {
567         eq_chkbox->SetValue( true );
568     } else {
569         eq_2p_chkbox->Disable();
570         eq_restoredefaults_button->Disable();
571         smooth_slider->Disable();
572         smooth_text->Disable();
573         preamp_slider->Disable();
574         preamp_text->Disable();
575         for( int i_index=0; i_index < 10; i_index++ )
576         {
577             band_sliders[i_index]->Disable();
578             band_texts[i_index]->Disable();
579         }
580     }
581     free( psz_af );
582
583     return panel;
584 }
585
586 /*******************************************************
587  * Event handlers
588  *******************************************************/
589
590 /* Keep aout up to date and update the bands if needed */
591 void ExtraPanel::OnIdle( wxIdleEvent &event )
592 {
593     CheckAout();
594     if( b_update == true )
595     {
596         if( b_my_update == true )
597         {
598             b_update = b_my_update = false;
599             return;
600         }
601         char *p = psz_bands;
602         for( int i = 0; i < 10; i++ )
603         {
604                 float f;
605                 char psz_val[5];
606                 int i_val;
607                 /* Read dB -20/20*/
608                 f = strtof( p, &p );
609                 i_val= (int)( ( f + 20 ) * 10 );
610                 band_sliders[i]->SetValue( 400 - i_val );
611                 i_values[i] = 400 - i_val;
612                 sprintf( psz_val, "%.1f", f );
613                 band_texts[i]->SetLabel( band_frequencies[i] + wxT("\n") +
614                                                 wxU( psz_val ) + wxT("dB") );
615                 if( p == NULL )
616                 {
617                     break;
618                 }
619                 p++;
620                 if( *p == 0 )
621                     break;
622         }
623         char psz_val[5];
624         int i_val = (int)( ( f_preamp + 20 ) * 10 );
625         sprintf( psz_val, "%.1f", f_preamp );
626         preamp_slider->SetValue( 400 - i_val );
627         const wxString preamp = wxT("Preamp\n");
628         preamp_text->SetLabel( preamp + wxU( psz_val ) + wxT( "dB" ) );
629         eq_chkbox->SetValue( TRUE );
630         b_update = false;
631     }
632 }
633
634 /*************************
635  *  Equalizer Panel events
636  *************************/
637 void ExtraPanel::OnEnableEqualizer( wxCommandEvent &event )
638 {
639     int i_index;
640     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
641                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
642     ChangeFiltersString( p_intf,p_aout, "equalizer",
643                          event.IsChecked() ? true : false );
644
645     if( event.IsChecked() )
646     {
647         eq_2p_chkbox->Enable();
648         eq_restoredefaults_button->Enable();
649         smooth_slider->Enable();
650         smooth_text->Enable();
651         preamp_slider->Enable();
652         preamp_text->Enable();
653         for( i_index=0; i_index < 10; i_index++ )
654         {
655             band_sliders[i_index]->Enable();
656             band_texts[i_index]->Enable();
657         }
658     } else {
659         eq_2p_chkbox->Disable();
660         eq_restoredefaults_button->Disable();
661         smooth_slider->Disable();
662         smooth_text->Disable();
663         preamp_slider->Disable();
664         preamp_text->Disable();
665         for( i_index=0; i_index < 10; i_index++ )
666         {
667             band_sliders[i_index]->Disable();
668             band_texts[i_index]->Disable();
669         }
670     }
671
672     if( p_aout != NULL )
673         vlc_object_release( p_aout );
674 }
675
676 void ExtraPanel::OnEqRestore( wxCommandEvent &event )
677 {
678     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
679                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
680     if( p_aout == NULL )
681     {
682         vlc_value_t val;
683         bool b_previous = eq_chkbox->IsChecked();
684         val.f_float = 12.0;
685         IntfPreampCallback( NULL, NULL, val,val, this );
686         config_PutFloat( p_intf, "equalizer-preamp", 12.0 );
687         val.psz_string = strdup( "0 0 0 0 0 0 0 0 0 0" );
688         IntfBandsCallback( NULL, NULL, val,val, this );
689         config_PutPsz( p_intf, "equalizer-bands",
690                                 "0 0 0 0 0 0 0 0 0 0");
691         config_PutPsz( p_intf, "equalizer-preset","flat" );
692         eq_chkbox->SetValue( b_previous );
693     }
694     else
695     {
696         var_SetFloat( p_aout, "equalizer-preamp", 12.0 );
697         config_PutFloat( p_intf, "equalizer-preamp", 12.0 );
698         var_SetString( p_aout, "equalizer-bands",
699                                 "0 0 0 0 0 0 0 0 0 0");
700         config_PutPsz( p_intf, "equalizer-bands",
701                                 "0 0 0 0 0 0 0 0 0 0");
702         var_SetString( p_aout , "equalizer-preset" , "flat" );
703         config_PutPsz( p_intf, "equalizer-preset","flat" );
704         vlc_object_release( p_aout );
705     }
706 }
707
708 void ExtraPanel::OnEq2Pass( wxCommandEvent &event )
709 {
710     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
711                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
712
713     bool b_2p = event.IsChecked() ? true : false;
714
715     if( p_aout == NULL )
716     {
717         config_PutInt( p_intf, "equalizer-2pass", b_2p );
718     }
719     else
720     {
721         var_SetBool( p_aout, "equalizer-2pass", b_2p );
722         config_PutInt( p_intf, "equalizer-2pass", b_2p );
723         if( eq_chkbox->IsChecked() )
724         {
725             for( int i = 0; i < p_aout->i_nb_inputs; i++ )
726             {
727                 p_aout->pp_inputs[i]->b_restart = true;
728             }
729         }
730         vlc_object_release( p_aout );
731     }
732 }
733
734 void ExtraPanel::OnEqSmooth( wxScrollEvent &event )
735 {
736     /* Max smoothing : 70% */
737     i_smooth = event.GetPosition() * 7;
738 }
739
740 void ExtraPanel::OnPreamp( wxScrollEvent &event )
741 {
742     float f= (float)( 400 - event.GetPosition() ) / 10 - 20 ;
743     char psz_val[5];
744
745     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
746                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
747
748     sprintf( psz_val, "%.1f", f );
749     const wxString preamp = wxT("Preamp\n");
750     preamp_text->SetLabel( preamp + wxU( psz_val ) + wxT( "dB" ) );
751
752     if( p_aout == NULL )
753     {
754         config_PutFloat( p_intf, "equalizer-preamp", f );
755     }
756     else
757     {
758         var_SetFloat( p_aout, "equalizer-preamp", f );
759         config_PutFloat( p_intf, "equalizer-preamp", f );
760         b_my_update = true;
761         vlc_object_release( p_aout );
762     }
763 }
764
765 void ExtraPanel::OnChangeEqualizer( wxScrollEvent &event )
766 {
767     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
768                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
769     char psz_values[102];
770     memset( psz_values, 0, 102 );
771
772
773     /* Smoothing */
774     int i_diff = event.GetPosition() - i_values[  event.GetId() - Band0_Event ];
775     i_values[ event.GetId() - Band0_Event] = event.GetPosition();
776
777     for( int i = event.GetId() + 1 ; i <= Band9_Event ; i++ )
778     {
779         int i_new = band_sliders[ i-Band0_Event ]->GetValue() +
780            (int)( i_diff * pow( (float)i_smooth / 100 , i- event.GetId() ) ) ;
781         if( i_new < 0 ) i_new = 0;
782         if( i_new > 400 ) i_new = 400;
783         band_sliders[ i-Band0_Event ]->SetValue( i_new );
784     }
785     for( int i = Band0_Event ; i < event.GetId() ; i++ )
786     {
787         int i_new =   band_sliders[ i-Band0_Event ]->GetValue() +
788            (int)( i_diff * pow( (float)i_smooth / 100 , event.GetId() - i  ) );
789         if( i_new < 0 ) i_new = 0;
790         if( i_new > 400 ) i_new = 400;
791         band_sliders[ i-Band0_Event ]->SetValue( i_new );
792     }
793
794     /* Write the new bands values */
795     for( int i = 0 ; i < 10 ; i++ )
796     {
797         char psz_val[5];
798         float f_val = (float)( 400 - band_sliders[i]->GetValue() ) / 10- 20 ;
799         sprintf( psz_values, "%s %f", psz_values, f_val );
800         sprintf( psz_val, "%.1f", f_val );
801         band_texts[i]->SetLabel( band_frequencies[i] + wxT("\n") +
802                         wxU( psz_val ) + wxT("dB" ) );
803     }
804     if( p_aout == NULL )
805     {
806         config_PutPsz( p_intf, "equalizer-bands", psz_values );
807     }
808     else
809     {
810         var_SetString( p_aout, "equalizer-bands", psz_values );
811         config_PutPsz( p_intf, "equalizer-bands", psz_values );
812         b_my_update = true;
813         vlc_object_release( p_aout );
814     }
815 }
816
817 /***********************
818  * Audio Panel events
819  ***********************/
820 void ExtraPanel::OnHeadphone( wxCommandEvent &event )
821 {
822     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
823                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
824     ChangeFiltersString( p_intf , p_aout, "headphone_channel_mixer",
825                          event.IsChecked() ? true : false );
826     if( p_aout != NULL )
827         vlc_object_release( p_aout );
828 }
829
830 void ExtraPanel::OnNormvol( wxCommandEvent &event )
831 {
832     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
833                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
834     ChangeFiltersString( p_intf , p_aout, "normvol",
835                          event.IsChecked() ? true : false );
836     if( p_aout != NULL )
837         vlc_object_release( p_aout );
838 }
839
840 void ExtraPanel::OnNormvolSlider( wxScrollEvent &event )
841 {
842     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
843                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
844     if( p_aout != NULL )
845     {
846         var_SetFloat( p_aout, "norm-max-level", (float)event.GetPosition()/10 );
847         vlc_object_release( p_aout );
848     }
849     else
850     {
851         config_PutFloat( p_intf, "norm-max-level",
852                         (float)event.GetPosition()/10 );
853     }
854 }
855 /***********************
856  *  Video Panel events
857  ***********************/
858 void ExtraPanel::OnEnableAdjust(wxCommandEvent& event)
859 {
860     ChangeVFiltersString( p_intf,  "adjust",
861                           event.IsChecked() ? true : false );
862
863     if( event.IsChecked() )
864     {
865         restoredefaults_button->Enable();
866         brightness_slider->Enable();
867         saturation_slider->Enable();
868         contrast_slider->Enable();
869         hue_slider->Enable();
870         gamma_slider->Enable();
871     }
872     else
873     {
874         restoredefaults_button->Disable();
875         brightness_slider->Disable();
876         saturation_slider->Disable();
877         contrast_slider->Disable();
878         hue_slider->Disable();
879         gamma_slider->Disable();
880     }
881 }
882
883 void ExtraPanel::OnRestoreDefaults( wxCommandEvent &event)
884 {
885     hue_slider->SetValue(0);
886     saturation_slider->SetValue(100);
887     brightness_slider->SetValue(100);
888     contrast_slider->SetValue(100),
889     gamma_slider->SetValue(10);
890
891     wxScrollEvent *hscroll_event = new wxScrollEvent(0, Hue_Event, 0);
892     OnAdjustUpdate(*hscroll_event);
893
894     wxScrollEvent *sscroll_event = new wxScrollEvent(0, Saturation_Event, 100);
895     OnAdjustUpdate(*sscroll_event);
896
897     wxScrollEvent *bscroll_event = new wxScrollEvent(0, Brightness_Event, 100);
898     OnAdjustUpdate(*bscroll_event);
899
900     wxScrollEvent *cscroll_event = new wxScrollEvent(0, Contrast_Event, 100);
901     OnAdjustUpdate(*cscroll_event);
902
903     wxScrollEvent *gscroll_event = new wxScrollEvent(0, Gamma_Event, 10);
904     OnAdjustUpdate(*gscroll_event);
905
906 }
907
908 void ExtraPanel::OnAdjustUpdate( wxScrollEvent &event)
909 {
910     vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find(p_intf,
911                                  VLC_OBJECT_VOUT, FIND_ANYWHERE);
912     if( p_vout == NULL )
913     {
914         switch( event.GetId() )
915         {
916             case Hue_Event:
917                 config_PutInt( p_intf , "hue" , event.GetPosition() );
918                 break;
919
920             case Saturation_Event:
921                 config_PutFloat( p_intf , "saturation" ,
922                                 (float)event.GetPosition()/100 );
923                 break;
924
925             case Brightness_Event:
926                 config_PutFloat( p_intf , "brightness" ,
927                                 (float)event.GetPosition()/100 );
928                 break;
929
930             case Contrast_Event:
931                 config_PutFloat( p_intf , "contrast" ,
932                                 (float)event.GetPosition()/100 );
933                 break;
934
935             case Gamma_Event:
936                 config_PutFloat( p_intf , "gamma" ,
937                                 (float)event.GetPosition()/10 );
938                 break;
939         }
940     }
941     else
942     {
943         vlc_value_t val;
944         switch( event.GetId() )
945         {
946             case Hue_Event:
947                 val.i_int = event.GetPosition();
948                 var_Set( p_vout, "hue", val );
949                 config_PutInt( p_intf , "hue" , event.GetPosition() );
950                 break;
951
952             case Saturation_Event:
953                 val.f_float = (float)event.GetPosition() / 100;
954                 var_Set( p_vout, "saturation", val );
955                 config_PutFloat( p_intf , "saturation" ,
956                                 (float)event.GetPosition()/100 );
957                 break;
958
959             case Brightness_Event:
960                 val.f_float = (float)event.GetPosition() / 100;
961                 var_Set( p_vout, "brightness", val );
962                 config_PutFloat( p_intf , "brightness" ,
963                                 (float)event.GetPosition()/100 );
964                 break;
965
966             case Contrast_Event:
967                 val.f_float = (float)event.GetPosition() / 100;
968                 var_Set( p_vout, "contrast", val );
969                 config_PutFloat( p_intf , "contrast" ,
970                                 (float)event.GetPosition()/100 );
971                 break;
972
973             case Gamma_Event:
974                 val.f_float = (float)event.GetPosition() / 10;
975                 var_Set( p_vout, "gamma", val );
976                 config_PutFloat( p_intf , "gamma" ,
977                                 (float)event.GetPosition()/10 );
978                 break;
979         }
980         vlc_object_release(p_vout);
981     }
982 }
983
984 /* FIXME */
985 void ExtraPanel::OnRatio( wxCommandEvent& event )
986 {
987    config_PutPsz( p_intf, "aspect-ratio", ratio_combo->GetValue().mb_str(wxConvUTF8) );
988 }
989
990
991 void ExtraPanel::OnSelectFilter(wxCommandEvent& event)
992 {
993     int i_filter = event.GetId() - Filter0_Event ;
994     if( vfilters[i_filter].psz_filter  )
995     {
996         ChangeVFiltersString( p_intf, vfilters[i_filter].psz_filter ,
997                               event.IsChecked() ? true : false );
998     }
999 }
1000
1001 void ExtraPanel::OnFiltersInfo(wxCommandEvent& event)
1002 {
1003     wxMessageBox( wxU( _("Filtering effects to apply to the video. "
1004                   "You must restart the stream for these settings to "
1005                   "take effect.\n\n"
1006                   "To configure these filters, go to Preferences / Video / "
1007                   "Filters. In order to control the order in which they "
1008                   "are applied, enter a filters string in the Video Filter "
1009                   "Module inside the preferences."
1010                   ) ),
1011                     wxU( _("More Information" ) ), wxOK | wxICON_INFORMATION,
1012                     this->p_parent );
1013 }
1014 /**********************************
1015  * Other functions
1016  **********************************/
1017 void ExtraPanel::CheckAout()
1018 {
1019     aout_instance_t *p_aout= (aout_instance_t *)vlc_object_find(p_intf,
1020                                  VLC_OBJECT_AOUT, FIND_ANYWHERE);
1021     if( p_aout != NULL )
1022     {
1023         if( p_aout != p_intf->p_sys->p_aout )
1024         {
1025             /* We want to know if someone changes the bands */
1026             if( var_AddCallback( p_aout, "equalizer-bands",
1027                                     IntfBandsCallback, this ) )
1028             {
1029                 /* The variable does not exist yet, wait */
1030                 vlc_object_release( p_aout );
1031                 return;
1032             }
1033             if( var_AddCallback( p_aout, "equalizer-preamp",
1034                                     IntfPreampCallback, this )  )
1035             {
1036                 vlc_object_release( p_aout );
1037                 return;
1038             }
1039             /* Ok, we have our variables, make a first update round */
1040             p_intf->p_sys->p_aout = p_aout;
1041
1042             f_preamp = var_GetFloat( p_aout, "equalizer-preamp" );
1043             psz_bands = var_GetNonEmptyString( p_aout, "equalizer-bands" );
1044             if( psz_bands == NULL )
1045                 psz_bands = strdup("");
1046             b_update = true;
1047         }
1048         vlc_object_release( p_aout );
1049     }
1050 }
1051
1052
1053 static void ChangeVFiltersString( intf_thread_t *p_intf,
1054                                  char *psz_name, bool b_add )
1055 {
1056     vout_thread_t *p_vout;
1057     char *psz_parser, *psz_string;
1058
1059     psz_string = config_GetPsz( p_intf, "vout-filter" );
1060
1061     if( !psz_string ) psz_string = strdup("");
1062
1063     psz_parser = strstr( psz_string, psz_name );
1064
1065     if( b_add )
1066     {
1067         if( !psz_parser )
1068         {
1069             psz_parser = psz_string;
1070             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
1071                             psz_string, psz_name );
1072             free( psz_parser );
1073         }
1074         else
1075         {
1076             return;
1077         }
1078     }
1079     else
1080     {
1081         if( psz_parser )
1082         {
1083             memmove( psz_parser, psz_parser + strlen(psz_name) +
1084                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
1085                             strlen(psz_parser + strlen(psz_name)) + 1 );
1086
1087             /* Remove trailing : : */
1088             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
1089             {
1090                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
1091             }
1092          }
1093          else
1094          {
1095              free( psz_string );
1096              return;
1097          }
1098     }
1099     /* Vout is not kept, so put that in the config */
1100     config_PutPsz( p_intf, "vout-filter", psz_string );
1101
1102     /* Try to set on the fly */
1103     p_vout = (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1104                                               FIND_ANYWHERE );
1105     if( p_vout )
1106     {
1107         var_SetString( p_vout, "vout-filter", psz_string );
1108         vlc_object_release( p_vout );
1109     }
1110
1111     free( psz_string );
1112 }
1113
1114
1115 static void ChangeFiltersString( intf_thread_t *p_intf,
1116                                  aout_instance_t * p_aout,
1117                                  char *psz_name, bool b_add )
1118 {
1119     char *psz_parser, *psz_string;
1120
1121     if( p_aout )
1122     {
1123         psz_string = var_GetNonEmptyString( p_aout, "audio-filter" );
1124     }
1125     else
1126     {
1127         psz_string = config_GetPsz( p_intf, "audio-filter" );
1128     }
1129
1130     if( !psz_string ) psz_string = strdup("");
1131
1132     psz_parser = strstr( psz_string, psz_name );
1133
1134     if( b_add )
1135     {
1136         if( !psz_parser )
1137         {
1138             psz_parser = psz_string;
1139             asprintf( &psz_string, (*psz_string) ? "%s:%s" : "%s%s",
1140                             psz_string, psz_name );
1141             free( psz_parser );
1142         }
1143         else
1144         {
1145             return;
1146         }
1147     }
1148     else
1149     {
1150         if( psz_parser )
1151         {
1152             memmove( psz_parser, psz_parser + strlen(psz_name) +
1153                             (*(psz_parser + strlen(psz_name)) == ':' ? 1 : 0 ),
1154                             strlen(psz_parser + strlen(psz_name)) + 1 );
1155
1156             if( *(psz_string+strlen(psz_string ) -1 ) == ':' )
1157             {
1158                 *(psz_string+strlen(psz_string ) -1 ) = '\0';
1159             }
1160          }
1161          else
1162          {
1163              free( psz_string );
1164              return;
1165          }
1166     }
1167
1168     if( p_aout == NULL )
1169     {
1170         config_PutPsz( p_intf, "audio-filter", psz_string );
1171     }
1172     else
1173     {
1174         var_SetString( p_aout, "audio-filter", psz_string );
1175         for( int i = 0; i < p_aout->i_nb_inputs; i++ )
1176         {
1177             p_aout->pp_inputs[i]->b_restart = true;
1178         }
1179     }
1180     free( psz_string );
1181 }
1182
1183
1184 static int IntfBandsCallback( vlc_object_t *p_this, char const *psz_cmd,
1185                           vlc_value_t oldval, vlc_value_t newval, void *param )
1186 {
1187     ExtraPanel *p_panel = (ExtraPanel *)param;
1188
1189     p_panel->psz_bands = strdup( newval.psz_string );
1190     p_panel->b_update = true;
1191
1192     return VLC_SUCCESS;
1193 }
1194
1195 static int IntfPreampCallback( vlc_object_t *p_this, char const *psz_cmd,
1196                           vlc_value_t oldval, vlc_value_t newval, void *param )
1197 {
1198     ExtraPanel *p_panel = (ExtraPanel *)param;
1199
1200     p_panel->f_preamp = newval.f_float;
1201     p_panel->b_update = true;
1202
1203     return VLC_SUCCESS;
1204 }
1205
1206 #if 0
1207 /**********************************************************************
1208  * A small window to contain the extrapanel in its undocked state
1209  **********************************************************************/
1210 BEGIN_EVENT_TABLE(ExtraWindow, wxFrame)
1211 END_EVENT_TABLE()
1212
1213
1214 ExtraWindow::ExtraWindow( intf_thread_t *_p_intf, wxWindow *p_parent,
1215                           wxPanel *_extra_panel ):
1216        wxFrame( p_parent, -1, wxU(_("Extended controls")), wxDefaultPosition,
1217                  wxDefaultSize, wxDEFAULT_FRAME_STYLE )
1218 {
1219     p_intf = _p_intf;
1220     SetIcon( *p_intf->p_sys->p_icon );
1221
1222     wxBoxSizer *window_sizer = new wxBoxSizer( wxVERTICAL );
1223     SetSizer( window_sizer );
1224
1225     panel = _extra_panel;
1226     window_sizer->Add( panel );
1227
1228     window_sizer->Layout();
1229     window_sizer->Fit( this );
1230
1231     Show();
1232 }
1233
1234 ExtraWindow::~ExtraWindow()
1235 {
1236     delete panel;
1237 }
1238 #endif