// Modified by:
// Created: 11/07/04
// RCS-ID: $Id$
-// Copyright: (c) Ryan Norton
+// Copyright: (c) 2004-2005 Ryan Norton, portions (c) 2004 Kevin Olliver
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
#if wxUSE_MEDIACTRL
+//---------------------------------------------------------------------------
+// Whether or not to use OSX 10.2's CreateMovieControl for native QuickTime
+// control - i.e. native positioning and event handling etc..
+//---------------------------------------------------------------------------
+#ifndef wxUSE_CREATEMOVIECONTROL
+# if defined( __WXMAC_OSX__ ) && ( MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_2 )
+# define wxUSE_CREATEMOVIECONTROL 1
+# else
+# define wxUSE_CREATEMOVIECONTROL 0
+# endif
+#endif
+
//===========================================================================
// BACKEND DECLARATIONS
//===========================================================================
#include <Gestalt.h>
#include <QuickTimeComponents.h> //Standard QT stuff
-//Determines whether version 6 of QT is installed
+//Determines whether version 4 of QT is installed (Pretty much for classic only)
Boolean _wxIsQuickTime4Installed (void)
{
short error;
return (error == noErr) && (((result >> 16) & 0xffff) >= 0x0400);
}
-class wxQTMediaBackend : public wxMediaBackend
+class WXDLLIMPEXP_MEDIA wxQTMediaBackend : public wxMediaBackend
{
public:
void FinishLoad();
wxSize m_bestSize; //Original movie size
+#ifdef __WXMAC_OSX__
struct MovieType** m_movie; //QT Movie handle/instance
+#else
+ Movie m_movie ;
+#endif
wxControl* m_ctrl; //Parent control
bool m_bVideo; //Whether or not we have video
class _wxQTTimer* m_timer; //Timer for streaming the movie
//
// wxQTMediaBackend
//
-// TODO: Use a less cludgy way to pause/get state/set state
-// TODO: Dynamically load from qtml.dll
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
};
//---------------------------------------------------------------------------
-// wxQTMediaBackend Destructor
+// wxQTMediaBackend Constructor
//
// Sets m_timer to NULL signifying we havn't loaded anything yet
//---------------------------------------------------------------------------
if(m_timer)
Cleanup();
- //Note that ExitMovies() is not neccessary...
+ //Note that ExitMovies() is not necessary...
ExitMovies();
}
const wxValidator& validator,
const wxString& name)
{
+ //Don't bother in Native control mode
+#if defined( __WXMAC__ ) && TARGET_API_MAC_OSX && ( MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_2 )
if (!_wxIsQuickTime4Installed())
return false;
+#endif
EnterMovies();
// Since we don't have a child window like most other
// backends, we don't need wxCLIP_CHILDREN
//
- if ( !ctrl->wxControl::Create(parent, id, pos, size,
+ if ( !
+
+#if wxUSE_CREATEMOVIECONTROL
+ ctrl->wxWindow::Create(parent, id, pos, size,
+ m_ctrl->MacRemoveBordersFromStyle(style),
+ name)
+#else
+ ctrl->wxControl::Create(parent, id, pos, size,
m_ctrl->MacRemoveBordersFromStyle(style),
- validator, name) )
+ validator, name)
+#endif
+ )
return false;
- //
- //Set our background color to black by default
- //
- ctrl->SetBackgroundColour(*wxBLACK);
+#if wxUSE_VALIDATORS
+ ctrl->SetValidator(validator);
+#endif
m_ctrl = ctrl;
return true;
// 1) Get an FSSpec from the Windows path name
// 2) Open the movie
// 3) Obtain the movie instance from the movie resource
-// 4)
+// 4) Close the movie resource
+// 5) Finish loading
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Load(const wxString& fileName)
{
short movieResFile;
FSSpec sfFile;
+ //FIXME:wxMacFilename2FSSpec crashes on empty string -
+ //does it crash on other strings too and should this
+ //"fix" be put in the carbon wxSound?
+ if (fileName.empty())
+ return false;
+
wxMacFilename2FSSpec( fileName , &sfFile );
if (OpenMovieFile (&sfFile, &movieResFile, fsRdPerm) != noErr)
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::Load (URL Version)
//
-// TODO
+// 1) Build an escaped URI from location
+// 2) Create a handle to store the URI string
+// 3) Put the URI string inside the handle
+// 4) Make a QuickTime URL data ref from the handle with the URI in it
+// 5) Clean up the URI string handle
+// 6) Do some prerolling
+// 7) Finish Loading
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Load(const wxURI& location)
{
return false;
//preroll movie for streaming
- //TODO:Async this?
+ //TODO:Async this using threads?
TimeValue timeNow;
Fixed playRate;
timeNow = GetMovieTime(m_movie, NULL);
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::FinishLoad
//
-// TODO
+// 1) Create the movie timer
+// 2) Get real size of movie for GetBestSize/sizers
+// 3) See if there is video in the movie, and if so then either
+// SetMovieGWorld if < 10.2 or use Native CreateMovieControl
+// 4) Set the movie time scale to something usable so that seeking
+// etc. will work correctly
+// 5) Refresh parent window
//---------------------------------------------------------------------------
void wxQTMediaBackend::FinishLoad()
{
m_bestSize.x = outRect.right - outRect.left;
m_bestSize.y = outRect.bottom - outRect.top;
-
+
//reparent movie/*AudioMediaCharacteristic*/
if(GetMovieIndTrackType(m_movie, 1,
VisualMediaCharacteristic,
movieTrackCharacteristic |
movieTrackEnabledOnly) != NULL)
{
+#if wxUSE_CREATEMOVIECONTROL
+ //
+ //Native CreateMovieControl QT control (Thanks to Kevin Olliver's
+ //wxQTMovie for some of this).
+ //
+ #define GetControlPeer(whatever) ctrl->m_peer
+ wxMediaCtrl* ctrl = (wxMediaCtrl*) m_ctrl;
+ Rect bounds = wxMacGetBoundsForControl(m_ctrl,
+ m_ctrl->GetPosition(),
+ m_ctrl->GetSize());
+
+ //Dispose of old control for new one
+ if (GetControlPeer(m_ctrl) && GetControlPeer(m_ctrl)->Ok() )
+ GetControlPeer(m_ctrl)->Dispose();
+
+ //Options-
+ //kMovieControlOptionXXX
+ //HideController - hide the movie controller
+ //LocateTopLeft - movie is pinned to top left rather than centered in the control
+ //EnableEditing - Allows programmatic editing and dragn'drop
+ //HandleEditingHI- Installs event stuff for edit menu - forces EnableEditing also
+ //SetKeysEnabled - Allows keyboard input
+ //ManuallyIdled - app handles movie idling rather than internal timer event loop
+ ::CreateMovieControl(
+ (WindowRef)
+ ctrl->MacGetTopLevelWindowRef(), //parent
+ &bounds, //control bounds
+ m_movie, //movie handle
+ kMovieControlOptionHideController
+ | kMovieControlOptionLocateTopLeft
+ | kMovieControlOptionSetKeysEnabled
+// | kMovieControlOptionManuallyIdled
+ , //flags
+ ctrl->m_peer->GetControlRefAddr() );
+
+ ::EmbedControl(ctrl->m_peer->GetControlRef(), (ControlRef)ctrl->GetParent()->GetHandle());
+#else
+ //
+ //"Emulation"
+ //
SetMovieGWorld(m_movie,
(CGrafPtr)
GetWindowPort(
m_ctrl->MacGetTopLevelWindowRef()
),
nil);
+#endif
}
//we want millisecond precision
//
//Here, if the parent of the control has a sizer - we
//tell it to recalculate the size of this control since
- //the user opened a seperate media file
+ //the user opened a separate media file
//
m_ctrl->InvalidateBestSize();
m_ctrl->GetParent()->Layout();
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::Play
//
-// TODO
+// 1) Start the QT movie
+// 2) Start the movie loading timer
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Play()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::Pause
//
-// TODO
+// 1) Stop the movie
+// 2) Stop the movie timer
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Pause()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::Stop
//
-// TODO
+// 1) Stop the movie
+// 2) Stop the movie timer
+// 3) Seek to the beginning of the movie
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Stop()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::GetPlaybackRate
//
-// TODO
+// 1) Get the movie playback rate from ::GetMovieRate
//---------------------------------------------------------------------------
double wxQTMediaBackend::GetPlaybackRate()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::SetPlaybackRate
//
-// TODO
+// 1) Convert dRate to Fixed and Set the movie rate through SetMovieRate
//---------------------------------------------------------------------------
bool wxQTMediaBackend::SetPlaybackRate(double dRate)
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::SetPosition
//
-// TODO
+// 1) Create a time record struct (TimeRecord) with appropriate values
+// 2) Pass struct to SetMovieTime
//---------------------------------------------------------------------------
bool wxQTMediaBackend::SetPosition(wxLongLong where)
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::GetPosition
//
-// TODO
+// Calls GetMovieTime
//---------------------------------------------------------------------------
wxLongLong wxQTMediaBackend::GetPosition()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::GetDuration
//
-// TODO
+// Calls GetMovieDuration
//---------------------------------------------------------------------------
wxLongLong wxQTMediaBackend::GetDuration()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::GetState
//
-// TODO
+// Determines the current state - the timer keeps track of whether or not
+// we are paused or stopped (if the timer is running we are playing)
//---------------------------------------------------------------------------
wxMediaState wxQTMediaBackend::GetState()
{
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::Cleanup
//
-// TODO
+// Diposes of the movie timer, Control if native, and stops and disposes
+// of the QT movie
//---------------------------------------------------------------------------
void wxQTMediaBackend::Cleanup()
{
delete m_timer;
m_timer = NULL;
+
+#if wxUSE_CREATEMOVIECONTROL
+ DisposeControl(((wxMediaCtrl*)m_ctrl)->m_peer->GetControlRef());
+#endif
StopMovie(m_movie);
DisposeMovie(m_movie);
}
//---------------------------------------------------------------------------
-// wxQTMediaBackend::Move
+// wxQTMediaBackend::GetVideoSize
//
-// TODO
+// Returns the actual size of the QT movie
//---------------------------------------------------------------------------
wxSize wxQTMediaBackend::GetVideoSize() const
{
//---------------------------------------------------------------------------
// wxQTMediaBackend::Move
//
-// TODO
+// We need to do this even when using native qt control because
+// CreateMovieControl is broken in this regard...
//---------------------------------------------------------------------------
void wxQTMediaBackend::Move(int x, int y, int w, int h)
{
+#if !wxUSE_CREATEMOVIECONTROL
if(m_timer)
{
+ if ( m_ctrl )
+ {
+ m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y);
+ }
+
Rect theRect = {y, x, y+h, x+w};
::SetMovieBox(m_movie, &theRect);
wxASSERT(::GetMoviesError() == noErr);
}
+#else
+ if(m_timer && m_ctrl)
+ {
+ m_ctrl->GetParent()->MacWindowToRootWindow(&x, &y);
+
+ ::MoveControl( (ControlRef) m_ctrl->GetHandle(), x, y );
+ m_ctrl->GetParent()->Refresh();
+ m_ctrl->GetParent()->Update();
+ }
+#endif
}
//in source file that contains stuff you don't directly use
-#include <wx/html/forcelnk.h>
+#include "wx/html/forcelnk.h"
FORCE_LINK_ME(basewxmediabackends);
#endif //wxUSE_MEDIACTRL