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