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