#include "wx/sizer.h" //for positioning controls/wxBoxSizer
#include "wx/timer.h" //timer for updating status bar
#include "wx/textdlg.h" //for getting user text from OpenURL
+#include "wx/notebook.h" //for wxNotebook and putting movies in pages
// ----------------------------------------------------------------------------
// Bail out if the user doesn't want one of the
#error "This is a GUI sample"
#endif
-#if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER
-#error "menus, slider, mediactrl, and timers must all enabled for this sample!"
+#if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || !wxUSE_NOTEBOOK
+#error "menus, slider, mediactrl, notebook, and timers must all be enabled for this sample!"
#endif
+#define MEDIASTUFF \
+ if (!m_notebook || !m_notebook->GetCurrentPage()) return; \
+ wxMediaCtrl* m_mediactrl = ((MyNotebookPage*)m_notebook->GetCurrentPage())->m_mediactrl; \
+ wxSlider* m_slider = ((MyNotebookPage*)m_notebook->GetCurrentPage())->m_slider;
+
// ============================================================================
// Declarations
// ============================================================================
wxID_OPENFILE,
wxID_PLAY,
wxID_PAUSE,
+// wxID_CLOSE, [built-in to wxWidgets]
// wxID_STOP, [built-in to wxWidgets]
// wxID_ABOUT, [built-in to wxWidgets]
// wxID_EXIT, [built-in to wxWidgets]
// id for our slider
wxID_SLIDER,
+ wxID_NOTEBOOK,
// id for our wxMediaCtrl
wxID_MEDIACTRL
};
void OnPlay(wxCommandEvent& event);
void OnPause(wxCommandEvent& event);
void OnStop(wxCommandEvent& event);
+ void OnClose(wxCommandEvent& event);
// Slider event handlers
void OnSeek(wxCommandEvent& event);
// Media event handlers
void OnMediaStop(wxMediaEvent& event);
+
+ void OnPageChange(wxNotebookEvent& event);
+ void OnClosePage(wxCommandEvent& event);
private:
// Rebuild base status string (see Implementation)
void ResetStatus();
- wxMediaCtrl* m_mediactrl; //Our media control
- wxSlider* m_slider; //The slider below our media control
class MyTimer* m_timer; //Timer to write info to status bar
wxString m_basestatus; //Base status string (see ResetStatus())
- int m_nLoops; //Counter, incremented each time media loops
+ wxNotebook* m_notebook;
// So that mytimer can access MyFrame's members
friend class MyTimer;
};
+class MyNotebookPage : public wxPanel
+{
+ MyNotebookPage(wxNotebook* boook);
+
+
+public:
+ friend class MyFrame;
+ wxMediaCtrl* m_mediactrl; //Our media control
+ wxSlider* m_slider; //The slider below our media control
+};
+
// ----------------------------------------------------------------------------
// MyTimer
// ----------------------------------------------------------------------------
menuFile->Append(wxID_PAUSE, _T("P&ause"), _T("Pause playback"));
menuFile->Append(wxID_STOP, _T("&Stop"), _T("Stop playback"));
menuFile->AppendSeparator();
+ menuFile->Append(wxID_CLOSE, _T("&Close"), _T("Close current notebook page"));
+ menuFile->AppendSeparator();
menuFile->AppendCheckItem(wxID_LOOP,
_T("&Loop"),
_T("Loop Selected Media"));
SetMenuBar(menuBar);
- //
- // Create and attach the first/main sizer
- //
- wxBoxSizer* vertsizer = new wxBoxSizer(wxVERTICAL);
- this->SetSizer(vertsizer);
- this->SetAutoLayout(true);
-
- //
- // Create our media control
- //
- m_mediactrl = new wxMediaCtrl(this, wxID_MEDIACTRL);
- vertsizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
-
- //
- // Create our slider
- //
- m_slider = new wxSlider(this, wxID_SLIDER, 0, //init
- 0, //start
- 0, //end
- wxDefaultPosition, wxDefaultSize,
- wxSL_HORIZONTAL );
- vertsizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
-
-
- //
- // Create the second sizer which will position things
- // vertically -
- //
- // -------Menu----------
- // [m_mediactrl]
- //
- // [m_slider]
- //
- wxBoxSizer* horzsizer = new wxBoxSizer(wxHORIZONTAL);
- vertsizer->Add(horzsizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
+ m_notebook = new wxNotebook(this, wxID_NOTEBOOK);
//
// Create our status bar
(wxObjectEventFunction) (wxEventFunction)
(wxCommandEventFunction) &MyFrame::OnStop);
+ this->Connect(wxID_CLOSE, wxEVT_COMMAND_MENU_SELECTED,
+ (wxObjectEventFunction) (wxEventFunction)
+ (wxCommandEventFunction) &MyFrame::OnClosePage);
//
// Slider events
(wxObjectEventFunction) (wxEventFunction)
(wxMediaEventFunction) &MyFrame::OnMediaStop);
+ this->Connect(wxID_NOTEBOOK, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED,
+ (wxObjectEventFunction) (wxEventFunction)
+ (wxNotebookEventFunction) &MyFrame::OnPageChange);
+
//
// End of Events
//
- //
- // Set our loop counter to 0
- //
- m_nLoops = 0;
-
//
// Create a timer to update our status bar
//
// ----------------------------------------------------------------------------
void MyFrame::ResetStatus()
{
+
+ MEDIASTUFF
+
m_basestatus = wxString::Format(_T("Size(x,y):%i,%i ")
_T("Length(Seconds):%u Speed:%1.1fx"),
m_mediactrl->GetBestSize().x,
m_slider->SetRange(0, (int)(m_mediactrl->Length() / 1000));
- m_nLoops = 0;
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
void MyFrame::OnLoop(wxCommandEvent& WXUNUSED(event))
{
+ MEDIASTUFF
m_mediactrl->Loop( !m_mediactrl->IsLooped() );
}
if(fd.ShowModal() == wxID_OK)
{
+ m_notebook->AddPage(new MyNotebookPage(m_notebook), fd.GetPath(), true);
+
+ MEDIASTUFF
+
if( !m_mediactrl->Load(fd.GetPath()) )
wxMessageBox(wxT("Couldn't load file!"));
// ----------------------------------------------------------------------------
void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
{
+ MEDIASTUFF
if( !m_mediactrl->Play() )
wxMessageBox(wxT("Couldn't play movie!"));
}
// ----------------------------------------------------------------------------
void MyFrame::OnPause(wxCommandEvent& WXUNUSED(event))
{
+ MEDIASTUFF
if( !m_mediactrl->Pause() )
wxMessageBox(wxT("Couldn't pause movie!"));
}
// ----------------------------------------------------------------------------
void MyFrame::OnStop(wxCommandEvent& WXUNUSED(event))
{
+ MEDIASTUFF
if( !m_mediactrl->Stop() )
wxMessageBox(wxT("Couldn't stop movie!"));
}
// ----------------------------------------------------------------------------
void MyFrame::OnSeek(wxCommandEvent& WXUNUSED(event))
{
+ MEDIASTUFF
if( m_mediactrl->Seek( m_slider->GetValue() * 1000 ) == wxInvalidOffset )
wxMessageBox(wxT("Couldn't seek in movie!"));
}
// MyFrame::OnMediaStop
//
// Called when the media is about to stop playing.
-// Here we just increase our loop counter
// ----------------------------------------------------------------------------
void MyFrame::OnMediaStop(wxMediaEvent& WXUNUSED(event))
{
- ++m_nLoops;
+}
+
+void MyFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event))
+{
+ ResetStatus();
+}
+
+void MyFrame::OnClosePage(wxCommandEvent& WXUNUSED(event))
+{
+ int sel = m_notebook->GetSelection();
+
+ if (sel != wxNOT_FOUND)
+ {
+ m_notebook->DeletePage(sel);
+ }
}
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ----------------------------------------------------------------------------
void MyTimer::Notify()
{
- long lPosition = (long)( m_frame->m_mediactrl->Tell() / 1000 );
- m_frame->m_slider->SetValue(lPosition);
+
+ if (!m_frame->m_notebook || !m_frame->m_notebook->GetCurrentPage()) return;
+ wxMediaCtrl* m_mediactrl = ((MyNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_mediactrl;
+ wxSlider* m_slider = ((MyNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_slider;
+ if (!m_mediactrl) return;
+
+ long lPosition = (long)( m_mediactrl->Tell() / 1000 );
+ m_slider->SetValue(lPosition);
#if wxUSE_STATUSBAR
m_frame->SetStatusText(wxString::Format(
- _T("%s Pos:%u State:%s Loops:%i"),
+ _T("%s Pos:%u State:%s"),
m_frame->m_basestatus.c_str(),
(unsigned int)lPosition,
- wxGetMediaStateText(m_frame->m_mediactrl->GetState()),
- m_frame->m_nLoops
+ wxGetMediaStateText(m_mediactrl->GetState())
+
)
);
#endif
+
+}
+
+
+MyNotebookPage::MyNotebookPage(wxNotebook* theBook) :
+ wxPanel(theBook, wxID_ANY)
+{
+
+ //
+ // Create and attach the first/main sizer
+ //
+ wxBoxSizer* vertsizer = new wxBoxSizer(wxVERTICAL);
+ this->SetSizer(vertsizer);
+ this->SetAutoLayout(true);
+
+ //
+ // Create our media control
+ //
+ m_mediactrl = new wxMediaCtrl(this, wxID_MEDIACTRL);
+ vertsizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
+
+ //
+ // Create our slider
+ //
+ m_slider = new wxSlider(this, wxID_SLIDER, 0, //init
+ 0, //start
+ 0, //end
+ wxDefaultPosition, wxDefaultSize,
+ wxSL_HORIZONTAL );
+ vertsizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
+
+
+ //
+ // Create the second sizer which will position things
+ // vertically -
+ //
+ // -------Menu----------
+ // [m_mediactrl]
+ //
+ // [m_slider]
+ //
+ wxBoxSizer* horzsizer = new wxBoxSizer(wxHORIZONTAL);
+ vertsizer->Add(horzsizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
+
}
+
//
// End of MediaPlayer sample
//
//---------------------------------------------------------------------------
// QT Includes
//---------------------------------------------------------------------------
-#include "wx/timer.h"
#include <QuickTime/QuickTime.h>
#include "wx/cocoa/autorelease.h"
NSMovieView* m_movieview; //NSMovieView instance
wxControl* m_ctrl; //Parent control
bool m_bVideo; //Whether or not we have video
- class _wxQTTimer* m_timer; //Timer for streaming the movie
DECLARE_DYNAMIC_CLASS(wxQTMediaBackend);
};
IMPLEMENT_DYNAMIC_CLASS(wxQTMediaBackend, wxMediaBackend);
-//Time between timer calls
-#define MOVIE_DELAY 100
-
-// --------------------------------------------------------------------------
-// wxQTTimer - Handle Asyncronous Playing
-// --------------------------------------------------------------------------
-class _wxQTTimer : public wxTimer
-{
-public:
- _wxQTTimer(Movie movie, wxQTMediaBackend* parent) :
- m_movie(movie), m_bPaused(false), m_parent(parent)
- {
- }
-
- ~_wxQTTimer()
- {
- }
-
- bool GetPaused() {return m_bPaused;}
- void SetPaused(bool bPaused) {m_bPaused = bPaused;}
-
- //-----------------------------------------------------------------------
- // _wxQTTimer::Notify
- //
- // 1) Checks to see if the movie is done, and if not continues
- // streaming the movie
- // 2) Sends the wxEVT_MEDIA_STOP event if we have reached the end of
- // the movie.
- //-----------------------------------------------------------------------
- void Notify()
- {
- if (!m_bPaused)
- {
- if(!IsMovieDone(m_movie))
- MoviesTask(m_movie, MOVIE_DELAY);
- else
- {
- wxMediaEvent theEvent(wxEVT_MEDIA_STOP,
- m_parent->m_ctrl->GetId());
- m_parent->m_ctrl->ProcessEvent(theEvent);
-
- if(theEvent.IsAllowed())
- {
- Stop();
- m_parent->Stop();
- wxASSERT(::GetMoviesError() == noErr);
-
- //send the event to our child
- wxMediaEvent theEvent(wxEVT_MEDIA_FINISHED,
- m_parent->m_ctrl->GetId());
- m_parent->m_ctrl->ProcessEvent(theEvent);
- }
- }
- }
- }
-
-protected:
- Movie m_movie; //Our movie instance
- bool m_bPaused; //Whether we are paused or not
- wxQTMediaBackend* m_parent; //Backend pointer
-};
-
//---------------------------------------------------------------------------
// wxQTMediaBackend Constructor
//
// Sets m_timer to NULL signifying we havn't loaded anything yet
//---------------------------------------------------------------------------
-wxQTMediaBackend::wxQTMediaBackend() : m_timer(NULL)
+wxQTMediaBackend::wxQTMediaBackend()
{
}
//---------------------------------------------------------------------------
wxQTMediaBackend::~wxQTMediaBackend()
{
- if(m_timer)
- Cleanup();
+ Cleanup();
//Note that ExitMovies() is not neccessary...
- ExitMovies();
+ ::ExitMovies();
}
//---------------------------------------------------------------------------
wxMediaCtrl* ctrl = (wxMediaCtrl*) inctrl;
//Create the control base
- wxASSERT(ctrl->CreateBase(parent,wid,pos,size,style, validator, size));
+ wxASSERT(ctrl->CreateBase(parent,wid,pos,size,style, validator, name));
//Create the NSMovieView
ctrl->SetNSView(NULL);
- NSView* theView = [[NSMovieView alloc] initWithFrame: ctrl->MakeDefaultNSRect(size)];
+ NSMovieView* theView = [[NSMovieView alloc] initWithFrame: ctrl->MakeDefaultNSRect(size)];
ctrl->SetNSView(theView);
[theView release];
ctrl->SetInitialFrameRect(pos,size);
}
+ [theView showController:false adjustingSize:true];
m_movieview = theView;
m_ctrl = ctrl;
return true;
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Load(const wxURI& location)
{
- if(m_timer)
- Cleanup();
+ Cleanup();
wxString theURI = location.BuildURI();
m_movie = (Movie) [[m_movieview movie] QTMovie];
- //preroll movie for streaming
- //TODO:Async this using threads?
- TimeValue timeNow;
- Fixed playRate;
- timeNow = GetMovieTime(m_movie, NULL);
- playRate = GetMoviePreferredRate(m_movie);
- PrePrerollMovie(m_movie, timeNow, playRate, NULL, NULL);
- PrerollMovie(m_movie, timeNow, playRate);
- SetMovieRate(m_movie, playRate);
-
FinishLoad();
return ::GetMoviesError() == noErr;
//---------------------------------------------------------------------------
// wxQTMediaBackend::FinishLoad
-//
-// 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_timer = new _wxQTTimer(m_movie, (wxQTMediaBackend*) this);
- wxASSERT(m_timer);
-
//get the real size of the movie
Rect outRect;
::GetMovieNaturalBoundsRect (m_movie, &outRect);
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Play()
{
- ::StartMovie(m_movie);
- m_timer->SetPaused(false);
- m_timer->Start(MOVIE_DELAY, wxTIMER_CONTINUOUS);
+ [m_movieview start:NULL];
return ::GetMoviesError() == noErr;
}
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Pause()
{
- ::StopMovie(m_movie);
- m_timer->SetPaused(true);
- m_timer->Stop();
+ [m_movieview stop:NULL];
return ::GetMoviesError() == noErr;
}
//---------------------------------------------------------------------------
bool wxQTMediaBackend::Stop()
{
- m_timer->SetPaused(false);
- m_timer->Stop();
-
- ::StopMovie(m_movie);
- if(::GetMoviesError() != noErr)
- return false;
-
- ::GoToBeginningOfMovie(m_movie);
+ [m_movieview stop:NULL];
+ [m_movieview gotoBeginning:NULL];
return ::GetMoviesError() == noErr;
}
//---------------------------------------------------------------------------
wxMediaState wxQTMediaBackend::GetState()
{
- if ( !m_timer || (m_timer->IsRunning() == false &&
- m_timer->GetPaused() == false) )
- return wxMEDIASTATE_STOPPED;
-
- if( m_timer->IsRunning() == true )
+ if ( [m_movieview isPlaying] )
return wxMEDIASTATE_PLAYING;
+
+ if( wxQTMediaBackend::GetPosition() == 0 )
+ return wxMEDIASTATE_STOPPED;
else
return wxMEDIASTATE_PAUSED;
}
//---------------------------------------------------------------------------
void wxQTMediaBackend::Cleanup()
{
- delete m_timer;
- m_timer = NULL;
-
- [[m_movieview movie] release];
- [m_movieview setMovie:NULL];
+ if([m_movieview movie])
+ {
+ [[m_movieview movie] release];
+ [m_movieview setMovie:NULL];
+ }
}
//---------------------------------------------------------------------------
if ( !
#if wxUSE_CREATEMOVIECONTROL
- ctrl->wxControl::Create(parent, id, pos, size,
- m_ctrl->MacRemoveBordersFromStyle(style),
- validator, name)
-#else
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)
#endif
)
return false;
+#if wxUSE_VALIDATORS
+ ctrl->SetValidator(validator);
+#endif
+
m_ctrl = ctrl;
return true;
}
//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());
//ManuallyIdled - app handles movie idling rather than internal timer event loop
::CreateMovieControl(
(WindowRef)
- m_ctrl->MacGetTopLevelWindowRef(), //parent
+ ctrl->MacGetTopLevelWindowRef(), //parent
&bounds, //control bounds
m_movie, //movie handle
kMovieControlOptionHideController
| kMovieControlOptionSetKeysEnabled
// | kMovieControlOptionManuallyIdled
, //flags
- GetControlPeer(m_ctrl)->GetControlRefAddr() );
+ ctrl->m_peer->GetControlRefAddr() );
- ::EmbedControl(GetControlPeer(m_ctrl)->GetControlRef(),
- (ControlRef) m_ctrl->GetParent()->GetHandle());
+ ::EmbedControl(ctrl->m_peer->GetControlRef(), (ControlRef)ctrl->GetParent()->GetHandle());
#else
//
//"Emulation"
m_timer = NULL;
#if wxUSE_CREATEMOVIECONTROL
- DisposeControl(GetControlPeer(m_ctrl)->GetControlRef());
+ DisposeControl(((wxMediaCtrl*)m_ctrl)->m_peer->GetControlRef());
#endif
StopMovie(m_movie);