]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/interface.cpp
fc49da1bca206b0cac14d1188a8eff765dbd4ad8
[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 UpdateVolume();
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 wxUSE_DRAG_AND_DROP
279     /* Associate drop targets with the main interface */
280     SetDropTarget( new DragAndDrop( p_intf ) );
281 #endif
282
283     SetupHotkeys();
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::Update()
301 {
302     /* Misc updates */
303     ((wxVolCtrl *)volctrl)->UpdateVolume();
304 }
305
306 void Interface::OnControlEvent( wxCommandEvent& event )
307 {
308     switch( event.GetId() )
309     {
310     case 0:
311         frame_sizer->Layout();
312         frame_sizer->Fit(this);
313         break;
314
315     case 1:
316         long i_style = GetWindowStyle();
317         if( event.GetInt() ) i_style |= wxSTAY_ON_TOP;
318         else i_style &= ~wxSTAY_ON_TOP;
319         SetWindowStyle( i_style );
320         break;
321     }
322 }
323
324 /*****************************************************************************
325  * Private methods.
326  *****************************************************************************/
327 void Interface::CreateOurMenuBar()
328 {
329     /* Create the "File" menu */
330     wxMenu *file_menu = new wxMenu;
331     file_menu->Append( OpenFileSimple_Event,
332                        wxU(_("Quick &Open File...\tCtrl-O")) );
333
334     file_menu->AppendSeparator();
335     file_menu->Append( OpenFile_Event, wxU(_("Open &File...\tCtrl-F")) );
336     file_menu->Append( OpenDisc_Event, wxU(_("Open &Disc...\tCtrl-D")) );
337     file_menu->Append( OpenNet_Event,
338                        wxU(_("Open &Network Stream...\tCtrl-N")) );
339     file_menu->Append( OpenCapture_Event,
340                        wxU(_("Open &Capture Device...\tCtrl-C")) );
341
342     file_menu->AppendSeparator();
343     file_menu->Append( StreamWizard_Event,
344                        wxU(_("Streaming &Wizard...\tCtrl-W")) );
345 #if 0
346     file_menu->Append( Wizard_Event, wxU(_("New Wizard...")) );
347 #endif
348     file_menu->AppendSeparator();
349     file_menu->Append( Exit_Event, wxU(_("E&xit\tCtrl-X")) );
350
351     /* Create the "View" menu */
352     wxMenu *view_menu = new wxMenu;
353     view_menu->Append( Playlist_Event, wxU(_("&Playlist...\tCtrl-P")) );
354     view_menu->Append( Logs_Event, wxU(_("&Messages...\tCtrl-M")) );
355     view_menu->Append( FileInfo_Event,
356                        wxU(_("Stream and Media &info...\tCtrl-I")) );
357
358     /* Create the "Auto-generated" menus */
359     p_settings_menu = SettingsMenu( p_intf, this );
360     p_audio_menu = AudioMenu( p_intf, this );
361     p_video_menu = VideoMenu( p_intf, this );
362     p_navig_menu = NavigMenu( p_intf, this );
363
364     /* Create the "Help" menu */
365     wxMenu *help_menu = new wxMenu;
366     help_menu->Append( About_Event, wxU(_("About VLC media player")) );
367
368     /* Append the freshly created menus to the menu bar... */
369     wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
370     menubar->Append( file_menu, wxU(_("&File")) );
371     menubar->Append( view_menu, wxU(_("&View")) );
372     menubar->Append( p_settings_menu, wxU(_("&Settings")) );
373     menubar->Append( p_audio_menu, wxU(_("&Audio")) );
374     menubar->Append( p_video_menu, wxU(_("&Video")) );
375     menubar->Append( p_navig_menu, wxU(_("&Navigation")) );
376     menubar->Append( help_menu, wxU(_("&Help")) );
377
378     /* Attach the menu bar to the frame */
379     SetMenuBar( menubar );
380
381     /* Find out size of menu bar */
382     int i_size = 0;
383     for( unsigned int i = 0; i < menubar->GetMenuCount(); i++ )
384     {
385         int i_width, i_height;
386         menubar->GetTextExtent( menubar->GetLabelTop(i), &i_width, &i_height );
387         i_size += i_width +
388 #if defined(__WXGTK__)
389             20 /* approximate margin */;
390 #else
391             4 /* approximate margin */;
392 #endif
393     }
394     frame_sizer->SetMinSize( i_size, -1 );
395
396     /* Intercept all menu events in our custom event handler */
397     PushEventHandler( new MenuEvtHandler( p_intf, this ) );
398
399 #if wxUSE_DRAG_AND_DROP
400     /* Associate drop targets with the menubar */
401     menubar->SetDropTarget( new DragAndDrop( p_intf ) );
402 #endif
403 }
404
405 class VLCVolCtrl : public wxControl
406 {
407 public:
408     VLCVolCtrl( intf_thread_t *p_intf, wxWindow *p_parent, wxGauge ** );
409     virtual ~VLCVolCtrl() {};
410
411     virtual void OnPaint( wxPaintEvent &event );
412
413   private:
414     DECLARE_EVENT_TABLE()
415 };
416
417 BEGIN_EVENT_TABLE(VLCVolCtrl, wxControl)
418    EVT_PAINT(VLCVolCtrl::OnPaint)
419 END_EVENT_TABLE()
420
421 VLCVolCtrl::VLCVolCtrl( intf_thread_t *p_intf, wxWindow *p_parent,
422                         wxGauge **pp_volctrl )
423   :wxControl( p_parent, -1, wxDefaultPosition, wxSize(64, 16), wxBORDER_NONE )
424 {
425     *pp_volctrl = new wxVolCtrl( p_intf, this, -1, wxPoint( 18, 0 ),
426                                  wxSize( 44, 16 ) );
427 }
428
429 void VLCVolCtrl::OnPaint( wxPaintEvent &evt )
430 {
431     wxPaintDC dc( this );
432     wxBitmap mPlayBitmap( speaker_xpm );
433     dc.DrawBitmap( mPlayBitmap, 1, 0, TRUE );
434 }
435
436 void Interface::CreateOurToolBar()
437 {
438 #define HELP_STOP N_("Stop")
439 #define HELP_PLAY N_("Play")
440 #define HELP_PAUSE N_("Pause")
441 #define HELP_PLO N_("Playlist")
442 #define HELP_PLP N_("Previous playlist item")
443 #define HELP_PLN N_("Next playlist item")
444 #define HELP_SLOW N_("Play slower")
445 #define HELP_FAST N_("Play faster")
446
447     wxLogNull LogDummy; /* Hack to suppress annoying log message on the win32
448                          * version because we don't include wx.rc */
449
450     wxToolBar *toolbar =
451         CreateToolBar( wxTB_HORIZONTAL | wxTB_FLAT | wxTB_DOCKABLE );
452
453     toolbar->SetToolBitmapSize( wxSize(TOOLBAR_BMP_WIDTH,TOOLBAR_BMP_HEIGHT) );
454
455     toolbar->AddTool( PlayStream_Event, wxT(""), wxBitmap( play_xpm ),
456                       wxU(_(HELP_PLAY)) );
457 #if 0
458     toolbar->AddTool( PlayStream_Event, wxT(""), wxBitmap( pause_xpm ),
459                       wxU(_(HELP_PAUSE)) );
460 #endif
461     toolbar->AddTool( StopStream_Event, wxT(""), wxBitmap( stop_xpm ),
462                       wxU(_(HELP_STOP)) );
463     toolbar->AddSeparator();
464     toolbar->AddTool( PrevStream_Event, wxT(""),
465                       wxBitmap( prev_xpm ), wxU(_(HELP_PLP)) );
466     toolbar->AddTool( SlowStream_Event, wxT(""),
467                       wxBitmap( slow_xpm ), wxU(_(HELP_SLOW)) );
468     toolbar->AddTool( FastStream_Event, wxT(""),
469                       wxBitmap( fast_xpm ), wxU(_(HELP_FAST)) );
470     toolbar->AddTool( NextStream_Event, wxT(""), wxBitmap( next_xpm ),
471                       wxU(_(HELP_PLN)) );
472     toolbar->AddSeparator();
473     toolbar->AddTool( Playlist_Event, wxT(""), wxBitmap( eject_xpm ),
474                       wxU(_(HELP_PLO)) );
475
476     wxControl *p_dummy_ctrl =
477         new wxControl( toolbar, -1, wxDefaultPosition,
478                        wxSize(64, 16 ), wxBORDER_NONE );
479
480     toolbar->AddControl( p_dummy_ctrl );
481
482     VLCVolCtrl *sound_control = new VLCVolCtrl( p_intf, toolbar, &volctrl );
483     toolbar->AddControl( sound_control );
484
485     toolbar->Realize();
486
487 #if wxUSE_DRAG_AND_DROP
488     /* Associate drop targets with the toolbar */
489     toolbar->SetDropTarget( new DragAndDrop( p_intf ) );
490 #endif
491 }
492
493 void Interface::CreateOurSlider()
494 {
495     /* Create a new frame and sizer containing the slider */
496     slider_frame = new wxPanel( this, -1, wxDefaultPosition, wxDefaultSize );
497     slider_frame->SetAutoLayout( TRUE );
498     wxBoxSizer *frame_sizer = new wxBoxSizer( wxHORIZONTAL );
499     //frame_sizer->SetMinSize( -1, 50 );
500
501     /* Create slider */
502     slider = new wxSlider( slider_frame, SliderScroll_Event, 0, 0,
503                            SLIDER_MAX_POS, wxDefaultPosition, wxDefaultSize );
504
505     /* Add everything to the frame */
506     frame_sizer->Add( slider, 1, wxEXPAND | wxALL, 5 );
507     slider_frame->SetSizer( frame_sizer );
508     frame_sizer->Layout();
509     frame_sizer->SetSizeHints(slider_frame);
510
511     /* Hide the slider by default */
512     slider_frame->Hide();
513 }
514
515
516 void Interface::CreateOurExtendedPanel()
517 {
518     char *psz_filters;
519
520     extra_frame = new wxPanel( this, -1, wxDefaultPosition, wxDefaultSize );
521     extra_frame->SetAutoLayout( TRUE );
522     wxBoxSizer *extra_sizer = new wxBoxSizer( wxHORIZONTAL );
523
524     /* Create static box to surround the adjust controls */
525     wxStaticBox *adjust_box =
526            new wxStaticBox( extra_frame, -1, wxU(_("Adjust Image")) );
527
528     /* Create the size for the frame */
529     wxStaticBoxSizer *adjust_sizer =
530         new wxStaticBoxSizer( adjust_box, wxVERTICAL );
531     adjust_sizer->SetMinSize( -1, 50 );
532     
533     /* Create flex grid */
534     wxFlexGridSizer *adjust_gridsizer =
535         new wxFlexGridSizer( 6, 2, 0, 0);
536     adjust_gridsizer->AddGrowableCol(1);
537
538     /* Create every controls */
539
540     /* Create the adjust button */
541     wxCheckBox * adjust_check = new wxCheckBox( extra_frame, Adjust_Event,
542                                                  wxU(_("Enable")));
543
544     /* Create the restore to defaults button */
545     restoredefaults_button = 
546         new wxButton( extra_frame, RestoreDefaults_Event,
547         wxU(_("Restore Defaults")), wxDefaultPosition);
548
549     wxStaticText *hue_text = new wxStaticText( extra_frame, -1,
550                                        wxU(_("Hue")) );
551     hue_slider = new wxSlider ( extra_frame, Hue_Event, 0, 0,
552                                 360, wxDefaultPosition, wxDefaultSize );
553
554
555     wxStaticText *contrast_text = new wxStaticText( extra_frame, -1,
556                                        wxU(_("Contrast")) );
557     contrast_slider = new wxSlider ( extra_frame, Contrast_Event, 0, 0,
558                                 200, wxDefaultPosition, wxDefaultSize);
559
560     wxStaticText *brightness_text = new wxStaticText( extra_frame, -1,
561                                        wxU(_("Brightness")) );
562     brightness_slider = new wxSlider ( extra_frame, Brightness_Event, 0, 0,
563                            200, wxDefaultPosition, wxDefaultSize) ;
564
565     wxStaticText *saturation_text = new wxStaticText( extra_frame, -1,
566                                           wxU(_("Saturation")) );
567     saturation_slider = new wxSlider ( extra_frame, Saturation_Event, 0, 0,
568                            300, wxDefaultPosition, wxDefaultSize );
569
570     wxStaticText *gamma_text = new wxStaticText( extra_frame, -1,
571                                           wxU(_("Gamma")) );
572     gamma_slider = new wxSlider ( extra_frame, Gamma_Event, 0, 0,
573                            100, wxDefaultPosition, wxDefaultSize );
574
575     adjust_gridsizer->Add(adjust_check, 1, wxEXPAND, 0);
576     adjust_gridsizer->Add(restoredefaults_button, 1, wxEXPAND, 0);
577     adjust_gridsizer->Add(hue_text, 1, wxEXPAND, 0);
578     adjust_gridsizer->Add(hue_slider, 1, wxEXPAND, 0);
579     adjust_gridsizer->Add(contrast_text, 1, wxEXPAND, 0);
580     adjust_gridsizer->Add(contrast_slider, 1, wxEXPAND, 0);
581     adjust_gridsizer->Add(brightness_text, 1, wxEXPAND, 0);
582     adjust_gridsizer->Add(brightness_slider, 1, wxEXPAND, 0);
583     adjust_gridsizer->Add(saturation_text, 1, wxEXPAND, 0);
584     adjust_gridsizer->Add(saturation_slider, 1, wxEXPAND, 0);
585     adjust_gridsizer->Add(gamma_text, 1, wxEXPAND, 0);
586     adjust_gridsizer->Add(gamma_slider, 1, wxEXPAND, 0);
587     
588     adjust_sizer->Add(adjust_gridsizer,1,wxEXPAND, 0);
589     
590     extra_sizer->Add(adjust_sizer,1,wxBOTTOM,5);
591
592     /* Create sizer to surround the other controls */
593     wxBoxSizer *other_sizer = new wxBoxSizer( wxVERTICAL );
594
595
596     wxStaticBox *video_box =
597             new wxStaticBox( extra_frame, -1, wxU(_("Video Options")) );
598     /* Create the sizer for the frame */
599     wxStaticBoxSizer *video_sizer =
600        new wxStaticBoxSizer( video_box, wxVERTICAL );
601     video_sizer->SetMinSize( -1, 50 );
602
603     static const wxString ratio_array[] =
604     {
605         wxT("4:3"),
606         wxT("16:9"),
607     };
608
609     wxBoxSizer *ratio_sizer = new wxBoxSizer( wxHORIZONTAL );
610     wxStaticText *ratio_text = new wxStaticText( extra_frame, -1,
611                                           wxU(_("Aspect Ratio")) );
612
613     ratio_combo = new wxComboBox( extra_frame, Ratio_Event, wxT(""),
614                                   wxDefaultPosition, wxSize(120,-1),
615                                   WXSIZEOF(ratio_array), ratio_array,
616                                   0 );
617
618     ratio_sizer->Add( ratio_text, 0, wxALL, 2 );
619     ratio_sizer->Add( ratio_combo, 0, wxALL, 2 );
620     ratio_sizer->Layout();
621
622     video_sizer->Add( ratio_sizer  , 0 , wxALL , 0 );
623     video_sizer->Layout();
624
625 #if 0
626     wxBoxSizer *visual_sizer = new wxBoxSizer( wxHORIZONTAL );
627
628     wxCheckBox *visual_checkbox = new wxCheckBox( extra_frame, Visual_Event,
629                                             wxU(_("Visualizations")) );
630
631     visual_sizer->Add( visual_checkbox, 0, wxEXPAND, 0);
632     visual_sizer->Layout();
633
634     wxStaticBox *audio_box =
635               new wxStaticBox( extra_frame, -1, wxU(_("Audio Options")) );
636     /* Create the sizer for the frame */
637     wxStaticBoxSizer *audio_sizer =
638         new wxStaticBoxSizer( audio_box, wxVERTICAL );
639     audio_sizer->SetMinSize( -1, 50 );
640
641     audio_sizer->Add( visual_sizer, 0, wxALL, 0);
642     audio_sizer->Layout();
643
644     other_sizer->Add( audio_sizer , 0 , wxALL | wxEXPAND , 0 );
645 #endif
646     other_sizer->Add( video_sizer, 0, wxALL | wxEXPAND , 0);
647     other_sizer->Layout();
648
649     extra_sizer->Add(other_sizer,0,wxBOTTOM,5);
650
651     extra_frame->SetSizer( extra_sizer );
652
653     /* Layout the whole panel */
654     extra_sizer->Layout();
655
656     extra_sizer->SetSizeHints(extra_frame);
657
658     /* Write down initial values */
659 #if 0
660     psz_filters = config_GetPsz( p_intf, "audio-filter" );
661     if( psz_filters && strstr( psz_filters, "visual" ) )
662     {
663         visual_checkbox->SetValue(1);
664     }
665     if( psz_filters ) free( psz_filters );
666 #endif
667     psz_filters = config_GetPsz( p_intf, "filter" );
668     if( psz_filters && strstr( psz_filters, "adjust" ) )
669     {
670         adjust_check->SetValue( 1 );
671         restoredefaults_button->Enable();
672         saturation_slider->Enable();
673         contrast_slider->Enable();
674         brightness_slider->Enable();
675         hue_slider->Enable();
676         gamma_slider->Enable();
677     }
678     else
679     {
680         adjust_check->SetValue( 0 );
681         restoredefaults_button->Disable();
682         saturation_slider->Disable();
683         contrast_slider->Disable();
684         brightness_slider->Disable();
685         hue_slider->Disable();
686         gamma_slider->Disable();
687     }
688     if( psz_filters ) free( psz_filters );
689
690     int i_value = config_GetInt( p_intf, "hue" );
691     if( i_value > 0 && i_value < 360 )
692         hue_slider->SetValue( i_value );
693
694     float f_value;
695     f_value = config_GetFloat( p_intf, "saturation" );
696     if( f_value > 0 && f_value < 5 )
697         saturation_slider->SetValue( (int)(100 * f_value) );
698     f_value = config_GetFloat( p_intf, "contrast" );
699     if( f_value > 0 && f_value < 4 )
700         contrast_slider->SetValue( (int)(100 * f_value) );
701     f_value = config_GetFloat( p_intf, "brightness" );
702     if( f_value > 0 && f_value < 2 )
703         brightness_slider->SetValue( (int)(100 * f_value) );
704     f_value = config_GetFloat( p_intf, "gamma" );
705     if( f_value > 0 && f_value < 10 )
706         gamma_slider->SetValue( (int)(10 * f_value) );
707
708     extra_frame->Hide();
709 }
710
711 static int ConvertHotkeyModifiers( int i_hotkey )
712 {
713     int i_accel_flags = 0;
714     if( i_hotkey & KEY_MODIFIER_ALT ) i_accel_flags |= wxACCEL_ALT;
715     if( i_hotkey & KEY_MODIFIER_CTRL ) i_accel_flags |= wxACCEL_CTRL;
716     if( i_hotkey & KEY_MODIFIER_SHIFT ) i_accel_flags |= wxACCEL_SHIFT;
717     if( !i_accel_flags ) i_accel_flags = wxACCEL_NORMAL;
718     return i_accel_flags;
719 }
720
721 static int ConvertHotkey( int i_hotkey )
722 {
723     int i_key = i_hotkey & ~KEY_MODIFIER;
724     if( i_key & KEY_ASCII ) return i_key & KEY_ASCII;
725     else if( i_key & KEY_SPECIAL )
726     {
727         switch ( i_key )
728         {
729         case KEY_LEFT: return WXK_LEFT;
730         case KEY_RIGHT: return WXK_RIGHT;
731         case KEY_UP: return WXK_UP;
732         case KEY_DOWN: return WXK_DOWN;
733         case KEY_SPACE: return WXK_SPACE;
734         case KEY_ENTER: return WXK_RETURN;
735         case KEY_F1: return WXK_F1;
736         case KEY_F2: return WXK_F2;
737         case KEY_F3: return WXK_F3;
738         case KEY_F4: return WXK_F4;
739         case KEY_F5: return WXK_F5;
740         case KEY_F6: return WXK_F6;
741         case KEY_F7: return WXK_F7;
742         case KEY_F8: return WXK_F8;
743         case KEY_F9: return WXK_F9;
744         case KEY_F10: return WXK_F10;
745         case KEY_F11: return WXK_F11;
746         case KEY_F12: return WXK_F12;
747         case KEY_HOME: return WXK_HOME;
748         case KEY_END: return WXK_HOME;
749         case KEY_MENU: return WXK_MENU;
750         case KEY_ESC: return WXK_ESCAPE;
751         case KEY_PAGEUP: return WXK_PRIOR;
752         case KEY_PAGEDOWN: return WXK_NEXT;
753         case KEY_TAB: return WXK_TAB;
754         case KEY_BACKSPACE: return WXK_BACK;
755         }
756     }
757     return WXK_F24;
758 }
759
760 void Interface::SetupHotkeys()
761 {
762     struct vlc_t::hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
763     int i_hotkeys;
764
765     /* Count number of hoteys */
766     for( i_hotkeys = 0; p_hotkeys[i_hotkeys].psz_action != NULL; i_hotkeys++ );
767
768     p_intf->p_sys->i_first_hotkey_event = wxID_HIGHEST + 7000;
769     p_intf->p_sys->i_hotkeys = i_hotkeys;
770
771     wxAcceleratorEntry p_entries[i_hotkeys];
772
773     /* Setup the hotkeys as accelerators */
774     for( int i = 0; i < i_hotkeys; i++ )
775     {
776         p_entries[i].Set( ConvertHotkeyModifiers( p_hotkeys[i].i_key ),
777                           ConvertHotkey( p_hotkeys[i].i_key ),
778                           p_intf->p_sys->i_first_hotkey_event + i );
779     }
780
781     wxAcceleratorTable accel( i_hotkeys, p_entries );
782
783     if( !accel.Ok() )
784     {
785         msg_Err( p_intf, "invalid accelerator table" );
786     }
787     else
788     {
789         SetAcceleratorTable( accel );
790         msg_Dbg( p_intf, "accelerator table loaded" );
791     }
792 }
793
794 /*****************************************************************************
795  * Event Handlers.
796  *****************************************************************************/
797
798 void Interface::OnMenuOpen(wxMenuEvent& event)
799 {
800 #if defined( __WXMSW__ )
801 #   define GetEventObject GetMenu
802 #endif
803
804     if( event.GetEventObject() == p_settings_menu )
805     {
806         p_settings_menu = SettingsMenu( p_intf, this, p_settings_menu );
807
808         /* Add static items */
809         p_settings_menu->AppendCheckItem( Extended_Event,
810             wxU(_("&Extended GUI") ) );
811         p_settings_menu->AppendCheckItem( Bookmarks_Event,
812             wxU(_("&Bookmarks...") ) );
813         p_settings_menu->Append( Prefs_Event, wxU(_("&Preferences...")) );
814     }
815
816     else if( event.GetEventObject() == p_audio_menu )
817     {
818         p_audio_menu = AudioMenu( p_intf, this, p_audio_menu );
819     }
820
821     else if( event.GetEventObject() == p_video_menu )
822     {
823         p_video_menu = VideoMenu( p_intf, this, p_video_menu );
824     }
825
826     else if( event.GetEventObject() == p_navig_menu )
827     {
828         p_navig_menu = NavigMenu( p_intf, this, p_navig_menu );
829     }
830
831 #if defined( __WXMSW__ )
832 #   undef GetEventObject
833 #endif
834 }
835
836 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
837 void Interface::OnContextMenu2(wxContextMenuEvent& event)
838 {
839     /* Only show the context menu for the main interface */
840     if( GetId() != event.GetId() )
841     {
842         event.Skip();
843         return;
844     }
845
846     if( p_intf->p_sys->pf_show_dialog )
847         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
848 }
849 #endif
850 void Interface::OnContextMenu(wxMouseEvent& event)
851 {
852     if( p_intf->p_sys->pf_show_dialog )
853         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
854 }
855
856 void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
857 {
858     /* TRUE is to force the frame to close. */
859     Close(TRUE);
860 }
861
862 void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
863 {
864     wxString msg;
865     msg.Printf( wxString(wxT("VLC media player " VERSION)) +
866         wxU(_(" (wxWindows interface)\n\n")) +
867         wxU(_("(c) 1996-2004 - the VideoLAN Team\n\n")) +
868         wxU( vlc_wraptext(INTF_ABOUT_MSG,WRAPCOUNT,ISUTF8) ) + wxT("\n\n") +
869         wxU(_("The VideoLAN team <videolan@videolan.org>\n"
870               "http://www.videolan.org/\n\n")) );
871
872     wxMessageBox( msg, wxString::Format(wxU(_("About %s")),
873                   wxT("VLC media player")), wxOK | wxICON_INFORMATION, this );
874 }
875
876 void Interface::OnShowDialog( wxCommandEvent& event )
877 {
878     if( p_intf->p_sys->pf_show_dialog )
879     {
880         int i_id;
881
882         switch( event.GetId() )
883         {
884         case OpenFileSimple_Event:
885             i_id = INTF_DIALOG_FILE_SIMPLE;
886             break;
887         case OpenAdv_Event:
888             i_id = INTF_DIALOG_FILE;
889         case OpenFile_Event:
890             i_id = INTF_DIALOG_FILE;
891             break;
892         case OpenDisc_Event:
893             i_id = INTF_DIALOG_DISC;
894             break;
895         case OpenNet_Event:
896             i_id = INTF_DIALOG_NET;
897             break;
898         case OpenCapture_Event:
899             i_id = INTF_DIALOG_CAPTURE;
900             break;
901         case OpenSat_Event:
902             i_id = INTF_DIALOG_SAT;
903             break;
904         case Playlist_Event:
905             i_id = INTF_DIALOG_PLAYLIST;
906             break;
907         case Logs_Event:
908             i_id = INTF_DIALOG_MESSAGES;
909             break;
910         case FileInfo_Event:
911             i_id = INTF_DIALOG_FILEINFO;
912             break;
913         case Prefs_Event:
914             i_id = INTF_DIALOG_PREFS;
915             break;
916         case StreamWizard_Event:
917             i_id = INTF_DIALOG_STREAMWIZARD;
918             break;
919         case Wizard_Event:
920             i_id = INTF_DIALOG_WIZARD;
921             break;
922         case Bookmarks_Event:
923             i_id = INTF_DIALOG_BOOKMARKS;
924             break;
925         default:
926             i_id = INTF_DIALOG_FILE;
927             break;
928         }
929
930         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
931     }
932 }
933
934 void Interface::OnExtended(wxCommandEvent& event)
935 {
936     if( b_extra == VLC_FALSE)
937     {
938         extra_frame->Show();
939         frame_sizer->Show( extra_frame );
940         b_extra = VLC_TRUE;
941     }
942     else
943     {
944         extra_frame->Hide();
945         frame_sizer->Hide( extra_frame );
946         b_extra = VLC_FALSE;
947     }
948     frame_sizer->Layout();
949     frame_sizer->Fit(this);
950 }
951
952 void Interface::OnEnableAdjust(wxCommandEvent& event)
953 {
954     char *psz_filters=config_GetPsz( p_intf, "filter");
955     char *psz_new = NULL;
956     if( event.IsChecked() )
957     {
958         if(psz_filters == NULL)
959         {
960             psz_new = strdup( "adjust" );
961         }
962         else
963         {
964             psz_new= (char *) malloc(strlen(psz_filters) + 8 );
965             sprintf( psz_new, "%s:adjust", psz_filters);
966         }
967         config_PutPsz( p_intf, "filter", psz_new );
968         vlc_value_t val;
969         vout_thread_t *p_vout =
970            (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
971                                        FIND_ANYWHERE );
972         if( p_vout != NULL )
973         {
974             val.psz_string = strdup( psz_new );
975             var_Set( p_vout, "filter", val);
976             vlc_object_release( p_vout );
977         }
978         if( val.psz_string ) free( val.psz_string );
979         restoredefaults_button->Enable();
980         brightness_slider->Enable();
981         saturation_slider->Enable();
982         contrast_slider->Enable();
983         hue_slider->Enable();
984         gamma_slider->Enable();
985     }
986     else
987     {
988         if( psz_filters != NULL )
989         {
990
991             char *psz_current;
992             unsigned int i=0;
993             for( i = 0; i< strlen(psz_filters ); i++)
994             {
995                 if ( !strncasecmp( &psz_filters[i],"adjust",6 ))
996                 {
997                     if(i > 0)
998                         if( psz_filters[i-1] == ':' ) i--;
999                     psz_current = strchr( &psz_filters[i+1] , ':' );
1000                     if( !psz_current )
1001                         psz_filters[i] = '\0';
1002                     else
1003                     {
1004                        memmove( &psz_filters[i] , psz_current,
1005                                 &psz_filters[strlen(psz_filters)]-psz_current
1006                                 +1);
1007                     }
1008                 }
1009             }
1010             config_PutPsz( p_intf, "filter", psz_filters);
1011             vlc_value_t val;
1012             val.psz_string = strdup( psz_filters );
1013             vout_thread_t *p_vout =
1014                (vout_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_VOUT,
1015                                        FIND_ANYWHERE );
1016             if( p_vout != NULL )
1017             {
1018                 var_Set( p_vout, "filter", val);
1019                 vlc_object_release( p_vout );
1020             }
1021             if( val.psz_string ) free( val.psz_string );
1022         }
1023         restoredefaults_button->Disable();
1024         brightness_slider->Disable();
1025         saturation_slider->Disable();
1026         contrast_slider->Disable();
1027         hue_slider->Disable();
1028         gamma_slider->Disable();
1029     }
1030     if(psz_filters) free(psz_filters);
1031     if(psz_new) free(psz_new);
1032 }
1033
1034 void Interface::OnRestoreDefaults( wxCommandEvent &event)
1035 {
1036     hue_slider->SetValue(0);
1037     saturation_slider->SetValue(100);
1038     brightness_slider->SetValue(100);
1039     contrast_slider->SetValue(100),
1040     gamma_slider->SetValue(10);
1041
1042     wxScrollEvent *hscroll_event = new wxScrollEvent(0, Hue_Event, 0);
1043     OnAdjustUpdate(*hscroll_event);
1044     
1045     wxScrollEvent *sscroll_event = new wxScrollEvent(0, Saturation_Event, 100);
1046     OnAdjustUpdate(*sscroll_event);
1047     
1048     wxScrollEvent *bscroll_event = new wxScrollEvent(0, Brightness_Event, 100);
1049     OnAdjustUpdate(*bscroll_event);
1050     
1051     wxScrollEvent *cscroll_event = new wxScrollEvent(0, Contrast_Event, 100);
1052     OnAdjustUpdate(*cscroll_event);
1053     
1054     wxScrollEvent *gscroll_event = new wxScrollEvent(0, Gamma_Event, 10);
1055     OnAdjustUpdate(*gscroll_event);
1056
1057 }
1058
1059 void Interface::OnAdjustUpdate( wxScrollEvent &event)
1060 {
1061     vout_thread_t *p_vout = (vout_thread_t *)vlc_object_find(p_intf, VLC_OBJECT_VOUT, FIND_ANYWHERE);
1062     if(p_vout == NULL)
1063         switch(event.GetId())
1064         {
1065             case Hue_Event: 
1066                 config_PutInt( p_intf , "hue" , event.GetPosition() );
1067                 break;
1068             
1069             case Saturation_Event: 
1070                 config_PutFloat( p_intf , "saturation" , (float)event.GetPosition()/100 );
1071                 break;
1072             
1073             case Brightness_Event: 
1074                 config_PutFloat( p_intf , "brightness" , (float)event.GetPosition()/100 );
1075                 break;
1076             
1077             case Contrast_Event: 
1078                 config_PutFloat( p_intf , "contrast" , (float)event.GetPosition()/100 );
1079                 break;
1080             
1081             case Gamma_Event: 
1082                 config_PutFloat( p_intf , "gamma" , (float)event.GetPosition()/10 );
1083                 break;
1084         }
1085     else
1086     {
1087         vlc_value_t val;
1088         switch(event.GetId())
1089         {
1090             case Hue_Event: 
1091                 val.i_int = event.GetPosition();
1092                 var_Set(p_vout, "hue", val);
1093                 break;
1094             
1095             case Saturation_Event:
1096                 val.f_float = (float)event.GetPosition()/100;
1097                 var_Set(p_vout, "saturation", val);
1098                 break;
1099             
1100             case Brightness_Event: 
1101                 val.f_float = (float)event.GetPosition()/100;
1102                 var_Set(p_vout, "brightness", val);
1103                 break;
1104             
1105             case Contrast_Event: 
1106                 val.f_float = (float)event.GetPosition()/100;
1107                 var_Set(p_vout, "contrast", val);
1108                 break;
1109             
1110             case Gamma_Event: 
1111                 val.f_float = (float)event.GetPosition()/10;
1112                 var_Set(p_vout, "gamma", val);
1113                 break;
1114         }
1115         vlc_object_release(p_vout);
1116     }
1117 }
1118
1119 void Interface::OnRatio( wxCommandEvent& event )
1120 {
1121    config_PutPsz( p_intf, "aspect-ratio", ratio_combo->GetValue().mb_str() );
1122 }
1123
1124 void Interface::OnEnableVisual(wxCommandEvent& event)
1125 {
1126     if( event.IsChecked() )
1127     {
1128         config_PutPsz( p_intf, "audio-filter", "visual" );
1129     }
1130     else
1131     {
1132         config_PutPsz( p_intf, "audio-filter", "" );
1133     }
1134 }
1135
1136 void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
1137 {
1138     wxCommandEvent dummy;
1139     playlist_t *p_playlist =
1140         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1141                                        FIND_ANYWHERE );
1142     if( p_playlist == NULL ) return;
1143
1144     if( p_playlist->i_size && p_playlist->i_enabled )
1145     {
1146         vlc_value_t state;
1147
1148         input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf,
1149                                                        VLC_OBJECT_INPUT,
1150                                                        FIND_ANYWHERE );
1151         if( p_input == NULL )
1152         {
1153             /* No stream was playing, start one */
1154             playlist_Play( p_playlist );
1155             TogglePlayButton( PLAYING_S );
1156             vlc_object_release( p_playlist );
1157             return;
1158         }
1159
1160         var_Get( p_input, "state", &state );
1161
1162         if( state.i_int != PAUSE_S )
1163         {
1164             /* A stream is being played, pause it */
1165             state.i_int = PAUSE_S;
1166         }
1167         else
1168         {
1169             /* Stream is paused, resume it */
1170             state.i_int = PLAYING_S;
1171         }
1172         var_Set( p_input, "state", state );
1173
1174         TogglePlayButton( state.i_int );
1175         vlc_object_release( p_input );
1176         vlc_object_release( p_playlist );
1177     }
1178     else
1179     {
1180         /* If the playlist is empty, open a file requester instead */
1181         vlc_object_release( p_playlist );
1182         OnShowDialog( dummy );
1183     }
1184 }
1185
1186 void Interface::OnStopStream( wxCommandEvent& WXUNUSED(event) )
1187 {
1188     playlist_t * p_playlist =
1189         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1190                                        FIND_ANYWHERE );
1191     if( p_playlist == NULL )
1192     {
1193         return;
1194     }
1195
1196     playlist_Stop( p_playlist );
1197     TogglePlayButton( PAUSE_S );
1198     vlc_object_release( p_playlist );
1199 }
1200
1201 void Interface::OnSliderUpdate( wxScrollEvent& event )
1202 {
1203     vlc_mutex_lock( &p_intf->change_lock );
1204
1205 #ifdef WIN32
1206     if( event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
1207         || event.GetEventType() == wxEVT_SCROLL_ENDSCROLL )
1208     {
1209 #endif
1210         if( p_intf->p_sys->i_slider_pos != event.GetPosition()
1211             && p_intf->p_sys->p_input )
1212         {
1213             vlc_value_t pos;
1214             pos.f_float = (float)event.GetPosition() / (float)SLIDER_MAX_POS;
1215
1216             var_Set( p_intf->p_sys->p_input, "position", pos );
1217         }
1218
1219 #ifdef WIN32
1220         p_intf->p_sys->b_slider_free = VLC_TRUE;
1221     }
1222     else
1223     {
1224         p_intf->p_sys->b_slider_free = VLC_FALSE;
1225
1226         if( p_intf->p_sys->p_input )
1227         {
1228             /* Update stream date */
1229 #define p_area p_intf->p_sys->p_input->stream.p_selected_area
1230             char psz_time[ MSTRTIME_MAX_SIZE ], psz_total[ MSTRTIME_MAX_SIZE ];
1231             mtime_t i_seconds;
1232             vlc_value_t val;
1233
1234             var_Get( p_intf->p_sys->p_input, "length",  &val );
1235             i_seconds = val.i_time / 1000000;
1236             secstotimestr ( psz_total, i_seconds );
1237
1238             statusbar->SetStatusText(
1239                 wxU(input_OffsetToTime( p_intf->p_sys->p_input,
1240                     psz_time, p_area->i_size * event.GetPosition()
1241                         / SLIDER_MAX_POS )) + wxString(wxT(" / ")) +
1242                         wxU(psz_total), 0 );
1243 #undef p_area
1244         }
1245     }
1246 #endif
1247
1248 #undef WIN32
1249     vlc_mutex_unlock( &p_intf->change_lock );
1250 }
1251
1252 void Interface::OnPrevStream( wxCommandEvent& WXUNUSED(event) )
1253 {
1254     playlist_t * p_playlist =
1255         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1256                                        FIND_ANYWHERE );
1257     if( p_playlist == NULL )
1258     {
1259         return;
1260     }
1261
1262     vlc_mutex_lock( &p_playlist->object_lock );
1263     if( p_playlist->p_input != NULL )
1264     {
1265         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1266         if( p_playlist->p_input->stream.p_selected_area->i_id > 1 )
1267         {
1268             vlc_value_t val; val.b_bool = VLC_TRUE;
1269             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1270             var_Set( p_playlist->p_input, "prev-title", val );
1271         } else
1272             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1273     }
1274     vlc_mutex_unlock( &p_playlist->object_lock );
1275
1276     playlist_Prev( p_playlist );
1277     vlc_object_release( p_playlist );
1278 }
1279
1280 void Interface::OnNextStream( wxCommandEvent& WXUNUSED(event) )
1281 {
1282     playlist_t * p_playlist =
1283         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1284                                        FIND_ANYWHERE );
1285     if( p_playlist == NULL )
1286     {
1287         return;
1288     }
1289
1290     vlc_mutex_lock( &p_playlist->object_lock );
1291     if( p_playlist->p_input != NULL )
1292     {
1293         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1294         if( p_playlist->p_input->stream.i_area_nb > 1 &&
1295             p_playlist->p_input->stream.p_selected_area->i_id <
1296               p_playlist->p_input->stream.i_area_nb - 1 )
1297         {
1298             vlc_value_t val; val.b_bool = VLC_TRUE;
1299             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1300             var_Set( p_playlist->p_input, "next-title", val );
1301         } else
1302             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1303     }
1304     vlc_mutex_unlock( &p_playlist->object_lock );
1305
1306     playlist_Next( p_playlist );
1307     vlc_object_release( p_playlist );
1308 }
1309
1310 void Interface::OnSlowStream( wxCommandEvent& WXUNUSED(event) )
1311 {
1312     input_thread_t *p_input =
1313         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1314                                            FIND_ANYWHERE );
1315     if( p_input )
1316     {
1317         vlc_value_t val; val.b_bool = VLC_TRUE;
1318
1319         var_Set( p_input, "rate-slower", val );
1320         vlc_object_release( p_input );
1321     }
1322 }
1323
1324 void Interface::OnFastStream( wxCommandEvent& WXUNUSED(event) )
1325 {
1326     input_thread_t *p_input =
1327         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1328                                            FIND_ANYWHERE );
1329     if( p_input )
1330     {
1331         vlc_value_t val; val.b_bool = VLC_TRUE;
1332
1333         var_Set( p_input, "rate-faster", val );
1334         vlc_object_release( p_input );
1335     }
1336 }
1337
1338 void Interface::TogglePlayButton( int i_playing_status )
1339 {
1340     if( i_playing_status == i_old_playing_status )
1341         return;
1342
1343     GetToolBar()->DeleteTool( PlayStream_Event );
1344
1345     if( i_playing_status == PLAYING_S )
1346     {
1347         GetToolBar()->InsertTool( 0, PlayStream_Event, wxU(_("Pause")),
1348                                   wxBitmap( pause_xpm ), wxNullBitmap,
1349                                   wxITEM_NORMAL, wxU(_(HELP_PAUSE)) );
1350     }
1351     else
1352     {
1353         GetToolBar()->InsertTool( 0, PlayStream_Event, wxU(_("Play")),
1354                                   wxBitmap( play_xpm ), wxNullBitmap,
1355                                   wxITEM_NORMAL, wxU(_(HELP_PLAY)) );
1356     }
1357
1358     GetToolBar()->Realize();
1359
1360     i_old_playing_status = i_playing_status;
1361 }
1362
1363 #if wxUSE_DRAG_AND_DROP
1364 /*****************************************************************************
1365  * Definition of DragAndDrop class.
1366  *****************************************************************************/
1367 DragAndDrop::DragAndDrop( intf_thread_t *_p_intf, vlc_bool_t _b_enqueue )
1368 {
1369     p_intf = _p_intf;
1370     b_enqueue = _b_enqueue;
1371 }
1372
1373 bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
1374                                const wxArrayString& filenames )
1375 {
1376     /* Add dropped files to the playlist */
1377
1378     playlist_t *p_playlist =
1379         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1380                                        FIND_ANYWHERE );
1381     if( p_playlist == NULL )
1382     {
1383         return FALSE;
1384     }
1385
1386     for( size_t i = 0; i < filenames.GetCount(); i++ )
1387         playlist_Add( p_playlist, (const char *)filenames[i].mb_str(),
1388                       (const char *)filenames[i].mb_str(),
1389                       PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
1390                       PLAYLIST_END );
1391
1392     vlc_object_release( p_playlist );
1393
1394     return TRUE;
1395 }
1396 #endif
1397
1398 /*****************************************************************************
1399  * Definition of VolCtrl class.
1400  *****************************************************************************/
1401 wxVolCtrl::wxVolCtrl( intf_thread_t *_p_intf, wxWindow* parent, wxWindowID id,
1402                       wxPoint point, wxSize size )
1403   : wxGauge( parent, id, 200, point, size, wxGA_HORIZONTAL | wxGA_SMOOTH )
1404 {
1405     p_intf = _p_intf;
1406     UpdateVolume();
1407 }
1408
1409 void wxVolCtrl::OnChange( wxMouseEvent& event )
1410 {
1411     if( !event.LeftDown() && !event.LeftIsDown() ) return;
1412
1413     int i_volume = event.GetX() * 200 / GetClientSize().GetWidth();
1414     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
1415     UpdateVolume();
1416 }
1417
1418 void wxVolCtrl::UpdateVolume()
1419 {
1420     audio_volume_t i_volume;
1421     aout_VolumeGet( p_intf, &i_volume );
1422
1423     int i_gauge_volume = i_volume * 200 * 2 / AOUT_VOLUME_MAX;
1424     if( i_gauge_volume == GetValue() ) return;
1425
1426     SetValue( i_gauge_volume );
1427     SetToolTip( wxString::Format((wxString)wxU(_("Volume")) + wxT(" %d"),
1428                 i_gauge_volume / 2 ) );
1429 }