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