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