]> git.saurik.com Git - wxWidgets.git/blame - src/common/mediactrlcmn.cpp
Applied patch [ 1192917 ] Grids with no row or col headers cause AV under wxGTK
[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
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
RN
109 {
110 delete m_imp;
111 m_imp = NULL;
112 return false;
113 }
114 }
115
4ac61319 116 SetBestFittingSize(size);
ff4aedc5
RN
117 return true;
118 }
119 else
120 {
121 wxClassInfo::sm_classTable->BeginFind();
122
f8fe8a9e 123 wxClassInfo* classInfo;
ff4aedc5 124
f8fe8a9e 125 while((classInfo = NextBackend()) != NULL)
ff4aedc5
RN
126 {
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 {
135 SetBestFittingSize(size);
ff4aedc5 136 return true;
4ac61319 137 }
ff4aedc5
RN
138 else
139 delete m_imp;
140 }
141 else
4ac61319
RN
142 {
143 SetBestFittingSize(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
RN
173 {
174 delete m_imp;
175 m_imp = NULL;
176 return false;
177 }
178
4ac61319 179 SetBestFittingSize(size);
ff4aedc5
RN
180 return true;
181 }
182 else
183 {
184 wxClassInfo::sm_classTable->BeginFind();
185
f8fe8a9e 186 wxClassInfo* classInfo;
ff4aedc5 187
f8fe8a9e 188 while((classInfo = NextBackend()) != NULL)
ff4aedc5
RN
189 {
190 if(!DoCreate(classInfo, parent, id,
191 pos, size, style, validator, name))
226ec5a7 192 continue;
ff4aedc5 193
4ac61319
RN
194 if (Load(location))
195 {
196 SetBestFittingSize(size);
ff4aedc5 197 return true;
4ac61319 198 }
ff4aedc5
RN
199 else
200 delete m_imp;
ff4aedc5
RN
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//---------------------------------------------------------------------------
213bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
214 wxWindow* parent, wxWindowID id,
226ec5a7 215 const wxPoint& pos,
ff4aedc5 216 const wxSize& size,
226ec5a7 217 long style,
ff4aedc5
RN
218 const wxValidator& validator,
219 const wxString& name)
220{
221 m_imp = (wxMediaBackend*)classInfo->CreateObject();
226ec5a7 222
ff4aedc5
RN
223 if( m_imp->CreateControl(this, parent, id, pos, size,
224 style, validator, name) )
225 {
ff4aedc5
RN
226 return true;
227 }
226ec5a7 228
ff4aedc5
RN
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
226ec5a7 240//
ff4aedc5 241//
43e8916f 242// STL isn't compatible with and will have a compilation error
ff4aedc5
RN
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//---------------------------------------------------------------------------
248wxClassInfo* 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//---------------------------------------------------------------------------
275wxMediaCtrl::~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//---------------------------------------------------------------------------
289bool wxMediaCtrl::Load(const wxString& fileName)
290{
291 if(m_imp)
292 return (m_bLoaded = m_imp->Load(fileName));
293 return false;
294}
295
296bool 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
9180b535
RN
309// wxMediaCtrl::Seek --> SetPosition
310// wxMediaCtrl::Tell --> GetPosition
311// wxMediaCtrl::Length --> GetDuration
ff4aedc5
RN
312// wxMediaCtrl::GetState
313// wxMediaCtrl::DoGetBestSize
6f8c67e7
JS
314// wxMediaCtrl::SetVolume
315// wxMediaCtrl::GetVolume
226ec5a7 316//
ff4aedc5
RN
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//---------------------------------------------------------------------------
321bool wxMediaCtrl::Play()
322{
323 if(m_imp && m_bLoaded)
324 return m_imp->Play();
325 return 0;
326}
327
328bool wxMediaCtrl::Pause()
329{
330 if(m_imp && m_bLoaded)
331 return m_imp->Pause();
332 return 0;
333}
334
335bool wxMediaCtrl::Stop()
336{
337 if(m_imp && m_bLoaded)
338 return m_imp->Stop();
339 return 0;
340}
341
342double wxMediaCtrl::GetPlaybackRate()
343{
344 if(m_imp && m_bLoaded)
345 return m_imp->GetPlaybackRate();
346 return 0;
347}
348
349bool wxMediaCtrl::SetPlaybackRate(double dRate)
350{
351 if(m_imp && m_bLoaded)
352 return m_imp->SetPlaybackRate(dRate);
353 return false;
354}
355
9180b535 356wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
ff4aedc5 357{
9180b535
RN
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;
ff4aedc5
RN
377}
378
9180b535 379wxFileOffset wxMediaCtrl::Tell()
ff4aedc5
RN
380{
381 if(m_imp && m_bLoaded)
9180b535
RN
382 return (wxFileOffset) m_imp->GetPosition().ToLong();
383 return wxInvalidOffset;
ff4aedc5
RN
384}
385
9180b535 386wxFileOffset wxMediaCtrl::Length()
ff4aedc5
RN
387{
388 if(m_imp && m_bLoaded)
9180b535
RN
389 return (wxFileOffset) m_imp->GetDuration().ToLong();
390 return wxInvalidOffset;
ff4aedc5
RN
391}
392
393wxMediaState wxMediaCtrl::GetState()
394{
395 if(m_imp && m_bLoaded)
396 return m_imp->GetState();
397 return wxMEDIASTATE_STOPPED;
398}
399
400wxSize wxMediaCtrl::DoGetBestSize() const
401{
402 if(m_imp)
403 return m_imp->GetVideoSize();
c47addef 404 return wxSize(0,0);
ff4aedc5
RN
405}
406
6f8c67e7
JS
407double wxMediaCtrl::GetVolume()
408{
409 if(m_imp && m_bLoaded)
410 return m_imp->GetVolume();
411 return 0.0;
412}
413
414bool wxMediaCtrl::SetVolume(double dVolume)
415{
416 if(m_imp && m_bLoaded)
417 return m_imp->SetVolume(dVolume);
418 return false;
419}
420
ff4aedc5
RN
421//---------------------------------------------------------------------------
422// wxMediaCtrl::DoMoveWindow
226ec5a7 423//
ff4aedc5
RN
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//---------------------------------------------------------------------------
429void 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
02250fa1 437#include "wx/html/forcelnk.h"
ff4aedc5
RN
438FORCE_LINK(basewxmediabackends);
439
440//---------------------------------------------------------------------------
441// End of compilation guard and of file
442//---------------------------------------------------------------------------
443#endif //wxUSE_MEDIACTRL
444
445