* added a wxwindows interface using the wxWindows cross-platform GUI framework.
[vlc.git] / 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.1 2002/11/18 13:02:16 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 <vlc/vlc.h>
33 #include <vlc/intf.h>
34
35 /* Let wxWindows 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 <wx/wxprec.h>
44 #include <wx/wx.h>
45
46 #include "wxwindows.h"
47 #include "wx/artprov.h"
48
49 /* include the toolbar graphics */
50 #include "bitmaps/file.xpm"
51 #include "bitmaps/disc.xpm"
52 #include "bitmaps/net.xpm"
53 #include "bitmaps/play.xpm"
54 #include "bitmaps/pause.xpm"
55 #include "bitmaps/stop.xpm"
56 #include "bitmaps/previous.xpm"
57 #include "bitmaps/next.xpm"
58 #include "bitmaps/playlist.xpm"
59 /*****************************************************************************
60  * Event Table.
61  *****************************************************************************/
62
63 const int ID_TOOLBAR = 500;
64
65 /* IDs for the controls and the menu commands */
66 enum
67 {
68     /* menu items */
69     Exit_Event = 1,
70     OpenFile_Event,
71     OpenDisc_Event,
72     OpenNet_Event,
73     OpenSat_Event,
74     EjectDisc_Event,
75
76     Logs_Event,
77
78     Audio_Event,
79     Subtitles_Event,
80     Prefs_Event,
81
82     SliderScroll_Event,
83     StopStream_Event,
84     PlayStream_Event,
85     PauseStream_Event,
86     PrevStream_Event,
87     NextStream_Event
88
89     /* it is important for the id corresponding to the "About" command to have
90      * this standard value as otherwise it won't be handled properly under Mac
91      * (where it is special and put into the "Apple" menu) */
92     About_Event = wxID_ABOUT,
93 };
94
95 BEGIN_EVENT_TABLE(Interface, wxFrame)
96     /* Menu events */
97     EVT_MENU(Exit_Event, Interface::OnExit)
98     EVT_MENU(About_Event, Interface::OnAbout)
99     EVT_MENU(OpenFile_Event, Interface::OnOpenFile)
100     /* Toolbar events */
101     EVT_MENU(OpenFile_Event, Interface::OnOpenFile)
102     EVT_MENU(StopStream_Event, Interface::OnStopStream)
103     EVT_MENU(PlayStream_Event, Interface::OnPlayStream)
104     EVT_MENU(PauseStream_Event, Interface::OnPauseStream)
105     EVT_MENU(PrevStream_Event, Interface::OnPrevStream)
106     EVT_MENU(NextStream_Event, Interface::OnNextStream)
107     /* Slider events */
108     EVT_COMMAND_SCROLL(SliderScroll_Event, Interface::OnSliderUpdate)
109 END_EVENT_TABLE()
110
111 /*****************************************************************************
112  * Constructor.
113  *****************************************************************************/
114 Interface::Interface( intf_thread_t *_p_intf ):
115     wxFrame( NULL, -1, "title", wxDefaultPosition, wxDefaultSize,
116              wxDEFAULT_FRAME_STYLE )
117 {
118
119     /* Initializations */
120     p_intf = _p_intf;
121
122     /* Give our interface a nice icon */
123     //SetIcon( wxICON(vlcicon) );
124
125     /* Create our "File" menu */
126 #define HELP_FILE  N_("Open a file")
127 #define HELP_DISC  N_("Open a DVD or (S)VCD")
128 #define HELP_NET   N_("Open a network stream")
129 #define HELP_SAT   N_("Open a satellite stream")
130 #define HELP_EJECT N_("Eject the DVD/CD")
131 #define HELP_EXIT  N_("Exit this program")
132     wxMenu *file_menu = new wxMenu;
133     file_menu->Append( OpenFile_Event, _("&Open File..."), HELP_FILE );
134     file_menu->Append( OpenDisc_Event, _("Open &Disc..."), HELP_DISC );
135     file_menu->Append( OpenNet_Event, _("&Network Stream..."), HELP_NET );
136 #if 0
137     file_menu->Append( OpenSat_Event, _("&Satellite Stream..."), HELP_NET );
138 #endif
139     file_menu->AppendSeparator();
140     file_menu->Append( EjectDisc_Event, _("&Eject Disc"), HELP_EJECT );
141     file_menu->AppendSeparator();
142     file_menu->Append( Exit_Event, _("E&xit"), HELP_EXIT );
143
144     /* Create our "View" menu */
145 #define HELP_LOGS  N_("Show the program logs")
146     wxMenu *view_menu = new wxMenu;
147     view_menu->Append( Logs_Event, _("&Logs..."), HELP_LOGS );
148
149     /* Create our "Settings" menu */
150 #define HELP_AUDIO N_("Change the current audio track")
151 #define HELP_SUBS  N_("Change the current subtitles stream")
152 #define HELP_PREFS N_("Go to the preferences menu")
153     wxMenu *settings_menu = new wxMenu;
154     settings_menu->Append( Audio_Event, _("&Audio"), HELP_AUDIO );
155     settings_menu->Append( Subtitles_Event, _("&Subtitles"), HELP_SUBS );
156     settings_menu->AppendSeparator();
157     settings_menu->Append( Prefs_Event, _("&Preferences..."), HELP_PREFS );
158
159     /* Create our "Help" menu */
160 #define HELP_ABOUT N_("About this program")
161     wxMenu *help_menu = new wxMenu;
162     help_menu->Append( About_Event, _("&About..."), HELP_ABOUT );
163
164     /* Append the freshly created menus to the menu bar... */
165     wxMenuBar *menubar = new wxMenuBar( wxMB_DOCKABLE );
166     menubar->Append( file_menu, _("&File") );
167     menubar->Append( view_menu, _("&View") );
168     menubar->Append( settings_menu, _("&Settings") );
169     menubar->Append( help_menu, _("&Help") );
170
171     /* Attach the menu bar to the frame */
172     SetMenuBar( menubar );
173
174     /* Create toolbar */
175 #define HELP_STOP N_("Stop current playlist item")
176 #define HELP_PLAY N_("Play current playlist item")
177 #define HELP_PAUSE N_("Pause current playlist item")
178 #define HELP_PLO N_("Open playlist")
179 #define HELP_PLP N_("Previous playlist item")
180 #define HELP_PLN N_("Next playlist item")
181     wxBitmap *p_bmp_file     = new wxBitmap( file_xpm );
182     wxBitmap *p_bmp_disc     = new wxBitmap( disc_xpm );
183     wxBitmap *p_bmp_net      = new wxBitmap( net_xpm );
184     wxBitmap *p_bmp_play     = new wxBitmap( play_xpm );
185     wxBitmap *p_bmp_stop     = new wxBitmap( stop_xpm );
186     wxBitmap *p_bmp_pause    = new wxBitmap( pause_xpm );
187     wxBitmap *p_bmp_prev     = new wxBitmap( previous_xpm );
188     wxBitmap *p_bmp_next     = new wxBitmap( next_xpm );
189     wxBitmap *p_bmp_playlist = new wxBitmap( playlist_xpm );
190
191     wxToolBar *toolbar = CreateToolBar(
192         wxTB_HORIZONTAL | wxTB_TEXT | wxTB_FLAT | wxTB_DOCKABLE, ID_TOOLBAR );
193
194     toolbar->AddTool( OpenFile_Event, _("File"), *p_bmp_file, HELP_FILE );
195     toolbar->AddTool( OpenFile_Event, _("Disc"), *p_bmp_disc, HELP_DISC );
196     toolbar->AddTool( OpenFile_Event, _("Net"), *p_bmp_net, HELP_NET );
197 #if 0
198     toolbar->AddTool( OpenFile_Event, _("Sat"), *p_bmp_net, HELP_SAT );
199 #endif
200     toolbar->AddSeparator();
201     toolbar->AddTool( StopStream_Event, _("Stop"), *p_bmp_stop, HELP_STOP );
202     toolbar->AddTool( PlayStream_Event, _("Play"), *p_bmp_play, HELP_PLAY );
203     toolbar->AddTool( PauseStream_Event, _("Pause"), *p_bmp_pause, HELP_PAUSE);
204     toolbar->AddSeparator();
205     toolbar->AddTool( wxID_OPEN, _("Playlist"), *p_bmp_playlist, HELP_PLO );
206     toolbar->AddTool( PrevStream_Event, _("Prev"), *p_bmp_prev, HELP_PLP );
207     toolbar->AddTool( NextStream_Event, _("Next"), *p_bmp_next, HELP_PLN );
208
209     toolbar->Realize();
210
211     /* Create slider */
212     wxBoxSizer *slider_sizer = new wxBoxSizer( wxVERTICAL );
213     slider = new wxSlider( this, SliderScroll_Event, 0, 0, 100,
214                            wxDefaultPosition, wxSize( 450, 50 ),
215                            wxSL_HORIZONTAL | wxSL_AUTOTICKS | wxSL_TOP );
216     slider_sizer->Add( slider, 0, wxGROW | wxALL | wxALIGN_CENTER, 5 );
217
218     /* use the sizer for layout */
219     slider->Hide();
220     slider_sizer->Layout();
221     SetSizerAndFit( slider_sizer );
222
223     /* Give the frame an optional statusbar. The '1' just means one field.
224      * A gripsizer will automatically get put on into the corner, if that
225      * is the normal OS behaviour for frames on that platform. Helptext
226      * for menu items and toolbar tools will automatically get displayed
227      * here. */
228     statusbar = CreateStatusBar(2);
229     int i_status_width[2] = {-1,-2};
230     statusbar->SetStatusWidths( 2, i_status_width );
231
232     SetTitle( COPYRIGHT_MESSAGE );
233     SetAutoLayout( TRUE );
234     Layout();
235 }
236
237 Interface::~Interface()
238 {
239 }
240
241 /*****************************************************************************
242  * Private methods.
243  *****************************************************************************/
244 void Interface::OnExit( wxCommandEvent& WXUNUSED(event) )
245 {
246     /* TRUE is to force the frame to close. */
247     Close(TRUE);
248 }
249
250 void Interface::OnAbout( wxCommandEvent& WXUNUSED(event) )
251 {
252     wxString msg;
253     msg.Printf( _("This is the about dialog of the VideoLAN Client.\n") );
254
255     wxMessageBox( msg, "About VideoLAN Client",
256                   wxOK | wxICON_INFORMATION, this );
257 }
258
259 void Interface::OnOpenFile( wxCommandEvent& WXUNUSED(event) )
260 {
261     wxFileDialog dialog
262                  (
263                     this,
264                     _T("Open file dialog"),
265                     _T(""),
266                     _T(""),
267                     _T("*.*")
268                  );
269
270     if (dialog.ShowModal() == wxID_OK)
271     {
272         wxString info;
273         info.Printf(_T("Full file name: %s\n")
274                     _T("Path: %s\n")
275                     _T("Name: %s"),
276                     dialog.GetPath().c_str(),
277                     dialog.GetDirectory().c_str(),
278                     dialog.GetFilename().c_str());
279         wxMessageDialog dialog2(this, info, _T("Selected file"));
280         dialog2.ShowModal();
281     }
282 }
283
284 void Interface::OnPlayStream( wxCommandEvent& WXUNUSED(event) )
285 {
286     wxCommandEvent dummy;
287     playlist_t *p_playlist =
288         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
289                                        FIND_ANYWHERE );
290     if( p_playlist == NULL )
291     {
292         OnOpenFile( dummy );
293         return;
294     }
295
296     /* If the playlist is empty, open a file requester instead */
297     vlc_mutex_lock( &p_playlist->object_lock );
298     if( p_playlist->i_size )
299     {
300         vlc_mutex_unlock( &p_playlist->object_lock );
301         playlist_Play( p_playlist );
302         vlc_object_release( p_playlist );
303     }
304     else
305     {
306         vlc_mutex_unlock( &p_playlist->object_lock );
307         vlc_object_release( p_playlist );
308         OnOpenFile( dummy );
309     }
310 }
311
312 void Interface::OnStopStream( wxCommandEvent& WXUNUSED(event) )
313 {
314     playlist_t * p_playlist =
315         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
316                                        FIND_ANYWHERE );
317     if( p_playlist == NULL )
318     {
319         return;
320     }
321
322     playlist_Stop( p_playlist );
323     vlc_object_release( p_playlist );
324 }
325
326 void Interface::OnPauseStream( wxCommandEvent& WXUNUSED(event) )
327 {
328     if( p_intf->p_sys->p_input == NULL )
329     {
330         return;
331     }
332
333     input_SetStatus( p_intf->p_sys->p_input, INPUT_STATUS_PAUSE );
334 }
335
336 void Interface::OnSliderUpdate( wxScrollEvent& event )
337 {
338     p_intf->p_sys->i_slider_pos = event.GetPosition();
339 }
340
341 void Interface::OnPrevStream( wxCommandEvent& WXUNUSED(event) )
342 {
343     playlist_t * p_playlist =
344         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
345                                        FIND_ANYWHERE );
346     if( p_playlist == NULL )
347     {
348         return;
349     }
350
351     playlist_Prev( p_playlist );
352     vlc_object_release( p_playlist );
353 }
354
355 void Interface::OnNextStream( wxCommandEvent& WXUNUSED(event) )
356 {
357     playlist_t * p_playlist =
358         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,
359                                        FIND_ANYWHERE );
360     if( p_playlist == NULL )
361     {
362         return;
363     }
364
365     playlist_Next( p_playlist );
366     vlc_object_release( p_playlist );
367 }