]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/interface.cpp
* modules/gui/wxwindows/interface.cpp: better heuristic for the interface size on...
[vlc] / modules / gui / wxwindows / interface.cpp
1 /*****************************************************************************
2  * interface.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001, 2003 VideoLAN
5  * $Id: interface.cpp,v 1.79 2003/12/16 13:22:51 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc/aout.h>
29 #include <vlc/vout.h>
30 #include <vlc/intf.h>
31 #include "stream_control.h"
32
33 #include "wxwindows.h"
34
35 /* include the toolbar graphics */
36 #include "bitmaps/file.xpm"
37
38 #include "bitmaps/disc.xpm"
39 #include "bitmaps/net.xpm"
40 #if 0
41  #include "bitmaps/sat.xpm"
42 #endif
43 #include "bitmaps/play.xpm"
44 #include "bitmaps/pause.xpm"
45 #include "bitmaps/stop.xpm"
46 #include "bitmaps/previous.xpm"
47 #include "bitmaps/next.xpm"
48 #include "bitmaps/playlist.xpm"
49 #include "bitmaps/fast.xpm"
50 #include "bitmaps/slow.xpm"
51
52 #include <wx/listctrl.h>
53
54 #define TOOLBAR_BMP_WIDTH 36
55 #define TOOLBAR_BMP_HEIGHT 36
56
57 /* include the icon graphic */
58 #include "../../../share/vlc32x32.xpm"
59
60 /*****************************************************************************
61  * Local class declarations.
62  *****************************************************************************/
63 class wxMenuExt: public wxMenu
64 {
65 public:
66     /* Constructor */
67     wxMenuExt( wxMenu* parentMenu, int id, const wxString& text,
68                    const wxString& helpString, wxItemKind kind,
69                    char *_psz_var, int _i_object_id, vlc_value_t _val,
70                    int _i_val_type );
71
72     virtual ~wxMenuExt() {};
73
74     char *psz_var;
75     int  i_val_type;
76     int  i_object_id;
77     vlc_value_t val;
78
79 private:
80
81 };
82
83 class wxVolCtrl: public wxGauge
84 {
85 public:
86     /* Constructor */
87     wxVolCtrl( intf_thread_t *_p_intf, wxWindow* parent, wxWindowID id );
88     virtual ~wxVolCtrl() {};
89
90     void Change( int i_volume );
91
92     void OnChange( wxMouseEvent& event );
93
94 private:
95     intf_thread_t *p_intf;
96
97     DECLARE_EVENT_TABLE();
98 };
99
100 BEGIN_EVENT_TABLE(wxVolCtrl, wxWindow)
101     /* Mouse events */
102     EVT_LEFT_DOWN(wxVolCtrl::OnChange)
103     EVT_MOTION(wxVolCtrl::OnChange)
104 END_EVENT_TABLE()
105
106 /*****************************************************************************
107  * Event Table.
108  *****************************************************************************/
109
110 /* IDs for the controls and the menu commands */
111 enum
112 {
113     /* menu items */
114     MenuDummy_Event = wxID_HIGHEST + 1000,
115     Exit_Event = wxID_HIGHEST,
116     OpenFileSimple_Event,
117     OpenAdv_Event,
118     OpenFile_Event,
119     OpenDisc_Event,
120     OpenNet_Event,
121     OpenSat_Event,
122     OpenOther_Event,
123     EjectDisc_Event,
124
125     Stream_Event,
126
127     Playlist_Event,
128     Logs_Event,
129     FileInfo_Event,
130
131     Prefs_Event,
132     Extra_Event,
133     Skins_Event,
134
135     SliderScroll_Event,
136     StopStream_Event,
137     PlayStream_Event,
138     PrevStream_Event,
139     NextStream_Event,
140     SlowStream_Event,
141     FastStream_Event,
142
143     Adjust_Event,
144     Hue_Event,
145     Contrast_Event,
146     Brightness_Event,
147     Saturation_Event,
148
149     Ratio_Event,
150     Visual_Event,
151
152     /* it is important for the id corresponding to the "About" command to have
153      * this standard value as otherwise it won't be handled properly under Mac
154      * (where it is special and put into the "Apple" menu) */
155     About_Event = wxID_ABOUT
156 };
157
158 BEGIN_EVENT_TABLE(Interface, wxFrame)
159     /* Menu events */
160     EVT_MENU(Exit_Event, Interface::OnExit)
161     EVT_MENU(About_Event, Interface::OnAbout)
162
163     EVT_MENU(Playlist_Event, Interface::OnShowDialog)
164     EVT_MENU(Logs_Event, Interface::OnShowDialog)
165     EVT_MENU(FileInfo_Event, Interface::OnShowDialog)
166     EVT_MENU(Prefs_Event, Interface::OnShowDialog)
167
168     EVT_MENU_OPEN(Interface::OnMenuOpen)
169
170     EVT_MENU( Extra_Event, Interface::OnExtra)
171     EVT_CHECKBOX( Adjust_Event, Interface::OnEnableAdjust)
172
173     EVT_COMBOBOX( Ratio_Event, Interface::OnRatio)
174     EVT_CHECKBOX( Visual_Event, Interface::OnEnableVisual)
175
176 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
177     EVT_CONTEXT_MENU(Interface::OnContextMenu2)
178 #endif
179     EVT_RIGHT_UP(Interface::OnContextMenu)
180
181     /* Toolbar events */
182     EVT_MENU(OpenFileSimple_Event, Interface::OnShowDialog)
183     EVT_MENU(OpenAdv_Event, Interface::OnShowDialog)
184     EVT_MENU(OpenFile_Event, Interface::OnShowDialog)
185     EVT_MENU(OpenDisc_Event, Interface::OnShowDialog)
186     EVT_MENU(OpenNet_Event, Interface::OnShowDialog)
187     EVT_MENU(OpenSat_Event, Interface::OnShowDialog)
188     EVT_MENU(Stream_Event, Interface::OnStream)
189     EVT_MENU(StopStream_Event, Interface::OnStopStream)
190     EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
191     EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
192     EVT_MENU(NextStream_Event, Interface::OnNextStream)
193     EVT_MENU(SlowStream_Event, Interface::OnSlowStream)
194     EVT_MENU(FastStream_Event, Interface::OnFastStream)
195
196     /* Slider events */
197     EVT_COMMAND_SCROLL(SliderScroll_Event, Interface::OnSliderUpdate)
198
199     EVT_COMMAND_SCROLL(Hue_Event, Interface::OnHueUpdate)
200     EVT_COMMAND_SCROLL(Contrast_Event, Interface::OnContrastUpdate)
201     EVT_COMMAND_SCROLL(Brightness_Event, Interface::OnBrightnessUpdate)
202     EVT_COMMAND_SCROLL(Saturation_Event, Interface::OnSaturationUpdate)
203
204 END_EVENT_TABLE()
205
206 /*****************************************************************************
207  * Constructor.
208  *****************************************************************************/
209 Interface::Interface( intf_thread_t *_p_intf ):
210     wxFrame( NULL, -1, wxT("VLC media player"),
211              wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE )
212 {
213     /* Initializations */
214     p_intf = _p_intf;
215     i_old_playing_status = PAUSE_S;
216     b_extra = VLC_FALSE;
217
218     /* Give our interface a nice little icon */
219     SetIcon( wxIcon( vlc_xpm ) );
220
221     /* Create a sizer for the main frame */
222     frame_sizer = new wxBoxSizer( wxVERTICAL );
223     SetSizer( frame_sizer );
224
225     /* Create a dummy widget that can get the keyboard focus */
226     wxWindow *p_dummy = new wxWindow( this, 0, wxDefaultPosition,
227                                       wxSize(0,0) );
228     p_dummy->SetFocus();
229     frame_sizer->Add( p_dummy, 0, wxEXPAND );
230
231     /* Creation of the menu bar */
232     CreateOurMenuBar();
233
234     /* Creation of the tool bar */
235     CreateOurToolBar();
236
237     /* Creation of the slider sub-window */
238     CreateOurSlider();
239     frame_sizer->Add( slider_frame, 0, wxEXPAND , 0 );
240     frame_sizer->Hide( slider_frame );
241
242     /* Create the extra panel */
243     CreateOurExtraPanel();
244     frame_sizer->Add( extra_frame, 0, wxEXPAND , 0 );
245     frame_sizer->Hide( extra_frame );
246
247     /* Creation of the status bar
248      * Helptext for menu items and toolbar tools will automatically get
249      * displayed here. */
250     int i_status_width[3] = {-6, -2, -9};
251     statusbar = CreateStatusBar( 3 );                            /* 2 fields */
252     statusbar->SetStatusWidths( 3, i_status_width );
253     statusbar->SetStatusText( wxString::Format(wxT("x%.2f"), 1.0), 1 );
254
255     /* Make sure we've got the right background colour */
256     SetBackgroundColour( slider_frame->GetBackgroundColour() );
257
258     /* Layout everything */
259     frame_sizer->Layout();
260     frame_sizer->Fit(this);
261
262 #if !defined(__WXX11__)
263     /* Associate drop targets with the main interface */
264     SetDropTarget( new DragAndDrop( p_intf ) );
265 #endif
266
267     UpdateAcceleratorTable();
268
269     /* Start timer */
270     timer = new Timer( p_intf, this );
271 }
272
273 Interface::~Interface()
274 {
275     if( p_intf->p_sys->p_wxwindow )
276     {
277         delete p_intf->p_sys->p_wxwindow;
278     }
279
280     /* Clean up */
281     delete timer;
282 }
283
284 /*****************************************************************************
285  * Private methods.
286  *****************************************************************************/
287 void Interface::CreateOurMenuBar()
288 {
289 #define HELP_SIMPLE N_("Quick file open")
290 #define HELP_ADV N_("Advanced open")
291 #define HELP_FILE  N_("Open a file")
292 #define HELP_DISC  N_("Open Disc Media")
293 #define HELP_NET   N_("Open a network stream")
294 #define HELP_SAT   N_("Open a satellite stream")
295 #define HELP_EJECT N_("Eject the DVD/CD")
296 #define HELP_EXIT  N_("Exit this program")
297
298 #define HELP_STREAMWIZARD N_("Open the streaming wizard")
299 #define HELP_OTHER N_("Open other types of inputs")
300
301 #define HELP_PLAYLIST   N_("Open the playlist")
302 #define HELP_LOGS       N_("Show the program logs")
303 #define HELP_FILEINFO       N_("Show information about the file being played")
304
305 #define HELP_PREFS N_("Go to the preferences menu")
306 #define EXTRA_PREFS N_("Shows the extended GUI")
307
308 #define HELP_ABOUT N_("About this program")
309
310     /* Create the "File" menu */
311     wxMenu *file_menu = new wxMenu;
312     file_menu->Append( OpenFileSimple_Event, wxU(_("Quick &Open ...")),
313                        wxU(_(HELP_SIMPLE)) );
314
315     file_menu->AppendSeparator();
316     file_menu->Append( OpenFile_Event, wxU(_("Open &File...")),
317                       wxU(_(HELP_FILE)));
318     file_menu->Append( OpenDisc_Event, wxU(_("Open &Disc...")),
319                       wxU(_(HELP_DISC)));
320     file_menu->Append( OpenNet_Event, wxU(_("Open &Network Stream...")),
321                       wxU(_(HELP_NET)));
322
323 #if 0
324     file_menu->Append( OpenSat_Event, wxU(_("Open &Satellite Stream...")),
325                        wxU(_(HELP_NET)) );
326 #endif
327     file_menu->AppendSeparator();
328     file_menu->Append( Stream_Event, wxU(_("Streaming Wizard...")),
329                        wxU(_(HELP_STREAMWIZARD)) );
330     file_menu->AppendSeparator();
331     file_menu->Append( Exit_Event, wxU(_("E&xit")), wxU(_(HELP_EXIT)) );
332
333     /* Create the "View" menu */
334     wxMenu *view_menu = new wxMenu;
335     view_menu->Append( Playlist_Event, wxU(_("&Playlist...")),
336                        wxU(_(HELP_PLAYLIST)) );
337     view_menu->Append( Logs_Event, wxU(_("&Messages...")), wxU(_(HELP_LOGS)) );
338     view_menu->Append( FileInfo_Event, wxU(_("&Stream and Media info...")),
339                        wxU(_(HELP_FILEINFO)) );
340
341     /* Create the "Settings" menu */
342     p_settings_menu = new wxMenu;
343     b_settings_menu = 1;
344
345     /* Create the "Audio" menu */
346     p_audio_menu = new wxMenu;
347     b_audio_menu = 1;
348
349     /* Create the "Video" menu */
350     p_video_menu = new wxMenu;
351     b_video_menu = 1;
352
353     /* Create the "Navigation" menu */
354     p_navig_menu = new wxMenu;
355     b_navig_menu = 1;
356
357     /* Create the "Help" menu */
358     wxMenu *help_menu = new wxMenu;
359     help_menu->Append( About_Event, wxU(_("&About...")), wxU(_(HELP_ABOUT)) );
360
361     /* Append the freshly created menus to the menu bar... */
362     wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
363     menubar->Append( file_menu, wxU(_("&File")) );
364     menubar->Append( view_menu, wxU(_("&View")) );
365     menubar->Append( p_settings_menu, wxU(_("&Settings")) );
366     menubar->Append( p_audio_menu, wxU(_("&Audio")) );
367     menubar->Append( p_video_menu, wxU(_("&Video")) );
368     menubar->Append( p_navig_menu, wxU(_("&Navigation")) );
369     menubar->Append( help_menu, wxU(_("&Help")) );
370
371     /* Attach the menu bar to the frame */
372     SetMenuBar( menubar );
373
374     /* Intercept all menu events in our custom event handler */
375     PushEventHandler( new MenuEvtHandler( p_intf, this ) );
376
377 #if !defined(__WXX11__)
378     /* Associate drop targets with the menubar */
379     menubar->SetDropTarget( new DragAndDrop( p_intf ) );
380 #endif
381 }
382
383 void Interface::CreateOurToolBar()
384 {
385 #define HELP_STOP N_("Stop current playlist item")
386
387 #define HELP_PLAY N_("Play current playlist item")
388 #define HELP_PAUSE N_("Pause current playlist item")
389 #define HELP_PLO N_("Open playlist")
390 #define HELP_PLP N_("Previous playlist item")
391 #define HELP_PLN N_("Next playlist item")
392 #define HELP_SLOW N_("Play slower")
393 #define HELP_FAST N_("Play faster")
394
395     wxLogNull LogDummy; /* Hack to suppress annoying log message on the win32
396                          * version because we don't include wx.rc */
397
398     wxToolBar *toolbar =
399         CreateToolBar( wxTB_HORIZONTAL | wxTB_FLAT | wxTB_DOCKABLE );
400
401     toolbar->SetToolBitmapSize( wxSize(TOOLBAR_BMP_WIDTH,TOOLBAR_BMP_HEIGHT) );
402
403     toolbar->AddTool( OpenFileSimple_Event, wxU(_("Quick")),
404                       wxBitmap( file_xpm ), wxU(_(HELP_SIMPLE)) );
405
406     toolbar->AddSeparator();
407     toolbar->AddTool( OpenFile_Event, wxU(_("File")), wxBitmap( file_xpm ),
408                       wxU(_(HELP_FILE)) );
409     toolbar->AddTool( OpenDisc_Event, wxU(_("Disc")), wxBitmap( disc_xpm ),
410                       wxU(_(HELP_DISC)) );
411     toolbar->AddTool( OpenNet_Event, wxU(_("Net")), wxBitmap( net_xpm ),
412                       wxU(_(HELP_NET)) );
413     toolbar->AddSeparator();
414
415     toolbar->AddTool( StopStream_Event, wxU(_("Stop")), wxBitmap( stop_xpm ),
416                       wxU(_(HELP_STOP)) );
417     toolbar->AddTool( PlayStream_Event, wxU(_("Play")), wxBitmap( play_xpm ),
418                       wxU(_(HELP_PLAY)) );
419
420     toolbar->AddSeparator();
421     toolbar->AddTool( Playlist_Event, wxU(_("Playlist")),
422                       wxBitmap( playlist_xpm ), wxU(_(HELP_PLO)) );
423     toolbar->AddTool( PrevStream_Event, wxU(_("Prev")),
424                       wxBitmap( previous_xpm ), wxU(_(HELP_PLP)) );
425     toolbar->AddTool( NextStream_Event, wxU(_("Next")), wxBitmap( next_xpm ),
426                       wxU(_(HELP_PLN)) );
427     toolbar->AddTool( SlowStream_Event, wxU(_("Slower")), wxBitmap( slow_xpm ),
428                       wxU(_(HELP_SLOW)) );
429     toolbar->AddTool( FastStream_Event, wxU(_("Faster")), wxBitmap( fast_xpm ),
430                       wxU(_(HELP_FAST)) );
431
432     toolbar->Realize();
433
434     /* Place the toolbar in a sizer, so we can calculate the width of the
435      * toolbar and set this as the minimum for the main frame size. */
436     wxBoxSizer *toolbar_sizer = new wxBoxSizer( wxHORIZONTAL );
437     toolbar_sizer->Add( toolbar, 1, 0, 0 );
438     toolbar_sizer->Layout();
439
440 #ifndef WIN32
441     frame_sizer->SetMinSize( toolbar_sizer->GetMinSize().GetWidth(), -1 );
442 #else /* That sucks but for some reason it works better */
443     frame_sizer->SetMinSize( toolbar_sizer->GetMinSize().GetWidth()*2/3, -1 );
444 #endif
445
446 #if !defined(__WXX11__)
447     /* Associate drop targets with the toolbar */
448     toolbar->SetDropTarget( new DragAndDrop( p_intf ) );
449 #endif
450 }
451
452 void Interface::CreateOurSlider()
453 {
454     /* Create a new frame and sizer containing the slider */
455     slider_frame = new wxPanel( this, -1, wxDefaultPosition, wxDefaultSize );
456     slider_frame->SetAutoLayout( TRUE );
457     wxBoxSizer *frame_sizer =
458         new wxBoxSizer( wxHORIZONTAL );
459
460     /* Create static box to surround the slider */
461     slider_box = new wxStaticBox( slider_frame, -1, wxT("") );
462
463     /* Create sizer for slider frame */
464     wxStaticBoxSizer *slider_sizer =
465         new wxStaticBoxSizer( slider_box, wxHORIZONTAL );
466     slider_sizer->SetMinSize( -1, 50 );
467
468     /* Create slider */
469     slider = new wxSlider( slider_frame, SliderScroll_Event, 0, 0,
470                            SLIDER_MAX_POS, wxDefaultPosition, wxDefaultSize );
471     slider_sizer->Add( slider, 1, wxEXPAND | wxALL, 5 );
472
473
474     volctrl = new wxVolCtrl( p_intf, slider_frame, -1 );
475
476     /* Add everything to the frame */
477     frame_sizer->Add( slider_sizer, 1, wxEXPAND | wxBOTTOM, 5 );
478     frame_sizer->Add( volctrl, 0, wxEXPAND | wxALL, 5 );
479     slider_frame->SetSizer( frame_sizer );
480     frame_sizer->Layout();
481     frame_sizer->SetSizeHints(slider_frame);
482
483     /* Hide the slider by default */
484     slider_frame->Hide();
485 }
486
487
488 void Interface::CreateOurExtraPanel()
489 {
490     char *psz_filters;
491
492     extra_frame = new wxPanel( this, -1, wxDefaultPosition, wxDefaultSize );
493     extra_frame->SetAutoLayout( TRUE );
494     wxBoxSizer *extra_sizer = new wxBoxSizer( wxHORIZONTAL );
495
496     /* Create static box to surround the adjust controls */
497     wxStaticBox *adjust_box =
498            new wxStaticBox( extra_frame, -1, wxU(_("Image adjust")) );
499
500     /* Create the size for the frame */
501     wxStaticBoxSizer *adjust_sizer =
502         new wxStaticBoxSizer( adjust_box, wxVERTICAL );
503     adjust_sizer->SetMinSize( -1, 50 );
504
505     /* Create every controls */
506
507     /* Create the adjust button */
508     wxCheckBox * adjust_check = new wxCheckBox( extra_frame, Adjust_Event,
509                                                  wxU(_("Enable")));
510
511
512     wxBoxSizer *hue_sizer = new wxBoxSizer( wxHORIZONTAL );
513     wxStaticText *hue_text = new wxStaticText( extra_frame, -1,
514                                        wxU(_("Hue")) );
515     hue_slider = new wxSlider ( extra_frame, Hue_Event, 0, 0,
516                                 360, wxDefaultPosition, wxDefaultSize );
517
518     hue_sizer->Add(hue_text,1, 0 ,0);
519     hue_sizer->Add(hue_slider,1, 0 ,0);
520     hue_sizer->Layout();
521
522     wxBoxSizer *contrast_sizer = new wxBoxSizer( wxHORIZONTAL );
523     wxStaticText *contrast_text = new wxStaticText( extra_frame, -1,
524                                        wxU(_("Contrast")) );
525     contrast_slider = new wxSlider ( extra_frame, Contrast_Event, 0, 0,
526                                 200, wxDefaultPosition, wxDefaultSize);
527     contrast_sizer->Add(contrast_text,1, 0 ,0);
528     contrast_sizer->Add(contrast_slider,1, 0 ,0);
529     contrast_sizer->Layout();
530
531     wxBoxSizer *brightness_sizer = new wxBoxSizer( wxHORIZONTAL );
532     wxStaticText *brightness_text = new wxStaticText( extra_frame, -1,
533                                        wxU(_("Brightness")) );
534     brightness_slider = new wxSlider ( extra_frame, Brightness_Event, 0, 0,
535                            200, wxDefaultPosition, wxDefaultSize) ;
536     brightness_sizer->Add(brightness_text,1,0,0);
537     brightness_sizer->Add(brightness_slider,1,0,0);
538     brightness_sizer->Layout();
539
540     wxBoxSizer *saturation_sizer = new wxBoxSizer( wxHORIZONTAL );
541     wxStaticText *saturation_text = new wxStaticText( extra_frame, -1,
542                                           wxU(_("Saturation")) );
543     saturation_slider = new wxSlider ( extra_frame, Saturation_Event, 0, 0,
544                            300, wxDefaultPosition, wxDefaultSize );
545     saturation_sizer->Add(saturation_text,1,0,0);
546     saturation_sizer->Add(saturation_slider,1,0,0);
547     saturation_sizer->Layout();
548
549     adjust_sizer->Add(adjust_check, 1, wxEXPAND, 0);
550     adjust_sizer->Add(hue_sizer, 1, wxEXPAND, 0);
551     adjust_sizer->Add(contrast_sizer, 1, wxEXPAND, 0);
552     adjust_sizer->Add(brightness_sizer, 1, wxEXPAND, 0);
553     adjust_sizer->Add(saturation_sizer, 1, wxEXPAND, 0);
554
555     extra_sizer->Add(adjust_sizer,1,wxBOTTOM,5);
556
557
558     /* Create sizer to surround the other controls */
559     wxBoxSizer *other_sizer = new wxBoxSizer( wxVERTICAL );
560
561
562     wxStaticBox *video_box =
563             new wxStaticBox( extra_frame, -1, wxU(_("Video Options")) );
564     /* Create the sizer for the frame */
565     wxStaticBoxSizer *video_sizer =
566        new wxStaticBoxSizer( video_box, wxVERTICAL );
567     video_sizer->SetMinSize( -1, 50 );
568
569     static const wxString ratio_array[] =
570     {
571         wxT("4:3"),
572         wxT("16:9"),
573     };
574
575     wxBoxSizer *ratio_sizer = new wxBoxSizer( wxHORIZONTAL );
576     wxStaticText *ratio_text = new wxStaticText( extra_frame, -1,
577                                           wxU(_("Ratio")) );
578
579     ratio_combo = new wxComboBox( extra_frame, Ratio_Event, wxT(""),
580                                   wxDefaultPosition, wxSize(120,-1),
581                                   WXSIZEOF(ratio_array), ratio_array,
582                                   0 );
583
584     ratio_sizer->Add( ratio_text, 0, wxALL, 2 );
585     ratio_sizer->Add( ratio_combo, 0, wxALL, 2 );
586     ratio_sizer->Layout();
587
588     video_sizer->Add( ratio_sizer  , 0 , wxALL , 0 );
589     video_sizer->Layout();
590
591     wxBoxSizer *visual_sizer = new wxBoxSizer( wxHORIZONTAL );
592
593     wxCheckBox *visual_checkbox = new wxCheckBox( extra_frame, Visual_Event,
594                                             wxU(_("Visualisation")) );
595
596     visual_sizer->Add( visual_checkbox, 0, wxEXPAND, 0);
597     visual_sizer->Layout();
598
599     wxStaticBox *audio_box =
600               new wxStaticBox( extra_frame, -1, wxU(_("Audio Options")) );
601     /* Create the sizer for the frame */
602     wxStaticBoxSizer *audio_sizer =
603         new wxStaticBoxSizer( audio_box, wxVERTICAL );
604     audio_sizer->SetMinSize( -1, 50 );
605
606     audio_sizer->Add( visual_sizer, 0, wxALL, 0);
607     audio_sizer->Layout();
608
609     other_sizer->Add( video_sizer, 0, wxALL | wxEXPAND , 0);
610     other_sizer->Add( audio_sizer , 0 , wxALL | wxEXPAND , 0 );
611     other_sizer->Layout();
612
613     extra_sizer->Add(other_sizer,0,wxBOTTOM,5);
614
615     extra_frame->SetSizer( extra_sizer );
616
617     /* Layout the whole panel */
618     extra_sizer->Layout();
619
620     extra_sizer->SetSizeHints(extra_frame);
621
622     /* Write down initial values */
623     psz_filters = config_GetPsz( p_intf, "audio-filter" );
624     if( psz_filters && strstr( psz_filters, "visual" ) )
625     {
626         visual_checkbox->SetValue(1);
627     }
628     if( psz_filters ) free( psz_filters );
629
630     psz_filters = config_GetPsz( p_intf, "filter" );
631     if( psz_filters && strstr( psz_filters, "adjust" ) )
632     {
633         adjust_check->SetValue( 1 );
634         saturation_slider->Enable();
635         contrast_slider->Enable();
636         brightness_slider->Enable();
637         hue_slider->Enable();
638     }
639     else
640     {
641         adjust_check->SetValue( 0 );
642         saturation_slider->Disable();
643         contrast_slider->Disable();
644         brightness_slider->Disable();
645         hue_slider->Disable();
646     }
647     if( psz_filters ) free( psz_filters );
648
649     int i_value = config_GetInt( p_intf, "hue" );
650     if( i_value > 0 && i_value < 360 )
651         hue_slider->SetValue( i_value );
652
653     float f_value;
654     f_value = config_GetFloat( p_intf, "saturation" );
655     if( f_value > 0 && f_value < 5 )
656         saturation_slider->SetValue( (int)(100 * f_value) );
657     f_value = config_GetFloat( p_intf, "contrast" );
658     if( f_value > 0 && f_value < 4 )
659         contrast_slider->SetValue( (int)(100 * f_value) );
660     f_value = config_GetFloat( p_intf, "brightness" );
661     if( f_value > 0 && f_value < 2 )
662         brightness_slider->SetValue( (int)(100 * f_value) );
663
664     extra_frame->Hide();
665 }
666
667 void Interface::UpdateAcceleratorTable()
668 {
669     /* Set some hotkeys */
670     wxAcceleratorEntry entries[7];
671     vlc_value_t val;
672     int i = 0;
673
674     var_Get( p_intf->p_vlc, "key-quit", &val );
675     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
676                       ConvertHotkey( val.i_int ), Exit_Event );
677     var_Get( p_intf->p_vlc, "key-stop", &val );
678     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
679                       ConvertHotkey( val.i_int ), StopStream_Event );
680     var_Get( p_intf->p_vlc, "key-play-pause", &val );
681     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
682                       ConvertHotkey( val.i_int ), PlayStream_Event );
683     var_Get( p_intf->p_vlc, "key-next", &val );
684     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
685                       ConvertHotkey( val.i_int ), NextStream_Event );
686     var_Get( p_intf->p_vlc, "key-prev", &val );
687     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
688                       ConvertHotkey( val.i_int ), PrevStream_Event );
689     var_Get( p_intf->p_vlc, "key-faster", &val );
690     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
691                       ConvertHotkey( val.i_int ), FastStream_Event );
692     var_Get( p_intf->p_vlc, "key-slower", &val );
693     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
694                       ConvertHotkey( val.i_int ), SlowStream_Event );
695
696     wxAcceleratorTable accel( 7, entries );
697
698     if( !accel.Ok() )
699         msg_Err( p_intf, "invalid accelerator table" );
700
701     SetAcceleratorTable( accel );
702     msg_Dbg( p_intf, "accelerator table loaded" );
703
704 }
705
706 /*****************************************************************************
707  * Event Handlers.
708  *****************************************************************************/
709 /* Work-around helper for buggy wxGTK */
710 void RecursiveDestroy( wxMenu *menu )
711 {
712     wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
713     for( ; node; )
714     {
715         wxMenuItem *item = node->GetData();
716         node = node->GetNext();
717
718         /* Delete the submenus */
719         wxMenu *submenu = item->GetSubMenu();
720         if( submenu )
721         {
722             RecursiveDestroy( submenu );
723         }
724         menu->Delete( item );
725     }
726 }
727
728 void Interface::OnMenuOpen(wxMenuEvent& event)
729 {
730 #if !defined( __WXMSW__ )
731     if( event.GetEventObject() == p_settings_menu )
732     {
733         if( b_settings_menu )
734         {
735             p_settings_menu = SettingsMenu( p_intf, this );
736
737             /* Add static items */
738             p_settings_menu->AppendCheckItem( Extra_Event,
739                              wxU(_("&Extended GUI") ), wxU(_(EXTRA_PREFS)) );
740             p_settings_menu->Append( Prefs_Event, wxU(_("&Preferences...")),
741                                      wxU(_(HELP_PREFS)) );
742
743             /* Work-around for buggy wxGTK */
744             wxMenu *menu = GetMenuBar()->GetMenu( 2 );
745             RecursiveDestroy( menu );
746             /* End work-around */
747
748             menu = GetMenuBar()->Replace( 2, p_settings_menu,
749                                           wxU(_("&Settings")));
750             if( menu ) delete menu;
751
752             b_settings_menu = 0;
753         }
754         else b_settings_menu = 1;
755     }
756     else if( event.GetEventObject() == p_audio_menu )
757     {
758         if( b_audio_menu )
759         {
760             p_audio_menu = AudioMenu( p_intf, this );
761
762             /* Work-around for buggy wxGTK */
763             wxMenu *menu = GetMenuBar()->GetMenu( 3 );
764             RecursiveDestroy( menu );
765             /* End work-around */
766
767             menu =
768                 GetMenuBar()->Replace( 3, p_audio_menu, wxU(_("&Audio")) );
769             if( menu ) delete menu;
770
771             b_audio_menu = 0;
772         }
773         else b_audio_menu = 1;
774     }
775     else if( event.GetEventObject() == p_video_menu )
776     {
777         if( b_video_menu )
778         {
779             p_video_menu = VideoMenu( p_intf, this );
780
781             /* Work-around for buggy wxGTK */
782             wxMenu *menu = GetMenuBar()->GetMenu( 4 );
783             RecursiveDestroy( menu );
784             /* End work-around */
785
786             menu =
787                 GetMenuBar()->Replace( 4, p_video_menu, wxU(_("&Video")) );
788             if( menu ) delete menu;
789
790             b_video_menu = 0;
791         }
792         else b_video_menu = 1;
793     }
794     else if( event.GetEventObject() == p_navig_menu )
795     {
796         if( b_navig_menu )
797         {
798             p_navig_menu = NavigMenu( p_intf, this );
799
800             /* Work-around for buggy wxGTK */
801             wxMenu *menu = GetMenuBar()->GetMenu( 5 );
802             RecursiveDestroy( menu );
803             /* End work-around */
804
805             menu =
806                 GetMenuBar()->Replace( 5, p_navig_menu, wxU(_("&Navigation")));
807             if( menu ) delete menu;
808
809             b_navig_menu = 0;
810         }
811         else b_navig_menu = 1;
812     }
813
814 #else
815     p_settings_menu = SettingsMenu( p_intf, this );
816     /* Add static items */
817     p_settings_menu->AppendCheckItem( Extra_Event, wxU(_("&Extended GUI") ),
818                                       wxU(_(EXTRA_PREFS)) );
819     p_settings_menu->Append( Prefs_Event, wxU(_("&Preferences...")),
820                              wxU(_(HELP_PREFS)) );
821     wxMenu *menu =
822         GetMenuBar()->Replace( 2, p_settings_menu, wxU(_("&Settings")) );
823     if( menu ) delete menu;
824
825     p_audio_menu = AudioMenu( p_intf, this );
826     menu = GetMenuBar()->Replace( 3, p_audio_menu, wxU(_("&Audio")) );
827     if( menu ) delete menu;
828
829     p_video_menu = VideoMenu( p_intf, this );
830     menu = GetMenuBar()->Replace( 4, p_video_menu, wxU(_("&Video")) );
831     if( menu ) delete menu;
832
833     p_navig_menu = NavigMenu( p_intf, this );
834     menu = GetMenuBar()->Replace( 5, p_navig_menu, wxU(_("&Navigation")) );
835     if( menu ) delete menu;
836 #endif
837
838 }
839
840 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
841 void Interface::OnContextMenu2(wxContextMenuEvent& event)
842 {
843     /* Only show the context menu for the main interface */
844     if( GetId() != event.GetId() )
845     {
846         event.Skip();
847         return;
848     }
849
850     if( p_intf->p_sys->pf_show_dialog )
851         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
852 }
853 #endif
854 void Interface::OnContextMenu(wxMouseEvent& event)
855 {
856     if( p_intf->p_sys->pf_show_dialog )
857         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
858 }
859
860 void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
861 {
862     /* TRUE is to force the frame to close. */
863     Close(TRUE);
864 }
865
866 void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
867 {
868     wxString msg;
869     msg.Printf( wxString(wxT("VLC media player " VERSION)) +
870         wxU(_(" (wxWindows interface)\n\n")) +
871         wxU(_("(C) 1996-2003 - the VideoLAN Team\n\n")) +
872         wxU( vlc_wraptext(INTF_ABOUT_MSG,WRAPCOUNT,ISUTF8) ) + wxT("\n\n") +
873         wxU(_("The VideoLAN team <videolan@videolan.org>\n"
874               "http://www.videolan.org/\n\n")) );
875
876     wxMessageBox( msg, wxString::Format(wxU(_("About %s")),
877                   wxT("VLC media player")), wxOK | wxICON_INFORMATION, this );
878 }
879
880 void Interface::OnShowDialog( wxCommandEvent& event )
881 {
882     if( p_intf->p_sys->pf_show_dialog )
883     {
884         int i_id;
885
886         switch( event.GetId() )
887         {
888         case OpenFileSimple_Event:
889             i_id = INTF_DIALOG_FILE_SIMPLE;
890             break;
891         case OpenAdv_Event:
892             i_id = INTF_DIALOG_FILE;
893         case OpenFile_Event:
894             i_id = INTF_DIALOG_FILE;
895             break;
896         case OpenDisc_Event:
897             i_id = INTF_DIALOG_DISC;
898             break;
899         case OpenNet_Event:
900             i_id = INTF_DIALOG_NET;
901             break;
902         case OpenSat_Event:
903             i_id = INTF_DIALOG_SAT;
904             break;
905         case Playlist_Event:
906             i_id = INTF_DIALOG_PLAYLIST;
907             break;
908         case Logs_Event:
909             i_id = INTF_DIALOG_MESSAGES;
910             break;
911         case FileInfo_Event:
912             i_id = INTF_DIALOG_FILEINFO;
913             break;
914         case Prefs_Event:
915             i_id = INTF_DIALOG_PREFS;
916             break;
917         default:
918             i_id = INTF_DIALOG_FILE;
919             break;
920
921         }
922
923         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
924     }
925 }
926
927
928 void Interface::OnStream( wxCommandEvent& event )
929 {
930     StreamDialog *p_stream_dialog = new StreamDialog(p_intf,this);
931     p_stream_dialog->Show();
932 }
933
934
935 void Interface::OnExtra(wxCommandEvent& event)
936 {
937     if( b_extra == VLC_FALSE)
938     {
939         extra_frame->Show();
940         frame_sizer->Show( extra_frame );
941         b_extra = VLC_TRUE;
942     }
943     else
944     {
945         extra_frame->Hide();
946         frame_sizer->Hide( extra_frame );
947         b_extra = VLC_FALSE;
948     }
949     frame_sizer->Layout();
950     frame_sizer->Fit(this);
951 }
952
953 void Interface::OnEnableAdjust(wxCommandEvent& event)
954 {
955     char *psz_filters=config_GetPsz( p_intf, "filter");
956     char *psz_new = NULL;
957     if( event.IsChecked() )
958     {
959         if(psz_filters == NULL)
960         {
961             psz_new = strdup( "adjust" );
962         }
963         else
964         {
965             psz_new= (char *) malloc(strlen(psz_filters) + 8 );
966             sprintf( psz_new, "%s:adjust", psz_filters);
967         }
968         config_PutPsz( p_intf, "filter", psz_new );
969         vlc_value_t val;
970         vout_thread_t *p_vout =
971            (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
972                                        FIND_ANYWHERE );
973         if( p_vout != NULL )
974         {
975             val.psz_string = strdup( psz_new );
976             var_Set( p_vout, "filter", val);
977             vlc_object_release( p_vout );
978         }
979         if( val.psz_string ) free( val.psz_string );
980         brightness_slider->Enable();
981         saturation_slider->Enable();
982         contrast_slider->Enable();
983         hue_slider->Enable();
984     }
985     else
986     {
987         if( psz_filters != NULL )
988         {
989
990             char *psz_current;
991             unsigned int i=0;
992             for( i = 0; i< strlen(psz_filters ); i++)
993             {
994                 if ( !strncasecmp( &psz_filters[i],"adjust",6 ))
995                 {
996                     if(i > 0)
997                         if( psz_filters[i-1] == ':' ) i--;
998                     psz_current = strchr( &psz_filters[i+1] , ':' );
999                     if( !psz_current )
1000                         psz_filters[i] = '\0';
1001                     else
1002                     {
1003                        memmove( &psz_filters[i] , psz_current,
1004                                 &psz_filters[strlen(psz_filters)]-psz_current
1005                                 +1);
1006                     }
1007                 }
1008             }
1009             config_PutPsz( p_intf, "filter", psz_filters);
1010             vlc_value_t val;
1011             val.psz_string = strdup( psz_filters );
1012             vout_thread_t *p_vout =
1013                (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1014                                        FIND_ANYWHERE );
1015             if( p_vout != NULL )
1016             {
1017                 var_Set( p_vout, "filter", val);
1018                 vlc_object_release( p_vout );
1019             }
1020             if( val.psz_string ) free( val.psz_string );
1021         }
1022         brightness_slider->Disable();
1023         saturation_slider->Disable();
1024         contrast_slider->Disable();
1025         hue_slider->Disable();
1026     }
1027     if(psz_filters) free(psz_filters);
1028     if(psz_new) free(psz_new);
1029 }
1030
1031 void Interface::OnHueUpdate( wxScrollEvent& event)
1032 {
1033    config_PutInt( p_intf , "hue" , event.GetPosition() );
1034 }
1035
1036 void Interface::OnSaturationUpdate( wxScrollEvent& event)
1037 {
1038    config_PutFloat( p_intf , "saturation" , (float)event.GetPosition()/100 );
1039 }
1040
1041 void Interface::OnBrightnessUpdate( wxScrollEvent& event)
1042 {
1043    config_PutFloat( p_intf , "brightness", (float)event.GetPosition()/100 );
1044 }
1045
1046 void Interface::OnContrastUpdate(wxScrollEvent& event)
1047 {
1048    config_PutFloat( p_intf , "contrast" , (float)event.GetPosition()/100 );
1049
1050 }
1051
1052 void Interface::OnRatio( wxCommandEvent& event )
1053 {
1054    config_PutPsz( p_intf, "aspect-ratio", ratio_combo->GetValue().mb_str() );
1055 }
1056
1057 void Interface::OnEnableVisual(wxCommandEvent& event)
1058 {
1059     if( event.IsChecked() )
1060     {
1061         config_PutPsz( p_intf, "audio-filter", "visual" );
1062     }
1063     else
1064     {
1065         config_PutPsz( p_intf, "audio-filter", "" );
1066     }
1067 }
1068
1069 void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
1070 {
1071     wxCommandEvent dummy;
1072     playlist_t *p_playlist =
1073         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1074                                        FIND_ANYWHERE );
1075     if( p_playlist == NULL ) return;
1076
1077     if( p_playlist->i_size && p_playlist->i_enabled )
1078     {
1079         vlc_value_t state;
1080
1081         input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf,
1082                                                        VLC_OBJECT_INPUT,
1083                                                        FIND_ANYWHERE );
1084         if( p_input == NULL )
1085         {
1086             /* No stream was playing, start one */
1087             playlist_Play( p_playlist );
1088             TogglePlayButton( PLAYING_S );
1089             vlc_object_release( p_playlist );
1090             return;
1091         }
1092
1093         var_Get( p_input, "state", &state );
1094
1095         if( state.i_int != PAUSE_S )
1096         {
1097             /* A stream is being played, pause it */
1098             state.i_int = PAUSE_S;
1099         }
1100         else
1101         {
1102             /* Stream is paused, resume it */
1103             state.i_int = PLAYING_S;
1104         }
1105         var_Set( p_input, "state", state );
1106
1107         TogglePlayButton( state.i_int );
1108         vlc_object_release( p_input );
1109         vlc_object_release( p_playlist );
1110     }
1111     else
1112     {
1113         /* If the playlist is empty, open a file requester instead */
1114         vlc_object_release( p_playlist );
1115         OnShowDialog( dummy );
1116     }
1117 }
1118
1119 void Interface::OnStopStream( wxCommandEvent& WXUNUSED(event) )
1120 {
1121     playlist_t * p_playlist =
1122         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1123                                        FIND_ANYWHERE );
1124     if( p_playlist == NULL )
1125     {
1126         return;
1127     }
1128
1129     playlist_Stop( p_playlist );
1130     TogglePlayButton( PAUSE_S );
1131     vlc_object_release( p_playlist );
1132 }
1133
1134 void Interface::OnSliderUpdate( wxScrollEvent& event )
1135 {
1136     vlc_mutex_lock( &p_intf->change_lock );
1137
1138 #ifdef WIN32
1139     if( event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
1140         || event.GetEventType() == wxEVT_SCROLL_ENDSCROLL )
1141     {
1142 #endif
1143         if( p_intf->p_sys->i_slider_pos != event.GetPosition()
1144             && p_intf->p_sys->p_input )
1145         {
1146             vlc_value_t pos;
1147             pos.f_float = (float)event.GetPosition() / (float)SLIDER_MAX_POS;
1148
1149             var_Set( p_intf->p_sys->p_input, "position", pos );
1150         }
1151
1152 #ifdef WIN32
1153         p_intf->p_sys->b_slider_free = VLC_TRUE;
1154     }
1155     else
1156     {
1157         p_intf->p_sys->b_slider_free = VLC_FALSE;
1158
1159         if( p_intf->p_sys->p_input )
1160         {
1161             /* Update stream date */
1162 #define p_area p_intf->p_sys->p_input->stream.p_selected_area
1163             char psz_time[ MSTRTIME_MAX_SIZE ];
1164
1165             slider_box->SetLabel(
1166                 wxU(input_OffsetToTime( p_intf->p_sys->p_input,
1167                                         psz_time,
1168                                         p_area->i_size * event.GetPosition()
1169                                         / SLIDER_MAX_POS )) );
1170 #undef p_area
1171         }
1172     }
1173 #endif
1174
1175     vlc_mutex_unlock( &p_intf->change_lock );
1176 }
1177
1178 void Interface::OnPrevStream( wxCommandEvent& WXUNUSED(event) )
1179 {
1180     playlist_t * p_playlist =
1181         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1182                                        FIND_ANYWHERE );
1183     if( p_playlist == NULL )
1184     {
1185         return;
1186     }
1187
1188     vlc_mutex_lock( &p_playlist->object_lock );
1189     if( p_playlist->p_input != NULL )
1190     {
1191         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1192         if( p_playlist->p_input->stream.p_selected_area->i_id > 1 )
1193         {
1194             vlc_value_t val; val.b_bool = VLC_TRUE;
1195             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1196             var_Set( p_playlist->p_input, "prev-title", val );
1197         } else 
1198             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1199     }
1200     vlc_mutex_unlock( &p_playlist->object_lock );
1201
1202     playlist_Prev( p_playlist );
1203     vlc_object_release( p_playlist );
1204 }
1205
1206 void Interface::OnNextStream( wxCommandEvent& WXUNUSED(event) )
1207 {
1208     playlist_t * p_playlist =
1209         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1210                                        FIND_ANYWHERE );
1211     if( p_playlist == NULL )
1212     {
1213         return;
1214     }
1215
1216     vlc_mutex_lock( &p_playlist->object_lock );
1217     if( p_playlist->p_input != NULL )
1218     {
1219         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1220         if( p_playlist->p_input->stream.i_area_nb > 1 &&
1221             p_playlist->p_input->stream.p_selected_area->i_id <
1222               p_playlist->p_input->stream.i_area_nb - 1 )
1223         {
1224             vlc_value_t val; val.b_bool = VLC_TRUE;
1225             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1226             var_Set( p_playlist->p_input, "next-title", val );
1227         } else 
1228             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1229     }
1230     vlc_mutex_unlock( &p_playlist->object_lock );
1231
1232     playlist_Next( p_playlist );
1233     vlc_object_release( p_playlist );
1234 }
1235
1236 void Interface::OnSlowStream( wxCommandEvent& WXUNUSED(event) )
1237 {
1238     input_thread_t *p_input =
1239         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1240                                            FIND_ANYWHERE );
1241     if( p_input )
1242     {
1243         vlc_value_t val; val.b_bool = VLC_TRUE;
1244
1245         var_Set( p_input, "rate-slower", val );
1246         vlc_object_release( p_input );
1247     }
1248 }
1249
1250 void Interface::OnFastStream( wxCommandEvent& WXUNUSED(event) )
1251 {
1252     input_thread_t *p_input =
1253         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1254                                            FIND_ANYWHERE );
1255     if( p_input )
1256     {
1257         vlc_value_t val; val.b_bool = VLC_TRUE;
1258
1259         var_Set( p_input, "rate-faster", val );
1260         vlc_object_release( p_input );
1261     }
1262 }
1263
1264 void Interface::TogglePlayButton( int i_playing_status )
1265 {
1266     if( i_playing_status == i_old_playing_status )
1267         return;
1268
1269     GetToolBar()->DeleteTool( PlayStream_Event );
1270
1271     if( i_playing_status == PLAYING_S )
1272     {
1273         GetToolBar()->InsertTool( 8, PlayStream_Event, wxU(_("Pause")),
1274                                   wxBitmap( pause_xpm ), wxNullBitmap,
1275                                   wxITEM_NORMAL, wxU(_(HELP_PAUSE)) );
1276     }
1277     else
1278     {
1279         GetToolBar()->InsertTool( 8, PlayStream_Event, wxU(_("Play")),
1280                                   wxBitmap( play_xpm ), wxNullBitmap,
1281                                   wxITEM_NORMAL, wxU(_(HELP_PLAY)) );
1282     }
1283
1284     GetToolBar()->Realize();
1285
1286     i_old_playing_status = i_playing_status;
1287 }
1288
1289 #if !defined(__WXX11__)
1290 /*****************************************************************************
1291  * Definition of DragAndDrop class.
1292  *****************************************************************************/
1293 DragAndDrop::DragAndDrop( intf_thread_t *_p_intf, vlc_bool_t _b_enqueue )
1294 {
1295     p_intf = _p_intf;
1296     b_enqueue = _b_enqueue;
1297 }
1298
1299 bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
1300                                const wxArrayString& filenames )
1301 {
1302     /* Add dropped files to the playlist */
1303
1304     playlist_t *p_playlist =
1305         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1306                                        FIND_ANYWHERE );
1307     if( p_playlist == NULL )
1308     {
1309         return FALSE;
1310     }
1311
1312     for( size_t i = 0; i < filenames.GetCount(); i++ )
1313         playlist_Add( p_playlist, (const char *)filenames[i].mb_str(), 0, 0,
1314                       PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
1315                       PLAYLIST_END );
1316
1317     vlc_object_release( p_playlist );
1318
1319     return TRUE;
1320 }
1321 #endif
1322
1323 /*****************************************************************************
1324  * Definition of wxVolCtrl class.
1325  *****************************************************************************/
1326 wxVolCtrl::wxVolCtrl( intf_thread_t *_p_intf, wxWindow* parent, wxWindowID id )
1327   : wxGauge( parent, id, 200, wxDefaultPosition, wxSize( 20, -1 ),
1328              wxGA_VERTICAL | wxGA_SMOOTH )
1329 {
1330     p_intf = _p_intf;
1331 }
1332
1333 void wxVolCtrl::OnChange( wxMouseEvent& event )
1334 {
1335     if( !event.LeftDown() && !event.LeftIsDown() ) return;
1336
1337     int i_volume = (GetClientSize().GetHeight() - event.GetY()) * 200 /
1338                     GetClientSize().GetHeight();
1339     Change( i_volume );
1340 }
1341
1342 void wxVolCtrl::Change( int i_volume )
1343 {
1344     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
1345     SetValue( i_volume );
1346     SetToolTip( wxString::Format((wxString)wxU(_("Volume")) + wxT(" %d"),
1347                 i_volume ) );
1348 }