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