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