]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/interface.cpp
Add some icons
[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
32 #include "wxwindows.h"
33
34 /* include the toolbar graphics */
35 #include "bitmaps/play.xpm"
36 #include "bitmaps/pause.xpm"
37 #include "bitmaps/stop.xpm"
38 #include "bitmaps/prev.xpm"
39 #include "bitmaps/next.xpm"
40 #include "bitmaps/eject.xpm"
41 #include "bitmaps/slow.xpm"
42 #include "bitmaps/fast.xpm"
43 #include "bitmaps/playlist.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     Wizard_Event,
122
123     Playlist_Event,
124     Logs_Event,
125     FileInfo_Event,
126
127     Prefs_Event,
128     Extended_Event,
129 //    Undock_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     /* it is important for the id corresponding to the "About" command to have
142      * this standard value as otherwise it won't be handled properly under Mac
143      * (where it is special and put into the "Apple" menu) */
144     About_Event = wxID_ABOUT
145 };
146
147 BEGIN_EVENT_TABLE(Interface, wxFrame)
148     /* Menu events */
149     EVT_MENU(Exit_Event, Interface::OnExit)
150     EVT_MENU(About_Event, Interface::OnAbout)
151
152     EVT_MENU(Playlist_Event, Interface::OnShowDialog)
153     EVT_MENU(Logs_Event, Interface::OnShowDialog)
154     EVT_MENU(FileInfo_Event, Interface::OnShowDialog)
155     EVT_MENU(Prefs_Event, Interface::OnShowDialog)
156
157     EVT_MENU_OPEN(Interface::OnMenuOpen)
158
159     EVT_MENU( Extended_Event, Interface::OnExtended )
160 //    EVT_MENU( Undock_Event, Interface::OnUndock )
161
162     EVT_MENU( Bookmarks_Event, Interface::OnShowDialog)
163
164 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
165     EVT_CONTEXT_MENU(Interface::OnContextMenu2)
166 #endif
167     EVT_RIGHT_UP(Interface::OnContextMenu)
168
169     /* Toolbar events */
170     EVT_MENU(OpenFileSimple_Event, Interface::OnShowDialog)
171     EVT_MENU(OpenAdv_Event, Interface::OnShowDialog)
172     EVT_MENU(OpenFile_Event, Interface::OnShowDialog)
173     EVT_MENU(OpenDisc_Event, Interface::OnShowDialog)
174     EVT_MENU(OpenNet_Event, Interface::OnShowDialog)
175     EVT_MENU(OpenCapture_Event, Interface::OnShowDialog)
176     EVT_MENU(OpenSat_Event, Interface::OnShowDialog)
177     EVT_MENU(Wizard_Event, Interface::OnShowDialog)
178     EVT_MENU(StopStream_Event, Interface::OnStopStream)
179     EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
180     EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
181     EVT_MENU(NextStream_Event, Interface::OnNextStream)
182     EVT_MENU(SlowStream_Event, Interface::OnSlowStream)
183     EVT_MENU(FastStream_Event, Interface::OnFastStream)
184
185     /* Slider events */
186     EVT_COMMAND_SCROLL(SliderScroll_Event, Interface::OnSliderUpdate)
187
188     /* Custom events */
189     EVT_COMMAND(0, wxEVT_INTF, Interface::OnControlEvent)
190     EVT_COMMAND(1, wxEVT_INTF, Interface::OnControlEvent)
191
192 END_EVENT_TABLE()
193
194 /*****************************************************************************
195  * Constructor.
196  *****************************************************************************/
197 Interface::Interface( intf_thread_t *_p_intf ):
198     wxFrame( NULL, -1, wxT("VLC media player"),
199              wxDefaultPosition, wxSize(700,100), wxDEFAULT_FRAME_STYLE )
200 {
201     /* Initializations */
202     p_intf = _p_intf;
203     i_old_playing_status = PAUSE_S;
204     b_extra = VLC_FALSE;
205 //    b_undock = VLC_FALSE;
206
207     extra_window = NULL;
208
209     /* Give our interface a nice little icon */
210     SetIcon( wxIcon( vlc_xpm ) );
211
212     /* Create a sizer for the main frame */
213     frame_sizer = new wxBoxSizer( wxVERTICAL );
214     SetSizer( frame_sizer );
215
216     /* Create a dummy widget that can get the keyboard focus */
217     wxWindow *p_dummy = new wxWindow( this, 0, wxDefaultPosition,
218                                       wxSize(0,0) );
219     p_dummy->SetFocus();
220     frame_sizer->Add( p_dummy, 0, 0 );
221
222     /* Creation of the menu bar */
223     CreateOurMenuBar();
224
225     /* Creation of the tool bar */
226     CreateOurToolBar();
227
228     /* Create the extra panel */
229     extra_frame = new ExtraPanel( p_intf, this );
230     frame_sizer->Add( extra_frame, 0, wxEXPAND , 0 );
231     frame_sizer->Hide( extra_frame );
232
233     /* Creation of the status bar
234      * Helptext for menu items and toolbar tools will automatically get
235      * displayed here. */
236     int i_status_width[3] = {-6, -2, -9};
237     statusbar = CreateStatusBar( 3 );                            /* 2 fields */
238     statusbar->SetStatusWidths( 3, i_status_width );
239     statusbar->SetStatusText( wxString::Format(wxT("x%.2f"), 1.0), 1 );
240
241     /* Video window */
242     if( config_GetInt( p_intf, "wxwin-embed" ) )
243     {
244         VideoWindow( p_intf, this );
245         frame_sizer->Add( p_intf->p_sys->p_video_sizer, 1, wxEXPAND , 0 );
246     }
247
248     /* Creation of the slider sub-window */
249     CreateOurSlider();
250     frame_sizer->Add( slider_frame, 0, wxEXPAND , 0 );
251     frame_sizer->Hide( slider_frame );
252
253     /* Make sure we've got the right background colour */
254     SetBackgroundColour( slider_frame->GetBackgroundColour() );
255
256     /* Layout everything */
257     frame_sizer->Layout();
258     frame_sizer->Fit(this);
259
260 #if wxUSE_DRAG_AND_DROP
261     /* Associate drop targets with the main interface */
262     SetDropTarget( new DragAndDrop( p_intf ) );
263 #endif
264
265     SetupHotkeys();
266
267     /* Start timer */
268     timer = new Timer( p_intf, this );
269 }
270
271 Interface::~Interface()
272 {
273     if( p_intf->p_sys->p_wxwindow )
274     {
275         delete p_intf->p_sys->p_wxwindow;
276     }
277
278     /* Clean up */
279     delete timer;
280 }
281
282 void Interface::Init()
283 {
284     /* Misc init */
285     SetupHotkeys();
286 }
287
288 void Interface::Update()
289 {
290     /* Misc updates */
291     ((wxVolCtrl *)volctrl)->UpdateVolume();
292 }
293
294 void Interface::OnControlEvent( wxCommandEvent& event )
295 {
296     switch( event.GetId() )
297     {
298     case 0:
299         frame_sizer->Layout();
300         frame_sizer->Fit(this);
301         break;
302
303     case 1:
304         long i_style = GetWindowStyle();
305         if( event.GetInt() ) i_style |= wxSTAY_ON_TOP;
306         else i_style &= ~wxSTAY_ON_TOP;
307         SetWindowStyle( i_style );
308         break;
309     }
310 }
311
312 /*****************************************************************************
313  * Private methods.
314  *****************************************************************************/
315 void Interface::CreateOurMenuBar()
316 {
317     /* Create the "File" menu */
318     wxMenu *file_menu = new wxMenu;
319     file_menu->Append( OpenFileSimple_Event,
320                        wxU(_("Quick &Open File...\tCtrl-O")) );
321
322     file_menu->AppendSeparator();
323     file_menu->Append( OpenFile_Event, wxU(_("Open &File...\tCtrl-F")) );
324     file_menu->Append( OpenDisc_Event, wxU(_("Open &Disc...\tCtrl-D")) );
325     file_menu->Append( OpenNet_Event,
326                        wxU(_("Open &Network Stream...\tCtrl-N")) );
327     file_menu->Append( OpenCapture_Event,
328                        wxU(_("Open &Capture Device...\tCtrl-C")) );
329
330     file_menu->AppendSeparator();
331     file_menu->Append( Wizard_Event, wxU(_("&Wizard...\tCtrl-W")) );
332     file_menu->AppendSeparator();
333     file_menu->Append( Exit_Event, wxU(_("E&xit\tCtrl-X")) );
334
335     /* Create the "View" menu */
336     wxMenu *view_menu = new wxMenu;
337     view_menu->Append( Playlist_Event, wxU(_("&Playlist...\tCtrl-P")) );
338     view_menu->Append( Logs_Event, wxU(_("&Messages...\tCtrl-M")) );
339     view_menu->Append( FileInfo_Event,
340                        wxU(_("Stream and Media &info...\tCtrl-I")) );
341
342     /* Create the "Auto-generated" menus */
343     p_settings_menu = SettingsMenu( p_intf, this );
344     p_audio_menu = AudioMenu( p_intf, this );
345     p_video_menu = VideoMenu( p_intf, this );
346     p_navig_menu = NavigMenu( p_intf, this );
347
348     /* Create the "Help" menu */
349     wxMenu *help_menu = new wxMenu;
350     help_menu->Append( About_Event, wxU(_("About VLC media player")) );
351
352     /* Append the freshly created menus to the menu bar... */
353     wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
354     menubar->Append( file_menu, wxU(_("&File")) );
355     menubar->Append( view_menu, wxU(_("&View")) );
356     menubar->Append( p_settings_menu, wxU(_("&Settings")) );
357     menubar->Append( p_audio_menu, wxU(_("&Audio")) );
358     menubar->Append( p_video_menu, wxU(_("&Video")) );
359     menubar->Append( p_navig_menu, wxU(_("&Navigation")) );
360     menubar->Append( help_menu, wxU(_("&Help")) );
361
362     /* Attach the menu bar to the frame */
363     SetMenuBar( menubar );
364
365     /* Find out size of menu bar */
366     int i_size = 0;
367     for( unsigned int i = 0; i < menubar->GetMenuCount(); i++ )
368     {
369         int i_width, i_height;
370         menubar->GetTextExtent( menubar->GetLabelTop(i), &i_width, &i_height );
371         i_size += i_width +
372 #if defined(__WXGTK__)
373             22 /* approximate margin */;
374 #else
375 #if (wxMAJOR_VERSION <= 2) && (wxMINOR_VERSION <= 5) && (wxRELEASE_NUMBER < 3)
376             4 /* approximate margin */;
377 #else
378             18 /* approximate margin */;
379 #endif
380 #endif
381     }
382     frame_sizer->SetMinSize( i_size, -1 );
383
384     /* Intercept all menu events in our custom event handler */
385     PushEventHandler( new MenuEvtHandler( p_intf, this ) );
386
387 #if wxUSE_DRAG_AND_DROP
388     /* Associate drop targets with the menubar */
389     menubar->SetDropTarget( new DragAndDrop( p_intf ) );
390 #endif
391 }
392
393 class VLCVolCtrl : public wxControl
394 {
395 public:
396     VLCVolCtrl( intf_thread_t *p_intf, wxWindow *p_parent, wxGauge ** );
397     virtual ~VLCVolCtrl() {};
398
399     virtual void OnPaint( wxPaintEvent &event );
400
401   private:
402     DECLARE_EVENT_TABLE()
403     int i_y_offset;
404 };
405
406 BEGIN_EVENT_TABLE(VLCVolCtrl, wxControl)
407    EVT_PAINT(VLCVolCtrl::OnPaint)
408 END_EVENT_TABLE()
409
410 #if defined(__WXGTK__)
411 #define VLCVOL_HEIGHT p_parent->GetSize().GetHeight()
412 #else
413 #define VLCVOL_HEIGHT TOOLBAR_BMP_HEIGHT
414 #endif
415 VLCVolCtrl::VLCVolCtrl( intf_thread_t *p_intf, wxWindow *p_parent,
416                         wxGauge **pp_volctrl )
417   :wxControl( p_parent, -1, wxDefaultPosition, wxSize(64, VLCVOL_HEIGHT ),
418               wxBORDER_NONE ),
419    i_y_offset((VLCVOL_HEIGHT - TOOLBAR_BMP_HEIGHT) / 2)
420 {
421     *pp_volctrl = new wxVolCtrl( p_intf, this, -1, wxPoint( 18, i_y_offset ),
422                                  wxSize( 44, TOOLBAR_BMP_HEIGHT ) );
423 }
424
425 void VLCVolCtrl::OnPaint( wxPaintEvent &evt )
426 {
427     wxPaintDC dc( this );
428     wxBitmap mPlayBitmap( speaker_xpm );
429     dc.DrawBitmap( mPlayBitmap, 0, i_y_offset, TRUE );
430 }
431
432 void Interface::CreateOurToolBar()
433 {
434 #define HELP_OPEN N_("Open")
435 #define HELP_STOP N_("Stop")
436 #define HELP_PLAY N_("Play")
437 #define HELP_PAUSE N_("Pause")
438 #define HELP_PLO N_("Playlist")
439 #define HELP_PLP N_("Previous playlist item")
440 #define HELP_PLN N_("Next playlist item")
441 #define HELP_SLOW N_("Play slower")
442 #define HELP_FAST N_("Play faster")
443
444     wxLogNull LogDummy; /* Hack to suppress annoying log message on the win32
445                          * version because we don't include wx.rc */
446
447     wxToolBar *toolbar =
448         CreateToolBar( wxTB_HORIZONTAL | wxTB_FLAT  ); //| wxTB_DOCKABLE );
449
450     toolbar->SetToolBitmapSize( wxSize(TOOLBAR_BMP_WIDTH,TOOLBAR_BMP_HEIGHT) );
451
452     toolbar->AddTool( OpenFile_Event, wxT(""),
453                       wxBitmap( eject_xpm ), wxU(_(HELP_OPEN)) );
454     toolbar->AddSeparator();
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( playlist_xpm ),
474                       wxU(_(HELP_PLO)) );
475
476     wxControl *p_dummy_ctrl =
477         new wxControl( toolbar, -1, wxDefaultPosition,
478                        wxSize(35, 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 static int ConvertHotkeyModifiers( int i_hotkey )
517 {
518     int i_accel_flags = 0;
519     if( i_hotkey & KEY_MODIFIER_ALT ) i_accel_flags |= wxACCEL_ALT;
520     if( i_hotkey & KEY_MODIFIER_CTRL ) i_accel_flags |= wxACCEL_CTRL;
521     if( i_hotkey & KEY_MODIFIER_SHIFT ) i_accel_flags |= wxACCEL_SHIFT;
522     if( !i_accel_flags ) i_accel_flags = wxACCEL_NORMAL;
523     return i_accel_flags;
524 }
525
526 static int ConvertHotkey( int i_hotkey )
527 {
528     int i_key = i_hotkey & ~KEY_MODIFIER;
529     if( i_key & KEY_ASCII ) return i_key & KEY_ASCII;
530     else if( i_key & KEY_SPECIAL )
531     {
532         switch ( i_key )
533         {
534         case KEY_LEFT: return WXK_LEFT;
535         case KEY_RIGHT: return WXK_RIGHT;
536         case KEY_UP: return WXK_UP;
537         case KEY_DOWN: return WXK_DOWN;
538         case KEY_SPACE: return WXK_SPACE;
539         case KEY_ENTER: return WXK_RETURN;
540         case KEY_F1: return WXK_F1;
541         case KEY_F2: return WXK_F2;
542         case KEY_F3: return WXK_F3;
543         case KEY_F4: return WXK_F4;
544         case KEY_F5: return WXK_F5;
545         case KEY_F6: return WXK_F6;
546         case KEY_F7: return WXK_F7;
547         case KEY_F8: return WXK_F8;
548         case KEY_F9: return WXK_F9;
549         case KEY_F10: return WXK_F10;
550         case KEY_F11: return WXK_F11;
551         case KEY_F12: return WXK_F12;
552         case KEY_HOME: return WXK_HOME;
553         case KEY_END: return WXK_HOME;
554         case KEY_MENU: return WXK_MENU;
555         case KEY_ESC: return WXK_ESCAPE;
556         case KEY_PAGEUP: return WXK_PRIOR;
557         case KEY_PAGEDOWN: return WXK_NEXT;
558         case KEY_TAB: return WXK_TAB;
559         case KEY_BACKSPACE: return WXK_BACK;
560         }
561     }
562     return WXK_F24;
563 }
564
565 void Interface::SetupHotkeys()
566 {
567     struct vlc_t::hotkey *p_hotkeys = p_intf->p_vlc->p_hotkeys;
568     int i_hotkeys;
569
570     /* Count number of hoteys */
571     for( i_hotkeys = 0; p_hotkeys[i_hotkeys].psz_action != NULL; i_hotkeys++ );
572
573     p_intf->p_sys->i_first_hotkey_event = wxID_HIGHEST + 7000;
574     p_intf->p_sys->i_hotkeys = i_hotkeys;
575
576     wxAcceleratorEntry p_entries[i_hotkeys];
577
578     /* Setup the hotkeys as accelerators */
579     for( int i = 0; i < i_hotkeys; i++ )
580     {
581         int i_mod = ConvertHotkeyModifiers( p_hotkeys[i].i_key );
582         int i_key = ConvertHotkey( p_hotkeys[i].i_key );
583
584 #ifdef WIN32
585         if( i_mod ) i_key = toupper(i_key);
586 #endif
587
588         p_entries[i].Set( i_mod, i_key,
589                           p_intf->p_sys->i_first_hotkey_event + i );
590     }
591
592     wxAcceleratorTable accel( i_hotkeys, p_entries );
593
594     if( !accel.Ok() )
595     {
596         msg_Err( p_intf, "invalid accelerator table" );
597     }
598     else
599     {
600         SetAcceleratorTable( accel );
601         msg_Dbg( p_intf, "accelerator table loaded" );
602     }
603 }
604
605 /*****************************************************************************
606  * Event Handlers.
607  *****************************************************************************/
608
609 void Interface::OnMenuOpen(wxMenuEvent& event)
610 {
611 #if defined( __WXMSW__ )
612 #   define GetEventObject GetMenu
613 #endif
614
615     if( event.GetEventObject() == p_settings_menu )
616     {
617         p_settings_menu = SettingsMenu( p_intf, this, p_settings_menu );
618
619         /* Add static items */
620         p_settings_menu->AppendCheckItem( Extended_Event,
621             wxU(_("&Extended GUI") ) );
622         if( b_extra ) p_settings_menu->Check( Extended_Event, TRUE );
623 #if 0
624         p_settings_menu->AppendCheckItem( Undock_Event,
625             wxU(_("&Undock Ext. GUI") ) );
626         if( b_undock ) p_settings_menu->Check( Undock_Event, TRUE );
627 #endif
628         p_settings_menu->Append( Bookmarks_Event, wxU(_("&Bookmarks...") ) );
629         p_settings_menu->Append( Prefs_Event, wxU(_("&Preferences...")) );
630     }
631
632     else if( event.GetEventObject() == p_audio_menu )
633     {
634         p_audio_menu = AudioMenu( p_intf, this, p_audio_menu );
635     }
636
637     else if( event.GetEventObject() == p_video_menu )
638     {
639         p_video_menu = VideoMenu( p_intf, this, p_video_menu );
640     }
641
642     else if( event.GetEventObject() == p_navig_menu )
643     {
644         p_navig_menu = NavigMenu( p_intf, this, p_navig_menu );
645     }
646
647 #if defined( __WXMSW__ )
648 #   undef GetEventObject
649 #endif
650 }
651
652 #if defined( __WXMSW__ ) || defined( __WXMAC__ )
653 void Interface::OnContextMenu2(wxContextMenuEvent& event)
654 {
655     /* Only show the context menu for the main interface */
656     if( GetId() != event.GetId() )
657     {
658         event.Skip();
659         return;
660     }
661
662     if( p_intf->p_sys->pf_show_dialog )
663         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
664 }
665 #endif
666 void Interface::OnContextMenu(wxMouseEvent& event)
667 {
668     if( p_intf->p_sys->pf_show_dialog )
669         p_intf->p_sys->pf_show_dialog( p_intf, INTF_DIALOG_POPUPMENU, 1, 0 );
670 }
671
672 void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
673 {
674     /* TRUE is to force the frame to close. */
675     Close(TRUE);
676 }
677
678 void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
679 {
680     wxString msg;
681     msg.Printf( wxString(wxT("VLC media player " PACKAGE_VERSION)) +
682         wxU(_(" (wxWindows interface)\n\n")) +
683         wxU(_("(c) 1996-2004 - the VideoLAN Team\n\n")) +
684         wxU( vlc_wraptext(INTF_ABOUT_MSG,WRAPCOUNT,ISUTF8) ) + wxT("\n\n") +
685         wxU(_("The VideoLAN team <videolan@videolan.org>\n"
686               "http://www.videolan.org/\n\n")) );
687
688     wxMessageBox( msg, wxString::Format(wxU(_("About %s")),
689                   wxT("VLC media player")), wxOK | wxICON_INFORMATION, this );
690 }
691
692 void Interface::OnShowDialog( wxCommandEvent& event )
693 {
694     if( p_intf->p_sys->pf_show_dialog )
695     {
696         int i_id;
697
698         switch( event.GetId() )
699         {
700         case OpenFileSimple_Event:
701             i_id = INTF_DIALOG_FILE_SIMPLE;
702             break;
703         case OpenAdv_Event:
704             i_id = INTF_DIALOG_FILE;
705         case OpenFile_Event:
706             i_id = INTF_DIALOG_FILE;
707             break;
708         case OpenDisc_Event:
709             i_id = INTF_DIALOG_DISC;
710             break;
711         case OpenNet_Event:
712             i_id = INTF_DIALOG_NET;
713             break;
714         case OpenCapture_Event:
715             i_id = INTF_DIALOG_CAPTURE;
716             break;
717         case OpenSat_Event:
718             i_id = INTF_DIALOG_SAT;
719             break;
720         case Playlist_Event:
721             i_id = INTF_DIALOG_PLAYLIST;
722             break;
723         case Logs_Event:
724             i_id = INTF_DIALOG_MESSAGES;
725             break;
726         case FileInfo_Event:
727             i_id = INTF_DIALOG_FILEINFO;
728             break;
729         case Prefs_Event:
730             i_id = INTF_DIALOG_PREFS;
731             break;
732         case Wizard_Event:
733             i_id = INTF_DIALOG_WIZARD;
734             break;
735         case Bookmarks_Event:
736             i_id = INTF_DIALOG_BOOKMARKS;
737             break;
738         default:
739             i_id = INTF_DIALOG_FILE;
740             break;
741         }
742
743         p_intf->p_sys->pf_show_dialog( p_intf, i_id, 1, 0 );
744     }
745 }
746
747 void Interface::OnExtended(wxCommandEvent& event)
748 {
749     b_extra = (b_extra == VLC_TRUE ? VLC_FALSE : VLC_TRUE );
750
751     if( b_extra == VLC_FALSE )
752     {
753         extra_frame->Hide();
754         frame_sizer->Hide( extra_frame );
755     }
756     else
757     {
758         extra_frame->Show();
759         frame_sizer->Show( extra_frame );
760     }
761     frame_sizer->Layout();
762     frame_sizer->Fit(this);
763 }
764
765 #if 0
766         if( b_undock == VLC_TRUE )
767         {
768                 fprintf(stderr,"Deleting window\n");
769             if( extra_window )
770             {
771                 delete extra_window;
772                 extra_window = NULL;
773             }
774         }
775         else
776         {
777             extra_frame->Hide();
778             frame_sizer->Hide( extra_frame );
779             frame_sizer->Layout();
780             frame_sizer->Fit(this);
781         }
782     }
783     else
784     {
785         if( b_undock == VLC_TRUE )
786         {
787                 fprintf(stderr,"Creating window\n");
788             extra_frame->Hide();
789             frame_sizer->Hide( extra_frame );
790             frame_sizer->Detach( extra_frame );
791             frame_sizer->Layout();
792             frame_sizer->Fit(this);
793             extra_window = new ExtraWindow( p_intf, this, extra_frame );
794         }
795         else
796         {
797                 fprintf(stderr,"Deleting window\n");
798             if( extra_window )
799             {
800                 delete extra_window;
801             }
802             extra_frame->Show();
803             frame_sizer->Show( extra_frame );
804             frame_sizer->Layout();
805             frame_sizer->Fit(this);
806         }
807     }
808 }
809
810 void Interface::OnUndock(wxCommandEvent& event)
811 {
812     b_undock = (b_undock == VLC_TRUE ? VLC_FALSE : VLC_TRUE );
813
814     if( b_extra == VLC_TRUE )
815     {
816         if( b_undock == VLC_FALSE )
817         {
818                 fprintf(stderr,"Deleting window\n");
819             if( extra_window )
820             {
821                 delete extra_window;
822                 extra_window = NULL;
823             }
824             extra_frame->Show();
825             frame_sizer->Show( extra_frame );
826             frame_sizer->Layout();
827             frame_sizer->Fit(this);
828         }
829         else
830         {
831                 fprintf(stderr,"Creating window\n");
832             extra_frame->Hide();
833             frame_sizer->Hide( extra_frame );
834             frame_sizer->Detach( extra_frame );
835             frame_sizer->Layout();
836             frame_sizer->Fit(this);
837             extra_window = new ExtraWindow( p_intf, this, extra_frame );
838         }
839     }
840 }
841 #endif
842
843 void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
844 {
845     wxCommandEvent dummy;
846     playlist_t *p_playlist =
847         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
848                                        FIND_ANYWHERE );
849     if( p_playlist == NULL ) return;
850
851     if( p_playlist->i_size && p_playlist->i_enabled )
852     {
853         vlc_value_t state;
854
855         input_thread_t *p_input = (input_thread_t *)vlc_object_find( p_intf,
856                                                        VLC_OBJECT_INPUT,
857                                                        FIND_ANYWHERE );
858         if( p_input == NULL )
859         {
860             /* No stream was playing, start one */
861             playlist_Play( p_playlist );
862             TogglePlayButton( PLAYING_S );
863             vlc_object_release( p_playlist );
864             return;
865         }
866
867         var_Get( p_input, "state", &state );
868
869         if( state.i_int != PAUSE_S )
870         {
871             /* A stream is being played, pause it */
872             state.i_int = PAUSE_S;
873         }
874         else
875         {
876             /* Stream is paused, resume it */
877             state.i_int = PLAYING_S;
878         }
879         var_Set( p_input, "state", state );
880
881         TogglePlayButton( state.i_int );
882         vlc_object_release( p_input );
883         vlc_object_release( p_playlist );
884     }
885     else
886     {
887         /* If the playlist is empty, open a file requester instead */
888         vlc_object_release( p_playlist );
889         OnShowDialog( dummy );
890     }
891 }
892
893 void Interface::OnStopStream( wxCommandEvent& WXUNUSED(event) )
894 {
895     playlist_t * p_playlist =
896         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
897                                        FIND_ANYWHERE );
898     if( p_playlist == NULL )
899     {
900         return;
901     }
902
903     playlist_Stop( p_playlist );
904     TogglePlayButton( PAUSE_S );
905     vlc_object_release( p_playlist );
906 }
907
908 void Interface::OnSliderUpdate( wxScrollEvent& event )
909 {
910     vlc_mutex_lock( &p_intf->change_lock );
911
912 #ifdef WIN32
913     if( event.GetEventType() == wxEVT_SCROLL_THUMBRELEASE
914         || event.GetEventType() == wxEVT_SCROLL_ENDSCROLL )
915     {
916 #endif
917         if( p_intf->p_sys->i_slider_pos != event.GetPosition()
918             && p_intf->p_sys->p_input )
919         {
920             vlc_value_t pos;
921             pos.f_float = (float)event.GetPosition() / (float)SLIDER_MAX_POS;
922
923             var_Set( p_intf->p_sys->p_input, "position", pos );
924         }
925
926 #ifdef WIN32
927         p_intf->p_sys->b_slider_free = VLC_TRUE;
928     }
929     else
930     {
931         p_intf->p_sys->b_slider_free = VLC_FALSE;
932
933         if( p_intf->p_sys->p_input )
934         {
935             /* Update stream date */
936             char psz_time[ MSTRTIME_MAX_SIZE ], psz_total[ MSTRTIME_MAX_SIZE ];
937             mtime_t i_seconds;
938             vlc_value_t val;
939
940             i_seconds = var_GetTime( p_intf->p_sys->p_input, "length" ) / I64C(1000000 );
941             secstotimestr( psz_total, i_seconds );
942
943             i_seconds = var_GetTime( p_intf->p_sys->p_input, "time" ) / I64C(1000000 );
944             secstotimestr( psz_time, i_seconds );
945
946             statusbar->SetStatusText( wxU(psz_time)+ wxString(wxT(" / ")) + wxU(psz_total), 0 );
947         }
948     }
949 #endif
950
951 #undef WIN32
952     vlc_mutex_unlock( &p_intf->change_lock );
953 }
954
955 void Interface::OnPrevStream( wxCommandEvent& WXUNUSED(event) )
956 {
957     playlist_t * p_playlist =
958         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
959                                        FIND_ANYWHERE );
960     if( p_playlist == NULL )
961     {
962         return;
963     }
964
965     /* FIXME --fenrir */
966 #if 0
967     if( p_playlist->p_input != NULL )
968     {
969         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
970         if( p_playlist->p_input->stream.p_selected_area->i_id > 1 )
971         {
972             vlc_value_t val; val.b_bool = VLC_TRUE;
973             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
974             var_Set( p_playlist->p_input, "prev-title", val );
975         } else
976             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
977     }
978     vlc_mutex_unlock( &p_playlist->object_lock );
979 #endif
980
981     playlist_Prev( p_playlist );
982     vlc_object_release( p_playlist );
983 }
984
985 void Interface::OnNextStream( wxCommandEvent& WXUNUSED(event) )
986 {
987     playlist_t * p_playlist =
988         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
989                                        FIND_ANYWHERE );
990     if( p_playlist == NULL )
991     {
992         return;
993     }
994
995     /* FIXME --fenrir */
996 #if 0
997     var_Change( p_input, "title", VLC_VAR_CHOICESCOUNT, &val, NULL );
998     vlc_mutex_lock( &p_playlist->object_lock );
999     if( p_playlist->p_input != NULL )
1000     {
1001         vlc_mutex_lock( &p_playlist->p_input->stream.stream_lock );
1002         if( p_playlist->p_input->stream.i_area_nb > 1 &&
1003             p_playlist->p_input->stream.p_selected_area->i_id <
1004               p_playlist->p_input->stream.i_area_nb - 1 )
1005         {
1006             vlc_value_t val; val.b_bool = VLC_TRUE;
1007             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1008             var_Set( p_playlist->p_input, "next-title", val );
1009         } else
1010             vlc_mutex_unlock( &p_playlist->p_input->stream.stream_lock );
1011     }
1012     vlc_mutex_unlock( &p_playlist->object_lock );
1013 #endif
1014     playlist_Next( p_playlist );
1015     vlc_object_release( p_playlist );
1016 }
1017
1018 void Interface::OnSlowStream( wxCommandEvent& WXUNUSED(event) )
1019 {
1020     input_thread_t *p_input =
1021         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1022                                            FIND_ANYWHERE );
1023     if( p_input )
1024     {
1025         vlc_value_t val; val.b_bool = VLC_TRUE;
1026
1027         var_Set( p_input, "rate-slower", val );
1028         vlc_object_release( p_input );
1029     }
1030 }
1031
1032 void Interface::OnFastStream( wxCommandEvent& WXUNUSED(event) )
1033 {
1034     input_thread_t *p_input =
1035         (input_thread_t *)vlc_object_find( p_intf, VLC_OBJECT_INPUT,
1036                                            FIND_ANYWHERE );
1037     if( p_input )
1038     {
1039         vlc_value_t val; val.b_bool = VLC_TRUE;
1040
1041         var_Set( p_input, "rate-faster", val );
1042         vlc_object_release( p_input );
1043     }
1044 }
1045
1046 void Interface::TogglePlayButton( int i_playing_status )
1047 {
1048     if( i_playing_status == i_old_playing_status )
1049         return;
1050
1051     GetToolBar()->DeleteTool( PlayStream_Event );
1052
1053     if( i_playing_status == PLAYING_S )
1054     {
1055         GetToolBar()->InsertTool( 2, PlayStream_Event, wxU(_("Pause")),
1056                                   wxBitmap( pause_xpm ), wxNullBitmap,
1057                                   wxITEM_NORMAL, wxU(_(HELP_PAUSE)) );
1058     }
1059     else
1060     {
1061         GetToolBar()->InsertTool( 2, PlayStream_Event, wxU(_("Play")),
1062                                   wxBitmap( play_xpm ), wxNullBitmap,
1063                                   wxITEM_NORMAL, wxU(_(HELP_PLAY)) );
1064     }
1065
1066     GetToolBar()->Realize();
1067
1068     i_old_playing_status = i_playing_status;
1069 }
1070
1071 #if wxUSE_DRAG_AND_DROP
1072 /*****************************************************************************
1073  * Definition of DragAndDrop class.
1074  *****************************************************************************/
1075 DragAndDrop::DragAndDrop( intf_thread_t *_p_intf, vlc_bool_t _b_enqueue )
1076 {
1077     p_intf = _p_intf;
1078     b_enqueue = _b_enqueue;
1079 }
1080
1081 bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
1082                                const wxArrayString& filenames )
1083 {
1084     /* Add dropped files to the playlist */
1085
1086     playlist_t *p_playlist =
1087         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
1088                                        FIND_ANYWHERE );
1089     if( p_playlist == NULL )
1090     {
1091         return FALSE;
1092     }
1093
1094     for( size_t i = 0; i < filenames.GetCount(); i++ )
1095         playlist_Add( p_playlist, (const char *)filenames[i].mb_str(),
1096                       (const char *)filenames[i].mb_str(),
1097                       PLAYLIST_APPEND | ((i | b_enqueue) ? 0 : PLAYLIST_GO),
1098                       PLAYLIST_END );
1099
1100     vlc_object_release( p_playlist );
1101
1102     return TRUE;
1103 }
1104 #endif
1105
1106 /*****************************************************************************
1107  * Definition of VolCtrl class.
1108  *****************************************************************************/
1109 wxVolCtrl::wxVolCtrl( intf_thread_t *_p_intf, wxWindow* parent, wxWindowID id,
1110                       wxPoint point, wxSize size )
1111   : wxGauge( parent, id, 200, point, size, wxGA_HORIZONTAL | wxGA_SMOOTH )
1112 {
1113     p_intf = _p_intf;
1114     UpdateVolume();
1115 }
1116
1117 void wxVolCtrl::OnChange( wxMouseEvent& event )
1118 {
1119     if( !event.LeftDown() && !event.LeftIsDown() ) return;
1120
1121     int i_volume = event.GetX() * 200 / GetClientSize().GetWidth();
1122     aout_VolumeSet( p_intf, i_volume * AOUT_VOLUME_MAX / 200 / 2 );
1123     UpdateVolume();
1124 }
1125
1126 void wxVolCtrl::UpdateVolume()
1127 {
1128     audio_volume_t i_volume;
1129     aout_VolumeGet( p_intf, &i_volume );
1130
1131     int i_gauge_volume = i_volume * 200 * 2 / AOUT_VOLUME_MAX;
1132     if( i_gauge_volume == GetValue() ) return;
1133
1134     SetValue( i_gauge_volume );
1135     SetToolTip( wxString::Format((wxString)wxU(_("Volume")) + wxT(" %d"),
1136                 i_gauge_volume / 2 ) );
1137 }