]> git.saurik.com Git - wxWidgets.git/blame - src/common/mediactrlcmn.cpp
compilation fix for PCH-less compilation after last commit
[wxWidgets.git] / src / common / mediactrlcmn.cpp
CommitLineData
ff4aedc5 1/////////////////////////////////////////////////////////////////////////////
32d4c30a 2// Name: src/common/mediactrl.cpp
ff4aedc5
RN
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
557002cf
VZ
12// TODO: Platform specific backend defaults?
13
ff4aedc5
RN
14//===========================================================================
15// Definitions
16//===========================================================================
17
18//---------------------------------------------------------------------------
19// Pre-compiled header stuff
20//---------------------------------------------------------------------------
21
ff4aedc5
RN
22#include "wx/wxprec.h"
23
24#ifdef __BORLANDC__
32d4c30a
WS
25 #pragma hdrstop
26#endif
27
28#if wxUSE_MEDIACTRL
29
30#ifndef WX_PRECOMP
31 #include "wx/hash.h"
ff4aedc5
RN
32#endif
33
34//---------------------------------------------------------------------------
35// Includes
36//---------------------------------------------------------------------------
37#include "wx/mediactrl.h"
ff4aedc5
RN
38
39//===========================================================================
40//
41// Implementation
226ec5a7 42//
ff4aedc5
RN
43//===========================================================================
44
45//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
46// RTTI and Event implementations
47//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
48
f74fd79b 49IMPLEMENT_CLASS(wxMediaCtrl, wxControl)
557002cf
VZ
50DEFINE_EVENT_TYPE(wxEVT_MEDIA_STATECHANGED)
51DEFINE_EVENT_TYPE(wxEVT_MEDIA_PLAY)
52DEFINE_EVENT_TYPE(wxEVT_MEDIA_PAUSE)
f74fd79b
VZ
53IMPLEMENT_CLASS(wxMediaBackend, wxObject)
54IMPLEMENT_DYNAMIC_CLASS(wxMediaEvent, wxEvent)
55DEFINE_EVENT_TYPE(wxEVT_MEDIA_FINISHED)
56DEFINE_EVENT_TYPE(wxEVT_MEDIA_LOADED)
57DEFINE_EVENT_TYPE(wxEVT_MEDIA_STOP)
ff4aedc5
RN
58
59//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
60//
61// wxMediaCtrl
62//
63//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
64
38647faa
WS
65//---------------------------------------------------------------------------
66// wxMediaBackend Destructor
67//
68// This is here because the DARWIN gcc compiler badly screwed up and
69// needs the destructor implementation in the source
70//---------------------------------------------------------------------------
71wxMediaBackend::~wxMediaBackend()
72{
73}
74
ff4aedc5
RN
75//---------------------------------------------------------------------------
76// wxMediaCtrl::Create (file version)
77// wxMediaCtrl::Create (URL version)
78//
79// Searches for a backend that is installed on the system (backends
80// starting with lower characters in the alphabet are given priority),
81// and creates the control from it
226ec5a7 82//
ff4aedc5
RN
83// This searches by searching the global RTTI hashtable, class by class,
84// attempting to call CreateControl on each one found that is a derivative
9180b535 85// of wxMediaBackend - if it succeeded Create returns true, otherwise
ff4aedc5
RN
86// it keeps iterating through the hashmap.
87//---------------------------------------------------------------------------
88bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
89 const wxString& fileName,
226ec5a7 90 const wxPoint& pos,
ff4aedc5 91 const wxSize& size,
226ec5a7 92 long style,
ff4aedc5
RN
93 const wxString& szBackend,
94 const wxValidator& validator,
95 const wxString& name)
96{
97 if(!szBackend.empty())
98 {
38647faa
WS
99 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
100
101 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
102 pos, size, style, validator, name))
ff4aedc5
RN
103 {
104 m_imp = NULL;
105 return false;
106 }
107
108 if (!fileName.empty())
109 {
4ac61319 110 if (!Load(fileName))
ff4aedc5
RN
111 {
112 delete m_imp;
113 m_imp = NULL;
114 return false;
115 }
116 }
117
170acdc9 118 SetInitialSize(size);
ff4aedc5
RN
119 return true;
120 }
121 else
122 {
644cb537 123 wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
ff4aedc5 124
644cb537 125 const wxClassInfo* classInfo;
ff4aedc5 126
644cb537 127 while((classInfo = NextBackend(&it)) != NULL)
ff4aedc5 128 {
644cb537 129 wxLogMessage( classInfo->GetClassName() );
ff4aedc5
RN
130 if(!DoCreate(classInfo, parent, id,
131 pos, size, style, validator, name))
226ec5a7 132 continue;
ff4aedc5
RN
133
134 if (!fileName.empty())
135 {
4ac61319
RN
136 if (Load(fileName))
137 {
170acdc9 138 SetInitialSize(size);
ff4aedc5 139 return true;
4ac61319 140 }
ff4aedc5
RN
141 else
142 delete m_imp;
143 }
144 else
4ac61319 145 {
170acdc9 146 SetInitialSize(size);
ff4aedc5 147 return true;
4ac61319 148 }
ff4aedc5
RN
149 }
150
151 m_imp = NULL;
152 return false;
153 }
154}
155
156bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
38647faa
WS
157 const wxURI& location,
158 const wxPoint& pos,
159 const wxSize& size,
160 long style,
161 const wxString& szBackend,
162 const wxValidator& validator,
163 const wxString& name)
ff4aedc5
RN
164{
165 if(!szBackend.empty())
166 {
38647faa
WS
167 wxClassInfo* pClassInfo = wxClassInfo::FindClass(szBackend);
168 if(!pClassInfo || !DoCreate(pClassInfo, parent, id,
169 pos, size, style, validator, name))
ff4aedc5
RN
170 {
171 m_imp = NULL;
172 return false;
173 }
174
4ac61319 175 if (!Load(location))
ff4aedc5
RN
176 {
177 delete m_imp;
178 m_imp = NULL;
179 return false;
180 }
181
170acdc9 182 SetInitialSize(size);
ff4aedc5
RN
183 return true;
184 }
185 else
186 {
644cb537 187 wxClassInfo::const_iterator it = wxClassInfo::begin_classinfo();
ff4aedc5 188
644cb537 189 const wxClassInfo* classInfo;
ff4aedc5 190
644cb537 191 while((classInfo = NextBackend(&it)) != NULL)
ff4aedc5
RN
192 {
193 if(!DoCreate(classInfo, parent, id,
194 pos, size, style, validator, name))
226ec5a7 195 continue;
ff4aedc5 196
4ac61319
RN
197 if (Load(location))
198 {
170acdc9 199 SetInitialSize(size);
ff4aedc5 200 return true;
4ac61319 201 }
ff4aedc5
RN
202 else
203 delete m_imp;
ff4aedc5
RN
204 }
205
206 m_imp = NULL;
207 return false;
208 }
209}
210
211//---------------------------------------------------------------------------
212// wxMediaCtrl::DoCreate
213//
214// Attempts to create the control from a backend
215//---------------------------------------------------------------------------
644cb537 216bool wxMediaCtrl::DoCreate(const wxClassInfo* classInfo,
ff4aedc5 217 wxWindow* parent, wxWindowID id,
226ec5a7 218 const wxPoint& pos,
ff4aedc5 219 const wxSize& size,
226ec5a7 220 long style,
ff4aedc5
RN
221 const wxValidator& validator,
222 const wxString& name)
223{
224 m_imp = (wxMediaBackend*)classInfo->CreateObject();
226ec5a7 225
ff4aedc5
RN
226 if( m_imp->CreateControl(this, parent, id, pos, size,
227 style, validator, name) )
228 {
ff4aedc5
RN
229 return true;
230 }
226ec5a7 231
ff4aedc5
RN
232 delete m_imp;
233 return false;
234}
235
236//---------------------------------------------------------------------------
557002cf 237// wxMediaCtrl::NextBackend (static)
ff4aedc5
RN
238//
239//
240// Search through the RTTI hashmap one at a
241// time, attempting to create each derivative
242// of wxMediaBackend
226ec5a7 243//
ff4aedc5 244//
43e8916f 245// STL isn't compatible with and will have a compilation error
ff4aedc5
RN
246// on a wxNode, however, wxHashTable::compatibility_iterator is
247// incompatible with the old 2.4 stable version - but since
557002cf 248// we're in 2.5+ only we don't need to worry about the new version
ff4aedc5 249//---------------------------------------------------------------------------
644cb537 250const wxClassInfo* wxMediaCtrl::NextBackend(wxClassInfo::const_iterator* it)
ff4aedc5 251{
644cb537
MB
252 for ( wxClassInfo::const_iterator end = wxClassInfo::end_classinfo();
253 *it != end; ++(*it) )
ff4aedc5 254 {
644cb537 255 const wxClassInfo* classInfo = **it;
ff4aedc5
RN
256 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
257 classInfo != CLASSINFO(wxMediaBackend) )
258 {
259 return classInfo;
260 }
ff4aedc5
RN
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//---------------------------------------------------------------------------
275wxMediaCtrl::~wxMediaCtrl()
276{
277 if (m_imp)
278 delete m_imp;
279}
280
281//---------------------------------------------------------------------------
282// wxMediaCtrl::Load (file version)
283// wxMediaCtrl::Load (URL version)
c5191fbd
VZ
284// wxMediaCtrl::Load (URL & Proxy version)
285// wxMediaCtrl::Load (wxInputStream version)
ff4aedc5
RN
286//
287// Here we call load of the backend - keeping
288// track of whether it was successful or not - which
289// will determine which later method calls work
290//---------------------------------------------------------------------------
291bool wxMediaCtrl::Load(const wxString& fileName)
292{
293 if(m_imp)
294 return (m_bLoaded = m_imp->Load(fileName));
295 return false;
296}
297
298bool wxMediaCtrl::Load(const wxURI& location)
299{
300 if(m_imp)
301 return (m_bLoaded = m_imp->Load(location));
302 return false;
303}
304
c5191fbd
VZ
305bool wxMediaCtrl::Load(const wxURI& location, const wxURI& proxy)
306{
307 if(m_imp)
308 return (m_bLoaded = m_imp->Load(location, proxy));
309 return false;
310}
311
ff4aedc5
RN
312//---------------------------------------------------------------------------
313// wxMediaCtrl::Play
314// wxMediaCtrl::Pause
315// wxMediaCtrl::Stop
316// wxMediaCtrl::GetPlaybackRate
317// wxMediaCtrl::SetPlaybackRate
9180b535
RN
318// wxMediaCtrl::Seek --> SetPosition
319// wxMediaCtrl::Tell --> GetPosition
320// wxMediaCtrl::Length --> GetDuration
ff4aedc5
RN
321// wxMediaCtrl::GetState
322// wxMediaCtrl::DoGetBestSize
6f8c67e7
JS
323// wxMediaCtrl::SetVolume
324// wxMediaCtrl::GetVolume
c5191fbd
VZ
325// wxMediaCtrl::ShowInterface
326// wxMediaCtrl::GetDownloadProgress
327// wxMediaCtrl::GetDownloadTotal
226ec5a7 328//
ff4aedc5
RN
329// 1) Check to see whether the backend exists and is loading
330// 2) Call the backend's version of the method, returning success
331// if the backend's version succeeds
332//---------------------------------------------------------------------------
333bool wxMediaCtrl::Play()
334{
335 if(m_imp && m_bLoaded)
336 return m_imp->Play();
337 return 0;
338}
339
340bool wxMediaCtrl::Pause()
341{
342 if(m_imp && m_bLoaded)
343 return m_imp->Pause();
344 return 0;
345}
346
347bool wxMediaCtrl::Stop()
348{
349 if(m_imp && m_bLoaded)
350 return m_imp->Stop();
351 return 0;
352}
353
354double wxMediaCtrl::GetPlaybackRate()
355{
356 if(m_imp && m_bLoaded)
357 return m_imp->GetPlaybackRate();
358 return 0;
359}
360
361bool wxMediaCtrl::SetPlaybackRate(double dRate)
362{
363 if(m_imp && m_bLoaded)
364 return m_imp->SetPlaybackRate(dRate);
365 return false;
366}
367
9180b535 368wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
ff4aedc5 369{
9180b535
RN
370 wxFileOffset offset;
371
372 switch (mode)
373 {
374 case wxFromStart:
375 offset = where;
376 break;
377 case wxFromEnd:
378 offset = Length() - where;
379 break;
380// case wxFromCurrent:
381 default:
382 offset = Tell() + where;
383 break;
384 }
385
386 if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
387 return offset;
388 return wxInvalidOffset;
ff4aedc5
RN
389}
390
9180b535 391wxFileOffset wxMediaCtrl::Tell()
ff4aedc5
RN
392{
393 if(m_imp && m_bLoaded)
9180b535
RN
394 return (wxFileOffset) m_imp->GetPosition().ToLong();
395 return wxInvalidOffset;
ff4aedc5
RN
396}
397
9180b535 398wxFileOffset wxMediaCtrl::Length()
ff4aedc5
RN
399{
400 if(m_imp && m_bLoaded)
9180b535
RN
401 return (wxFileOffset) m_imp->GetDuration().ToLong();
402 return wxInvalidOffset;
ff4aedc5
RN
403}
404
405wxMediaState wxMediaCtrl::GetState()
406{
407 if(m_imp && m_bLoaded)
408 return m_imp->GetState();
409 return wxMEDIASTATE_STOPPED;
410}
411
412wxSize wxMediaCtrl::DoGetBestSize() const
413{
414 if(m_imp)
415 return m_imp->GetVideoSize();
c47addef 416 return wxSize(0,0);
ff4aedc5
RN
417}
418
32d4c30a 419double wxMediaCtrl::GetVolume()
6f8c67e7
JS
420{
421 if(m_imp && m_bLoaded)
422 return m_imp->GetVolume();
423 return 0.0;
424}
425
32d4c30a 426bool wxMediaCtrl::SetVolume(double dVolume)
6f8c67e7
JS
427{
428 if(m_imp && m_bLoaded)
429 return m_imp->SetVolume(dVolume);
430 return false;
431}
432
32d4c30a 433bool wxMediaCtrl::ShowPlayerControls(wxMediaCtrlPlayerControls flags)
c5191fbd
VZ
434{
435 if(m_imp)
436 return m_imp->ShowPlayerControls(flags);
437 return false;
438}
439
440wxFileOffset wxMediaCtrl::GetDownloadProgress()
441{
442 if(m_imp && m_bLoaded)
443 return (wxFileOffset) m_imp->GetDownloadProgress().ToLong();
444 return wxInvalidOffset;
445}
446
447wxFileOffset wxMediaCtrl::GetDownloadTotal()
448{
449 if(m_imp && m_bLoaded)
450 return (wxFileOffset) m_imp->GetDownloadTotal().ToLong();
451 return wxInvalidOffset;
452}
453
ff4aedc5
RN
454//---------------------------------------------------------------------------
455// wxMediaCtrl::DoMoveWindow
226ec5a7 456//
ff4aedc5
RN
457// 1) Call parent's version so that our control's window moves where
458// it's supposed to
459// 2) If the backend exists and is loaded, move the video
460// of the media to where our control's window is now located
461//---------------------------------------------------------------------------
462void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
463{
464 wxControl::DoMoveWindow(x,y,w,h);
465
466 if(m_imp)
467 m_imp->Move(x, y, w, h);
468}
469
0c81ef7f
SC
470//---------------------------------------------------------------------------
471// wxMediaCtrl::MacVisibilityChanged
472//---------------------------------------------------------------------------
473#ifdef __WXMAC__
474void wxMediaCtrl::MacVisibilityChanged()
475{
476 wxControl::MacVisibilityChanged();
32d4c30a 477
0c81ef7f 478 if(m_imp)
32d4c30a 479 m_imp->MacVisibilityChanged();
0c81ef7f
SC
480}
481#endif
482
bf354396
VZ
483//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
484//
485// wxMediaBackendCommonBase
486//
487//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
488
489void wxMediaBackendCommonBase::NotifyMovieSizeChanged()
490{
491 // our best size changed after opening a new file
492 m_ctrl->InvalidateBestSize();
493 m_ctrl->SetSize(m_ctrl->GetSize());
494
495 // if the parent of the control has a sizer ask it to refresh our size
496 wxWindow * const parent = m_ctrl->GetParent();
497 if ( parent->GetSizer() )
498 {
499 m_ctrl->GetParent()->Layout();
500 m_ctrl->GetParent()->Refresh();
501 m_ctrl->GetParent()->Update();
502 }
503}
504
505void wxMediaBackendCommonBase::NotifyMovieLoaded()
506{
507 NotifyMovieSizeChanged();
508
509 // notify about movie being fully loaded
510 QueueEvent(wxEVT_MEDIA_LOADED);
511}
512
513bool wxMediaBackendCommonBase::SendStopEvent()
514{
515 wxMediaEvent theEvent(wxEVT_MEDIA_STOP, m_ctrl->GetId());
516
517 return !m_ctrl->ProcessEvent(theEvent) || theEvent.IsAllowed();
518}
519
520void wxMediaBackendCommonBase::QueueEvent(wxEventType evtType)
521{
522 wxMediaEvent theEvent(evtType, m_ctrl->GetId());
523 m_ctrl->AddPendingEvent(theEvent);
524}
525
557002cf
VZ
526void wxMediaBackendCommonBase::QueuePlayEvent()
527{
528 QueueEvent(wxEVT_MEDIA_STATECHANGED);
529 QueueEvent(wxEVT_MEDIA_PLAY);
530}
531
532void wxMediaBackendCommonBase::QueuePauseEvent()
533{
534 QueueEvent(wxEVT_MEDIA_STATECHANGED);
535 QueueEvent(wxEVT_MEDIA_PAUSE);
536}
537
538void wxMediaBackendCommonBase::QueueStopEvent()
539{
540 QueueEvent(wxEVT_MEDIA_STATECHANGED);
541 QueueEvent(wxEVT_MEDIA_STOP);
542}
543
544
545//
546// Force link default backends in -
547// see http://wiki.wxwidgets.org/wiki.pl?RTTI
548//
02250fa1 549#include "wx/html/forcelnk.h"
ff4aedc5 550
557002cf 551#ifdef __WXMSW__ // MSW has huge backends so we do it seperately
f74fd79b
VZ
552FORCE_LINK(wxmediabackend_am)
553FORCE_LINK(wxmediabackend_wmp10)
557002cf 554#else
f74fd79b 555FORCE_LINK(basewxmediabackends)
557002cf 556#endif
ff4aedc5 557
32d4c30a 558#endif //wxUSE_MEDIACTRL