]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/interface.cpp
31a22a3498326563b989aaa99089860d32947f07
[vlc] / modules / gui / wxwindows / interface.cpp
1 /*****************************************************************************
2  * interface.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2004, 2003 VideoLAN
5  * $Id: interface.cpp,v 1.86 2004/01/25 18:18:50 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 #define TOOLBAR_BMP_WIDTH 36
53 #define TOOLBAR_BMP_HEIGHT 36
54
55 /* include the icon graphic */
56 #include "../../../share/vlc32x32.xpm"
57
58 /*****************************************************************************
59  * Local class declarations.
60  *****************************************************************************/
61 class wxMenuExt: public wxMenu
62 {
63 public:
64     /* Constructor */
65     wxMenuExt( wxMenu* parentMenu, int id, const wxString& text,
66                    const wxString& helpString, wxItemKind kind,
67                    char *_psz_var, int _i_object_id, vlc_value_t _val,
68                    int _i_val_type );
69
70     virtual ~wxMenuExt() {};
71
72     char *psz_var;
73     int  i_val_type;
74     int  i_object_id;
75     vlc_value_t val;
76
77 private:
78
79 };
80
81 class wxVolCtrl: public wxGauge
82 {
83 public:
84     /* Constructor */
85     wxVolCtrl( intf_thread_t *_p_intf, wxWindow* parent, wxWindowID id );
86     virtual ~wxVolCtrl() {};
87
88     void Change( int i_volume );
89
90     void OnChange( wxMouseEvent& event );
91
92 private:
93     intf_thread_t *p_intf;
94
95     DECLARE_EVENT_TABLE();
96 };
97
98 BEGIN_EVENT_TABLE(wxVolCtrl, wxWindow)
99     /* Mouse events */
100     EVT_LEFT_DOWN(wxVolCtrl::OnChange)
101     EVT_MOTION(wxVolCtrl::OnChange)
102 END_EVENT_TABLE()
103
104 /*****************************************************************************
105  * Event Table.
106  *****************************************************************************/
107
108 /* IDs for the controls and the menu commands */
109 enum
110 {
111     /* menu items */
112     MenuDummy_Event = wxID_HIGHEST + 1000,
113     Exit_Event = wxID_HIGHEST,
114     OpenFileSimple_Event,
115     OpenAdv_Event,
116     OpenFile_Event,
117     OpenDisc_Event,
118     OpenNet_Event,
119     OpenSat_Event,
120     OpenOther_Event,
121     EjectDisc_Event,
122
123     Stream_Event,
124
125     Playlist_Event,
126     Logs_Event,
127     FileInfo_Event,
128
129     Prefs_Event,
130     Extra_Event,
131     Skins_Event,
132
133     SliderScroll_Event,
134     StopStream_Event,
135     PlayStream_Event,
136     PrevStream_Event,
137     NextStream_Event,
138     SlowStream_Event,
139     FastStream_Event,
140
141     Adjust_Event,
142     Hue_Event,
143     Contrast_Event,
144     Brightness_Event,
145     Saturation_Event,
146     Gamma_Event,
147
148     Ratio_Event,
149     Visual_Event,
150
151     /* it is important for the id corresponding to the "About" command to have
152      * this standard value as otherwise it won't be handled properly under Mac
153      * (where it is special and put into the "Apple" menu) */
154     About_Event = wxID_ABOUT
155 };
156
157 BEGIN_EVENT_TABLE(Interface, wxFrame)
158     /* Menu events */
159     EVT_MENU(Exit_Event, Interface::OnExit)
160     EVT_MENU(About_Event, Interface::OnAbout)
161
162     EVT_MENU(Playlist_Event, Interface::OnShowDialog)
163     EVT_MENU(Logs_Event, Interface::OnShowDialog)
164     EVT_MENU(FileInfo_Event, Interface::OnShowDialog)
165     EVT_MENU(Prefs_Event, Interface::OnShowDialog)
166
167     EVT_MENU_OPEN(Interface::OnMenuOpen)
168
169     EVT_MENU( Extra_Event, Interface::OnExtra)
170     EVT_CHECKBOX( Adjust_Event, Interface::OnEnableAdjust)
171
172     EVT_TEXT( Ratio_Event, Interface::OnRatio)
173     EVT_CHECKBOX( Visual_Event, Interface::OnEnableVisual)
174
175 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
176     EVT_CONTEXT_MENU(Interface::OnContextMenu2)
177 #endif
178     EVT_RIGHT_UP(Interface::OnContextMenu)
179
180     /* Toolbar events */
181     EVT_MENU(OpenFileSimple_Event, Interface::OnShowDialog)
182     EVT_MENU(OpenAdv_Event, Interface::OnShowDialog)
183     EVT_MENU(OpenFile_Event, Interface::OnShowDialog)
184     EVT_MENU(OpenDisc_Event, Interface::OnShowDialog)
185     EVT_MENU(OpenNet_Event, Interface::OnShowDialog)
186     EVT_MENU(OpenSat_Event, Interface::OnShowDialog)
187     EVT_MENU(Stream_Event, Interface::OnStream)
188     EVT_MENU(StopStream_Event, Interface::OnStopStream)
189     EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
190     EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
191     EVT_MENU(NextStream_Event, Interface::OnNextStream)
192     EVT_MENU(SlowStream_Event, Interface::OnSlowStream)
193     EVT_MENU(FastStream_Event, Interface::OnFastStream)
194
195     /* Slider events */
196     EVT_COMMAND_SCROLL(SliderScroll_Event, Interface::OnSliderUpdate)
197
198     EVT_COMMAND_SCROLL(Hue_Event, Interface::OnHueUpdate)
199     EVT_COMMAND_SCROLL(Contrast_Event, Interface::OnContrastUpdate)
200     EVT_COMMAND_SCROLL(Brightness_Event, Interface::OnBrightnessUpdate)
201     EVT_COMMAND_SCROLL(Saturation_Event, Interface::OnSaturationUpdate)
202     EVT_COMMAND_SCROLL(Gamma_Event, Interface::OnGammaUpdate)
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, wxSize(700,100), 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 File...")),
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 VLC media player")), 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")
386
387 #define HELP_PLAY N_("Play")
388 #define HELP_PAUSE N_("Pause")
389 #define HELP_PLO N_("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, wxT(""),
404                       wxBitmap( file_xpm ), wxU(_(HELP_SIMPLE)) );
405
406     toolbar->AddSeparator();
407     toolbar->AddTool( OpenFile_Event, wxT(""), wxBitmap( file_xpm ),
408                       wxU(_(HELP_FILE)) );
409     toolbar->AddTool( OpenDisc_Event, wxT(""), wxBitmap( disc_xpm ),
410                       wxU(_(HELP_DISC)) );
411     toolbar->AddTool( OpenNet_Event, wxT(""), wxBitmap( net_xpm ),
412                       wxU(_(HELP_NET)) );
413     toolbar->AddSeparator();
414
415     toolbar->AddTool( StopStream_Event, wxT(""), wxBitmap( stop_xpm ),
416                       wxU(_(HELP_STOP)) );
417     toolbar->AddTool( PlayStream_Event, wxT(""), wxBitmap( play_xpm ),
418                       wxU(_(HELP_PLAY)) );
419
420     toolbar->AddSeparator();
421     toolbar->AddTool( Playlist_Event, wxT(""),
422                       wxBitmap( playlist_xpm ), wxU(_(HELP_PLO)) );
423     toolbar->AddTool( PrevStream_Event, wxT(""),
424                       wxBitmap( previous_xpm ), wxU(_(HELP_PLP)) );
425     toolbar->AddTool( NextStream_Event, wxT(""), wxBitmap( next_xpm ),
426                       wxU(_(HELP_PLN)) );
427     toolbar->AddTool( SlowStream_Event, wxT(""), wxBitmap( slow_xpm ),
428                       wxU(_(HELP_SLOW)) );
429     toolbar->AddTool( FastStream_Event, wxT(""), 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(_("Adjust Image")) );
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     wxBoxSizer *gamma_sizer = new wxBoxSizer( wxHORIZONTAL );
550     wxStaticText *gamma_text = new wxStaticText( extra_frame, -1,
551                                           wxU(_("Gamma")) );
552     gamma_slider = new wxSlider ( extra_frame, Gamma_Event, 0, 0,
553                            100, wxDefaultPosition, wxDefaultSize );
554     gamma_sizer->Add(gamma_text,1,0,0);
555     gamma_sizer->Add(gamma_slider,1,0,0);
556     gamma_sizer->Layout();
557
558     adjust_sizer->Add(adjust_check, 1, wxEXPAND, 0);
559     adjust_sizer->Add(hue_sizer, 1, wxEXPAND, 0);
560     adjust_sizer->Add(contrast_sizer, 1, wxEXPAND, 0);
561     adjust_sizer->Add(brightness_sizer, 1, wxEXPAND, 0);
562     adjust_sizer->Add(saturation_sizer, 1, wxEXPAND, 0);
563     adjust_sizer->Add(gamma_sizer, 1, wxEXPAND, 0);
564
565     extra_sizer->Add(adjust_sizer,1,wxBOTTOM,5);
566
567     /* Create sizer to surround the other controls */
568     wxBoxSizer *other_sizer = new wxBoxSizer( wxVERTICAL );
569
570
571     wxStaticBox *video_box =
572             new wxStaticBox( extra_frame, -1, wxU(_("Video Options")) );
573     /* Create the sizer for the frame */
574     wxStaticBoxSizer *video_sizer =
575        new wxStaticBoxSizer( video_box, wxVERTICAL );
576     video_sizer->SetMinSize( -1, 50 );
577
578     static const wxString ratio_array[] =
579     {
580         wxT("4:3"),
581         wxT("16:9"),
582     };
583
584     wxBoxSizer *ratio_sizer = new wxBoxSizer( wxHORIZONTAL );
585     wxStaticText *ratio_text = new wxStaticText( extra_frame, -1,
586                                           wxU(_("Aspect Ratio")) );
587
588     ratio_combo = new wxComboBox( extra_frame, Ratio_Event, wxT(""),
589                                   wxDefaultPosition, wxSize(120,-1),
590                                   WXSIZEOF(ratio_array), ratio_array,
591                                   0 );
592
593     ratio_sizer->Add( ratio_text, 0, wxALL, 2 );
594     ratio_sizer->Add( ratio_combo, 0, wxALL, 2 );
595     ratio_sizer->Layout();
596
597     video_sizer->Add( ratio_sizer  , 0 , wxALL , 0 );
598     video_sizer->Layout();
599
600 #if 0
601     wxBoxSizer *visual_sizer = new wxBoxSizer( wxHORIZONTAL );
602
603     wxCheckBox *visual_checkbox = new wxCheckBox( extra_frame, Visual_Event,
604                                             wxU(_("Visualisations")) );
605
606     visual_sizer->Add( visual_checkbox, 0, wxEXPAND, 0);
607     visual_sizer->Layout();
608
609     wxStaticBox *audio_box =
610               new wxStaticBox( extra_frame, -1, wxU(_("Audio Options")) );
611     /* Create the sizer for the frame */
612     wxStaticBoxSizer *audio_sizer =
613         new wxStaticBoxSizer( audio_box, wxVERTICAL );
614     audio_sizer->SetMinSize( -1, 50 );
615
616     audio_sizer->Add( visual_sizer, 0, wxALL, 0);
617     audio_sizer->Layout();
618
619     other_sizer->Add( audio_sizer , 0 , wxALL | wxEXPAND , 0 );
620 #endif
621     other_sizer->Add( video_sizer, 0, wxALL | wxEXPAND , 0);
622     other_sizer->Layout();
623
624     extra_sizer->Add(other_sizer,0,wxBOTTOM,5);
625
626     extra_frame->SetSizer( extra_sizer );
627
628     /* Layout the whole panel */
629     extra_sizer->Layout();
630
631     extra_sizer->SetSizeHints(extra_frame);
632
633     /* Write down initial values */
634 #if 0
635     psz_filters = config_GetPsz( p_intf, "audio-filter" );
636     if( psz_filters && strstr( psz_filters, "visual" ) )
637     {
638         visual_checkbox->SetValue(1);
639     }
640     if( psz_filters ) free( psz_filters );
641 #endif
642     psz_filters = config_GetPsz( p_intf, "filter" );
643     if( psz_filters && strstr( psz_filters, "adjust" ) )
644     {
645         adjust_check->SetValue( 1 );
646         saturation_slider->Enable();
647         contrast_slider->Enable();
648         brightness_slider->Enable();
649         hue_slider->Enable();
650         gamma_slider->Enable();
651     }
652     else
653     {
654         adjust_check->SetValue( 0 );
655         saturation_slider->Disable();
656         contrast_slider->Disable();
657         brightness_slider->Disable();
658         hue_slider->Disable();
659         gamma_slider->Disable();
660     }
661     if( psz_filters ) free( psz_filters );
662
663     int i_value = config_GetInt( p_intf, "hue" );
664     if( i_value > 0 && i_value < 360 )
665         hue_slider->SetValue( i_value );
666
667     float f_value;
668     f_value = config_GetFloat( p_intf, "saturation" );
669     if( f_value > 0 && f_value < 5 )
670         saturation_slider->SetValue( (int)(100 * f_value) );
671     f_value = config_GetFloat( p_intf, "contrast" );
672     if( f_value > 0 && f_value < 4 )
673         contrast_slider->SetValue( (int)(100 * f_value) );
674     f_value = config_GetFloat( p_intf, "brightness" );
675     if( f_value > 0 && f_value < 2 )
676         brightness_slider->SetValue( (int)(100 * f_value) );
677     f_value = config_GetFloat( p_intf, "gamma" );
678     if( f_value > 0 && f_value < 10 )
679         gamma_slider->SetValue( (int)(10 * f_value) );
680
681     extra_frame->Hide();
682 }
683
684 void Interface::UpdateAcceleratorTable()
685 {
686     /* Set some hotkeys */
687     wxAcceleratorEntry entries[7];
688     vlc_value_t val;
689     int i = 0;
690
691     var_Get( p_intf->p_vlc, "key-quit", &val );
692     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
693                       ConvertHotkey( val.i_int ), Exit_Event );
694     var_Get( p_intf->p_vlc, "key-stop", &val );
695     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
696                       ConvertHotkey( val.i_int ), StopStream_Event );
697     var_Get( p_intf->p_vlc, "key-play-pause", &val );
698     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
699                       ConvertHotkey( val.i_int ), PlayStream_Event );
700     var_Get( p_intf->p_vlc, "key-next", &val );
701     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
702                       ConvertHotkey( val.i_int ), NextStream_Event );
703     var_Get( p_intf->p_vlc, "key-prev", &val );
704     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
705                       ConvertHotkey( val.i_int ), PrevStream_Event );
706     var_Get( p_intf->p_vlc, "key-faster", &val );
707     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
708                       ConvertHotkey( val.i_int ), FastStream_Event );
709     var_Get( p_intf->p_vlc, "key-slower", &val );
710     entries[i++].Set( ConvertHotkeyModifiers( val.i_int ),
711                       ConvertHotkey( val.i_int ), SlowStream_Event );
712
713     wxAcceleratorTable accel( 7, entries );
714
715     if( !accel.Ok() )
716         msg_Err( p_intf, "invalid accelerator table" );
717
718     SetAcceleratorTable( accel );
719     msg_Dbg( p_intf, "accelerator table loaded" );
720
721 }
722
723 /*****************************************************************************
724  * Event Handlers.
725  *****************************************************************************/
726 /* Work-around helper for buggy wxGTK */
727 void RecursiveDestroy( wxMenu *menu )
728 {
729     wxMenuItemList::Node *node = menu->GetMenuItems().GetFirst();
730     for( ; node; )
731     {
732         wxMenuItem *item = node->GetData();
733         node = node->GetNext();
734
735         /* Delete the submenus */
736         wxMenu *submenu = item->GetSubMenu();
737         if( submenu )
738         {
739             RecursiveDestroy( submenu );
740         }
741         menu->Delete( item );
742     }
743 }
744
745 void Interface::OnMenuOpen(wxMenuEvent& event)
746 {
747 #if !defined( __WXMSW__ )
748     if( event.GetEventObject() == p_settings_menu )
749     {
750         if( b_settings_menu )
751         {
752             p_settings_menu = SettingsMenu( p_intf, this );
753
754             /* Add static items */
755             p_settings_menu->AppendCheckItem( Extra_Event,
756                              wxU(_("&Extended GUI") ), wxU(_(EXTRA_PREFS)) );
757             p_settings_menu->Append( Prefs_Event, wxU(_("&Preferences...")),
758                                      wxU(_(HELP_PREFS)) );
759
760             /* Work-around for buggy wxGTK */
761             wxMenu *menu = GetMenuBar()->GetMenu( 2 );
762             RecursiveDestroy( menu );
763             /* End work-around */
764
765             menu = GetMenuBar()->Replace( 2, p_settings_menu,
766                                           wxU(_("&Settings")));
767             if( menu ) delete menu;
768
769             b_settings_menu = 0;
770         }
771         else b_settings_menu = 1;
772     }
773     else if( event.GetEventObject() == p_audio_menu )
774     {
775         if( b_audio_menu )
776         {
777             p_audio_menu = AudioMenu( p_intf, this );
778
779             /* Work-around for buggy wxGTK */
780             wxMenu *menu = GetMenuBar()->GetMenu( 3 );
781             RecursiveDestroy( menu );
782             /* End work-around */
783
784             menu =
785                 GetMenuBar()->Replace( 3, p_audio_menu, wxU(_("&Audio")) );
786             if( menu ) delete menu;
787
788             b_audio_menu = 0;
789         }
790         else b_audio_menu = 1;
791     }
792     else if( event.GetEventObject() == p_video_menu )
793     {
794         if( b_video_menu )
795         {
796             p_video_menu = VideoMenu( p_intf, this );
797
798             /* Work-around for buggy wxGTK */
799             wxMenu *menu = GetMenuBar()->GetMenu( 4 );
800             RecursiveDestroy( menu );
801             /* End work-around */
802
803             menu =
804                 GetMenuBar()->Replace( 4, p_video_menu, wxU(_("&Video")) );
805             if( menu ) delete menu;
806
807             b_video_menu = 0;
808         }
809         else b_video_menu = 1;
810     }
811     else if( event.GetEventObject() == p_navig_menu )
812     {
813         if( b_navig_menu )
814         {
815             p_navig_menu = NavigMenu( p_intf, this );
816
817             /* Work-around for buggy wxGTK */
818             wxMenu *menu = GetMenuBar()->GetMenu( 5 );
819             RecursiveDestroy( menu );
820             /* End work-around */
821
822             menu =
823                 GetMenuBar()->Replace( 5, p_navig_menu, wxU(_("&Navigation")));
824             if( menu ) delete menu;
825
826             b_navig_menu = 0;
827         }
828         else b_navig_menu = 1;
829     }
830
831 #else
832     p_settings_menu = SettingsMenu( p_intf, this );
833     /* Add static items */
834     p_settings_menu->AppendCheckItem( Extra_Event, wxU(_("&Extended GUI") ),
835                                       wxU(_(EXTRA_PREFS)) );
836     p_settings_menu->Append( Prefs_Event, wxU(_("&Preferences...")),
837                              wxU(_(HELP_PREFS)) );
838     wxMenu *menu =
839         GetMenuBar()->Replace( 2, p_settings_menu, wxU(_("&Settings")) );
840     if( menu ) delete menu;
841
842     p_audio_menu = AudioMenu( p_intf, this );
843     menu = GetMenuBar()->Replace( 3, p_audio_menu, wxU(_("&Audio")) );
844     if( menu ) delete menu;
845
846     p_video_menu = VideoMenu( p_intf, this );
847     menu = GetMenuBar()->Replace( 4, p_video_menu, wxU(_("&Video")) );
848     if( menu ) delete menu;
849
850     p_navig_menu = NavigMenu( p_intf, this );
851     menu = GetMenuBar()->Replace( 5, p_navig_menu, wxU(_("&Navigation")) );
852     if( menu ) delete menu;
853 #endif
854
855 }
856
857 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
858 void Interface::OnContextMenu2(wxContextMenuEvent& event)
859 {
860     /* Only show the context menu for the main interface */
861     if( GetId() != event.GetId() )
862     {
863         event.Skip();
864         return;
865     }
866
867     if( p_intf->p_sys->pf_show_dialog )
868         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
869 }
870 #endif
871 void Interface::OnContextMenu(wxMouseEvent& event)
872 {
873     if( p_intf->p_sys->pf_show_dialog )
874         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
875 }
876
877 void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
878 {
879     /* TRUE is to force the frame to close. */
880     Close(TRUE);
881 }
882
883 void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
884 {
885     wxString msg;
886     msg.Printf( wxString(wxT("VLC media player " VERSION)) +
887         wxU(_(" (wxWindows interface)\n\n")) +
888         wxU(_("(c) 1996-2004 - the VideoLAN Team\n\n")) +
889         wxU( vlc_wraptext(INTF_ABOUT_MSG,WRAPCOUNT,ISUTF8) ) + wxT("\n\n") +
890         wxU(_("The VideoLAN team <videolan@videolan.org>\n"
891               "http://www.videolan.org/\n\n")) );
892
893     wxMessageBox( msg, wxString::Format(wxU(_("About %s")),
894                   wxT("VLC media player")), wxOK | wxICON_INFORMATION, this );
895 }
896
897 void Interface::OnShowDialog( wxCommandEvent& event )
898 {
899     if( p_intf->p_sys->pf_show_dialog )
900     {
901         int i_id;
902
903         switch( event.GetId() )
904         {
905         case OpenFileSimple_Event:
906             i_id = INTF_DIALOG_FILE_SIMPLE;
907             break;
908         case OpenAdv_Event:
909             i_id = INTF_DIALOG_FILE;
910         case OpenFile_Event:
911             i_id = INTF_DIALOG_FILE;
912             break;
913         case OpenDisc_Event:
914             i_id = INTF_DIALOG_DISC;
915             break;
916         case OpenNet_Event:
917             i_id = INTF_DIALOG_NET;
918             break;
919         case OpenSat_Event:
920             i_id = INTF_DIALOG_SAT;
921             break;
922         case Playlist_Event:
923             i_id = INTF_DIALOG_PLAYLIST;
924             break;
925         case Logs_Event:
926             i_id = INTF_DIALOG_MESSAGES;
927             break;
928         case FileInfo_Event:
929             i_id = INTF_DIALOG_FILEINFO;
930             break;
931         case Prefs_Event:
932             i_id = INTF_DIALOG_PREFS;
933             break;
934         default:
935             i_id = INTF_DIALOG_FILE;
936             break;
937
938         }
939
940         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
941     }
942 }
943
944
945 void Interface::OnStream( wxCommandEvent& event )
946 {
947     StreamDialog *p_stream_dialog = new StreamDialog(p_intf,this);
948     p_stream_dialog->Show();
949 }
950
951
952 void Interface::OnExtra(wxCommandEvent& event)
953 {
954     if( b_extra == VLC_FALSE)
955     {
956         extra_frame->Show();
957         frame_sizer->Show( extra_frame );
958         b_extra = VLC_TRUE;
959     }
960     else
961     {
962         extra_frame->Hide();
963         frame_sizer->Hide( extra_frame );
964         b_extra = VLC_FALSE;
965     }
966     frame_sizer->Layout();
967     frame_sizer->Fit(this);
968 }
969
970 void Interface::OnEnableAdjust(wxCommandEvent& event)
971 {
972     char *psz_filters=config_GetPsz( p_intf, "filter");
973     char *psz_new = NULL;
974     if( event.IsChecked() )
975     {
976         if(psz_filters == NULL)
977         {
978             psz_new = strdup( "adjust" );
979         }
980         else
981         {
982             psz_new= (char *) malloc(strlen(psz_filters) + 8 );
983             sprintf( psz_new, "%s:adjust", psz_filters);
984         }
985         config_PutPsz( p_intf, "filter", psz_new );
986         vlc_value_t val;
987         vout_thread_t *p_vout =
988            (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
989                                        FIND_ANYWHERE );
990         if( p_vout != NULL )
991         {
992             val.psz_string = strdup( psz_new );
993             var_Set( p_vout, "filter", val);
994             vlc_object_release( p_vout );
995         }
996         if( val.psz_string ) free( val.psz_string );
997         brightness_slider->Enable();
998         saturation_slider->Enable();
999         contrast_slider->Enable();
1000         hue_slider->Enable();
1001         gamma_slider->Enable();
1002     }
1003     else
1004     {
1005         if( psz_filters != NULL )
1006         {
1007
1008             char *psz_current;
1009             unsigned int i=0;
1010             for( i = 0; i< strlen(psz_filters ); i++)
1011             {
1012                 if ( !strncasecmp( &psz_filters[i],"adjust",6 ))
1013                 {
1014                     if(i > 0)
1015                         if( psz_filters[i-1] == ':' ) i--;
1016                     psz_current = strchr( &psz_filters[i+1] , ':' );
1017                     if( !psz_current )
1018                         psz_filters[i] = '\0';
1019                     else
1020                     {
1021                        memmove( &psz_filters[i] , psz_current,
1022                                 &psz_filters[strlen(psz_filters)]-psz_current
1023                                 +1);
1024                     }
1025                 }
1026             }
1027             config_PutPsz( p_intf, "filter", psz_filters);
1028             vlc_value_t val;
1029             val.psz_string = strdup( psz_filters );
1030             vout_thread_t *p_vout =
1031                (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1032                                        FIND_ANYWHERE );
1033             if( p_vout != NULL )
1034             {
1035                 var_Set( p_vout, "filter", val);
1036                 vlc_object_release( p_vout );
1037             }
1038             if( val.psz_string ) free( val.psz_string );
1039         }
1040         brightness_slider->Disable();
1041         saturation_slider->Disable();
1042         contrast_slider->Disable();
1043         hue_slider->Disable();
1044         gamma_slider->Disable();
1045     }
1046     if(psz_filters) free(psz_filters);
1047     if(psz_new) free(psz_new);
1048 }
1049
1050 void Interface::OnHueUpdate( wxScrollEvent& event)
1051 {
1052     config_PutInt( p_intf , "hue" , event.GetPosition() );
1053 }
1054
1055 void Interface::OnSaturationUpdate( wxScrollEvent& event)
1056 {
1057     config_PutFloat( p_intf , "saturation" , (float)event.GetPosition()/100 );
1058 }
1059
1060 void Interface::OnBrightnessUpdate( wxScrollEvent& event)
1061 {
1062     config_PutFloat( p_intf , "brightness", (float)event.GetPosition()/100 );
1063 }
1064
1065 void Interface::OnContrastUpdate(wxScrollEvent& event)
1066 {
1067     config_PutFloat( p_intf , "contrast" , (float)event.GetPosition()/100 );
1068 }
1069
1070 void Interface::OnGammaUpdate(wxScrollEvent& event)
1071 {
1072     config_PutFloat( p_intf , "gamma" , (float)event.GetPosition()/10 );
1073 }
1074
1075 void Interface::OnRatio( wxCommandEvent& event )
1076 {
1077    config_PutPsz( p_intf, "aspect-ratio", ratio_combo->GetValue().mb_str() );
1078 }
1079
1080 void Interface::OnEnableVisual(wxCommandEvent& event)
1081 {
1082     if( event.IsChecked() )
1083     {
1084         config_PutPsz( p_intf, "audio-filter", "visual" );
1085     }
1086     else
1087     {
1088         config_PutPsz( p_intf, "audio-filter", "" );
1089     }
1090 }
1091
1092 void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
1093 {
1094     wxCommandEvent dummy;
1095     playlist_t *p_playlist =
1096         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1097                                        FIND_ANYWHERE );
1098     if( p_playlist == NULL ) return;
1099
1100     if( p_playlist->i_size && p_playlist->i_enabled )
1101     {
1102         vlc_value_t state;
1103
1104         input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf,
1105                                                        VLC_OBJECT_INPUT,
1106                                                        FIND_ANYWHERE );
1107         if( p_input == NULL )
1108         {
1109             /* No stream was playing, start one */
1110             playlist_Play( p_playlist );
1111             TogglePlayButton( PLAYING_S );
1112             vlc_object_release( p_playlist );
1113             return;
1114         }
1115
1116         var_Get( p_input, "state", &state );
1117
1118         if( state.i_int != PAUSE_S )
1119         {
1120             /* A stream is being played, pause it */
1121             state.i_int = PAUSE_S;
1122         }
1123         else
1124         {
1125             /* Stream is paused, resume it */
1126             state.i_int = PLAYING_S;
1127         }
1128         var_Set( p_input, "state", state );
1129
1130         TogglePlayButton( state.i_int );
1131         vlc_object_release( p_input );
1132         vlc_object_release( p_playlist );
1133     }
1134     else
1135     {
1136         /* If the playlist is empty, open a file requester instead */
1137         vlc_object_release( p_playlist );
1138         OnShowDialog( dummy );
1139     }
1140 }
1141
1142 void Interface::OnStopStream( wxCommandEvent& WXUNUSED(event) )
1143 {
1144     playlist_t * p_playlist =
1145         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1146                                        FIND_ANYWHERE );
1147     if( p_playlist == NULL )
1148     {
1149         return;
1150     }
1151
1152     playlist_Stop( p_playlist );
1153     TogglePlayButton( PAUSE_S );
1154     vlc_object_release( p_playlist );
1155 }
1156
1157 void Interface::OnSliderUpdate( wxScrollEvent& event )
1158 {
1159     vlc_mutex_lock( &p_intf->change_lock );
1160
1161 #ifdef WIN32
1162     if( event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
1163         || event.GetEventType() == wxEVT_SCROLL_ENDSCROLL )
1164     {
1165 #endif
1166         if( p_intf->p_sys->i_slider_pos != event.GetPosition()
1167             && p_intf->p_sys->p_input )
1168         {
1169             vlc_value_t pos;
1170             pos.f_float = (float)event.GetPosition() / (float)SLIDER_MAX_POS;
1171
1172             var_Set( p_intf->p_sys->p_input, "position", pos );
1173         }
1174
1175 #ifdef WIN32
1176         p_intf->p_sys->b_slider_free = VLC_TRUE;
1177     }
1178     else
1179     {
1180         p_intf->p_sys->b_slider_free = VLC_FALSE;
1181
1182         if( p_intf->p_sys->p_input )
1183         {
1184             /* Update stream date */
1185 #define p_area p_intf->p_sys->p_input->stream.p_selected_area
1186             char psz_time[ MSTRTIME_MAX_SIZE ];
1187
1188             slider_box->SetLabel(
1189                 wxU(input_OffsetToTime( p_intf->p_sys->p_input,
1190                                         psz_time,
1191                                         p_area->i_size * event.GetPosition()
1192                                         / SLIDER_MAX_POS )) );
1193 #undef p_area
1194         }
1195     }
1196 #endif
1197
1198 #undef WIN32
1199     vlc_mutex_unlock( &p_intf->change_lock );
1200 }
1201
1202 void Interface::OnPrevStream( wxCommandEvent& WXUNUSED(event) )
1203 {
1204     playlist_t * p_playlist =
1205         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1206                                        FIND_ANYWHERE );
1207     if( p_playlist == NULL )
1208     {
1209         return;
1210     }
1211
1212     vlc_mutex_lock( &p_playlist->object_lock );
1213     if( p_playlist->p_input != NULL )
1214     {
1215         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1216         if( p_playlist->p_input->stream.p_selected_area->i_id > 1 )
1217         {
1218             vlc_value_t val; val.b_bool = VLC_TRUE;
1219             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1220             var_Set( p_playlist->p_input, "prev-title", val );
1221         } else
1222             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1223     }
1224     vlc_mutex_unlock( &p_playlist->object_lock );
1225
1226     playlist_Prev( p_playlist );
1227     vlc_object_release( p_playlist );
1228 }
1229
1230 void Interface::OnNextStream( wxCommandEvent& WXUNUSED(event) )
1231 {
1232     playlist_t * p_playlist =
1233         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1234                                        FIND_ANYWHERE );
1235     if( p_playlist == NULL )
1236     {
1237         return;
1238     }
1239
1240     vlc_mutex_lock( &p_playlist->object_lock );
1241     if( p_playlist->p_input != NULL )
1242     {
1243         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1244         if( p_playlist->p_input->stream.i_area_nb > 1 &&
1245             p_playlist->p_input->stream.p_selected_area->i_id <
1246               p_playlist->p_input->stream.i_area_nb - 1 )
1247         {
1248             vlc_value_t val; val.b_bool = VLC_TRUE;
1249             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1250             var_Set( p_playlist->p_input, "next-title", val );
1251         } else
1252             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1253     }
1254     vlc_mutex_unlock( &p_playlist->object_lock );
1255
1256     playlist_Next( p_playlist );
1257     vlc_object_release( p_playlist );
1258 }
1259
1260 void Interface::OnSlowStream( wxCommandEvent& WXUNUSED(event) )
1261 {
1262     input_thread_t *p_input =
1263         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1264                                            FIND_ANYWHERE );
1265     if( p_input )
1266     {
1267         vlc_value_t val; val.b_bool = VLC_TRUE;
1268
1269         var_Set( p_input, "rate-slower", val );
1270         vlc_object_release( p_input );
1271     }
1272 }
1273
1274 void Interface::OnFastStream( wxCommandEvent& WXUNUSED(event) )
1275 {
1276     input_thread_t *p_input =
1277         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1278                                            FIND_ANYWHERE );
1279     if( p_input )
1280     {
1281         vlc_value_t val; val.b_bool = VLC_TRUE;
1282
1283         var_Set( p_input, "rate-faster", val );
1284         vlc_object_release( p_input );
1285     }
1286 }
1287
1288 void Interface::TogglePlayButton( int i_playing_status )
1289 {
1290     if( i_playing_status == i_old_playing_status )
1291         return;
1292
1293     GetToolBar()->DeleteTool( PlayStream_Event );
1294
1295     if( i_playing_status == PLAYING_S )
1296     {
1297         GetToolBar()->InsertTool( 8, PlayStream_Event, wxU(_("Pause")),
1298                                   wxBitmap( pause_xpm ), wxNullBitmap,
1299                                   wxITEM_NORMAL, wxU(_(HELP_PAUSE)) );
1300     }
1301     else
1302     {
1303         GetToolBar()->InsertTool( 8, PlayStream_Event, wxU(_("Play")),
1304                                   wxBitmap( play_xpm ), wxNullBitmap,
1305                                   wxITEM_NORMAL, wxU(_(HELP_PLAY)) );
1306     }
1307
1308     GetToolBar()->Realize();
1309
1310     i_old_playing_status = i_playing_status;
1311 }
1312
1313 #if !defined(__WXX11__)
1314 /*****************************************************************************
1315  * Definition of DragAndDrop class.
1316  *****************************************************************************/
1317 DragAndDrop::DragAndDrop( intf_thread_t *_p_intf, vlc_bool_t _b_enqueue )
1318 {
1319     p_intf = _p_intf;
1320     b_enqueue = _b_enqueue;
1321 }
1322
1323 bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
1324                                const wxArrayString& filenames )
1325 {
1326     /* Add dropped files to the playlist */
1327
1328     playlist_t *p_playlist =
1329         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1330                                        FIND_ANYWHERE );
1331     if( p_playlist == NULL )
1332     {
1333         return FALSE;
1334     }
1335
1336     for( size_t i = 0; i < filenames.GetCount(); i++ )
1337         playlist_Add( p_playlist, (const char *)filenames[i].mb_str(),
1338                       (const char *)filenames[i].mb_str(),
1339                       PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
1340                       PLAYLIST_END );
1341
1342     vlc_object_release( p_playlist );
1343
1344     return TRUE;
1345 }
1346 #endif
1347
1348 /*****************************************************************************
1349  * Definition of wxVolCtrl class.
1350  *****************************************************************************/
1351 wxVolCtrl::wxVolCtrl( intf_thread_t *_p_intf, wxWindow* parent, wxWindowID id )
1352   : wxGauge( parent, id, 200, wxDefaultPosition, wxSize( 20, -1 ),
1353              wxGA_VERTICAL | wxGA_SMOOTH )
1354 {
1355     p_intf = _p_intf;
1356 }
1357
1358 void wxVolCtrl::OnChange( wxMouseEvent& event )
1359 {
1360     if( !event.LeftDown() && !event.LeftIsDown() ) return;
1361
1362     int i_volume = (GetClientSize().GetHeight() - event.GetY()) * 200 /
1363                     GetClientSize().GetHeight();
1364     Change( i_volume );
1365 }
1366
1367 void wxVolCtrl::Change( int i_volume )
1368 {
1369     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
1370     SetValue( i_volume );
1371     SetToolTip( wxString::Format((wxString)wxU(_("Volume")) + wxT(" %d"),
1372                 i_volume ) );
1373 }