]> git.saurik.com Git - wxWidgets.git/blame - src/common/mediactrlcmn.cpp
use popen() instead of wxExecute(), it works inside wxYield() unlike the latter
[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
f8fe8a9e 111 wxClassInfo* classInfo;
ff4aedc5 112
f8fe8a9e 113 while((classInfo = NextBackend()) != NULL)
ff4aedc5
RN
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
136 m_imp = NULL;
137 return false;
138 }
139}
140
141bool wxMediaCtrl::Create(wxWindow* parent, wxWindowID id,
142 const wxURI& location,
226ec5a7 143 const wxPoint& pos,
ff4aedc5 144 const wxSize& size,
226ec5a7 145 long style,
ff4aedc5
RN
146 const wxString& szBackend,
147 const wxValidator& validator,
148 const wxString& name)
149{
150 if(!szBackend.empty())
151 {
152 if(!DoCreate(wxClassInfo::FindClass(szBackend), parent, id,
153 pos, size, style, validator, name))
154 {
155 m_imp = NULL;
156 return false;
157 }
158
4ac61319 159 if (!Load(location))
ff4aedc5
RN
160 {
161 delete m_imp;
162 m_imp = NULL;
163 return false;
164 }
165
4ac61319 166 SetBestFittingSize(size);
ff4aedc5
RN
167 return true;
168 }
169 else
170 {
171 wxClassInfo::sm_classTable->BeginFind();
172
f8fe8a9e 173 wxClassInfo* classInfo;
ff4aedc5 174
f8fe8a9e 175 while((classInfo = NextBackend()) != NULL)
ff4aedc5
RN
176 {
177 if(!DoCreate(classInfo, parent, id,
178 pos, size, style, validator, name))
226ec5a7 179 continue;
ff4aedc5 180
4ac61319
RN
181 if (Load(location))
182 {
183 SetBestFittingSize(size);
ff4aedc5 184 return true;
4ac61319 185 }
ff4aedc5
RN
186 else
187 delete m_imp;
ff4aedc5
RN
188 }
189
190 m_imp = NULL;
191 return false;
192 }
193}
194
195//---------------------------------------------------------------------------
196// wxMediaCtrl::DoCreate
197//
198// Attempts to create the control from a backend
199//---------------------------------------------------------------------------
200bool wxMediaCtrl::DoCreate(wxClassInfo* classInfo,
201 wxWindow* parent, wxWindowID id,
226ec5a7 202 const wxPoint& pos,
ff4aedc5 203 const wxSize& size,
226ec5a7 204 long style,
ff4aedc5
RN
205 const wxValidator& validator,
206 const wxString& name)
207{
208 m_imp = (wxMediaBackend*)classInfo->CreateObject();
226ec5a7 209
ff4aedc5
RN
210 if( m_imp->CreateControl(this, parent, id, pos, size,
211 style, validator, name) )
212 {
ff4aedc5
RN
213 return true;
214 }
226ec5a7 215
ff4aedc5
RN
216 delete m_imp;
217 return false;
218}
219
220//---------------------------------------------------------------------------
221// wxMediaCtrl::NextBackend
222//
223//
224// Search through the RTTI hashmap one at a
225// time, attempting to create each derivative
226// of wxMediaBackend
226ec5a7 227//
ff4aedc5
RN
228//
229// STL isn't compatable with and will have a compilation error
230// on a wxNode, however, wxHashTable::compatibility_iterator is
231// incompatible with the old 2.4 stable version - but since
232// we're in 2.5 only we don't need to worry about this
233// static
234//---------------------------------------------------------------------------
235wxClassInfo* wxMediaCtrl::NextBackend()
236{
237 wxHashTable::compatibility_iterator
238 node = wxClassInfo::sm_classTable->Next();
239 while (node)
240 {
241 wxClassInfo* classInfo = (wxClassInfo *)node->GetData();
242 if ( classInfo->IsKindOf(CLASSINFO(wxMediaBackend)) &&
243 classInfo != CLASSINFO(wxMediaBackend) )
244 {
245 return classInfo;
246 }
247 node = wxClassInfo::sm_classTable->Next();
248 }
249
250 //
251 // Nope - couldn't successfully find one... fail
252 //
253 return NULL;
254}
255
256
257//---------------------------------------------------------------------------
258// wxMediaCtrl Destructor
259//
260// Free up the backend if it exists
261//---------------------------------------------------------------------------
262wxMediaCtrl::~wxMediaCtrl()
263{
264 if (m_imp)
265 delete m_imp;
266}
267
268//---------------------------------------------------------------------------
269// wxMediaCtrl::Load (file version)
270// wxMediaCtrl::Load (URL version)
271//
272// Here we call load of the backend - keeping
273// track of whether it was successful or not - which
274// will determine which later method calls work
275//---------------------------------------------------------------------------
276bool wxMediaCtrl::Load(const wxString& fileName)
277{
278 if(m_imp)
279 return (m_bLoaded = m_imp->Load(fileName));
280 return false;
281}
282
283bool wxMediaCtrl::Load(const wxURI& location)
284{
285 if(m_imp)
286 return (m_bLoaded = m_imp->Load(location));
287 return false;
288}
289
290//---------------------------------------------------------------------------
291// wxMediaCtrl::Play
292// wxMediaCtrl::Pause
293// wxMediaCtrl::Stop
294// wxMediaCtrl::GetPlaybackRate
295// wxMediaCtrl::SetPlaybackRate
9180b535
RN
296// wxMediaCtrl::Seek --> SetPosition
297// wxMediaCtrl::Tell --> GetPosition
298// wxMediaCtrl::Length --> GetDuration
ff4aedc5
RN
299// wxMediaCtrl::GetState
300// wxMediaCtrl::DoGetBestSize
226ec5a7 301//
ff4aedc5
RN
302// 1) Check to see whether the backend exists and is loading
303// 2) Call the backend's version of the method, returning success
304// if the backend's version succeeds
305//---------------------------------------------------------------------------
306bool wxMediaCtrl::Play()
307{
308 if(m_imp && m_bLoaded)
309 return m_imp->Play();
310 return 0;
311}
312
313bool wxMediaCtrl::Pause()
314{
315 if(m_imp && m_bLoaded)
316 return m_imp->Pause();
317 return 0;
318}
319
320bool wxMediaCtrl::Stop()
321{
322 if(m_imp && m_bLoaded)
323 return m_imp->Stop();
324 return 0;
325}
326
327double wxMediaCtrl::GetPlaybackRate()
328{
329 if(m_imp && m_bLoaded)
330 return m_imp->GetPlaybackRate();
331 return 0;
332}
333
334bool wxMediaCtrl::SetPlaybackRate(double dRate)
335{
336 if(m_imp && m_bLoaded)
337 return m_imp->SetPlaybackRate(dRate);
338 return false;
339}
340
9180b535 341wxFileOffset wxMediaCtrl::Seek(wxFileOffset where, wxSeekMode mode)
ff4aedc5 342{
9180b535
RN
343 wxFileOffset offset;
344
345 switch (mode)
346 {
347 case wxFromStart:
348 offset = where;
349 break;
350 case wxFromEnd:
351 offset = Length() - where;
352 break;
353// case wxFromCurrent:
354 default:
355 offset = Tell() + where;
356 break;
357 }
358
359 if(m_imp && m_bLoaded && m_imp->SetPosition(offset))
360 return offset;
361 return wxInvalidOffset;
ff4aedc5
RN
362}
363
9180b535 364wxFileOffset wxMediaCtrl::Tell()
ff4aedc5 365{
9180b535 366 //FIXME
ff4aedc5 367 if(m_imp && m_bLoaded)
9180b535
RN
368 return (wxFileOffset) m_imp->GetPosition().ToLong();
369 return wxInvalidOffset;
ff4aedc5
RN
370}
371
9180b535 372wxFileOffset wxMediaCtrl::Length()
ff4aedc5 373{
9180b535 374 //FIXME
ff4aedc5 375 if(m_imp && m_bLoaded)
9180b535
RN
376 return (wxFileOffset) m_imp->GetDuration().ToLong();
377 return wxInvalidOffset;
ff4aedc5
RN
378}
379
380wxMediaState wxMediaCtrl::GetState()
381{
382 if(m_imp && m_bLoaded)
383 return m_imp->GetState();
384 return wxMEDIASTATE_STOPPED;
385}
386
387wxSize wxMediaCtrl::DoGetBestSize() const
388{
389 if(m_imp)
390 return m_imp->GetVideoSize();
c47addef 391 return wxSize(0,0);
ff4aedc5
RN
392}
393
394//---------------------------------------------------------------------------
395// wxMediaCtrl::DoMoveWindow
226ec5a7 396//
ff4aedc5
RN
397// 1) Call parent's version so that our control's window moves where
398// it's supposed to
399// 2) If the backend exists and is loaded, move the video
400// of the media to where our control's window is now located
401//---------------------------------------------------------------------------
402void wxMediaCtrl::DoMoveWindow(int x, int y, int w, int h)
403{
404 wxControl::DoMoveWindow(x,y,w,h);
405
406 if(m_imp)
407 m_imp->Move(x, y, w, h);
408}
409
ff4aedc5
RN
410//DARWIN gcc compiler badly screwed up - needs destructor impl in source
411wxMediaBackend::~wxMediaBackend()
412{ }
02250fa1 413#include "wx/html/forcelnk.h"
ff4aedc5
RN
414FORCE_LINK(basewxmediabackends);
415
416//---------------------------------------------------------------------------
417// End of compilation guard and of file
418//---------------------------------------------------------------------------
419#endif //wxUSE_MEDIACTRL
420
421