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