]> git.saurik.com Git - wxWidgets.git/blob - src/common/mediactrlcmn.cpp
handle '&' in the names of the files in the history correctly by quoting it
[wxWidgets.git] / src / common / mediactrlcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: common/mediactrl.cpp
3 // Purpose: wxMediaCtrl common code
4 // Author: Ryan Norton <wxprojects@comcast.net>
5 // Modified by:
6 // Created: 11/07/04
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 //===========================================================================
13 // Definitions
14 //===========================================================================
15
16 //---------------------------------------------------------------------------
17 // Pre-compiled header stuff
18 //---------------------------------------------------------------------------
19
20 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
21 #pragma implementation "mediactrl.h"
22 #endif
23
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 //---------------------------------------------------------------------------
31 // Includes
32 //---------------------------------------------------------------------------
33 #include "wx/mediactrl.h"
34 #include "wx/hash.h"
35
36 //---------------------------------------------------------------------------
37 // Compilation guard
38 //---------------------------------------------------------------------------
39 #if wxUSE_MEDIACTRL
40
41 //===========================================================================
42 //
43 // Implementation
44 //
45 //===========================================================================
46
47 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
48 // RTTI and Event implementations
49 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
50
51 IMPLEMENT_CLASS(wxMediaCtrl, wxControl);
52 IMPLEMENT_CLASS(wxMediaBackend, wxObject);
53 IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent);
54 DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED);
55 DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP);
56
57 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
58 //
59 // wxMediaCtrl
60 //
61 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
62
63 //---------------------------------------------------------------------------
64 // wxMediaBackend Destructor
65 //
66 // This is here because the DARWIN gcc compiler badly screwed up and
67 // needs the destructor implementation in the source
68 //---------------------------------------------------------------------------
69 wxMediaBackend::~wxMediaBackend()
70 {
71 }
72
73 //---------------------------------------------------------------------------
74 // wxMediaCtrl::Create (file version)
75 // wxMediaCtrl::Create (URL version)
76 //
77 // Searches for a backend that is installed on the system (backends
78 // starting with lower characters in the alphabet are given priority),
79 // and creates the control from it
80 //
81 // This searches by searching the global RTTI hashtable, class by class,
82 // attempting to call CreateControl on each one found that is a derivative
83 // of wxMediaBackend - if it succeeded Create returns true, otherwise
84 // it keeps iterating through the hashmap.
85 //---------------------------------------------------------------------------
86 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
87 const wxString& fileName,
88 const wxPoint& pos,
89 const wxSize& size,
90 long style,
91 const wxString& szBackend,
92 const wxValidator& validator,
93 const wxString& name)
94 {
95 if(!szBackend.empty())
96 {
97 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
98
99 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
100 pos, size, style, validator, name))
101 {
102 m_imp = NULL;
103 return false;
104 }
105
106 if (!fileName.empty())
107 {
108 if (!Load(fileName))
109 {
110 delete m_imp;
111 m_imp = NULL;
112 return false;
113 }
114 }
115
116 SetBestFittingSize(size);
117 return true;
118 }
119 else
120 {
121 wxClassInfo::sm_classTable->BeginFind();
122
123 wxClassInfo* classInfo;
124
125 while((classInfo = NextBackend()) != NULL)
126 {
127 if(!DoCreate(classInfo, parent, id,
128 pos, size, style, validator, name))
129 continue;
130
131 if (!fileName.empty())
132 {
133 if (Load(fileName))
134 {
135 SetBestFittingSize(size);
136 return true;
137 }
138 else
139 delete m_imp;
140 }
141 else
142 {
143 SetBestFittingSize(size);
144 return true;
145 }
146 }
147
148 m_imp = NULL;
149 return false;
150 }
151 }
152
153 bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
154 const wxURI& location,
155 const wxPoint& pos,
156 const wxSize& size,
157 long style,
158 const wxString& szBackend,
159 const wxValidator& validator,
160 const wxString& name)
161 {
162 if(!szBackend.empty())
163 {
164 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
165 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
166 pos, size, style, validator, name))
167 {
168 m_imp = NULL;
169 return false;
170 }
171
172 if (!Load(location))
173 {
174 delete m_imp;
175 m_imp = NULL;
176 return false;
177 }
178
179 SetBestFittingSize(size);
180 return true;
181 }
182 else
183 {
184 wxClassInfo::sm_classTable->BeginFind();
185
186 wxClassInfo* classInfo;
187
188 while((classInfo = NextBackend()) != NULL)
189 {
190 if(!DoCreate(classInfo, parent, id,
191 pos, size, style, validator, name))
192 continue;
193
194 if (Load(location))
195 {
196 SetBestFittingSize(size);
197 return true;
198 }
199 else
200 delete m_imp;
201 }
202
203 m_imp = NULL;
204 return false;
205 }
206 }
207
208 //---------------------------------------------------------------------------
209 // wxMediaCtrl::DoCreate
210 //
211 // Attempts to create the control from a backend
212 //---------------------------------------------------------------------------
213 bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
214 wxWindow* parent, wxWindowID id,
215 const wxPoint& pos,
216 const wxSize& size,
217 long style,
218 const wxValidator& validator,
219 const wxString& name)
220 {
221 m_imp = (wxMediaBackend*)classInfo->CreateObject();
222
223 if( m_imp->CreateControl(this, parent, id, pos, size,
224 style, validator, name) )
225 {
226 return true;
227 }
228
229 delete m_imp;
230 return false;
231 }
232
233 //---------------------------------------------------------------------------
234 // wxMediaCtrl::NextBackend
235 //
236 //
237 // Search through the RTTI hashmap one at a
238 // time, attempting to create each derivative
239 // of wxMediaBackend
240 //
241 //
242 // STL isn't compatible with and will have a compilation error
243 // on a wxNode, however, wxHashTable::compatibility_iterator is
244 // incompatible with the old 2.4 stable version - but since
245 // we're in 2.5 only we don't need to worry about this
246 // static
247 //---------------------------------------------------------------------------
248 wxClassInfo* wxMediaCtrl::NextBackend()
249 {
250 wxHashTable::compatibility_iterator
251 node = wxClassInfo::sm_classTable->Next();
252 while (node)
253 {
254 wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
255 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
256 classInfo != CLASSINFO(wxMediaBackend) )
257 {
258 return classInfo;
259 }
260 node = wxClassInfo::sm_classTable->Next();
261 }
262
263 //
264 // Nope - couldn't successfully find one... fail
265 //
266 return NULL;
267 }
268
269
270 //---------------------------------------------------------------------------
271 // wxMediaCtrl Destructor
272 //
273 // Free up the backend if it exists
274 //---------------------------------------------------------------------------
275 wxMediaCtrl::~wxMediaCtrl()
276 {
277 if (m_imp)
278 delete m_imp;
279 }
280
281 //---------------------------------------------------------------------------
282 // wxMediaCtrl::Load (file version)
283 // wxMediaCtrl::Load (URL version)
284 //
285 // Here we call load of the backend - keeping
286 // track of whether it was successful or not - which
287 // will determine which later method calls work
288 //---------------------------------------------------------------------------
289 bool wxMediaCtrl::Load(const wxString& fileName)
290 {
291 if(m_imp)
292 return (m_bLoaded = m_imp->Load(fileName));
293 return false;
294 }
295
296 bool wxMediaCtrl::Load(const wxURI& location)
297 {
298 if(m_imp)
299 return (m_bLoaded = m_imp->Load(location));
300 return false;
301 }
302
303 //---------------------------------------------------------------------------
304 // wxMediaCtrl::Play
305 // wxMediaCtrl::Pause
306 // wxMediaCtrl::Stop
307 // wxMediaCtrl::GetPlaybackRate
308 // wxMediaCtrl::SetPlaybackRate
309 // wxMediaCtrl::Seek --> SetPosition
310 // wxMediaCtrl::Tell --> GetPosition
311 // wxMediaCtrl::Length --> GetDuration
312 // wxMediaCtrl::GetState
313 // wxMediaCtrl::DoGetBestSize
314 // wxMediaCtrl::SetVolume
315 // wxMediaCtrl::GetVolume
316 //
317 // 1) Check to see whether the backend exists and is loading
318 // 2) Call the backend's version of the method, returning success
319 // if the backend's version succeeds
320 //---------------------------------------------------------------------------
321 bool wxMediaCtrl::Play()
322 {
323 if(m_imp && m_bLoaded)
324 return m_imp->Play();
325 return 0;
326 }
327
328 bool wxMediaCtrl::Pause()
329 {
330 if(m_imp && m_bLoaded)
331 return m_imp->Pause();
332 return 0;
333 }
334
335 bool wxMediaCtrl::Stop()
336 {
337 if(m_imp && m_bLoaded)
338 return m_imp->Stop();
339 return 0;
340 }
341
342 double wxMediaCtrl::GetPlaybackRate()
343 {
344 if(m_imp && m_bLoaded)
345 return m_imp->GetPlaybackRate();
346 return 0;
347 }
348
349 bool wxMediaCtrl::SetPlaybackRate(double dRate)
350 {
351 if(m_imp && m_bLoaded)
352 return m_imp->SetPlaybackRate(dRate);
353 return false;
354 }
355
356 wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
357 {
358 wxFileOffset offset;
359
360 switch (mode)
361 {
362 case wxFromStart:
363 offset = where;
364 break;
365 case wxFromEnd:
366 offset = Length() - where;
367 break;
368 // case wxFromCurrent:
369 default:
370 offset = Tell() + where;
371 break;
372 }
373
374 if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
375 return offset;
376 return wxInvalidOffset;
377 }
378
379 wxFileOffset wxMediaCtrl::Tell()
380 {
381 if(m_imp && m_bLoaded)
382 return (wxFileOffset) m_imp->GetPosition().ToLong();
383 return wxInvalidOffset;
384 }
385
386 wxFileOffset wxMediaCtrl::Length()
387 {
388 if(m_imp && m_bLoaded)
389 return (wxFileOffset) m_imp->GetDuration().ToLong();
390 return wxInvalidOffset;
391 }
392
393 wxMediaState wxMediaCtrl::GetState()
394 {
395 if(m_imp && m_bLoaded)
396 return m_imp->GetState();
397 return wxMEDIASTATE_STOPPED;
398 }
399
400 wxSize wxMediaCtrl::DoGetBestSize() const
401 {
402 if(m_imp)
403 return m_imp->GetVideoSize();
404 return wxSize(0,0);
405 }
406
407 double wxMediaCtrl::GetVolume()
408 {
409 if(m_imp && m_bLoaded)
410 return m_imp->GetVolume();
411 return 0.0;
412 }
413
414 bool wxMediaCtrl::SetVolume(double dVolume)
415 {
416 if(m_imp && m_bLoaded)
417 return m_imp->SetVolume(dVolume);
418 return false;
419 }
420
421 //---------------------------------------------------------------------------
422 // wxMediaCtrl::DoMoveWindow
423 //
424 // 1) Call parent's version so that our control's window moves where
425 // it's supposed to
426 // 2) If the backend exists and is loaded, move the video
427 // of the media to where our control's window is now located
428 //---------------------------------------------------------------------------
429 void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
430 {
431 wxControl::DoMoveWindow(x,y,w,h);
432
433 if(m_imp)
434 m_imp->Move(x, y, w, h);
435 }
436
437 #include "wx/html/forcelnk.h"
438 FORCE_LINK(basewxmediabackends);
439
440 //---------------------------------------------------------------------------
441 // End of compilation guard and of file
442 //---------------------------------------------------------------------------
443 #endif //wxUSE_MEDIACTRL
444
445