]> git.sesse.net Git - vlc/blob - modules/gui/wxwindows/interface.cpp
* modules/gui/wxwindows/*: misc improvements to the main interface, implementation of
[vlc] / modules / gui / wxwindows / interface.cpp
1 /*****************************************************************************
2  * interface.cpp : wxWindows plugin for vlc
3  *****************************************************************************
4  * Copyright (C) 2000-2001 VideoLAN
5  * $Id: interface.cpp,v 1.7 2002/11/23 14:28:51 gbazin Exp $
6  *
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <errno.h>                                                 /* ENOMEM */
29 #include <string.h>                                            /* strerror() */
30 #include <stdio.h>
31
32 #include <wx/wxprec.h>
33 #include <wx/wx.h>
34
35 /* Let vlc take care of the i18n stuff */
36 #undef _
37
38 #ifdef WIN32                                                 /* mingw32 hack */
39 #undef Yield
40 #undef CreateDialog
41 #endif
42
43 #include <vlc/vlc.h>
44 #include <vlc/intf.h>
45
46 #include "wxwindows.h"
47
48 /* include the toolbar graphics */
49 #include "bitmaps/file.xpm"
50 #include "bitmaps/disc.xpm"
51 #include "bitmaps/net.xpm"
52 #if 0
53 #include "bitmaps/sat.xpm"
54 #endif
55 #include "bitmaps/play.xpm"
56 #include "bitmaps/pause.xpm"
57 #include "bitmaps/stop.xpm"
58 #include "bitmaps/previous.xpm"
59 #include "bitmaps/next.xpm"
60 #include "bitmaps/playlist.xpm"
61
62 /* include the icon graphic */
63 #include "share/vlc32x32.xpm"
64
65 /*****************************************************************************
66  * Local class declarations.
67  *****************************************************************************/
68
69 /*****************************************************************************
70  * Event Table.
71  *****************************************************************************/
72
73 /* IDs for the controls and the menu commands */
74 enum
75 {
76     /* menu items */
77     Exit_Event = 1,
78     OpenFile_Event,
79     OpenDisc_Event,
80     OpenNet_Event,
81     OpenSat_Event,
82     EjectDisc_Event,
83
84     Playlist_Event,
85     Logs_Event,
86
87     Audio_Event,
88     Subtitles_Event,
89     Prefs_Event,
90
91     SliderScroll_Event,
92     StopStream_Event,
93     PlayStream_Event,
94     PauseStream_Event,
95     PrevStream_Event,
96     NextStream_Event,
97
98     /* it is important for the id corresponding to the "About" command to have
99      * this standard value as otherwise it won't be handled properly under Mac
100      * (where it is special and put into the "Apple" menu) */
101     About_Event = wxID_ABOUT
102 };
103
104 BEGIN_EVENT_TABLE(Interface, wxFrame)
105     /* Menu events */
106     EVT_MENU(Exit_Event, Interface::OnExit)
107     EVT_MENU(About_Event, Interface::OnAbout)
108     EVT_MENU(Playlist_Event, Interface::OnPlaylist)
109     EVT_MENU(OpenFile_Event, Interface::OnOpenFile)
110     /* Toolbar events */
111     EVT_MENU(OpenFile_Event, Interface::OnOpenFile)
112     EVT_MENU(StopStream_Event, Interface::OnStopStream)
113     EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
114     EVT_MENU(PauseStream_Event, Interface::OnPauseStream)
115     EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
116     EVT_MENU(NextStream_Event, Interface::OnNextStream)
117     /* Slider events */
118     EVT_COMMAND_SCROLL(SliderScroll_Event, Interface::OnSliderUpdate)
119 END_EVENT_TABLE()
120
121 /*****************************************************************************
122  * Constructor.
123  *****************************************************************************/
124 Interface::Interface( intf_thread_t *_p_intf ):
125     wxFrame( NULL, -1, "title", wxDefaultPosition, wxDefaultSize,
126              wxDEFAULT_FRAME_STYLE )
127 {
128     /* Initializations */
129     p_intf = _p_intf;
130
131     /* Give our interface a nice little icon */
132     SetIcon( *new wxIcon( vlc_xpm ) );
133
134     /* Create a sizer for the main frame */
135     frame_sizer = new wxBoxSizer( wxHORIZONTAL );
136     SetSizer( frame_sizer );
137
138     /* Creation of the menu bar */
139     CreateOurMenuBar();
140
141     /* Creation of the tool bar */
142     CreateOurToolBar();
143
144     /* Creation of the slider sub-window */
145     CreateOurSlider();
146
147     /* Creation of the status bar 
148      * Helptext for menu items and toolbar tools will automatically get
149      * displayed here. */
150     int i_status_width[2] = {-2,-3};
151     statusbar = CreateStatusBar( 2 );                            /* 2 fields */
152     statusbar->SetStatusWidths( 2, i_status_width );
153
154     SetTitle( COPYRIGHT_MESSAGE );
155
156     /* Layout everything */
157     SetAutoLayout( TRUE );
158     frame_sizer->Layout();
159     frame_sizer->SetSizeHints(this);
160
161     /* Associate drop targets with the main interface */
162     SetDropTarget( new DragAndDrop( p_intf ) );
163 }
164
165 Interface::~Interface()
166 {
167 }
168
169 /*****************************************************************************
170  * Private methods.
171  *****************************************************************************/
172 void Interface::CreateOurMenuBar()
173 {
174 #define HELP_FILE  N_("Open a file")
175 #define HELP_DISC  N_("Open a DVD or (S)VCD")
176 #define HELP_NET   N_("Open a network stream")
177 #define HELP_SAT   N_("Open a satellite stream")
178 #define HELP_EJECT N_("Eject the DVD/CD")
179 #define HELP_EXIT  N_("Exit this program")
180
181 #define HELP_PLAYLIST   N_("Open the playlist")
182 #define HELP_LOGS       N_("Show the program logs")
183
184 #define HELP_AUDIO N_("Change the current audio track")
185 #define HELP_SUBS  N_("Change the current subtitles stream")
186 #define HELP_PREFS N_("Go to the preferences menu")
187
188 #define HELP_ABOUT N_("About this program")
189
190     /* Create the "File" menu */
191     wxMenu *file_menu = new wxMenu;
192     file_menu->Append( OpenFile_Event, _("&Open File..."), HELP_FILE );
193     file_menu->Append( OpenDisc_Event, _("Open &Disc..."), HELP_DISC );
194     file_menu->Append( OpenNet_Event, _("&Network Stream..."), HELP_NET );
195 #if 0
196     file_menu->Append( OpenSat_Event, _("&Satellite Stream..."), HELP_NET );
197 #endif
198     file_menu->AppendSeparator();
199     file_menu->Append( EjectDisc_Event, _("&Eject Disc"), HELP_EJECT );
200     file_menu->AppendSeparator();
201     file_menu->Append( Exit_Event, _("E&xit"), HELP_EXIT );
202
203     /* Create the "View" menu */
204     wxMenu *view_menu = new wxMenu;
205     view_menu->Append( Playlist_Event, _("&Playlist..."), HELP_PLAYLIST );
206     view_menu->Append( Logs_Event, _("&Logs..."), HELP_LOGS );
207
208     /* Create the "Settings" menu */
209     wxMenu *settings_menu = new wxMenu;
210     settings_menu->Append( Audio_Event, _("&Audio"), HELP_AUDIO );
211     settings_menu->Append( Subtitles_Event, _("&Subtitles"), HELP_SUBS );
212     settings_menu->AppendSeparator();
213     settings_menu->Append( Prefs_Event, _("&Preferences..."), HELP_PREFS );
214
215     /* Create the "Help" menu */
216     wxMenu *help_menu = new wxMenu;
217     help_menu->Append( About_Event, _("&About..."), HELP_ABOUT );
218
219     /* Append the freshly created menus to the menu bar... */
220     wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
221     menubar->Append( file_menu, _("&File") );
222     menubar->Append( view_menu, _("&View") );
223     menubar->Append( settings_menu, _("&Settings") );
224     menubar->Append( help_menu, _("&Help") );
225
226     /* Attach the menu bar to the frame */
227     SetMenuBar( menubar );
228
229     /* Associate drop targets with the menubar */
230     menubar->SetDropTarget( new DragAndDrop( p_intf ) );
231 }
232
233 void Interface::CreateOurToolBar()
234 {
235 #define HELP_STOP N_("Stop current playlist item")
236 #define HELP_PLAY N_("Play current playlist item")
237 #define HELP_PAUSE N_("Pause current playlist item")
238 #define HELP_PLO N_("Open playlist")
239 #define HELP_PLP N_("Previous playlist item")
240 #define HELP_PLN N_("Next playlist item")
241
242     wxBitmap *p_bmp_file     = new wxBitmap( file_xpm );
243     wxBitmap *p_bmp_disc     = new wxBitmap( disc_xpm );
244     wxBitmap *p_bmp_net      = new wxBitmap( net_xpm );
245     wxBitmap *p_bmp_play     = new wxBitmap( play_xpm );
246     wxBitmap *p_bmp_stop     = new wxBitmap( stop_xpm );
247     wxBitmap *p_bmp_pause    = new wxBitmap( pause_xpm );
248     wxBitmap *p_bmp_prev     = new wxBitmap( previous_xpm );
249     wxBitmap *p_bmp_next     = new wxBitmap( next_xpm );
250     wxBitmap *p_bmp_playlist = new wxBitmap( playlist_xpm );
251
252     wxToolBar *toolbar = CreateToolBar(
253         wxTB_HORIZONTAL | wxTB_TEXT | wxTB_FLAT | wxTB_DOCKABLE );
254
255     toolbar->AddTool( OpenFile_Event, _("File"), *p_bmp_file, HELP_FILE );
256     toolbar->AddTool( OpenFile_Event, _("Disc"), *p_bmp_disc, HELP_DISC );
257     toolbar->AddTool( OpenFile_Event, _("Net"), *p_bmp_net, HELP_NET );
258 #if 0
259     toolbar->AddTool( OpenFile_Event, _("Sat"), *p_bmp_net, HELP_SAT );
260 #endif
261     toolbar->AddSeparator();
262     toolbar->AddTool( StopStream_Event, _("Stop"), *p_bmp_stop, HELP_STOP );
263     toolbar->AddTool( PlayStream_Event, _("Play"), *p_bmp_play, HELP_PLAY );
264     toolbar->AddTool( PauseStream_Event, _("Pause"), *p_bmp_pause, HELP_PAUSE);
265     toolbar->AddSeparator();
266     toolbar->AddTool( Playlist_Event, _("Playlist"), *p_bmp_playlist,
267                       HELP_PLO );
268     toolbar->AddTool( PrevStream_Event, _("Prev"), *p_bmp_prev, HELP_PLP );
269     toolbar->AddTool( NextStream_Event, _("Next"), *p_bmp_next, HELP_PLN );
270
271     toolbar->Realize();
272
273     /* Place the toolbar in a sizer, so we can calculate the width of the
274      * toolbar and set this as the minimum for the main frame size. */
275     wxBoxSizer *toolbar_sizer = new wxBoxSizer( wxHORIZONTAL );
276     toolbar_sizer->Add( toolbar, 0, 0, 0 );
277     toolbar_sizer->Layout();
278     frame_sizer->SetMinSize( toolbar_sizer->GetMinSize().GetWidth(), -1 );
279
280     /* Associate drop targets with the toolbar */
281     toolbar->SetDropTarget( new DragAndDrop( p_intf ) );
282 }
283
284 void Interface::CreateOurSlider()
285 {
286     /* Create a new frame containing the slider */
287     slider_frame = new wxPanel( this, -1, wxDefaultPosition, wxSize(-1,50) );
288     slider_frame->SetAutoLayout( TRUE );
289     slider_frame->Hide();
290
291     /* Create static box to surround the slider */
292     slider_box = new wxStaticBox( slider_frame, -1, "" );
293
294     /* Create sizer for slider frame */
295     wxStaticBoxSizer *slider_sizer =
296         new wxStaticBoxSizer( slider_box, wxHORIZONTAL );
297     slider_frame->SetSizer( slider_sizer );
298
299     /* Create slider */
300     slider = new wxSlider( slider_frame, SliderScroll_Event, 0, 0,
301                            SLIDER_MAX_POS, wxDefaultPosition, wxDefaultSize );
302     slider_sizer->Add( slider, 1, wxGROW | wxALL, 5 );
303     slider_sizer->Layout();
304 }
305
306 /*****************************************************************************
307  * Event Handlers.
308  *****************************************************************************/
309 void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
310 {
311     /* TRUE is to force the frame to close. */
312     Close(TRUE);
313 }
314
315 void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
316 {
317     wxString msg;
318     msg.Printf( _("This is the about dialog of the VideoLAN Client.\n") );
319
320     wxMessageBox( msg, _("About VideoLAN Client"),
321                   wxOK | wxICON_INFORMATION, this );
322 }
323
324 void Interface::OnPlaylist( wxCommandEvent& WXUNUSED(event) )
325 {
326     /* Show/hide the playlist window */
327     wxFrame *p_playlist_window = p_intf->p_sys->p_playlist_window;
328     if( p_playlist_window )
329     {
330         p_playlist_window->Show( ! p_playlist_window->IsShown() );
331     }
332 }
333
334 void Interface::OnOpenFile( wxCommandEvent& WXUNUSED(event) )
335 {
336     wxFileDialog dialog( this, _("Open file"), _(""), _(""), _("*.*") );
337
338     if( dialog.ShowModal() == wxID_OK )
339     {
340         /* Update the playlist */
341         playlist_t *p_playlist =
342             (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
343                                            FIND_ANYWHERE );
344         if( p_playlist == NULL )
345         {
346             return;
347         }
348
349         playlist_Add( p_playlist, (char *)dialog.GetPath().c_str(),
350                       PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
351
352         /* Rebuild the playlist */
353         p_intf->p_sys->p_playlist_window->Rebuild();
354
355         vlc_object_release( p_playlist );
356     }
357 }
358
359 void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
360 {
361     wxCommandEvent dummy;
362     playlist_t *p_playlist =
363         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
364                                        FIND_ANYWHERE );
365     if( p_playlist == NULL )
366     {
367         OnOpenFile( dummy );
368         return;
369     }
370
371     /* If the playlist is empty, open a file requester instead */
372     vlc_mutex_lock( &p_playlist->object_lock );
373     if( p_playlist->i_size )
374     {
375         vlc_mutex_unlock( &p_playlist->object_lock );
376         playlist_Play( p_playlist );
377         vlc_object_release( p_playlist );
378     }
379     else
380     {
381         vlc_mutex_unlock( &p_playlist->object_lock );
382         vlc_object_release( p_playlist );
383         OnOpenFile( dummy );
384     }
385 }
386
387 void Interface::OnStopStream( wxCommandEvent& WXUNUSED(event) )
388 {
389     playlist_t * p_playlist =
390         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
391                                        FIND_ANYWHERE );
392     if( p_playlist == NULL )
393     {
394         return;
395     }
396
397     playlist_Stop( p_playlist );
398     vlc_object_release( p_playlist );
399 }
400
401 void Interface::OnPauseStream( wxCommandEvent& WXUNUSED(event) )
402 {
403     if( p_intf->p_sys->p_input == NULL )
404     {
405         return;
406     }
407
408     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
409 }
410
411 void Interface::OnSliderUpdate( wxScrollEvent& event )
412 {
413     p_intf->p_sys->i_slider_pos = event.GetPosition();
414 }
415
416 void Interface::OnPrevStream( wxCommandEvent& WXUNUSED(event) )
417 {
418     playlist_t * p_playlist =
419         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
420                                        FIND_ANYWHERE );
421     if( p_playlist == NULL )
422     {
423         return;
424     }
425
426     playlist_Prev( p_playlist );
427     vlc_object_release( p_playlist );
428 }
429
430 void Interface::OnNextStream( wxCommandEvent& WXUNUSED(event) )
431 {
432     playlist_t * p_playlist =
433         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
434                                        FIND_ANYWHERE );
435     if( p_playlist == NULL )
436     {
437         return;
438     }
439
440     playlist_Next( p_playlist );
441     vlc_object_release( p_playlist );
442 }
443
444 /*****************************************************************************
445  * Definition of DragAndDrop class.
446  *****************************************************************************/
447 DragAndDrop::DragAndDrop( intf_thread_t *_p_intf )
448 {
449     p_intf = _p_intf;
450 }
451
452 bool DragAndDrop::OnDropFiles( wxCoord, wxCoord,
453                                const wxArrayString& filenames )
454 {
455     unsigned int i;
456
457     /* Add dropped files to the playlist */
458
459     playlist_t *p_playlist =
460         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
461                                        FIND_ANYWHERE );
462     if( p_playlist == NULL )
463     {
464         return FALSE;
465     }
466
467     for( i = 0; i < filenames.GetCount(); i++ )
468         playlist_Add( p_playlist, (char *)filenames[i].c_str(),
469                       PLAYLIST_APPEND | PLAYLIST_GO, PLAYLIST_END );
470
471     /* Rebuild the playlist */
472     p_intf->p_sys->p_playlist_window->Rebuild();
473
474     vlc_object_release( p_playlist );
475
476     return TRUE;
477 }