PageRenderTime 27ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/ExtLibs/wxWidgets/src/common/mediactrlcmn.cpp

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