* Makefile.am:
[vlc.git] / modules / gui / skins / src / dialogs.cpp
1 /*****************************************************************************\r
2  * dialogs.cpp: Handles all the different dialog boxes we provide.\r
3  *****************************************************************************\r
4  * Copyright (C) 2003 VideoLAN\r
5  * $Id: dialogs.cpp,v 1.8 2003/06/28 13:04:52 sam Exp $\r
6  *\r
7  * Authors: Gildas Bazin <gbazin@netcourrier.com>\r
8  *\r
9  * This program is free software; you can redistribute it and/or modify\r
10  * it under the terms of the GNU General Public License as published by\r
11  * the Free Software Foundation; either version 2 of the License, or\r
12  * (at your option) any later version.\r
13  *\r
14  * This program is distributed in the hope that it will be useful,\r
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
17  * GNU General Public License for more details.\r
18  *\r
19  * You should have received a copy of the GNU General Public License\r
20  * along with this program; if not, write to the Free Software\r
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111,\r
22  * USA.\r
23  *****************************************************************************/\r
24 \r
25 //--- VLC -------------------------------------------------------------------\r
26 #include <vlc/vlc.h>\r
27 #include <vlc/intf.h>\r
28 \r
29 //--- SKIN ------------------------------------------------------------------\r
30 #include "../os_api.h"\r
31 #include "event.h"\r
32 #include "banks.h"\r
33 #include "theme.h"\r
34 #include "../os_theme.h"\r
35 #include "themeloader.h"\r
36 #include "window.h"\r
37 #include "vlcproc.h"\r
38 #include "skin_common.h"\r
39 #include "dialogs.h"\r
40 \r
41 /* Callback prototype */\r
42 int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,\r
43                  vlc_value_t old_val, vlc_value_t new_val, void *param );\r
44 \r
45 #if defined(MODULE_NAME_IS_basic_skins)\r
46 \r
47 // Constructor\r
48 Dialogs::Dialogs( intf_thread_t *_p_intf ){}\r
49 // Destructor\r
50 Dialogs::~Dialogs(){}\r
51 \r
52 void Dialogs::ShowOpen( bool b_play ){}\r
53 void Dialogs::ShowOpenSkin(){}\r
54 void Dialogs::ShowMessages(){}\r
55 void Dialogs::ShowPrefs(){}\r
56 void Dialogs::ShowFileInfo(){}\r
57 void Dialogs::ShowPopup(){}\r
58 \r
59 #else // !MODULE_NAME_IS_basic_skins\r
60 \r
61 #include "../../wxwindows/wxwindows.h"\r
62 #include "../../../../share/vlc32x32.xpm"       // include the graphic icon\r
63 \r
64 #define ShowOpen_Event     0\r
65 #define ShowOpenSkin_Event 1\r
66 #define ShowMessages_Event 2\r
67 #define ShowPrefs_Event    3\r
68 #define ShowFileInfo_Event 4\r
69 #define ShowPopup_Event    5\r
70 #define ExitThread_Event   99\r
71 \r
72 //---------------------------------------------------------------------------\r
73 // Local classes declarations.\r
74 //---------------------------------------------------------------------------\r
75 \r
76 DEFINE_EVENT_TYPE(wxEVT_DIALOG)\r
77 \r
78 class Instance: public wxApp\r
79 {\r
80 public:\r
81     Instance();\r
82 #ifdef GTK2_SKINS\r
83     Instance( intf_thread_t *_p_intf, CallBackObjects *callback );\r
84 #else\r
85     Instance( intf_thread_t *_p_intf );\r
86 #endif\r
87 \r
88     bool OnInit();\r
89     int  OnExit();\r
90 \r
91 private:\r
92     intf_thread_t *p_intf;\r
93 \r
94 #ifdef GTK2_SKINS\r
95     CallBackObjects *callbackobj;\r
96 #endif\r
97 \r
98     DECLARE_EVENT_TABLE();\r
99 };\r
100 \r
101 BEGIN_EVENT_TABLE(Instance, wxApp)\r
102     EVT_COMMAND(ShowOpen_Event, wxEVT_DIALOG, Dialogs::OnShowOpen)\r
103     EVT_COMMAND(ShowOpenSkin_Event, wxEVT_DIALOG, Dialogs::OnShowOpenSkin)\r
104     EVT_COMMAND(ShowMessages_Event, wxEVT_DIALOG, Dialogs::OnShowMessages)\r
105     EVT_COMMAND(ShowPrefs_Event, wxEVT_DIALOG, Dialogs::OnShowPrefs)\r
106     EVT_COMMAND(ShowFileInfo_Event, wxEVT_DIALOG, Dialogs::OnShowFileInfo)\r
107     EVT_COMMAND(ShowPopup_Event, wxEVT_DIALOG, Dialogs::OnShowPopup)\r
108     EVT_COMMAND(ExitThread_Event, wxEVT_DIALOG, Dialogs::OnExitThread)\r
109 END_EVENT_TABLE()\r
110 \r
111 //---------------------------------------------------------------------------\r
112 // Implementation of Instance class\r
113 //---------------------------------------------------------------------------\r
114 Instance::Instance( )\r
115 {\r
116 }\r
117 \r
118 #ifdef GTK2_SKINS\r
119 Instance::Instance( intf_thread_t *_p_intf, CallBackObjects *callback )\r
120 {\r
121     // Initialization\r
122     p_intf = _p_intf;\r
123     callbackobj = callback;\r
124 }\r
125 #else\r
126 Instance::Instance( intf_thread_t *_p_intf )\r
127 {\r
128     // Initialization\r
129     p_intf = _p_intf;\r
130 }\r
131 #endif\r
132 \r
133 IMPLEMENT_APP_NO_MAIN(Instance)\r
134 \r
135 bool Instance::OnInit()\r
136 {\r
137     p_intf->p_sys->p_icon = new wxIcon( vlc_xpm );\r
138 \r
139 #ifdef GTK2_SKINS\r
140     // Set event callback. Yes, it's a big hack ;)\r
141     gdk_event_handler_set( GTK2Proc, (gpointer)callbackobj, NULL );\r
142 #endif\r
143 \r
144     // Create all the dialog boxes\r
145     p_intf->p_sys->p_dialogs->OpenDlg =\r
146         new OpenDialog( p_intf, NULL, FILE_ACCESS );\r
147     p_intf->p_sys->p_dialogs->MessagesDlg = new Messages( p_intf, NULL );\r
148     p_intf->p_sys->p_dialogs->PrefsDlg = new PrefsDialog( p_intf, NULL );\r
149     p_intf->p_sys->p_dialogs->FileInfoDlg = new FileInfo( p_intf, NULL );\r
150 \r
151 #ifdef GTK2_SKINS\r
152     // Add timer\r
153     g_timeout_add( 200, (GSourceFunc)RefreshTimer, (gpointer)p_intf );\r
154 #endif\r
155 \r
156     // OK, initialization is over, now the other thread can go on working...\r
157     vlc_thread_ready( p_intf->p_sys->p_dialogs->p_thread );\r
158 \r
159     /* Register callback for the intf-popupmenu variable */\r
160     playlist_t *p_playlist =\r
161         (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST,\r
162                                        FIND_ANYWHERE );\r
163     if( p_playlist != NULL )\r
164     {\r
165         var_AddCallback( p_playlist, "intf-popupmenu", PopupMenuCB,\r
166                          p_intf->p_sys->p_dialogs );\r
167         vlc_object_release( p_playlist );\r
168     }\r
169 \r
170     /* Intercept all menu events in our custom event handler */\r
171     p_intf->p_sys->p_dialogs->OpenDlg->PushEventHandler(\r
172         new MenuEvtHandler( p_intf, NULL ) );\r
173 \r
174     return TRUE;\r
175 }\r
176 \r
177 int Instance::OnExit()\r
178 {\r
179     // Delete evertything\r
180     delete p_intf->p_sys->p_dialogs->FileInfoDlg;\r
181     delete p_intf->p_sys->p_dialogs->PrefsDlg;\r
182     delete p_intf->p_sys->p_dialogs->MessagesDlg;\r
183     delete p_intf->p_sys->p_dialogs->OpenDlg;\r
184     delete p_intf->p_sys->p_icon;\r
185 \r
186     return 0;\r
187 }\r
188 \r
189 //---------------------------------------------------------------------------\r
190 #if !defined(__BUILTIN__) && defined( WIN32 )\r
191 HINSTANCE hInstance = 0;\r
192 extern "C" BOOL WINAPI\r
193 DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)\r
194 {\r
195     hInstance = (HINSTANCE)hModule;\r
196     return TRUE;\r
197 }\r
198 #endif\r
199 \r
200 //---------------------------------------------------------------------------\r
201 // Thread callback\r
202 // We create all wxWindows dialogs in a separate thread because we don't want\r
203 // any interaction with our own message loop\r
204 //---------------------------------------------------------------------------\r
205 void SkinsDialogsThread( dialogs_thread_t *p_thread )\r
206 {\r
207 #if !defined( WIN32 )\r
208     static char  *p_args[] = { "" };\r
209 #endif\r
210     intf_thread_t *p_intf = p_thread->p_intf;\r
211 \r
212     /* Hack to pass the p_intf pointer to the new wxWindow Instance object */\r
213     wxTheApp = new Instance( p_intf );\r
214 \r
215 #if defined( WIN32 )\r
216 #if !defined(__BUILTIN__)\r
217     wxEntry( hInstance/*GetModuleHandle(NULL)*/, NULL, NULL, SW_SHOW, TRUE );\r
218 #else\r
219     wxEntry( GetModuleHandle( NULL ), NULL, NULL, SW_SHOW, TRUE );\r
220 #endif\r
221 #else\r
222     wxEntry( 1, p_args );\r
223 #endif\r
224 \r
225     return;\r
226 }\r
227 \r
228 //---------------------------------------------------------------------------\r
229 // Implementation of Dialogs class\r
230 //---------------------------------------------------------------------------\r
231 Dialogs::Dialogs( intf_thread_t *_p_intf )\r
232 {\r
233     p_intf = _p_intf;\r
234     p_intf->p_sys->p_dialogs = this;\r
235     b_popup_change = VLC_FALSE;\r
236 \r
237     p_thread = (dialogs_thread_t *)vlc_object_create( p_intf,\r
238                                                 sizeof(dialogs_thread_t) );\r
239     p_thread->p_intf = p_intf;\r
240 \r
241     // Create a new thread for wxWindows\r
242     if( vlc_thread_create( p_thread, "Skins Dialogs Thread",\r
243                            SkinsDialogsThread, 0, VLC_TRUE ) )\r
244     {\r
245         OpenDlg = NULL;\r
246         msg_Err( p_intf, "cannot create SkinsDialogsThread" );\r
247     }\r
248 }\r
249 \r
250 Dialogs::~Dialogs()\r
251 {\r
252     wxCommandEvent event( wxEVT_DIALOG, ExitThread_Event );\r
253     event.SetClientData( this );\r
254 \r
255     wxTheApp->AddPendingEvent( event );\r
256 \r
257     vlc_thread_join( p_thread );\r
258 }\r
259 \r
260 void Dialogs::ShowOpen( bool b_play )\r
261 {\r
262     wxCommandEvent event( wxEVT_DIALOG, ShowOpen_Event );\r
263     event.SetClientData( this );\r
264     event.SetInt( b_play );\r
265 \r
266     wxTheApp->AddPendingEvent( event );\r
267 }\r
268 \r
269 void Dialogs::ShowOpenSkin()\r
270 {\r
271     wxCommandEvent event( wxEVT_DIALOG, ShowOpenSkin_Event );\r
272     event.SetClientData( this );\r
273 \r
274     wxTheApp->AddPendingEvent( event );\r
275 }\r
276 \r
277 void Dialogs::ShowMessages()\r
278 {\r
279     wxCommandEvent event( wxEVT_DIALOG, ShowMessages_Event );\r
280     event.SetClientData( this );\r
281 \r
282     wxTheApp->AddPendingEvent( event );\r
283 }\r
284 \r
285 void Dialogs::ShowPrefs()\r
286 {\r
287     wxCommandEvent event( wxEVT_DIALOG, ShowPrefs_Event );\r
288     event.SetClientData( this );\r
289 \r
290     wxTheApp->AddPendingEvent( event );\r
291 }\r
292 \r
293 void Dialogs::ShowFileInfo()\r
294 {\r
295     wxCommandEvent event( wxEVT_DIALOG, ShowFileInfo_Event );\r
296     event.SetClientData( this );\r
297 \r
298     wxTheApp->AddPendingEvent( event );\r
299 }\r
300 \r
301 void Dialogs::ShowPopup()\r
302 {\r
303     wxCommandEvent event( wxEVT_DIALOG, ShowPopup_Event );\r
304     event.SetClientData( this );\r
305 \r
306     wxTheApp->AddPendingEvent( event );\r
307 }\r
308 \r
309 void Dialogs::OnShowOpen( wxCommandEvent& event )\r
310 {\r
311     Dialogs *p_dialogs = (Dialogs *)event.GetClientData();\r
312     bool b_play = event.GetInt() ? TRUE : FALSE;\r
313 \r
314     if( p_dialogs->OpenDlg->IsShown() ) return;\r
315  \r
316     if( p_dialogs->OpenDlg->ShowModal() != wxID_OK )\r
317     {\r
318         return;\r
319     }\r
320 \r
321     // Check if playlist is available\r
322     playlist_t *p_playlist = p_dialogs->p_intf->p_sys->p_playlist;\r
323     if( p_playlist == NULL )\r
324     {\r
325         return;\r
326     }\r
327 \r
328     if( b_play )\r
329     {\r
330         // Append and play\r
331         for( size_t i = 0; i < p_dialogs->OpenDlg->mrl.GetCount(); i++ )\r
332         {\r
333             playlist_Add( p_playlist,\r
334                 (const char *)p_dialogs->OpenDlg->mrl[i].mb_str(),\r
335                 PLAYLIST_APPEND | (i ? 0 : PLAYLIST_GO), PLAYLIST_END );\r
336         }\r
337         p_dialogs->p_intf->p_sys->p_theme->EvtBank->Get( "play" )->SendEvent();\r
338     }\r
339     else\r
340     {\r
341         // Append only\r
342         for( size_t i = 0; i < p_dialogs->OpenDlg->mrl.GetCount(); i++ )\r
343         {\r
344             playlist_Add( p_playlist,\r
345                 (const char *)p_dialogs->OpenDlg->mrl[i].mb_str(),\r
346                 PLAYLIST_APPEND, PLAYLIST_END );\r
347         }\r
348     }\r
349 \r
350     // Refresh interface !\r
351     p_dialogs->p_intf->p_sys->p_theme->EvtBank->Get( "playlist_refresh" )\r
352         ->PostSynchroMessage();\r
353 \r
354     return;\r
355 }\r
356 \r
357 void Dialogs::OnShowOpenSkin( wxCommandEvent& event )\r
358 {\r
359     Dialogs *p_dialogs = (Dialogs *)event.GetClientData();\r
360     intf_thread_t *p_intf = p_dialogs->p_intf;\r
361 \r
362     wxFileDialog dialog( NULL,\r
363         wxU(_("Open a skin file")), wxT(""), wxT(""),\r
364         wxT("Skin files (*.vlt)|*.vlt|Skin files (*.xml)|*.xml|"\r
365             "All files|*.*"), wxOPEN );\r
366 \r
367     if( dialog.ShowModal() == wxID_OK )\r
368     {\r
369         p_intf->p_sys->p_new_theme_file =\r
370            new char[strlen(dialog.GetPath().mb_str()) + 1];\r
371 \r
372         strcpy( p_intf->p_sys->p_new_theme_file,\r
373                 dialog.GetPath().mb_str() );\r
374 \r
375         // Tell vlc to change skin after hiding interface\r
376         OSAPI_PostMessage( NULL, VLC_HIDE, VLC_LOAD_SKIN, 0 );\r
377     }\r
378 }\r
379 \r
380 void Dialogs::OnShowMessages( wxCommandEvent& event )\r
381 {\r
382     Dialogs *p_dialogs = (Dialogs *)event.GetClientData();\r
383     p_dialogs->MessagesDlg->Show( !p_dialogs->MessagesDlg->IsShown() );\r
384 }\r
385 \r
386 void Dialogs::OnShowPrefs( wxCommandEvent& event )\r
387 {\r
388     Dialogs *p_dialogs = (Dialogs *)event.GetClientData();\r
389     p_dialogs->PrefsDlg->Show( !p_dialogs->PrefsDlg->IsShown() );\r
390 }\r
391 \r
392 void Dialogs::OnShowFileInfo( wxCommandEvent& event )\r
393 {\r
394     Dialogs *p_dialogs = (Dialogs *)event.GetClientData();\r
395     p_dialogs->FileInfoDlg->Show( !p_dialogs->FileInfoDlg->IsShown() );\r
396 }\r
397 \r
398 void Dialogs::OnShowPopup( wxCommandEvent& event )\r
399 {\r
400     Dialogs *p_dialogs = (Dialogs *)event.GetClientData();\r
401 \r
402     wxPoint mousepos = wxGetMousePosition();\r
403 \r
404     wxMouseEvent mouseevent = wxMouseEvent( wxEVT_RIGHT_UP );\r
405     mouseevent.m_x = p_dialogs->OpenDlg->ScreenToClient(mousepos).x;\r
406     mouseevent.m_y = p_dialogs->OpenDlg->ScreenToClient(mousepos).y;\r
407 \r
408     ::PopupMenu( p_dialogs->p_intf,\r
409                  p_dialogs->OpenDlg, mouseevent.GetPosition() );\r
410 }\r
411 \r
412 void Dialogs::OnExitThread( wxCommandEvent& event )\r
413 {\r
414     wxTheApp->ExitMainLoop();\r
415 }\r
416 #endif // MODULE_NAME_IS_basic_skins\r
417 \r
418 /*****************************************************************************\r
419  * PopupMenuCB: callback triggered by the intf-popupmenu playlist variable.\r
420  *  We don't show the menu directly here because we don't want the\r
421  *  caller to block for a too long time.\r
422  *****************************************************************************/\r
423 int PopupMenuCB( vlc_object_t *p_this, const char *psz_variable,\r
424                  vlc_value_t old_val, vlc_value_t new_val, void *param )\r
425 {\r
426 #if !defined(MODULE_NAME_IS_basic_skins)\r
427     Dialogs *p_dialogs = (Dialogs *)param;\r
428 \r
429     p_dialogs->ShowPopup();\r
430 #endif\r
431 \r
432     return VLC_SUCCESS;\r
433 }\r