X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/af82bc101e4e06fc54620476a3c52f1e0e90469d..814028444d682b23af3809227cd485f4bebc1286:/samples/mediaplayer/mediaplayer.cpp?ds=sidebyside diff --git a/samples/mediaplayer/mediaplayer.cpp b/samples/mediaplayer/mediaplayer.cpp index 998dcce962..0b56f3f53f 100644 --- a/samples/mediaplayer/mediaplayer.cpp +++ b/samples/mediaplayer/mediaplayer.cpp @@ -29,11 +29,7 @@ // 1) Certain backends can't play the same media file at the same time (MCI, // Cocoa NSMovieView-Quicktime). // 2) Positioning on Mac Carbon is messed up if put in a sub-control like a -// Notebook (like this sample does) on OS versions < 10.2. -// 3) On unix the video may not work - it only checks for a few video -// sinks - xvimagesink, ximagesink and whatever gnome preferences has - -// if gnome preferences is not available or you have a different video -// sink then those two (such as sdlvideosink) then you'll get black video +// Notebook (like this sample does). // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // ============================================================================ @@ -58,32 +54,41 @@ // Headers // ---------------------------------------------------------------------------- -#include "wx/mediactrl.h" //for wxMediaCtrl -#include "wx/filedlg.h" //for opening files from OpenFile -#include "wx/slider.h" //for a slider for seeking within media -#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/Debug -#include "wx/notebook.h" //for wxNotebook and putting movies in pages -#include "wx/cmdline.h" //for wxCmdLineParser (optional) -#include "wx/listctrl.h" //for wxListCtrl -#include "wx/dnd.h" //drag and drop for the playlist -#include "wx/filename.h" //For wxFileName::GetName() -#include "wx/config.h" //for native wxConfig +#include "wx/mediactrl.h" // for wxMediaCtrl +#include "wx/filedlg.h" // for opening files from OpenFile +#include "wx/slider.h" // for a slider for seeking within media +#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/Debug +#include "wx/notebook.h" // for wxNotebook and putting movies in pages +#include "wx/cmdline.h" // for wxCmdLineParser (optional) +#include "wx/listctrl.h" // for wxListCtrl +#include "wx/dnd.h" // drag and drop for the playlist +#include "wx/filename.h" // For wxFileName::GetName() +#include "wx/config.h" // for native wxConfig + +// Under MSW we have several different backends but when linking statically +// they may be discarded by the linker (this definitely happens with MSVC) so +// force linking them. You don't have to do this in your code if you don't plan +// to use them, of course. +#if defined(__WXMSW__) && !defined(WXUSINGDLL) + #include "wx/link.h" + wxFORCE_LINK_MODULE(wxmediabackend_am) + wxFORCE_LINK_MODULE(wxmediabackend_qt) + wxFORCE_LINK_MODULE(wxmediabackend_wmp10) +#endif // static wxMSW build + +#ifndef wxHAS_IMAGES_IN_RESOURCES + #include "../sample.xpm" +#endif // ---------------------------------------------------------------------------- // Bail out if the user doesn't want one of the // things we need // ---------------------------------------------------------------------------- -// RN: I'm not sure why this is here - even minimal doesn't check for -// wxUSE_GUI. I may have added it myself though... -#if !wxUSE_GUI -#error "This is a GUI sample" -#endif - #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || \ - !wxUSE_NOTEBOOK || !wxUSE_LISTCTRL || !wxUSE_DRAG_AND_DROP + !wxUSE_NOTEBOOK || !wxUSE_LISTCTRL #error "Not all required elements are enabled. Please modify setup.h!" #endif @@ -116,6 +121,8 @@ enum // wxID_EXIT, [built-in to wxWidgets] // Control event IDs wxID_SLIDER, + wxID_PBSLIDER, + wxID_VOLSLIDER, wxID_NOTEBOOK, wxID_MEDIACTRL, wxID_BUTTONNEXT, @@ -136,7 +143,7 @@ class wxMediaPlayerApp : public wxApp { public: #ifdef __WXMAC__ - virtual void MacOpenFile(const wxString & fileName ); + virtual void MacOpenFiles(const wxArrayString & fileNames ); #endif virtual bool OnInit(); @@ -179,9 +186,6 @@ public: void OnSelectBackend(wxCommandEvent& event); - // Notebook event handlers - void OnPageChange(wxNotebookEvent& event); - // Key event handlers void OnKeyDown(wxKeyEvent& event); @@ -198,25 +202,14 @@ public: void OnClose(wxCloseEvent& event); private: - // Rebuild base status string (see Implementation) - void ResetStatus(); - // Common open file code void OpenFile(bool bNewPage); void OpenURL(bool bNewPage); void DoOpenFile(const wxString& path, bool bNewPage); void DoPlayFile(const wxString& path); - // Get the controls of current notebook page - wxMediaCtrl* GetCurrentMediaCtrl(); - wxSlider* GetCurrentSlider(); - wxGauge* GetCurrentGauge(); - - int m_nLastFileId; //List ID of played file in listctrl - wxString m_szFile; //Name of currently playing file/location - class wxMediaPlayerTimer* m_timer; //Timer to write info to status bar - wxString m_basestatus; //Base status string (see ResetStatus()) - wxNotebook* m_notebook; //Notebook containing our pages + class wxMediaPlayerTimer* m_timer; // Timer to write info to status bar + wxNotebook* m_notebook; // Notebook containing our pages // Maybe I should use more accessors, but for simplicity // I'll allow the other classes access to our members @@ -239,30 +232,40 @@ class wxMediaPlayerNotebookPage : public wxPanel // Slider event handlers void OnBeginSeek(wxScrollEvent& event); void OnEndSeek(wxScrollEvent& event); + void OnPBChange(wxScrollEvent& event); + void OnVolChange(wxScrollEvent& event); // Media event handlers + void OnMediaPlay(wxMediaEvent& event); + void OnMediaPause(wxMediaEvent& event); + void OnMediaStop(wxMediaEvent& event); void OnMediaFinished(wxMediaEvent& event); public: - bool IsBeingDragged(); //accessor for m_bIsBeingDragged + bool IsBeingDragged(); // accessor for m_bIsBeingDragged - //make wxMediaPlayerFrame able to access the private members + // make wxMediaPlayerFrame able to access the private members friend class wxMediaPlayerFrame; - wxMediaCtrl* m_mediactrl; //Our media control - class wxMediaPlayerListCtrl* m_playlist; //Our playlist - wxSlider* m_slider; //The slider below our media control - int m_nLoops; //Number of times media has looped - bool m_bLoop; //Whether we are looping or not - bool m_bIsBeingDragged; //Whether the user is dragging the scroll bar - wxMediaPlayerFrame* m_parentFrame; //Main wxFrame of our sample - wxButton* m_prevButton; //Go to previous file button - wxButton* m_playButton; //Play/pause file button - wxButton* m_stopButton; //Stop playing file button - wxButton* m_nextButton; //Next file button - wxButton* m_vdButton; //Volume down button - wxButton* m_vuButton; //Volume up button - wxGauge* m_gauge; //Gauge to keep in line with slider + int m_nLastFileId; // List ID of played file in listctrl + wxString m_szFile; // Name of currently playing file/location + + wxMediaCtrl* m_mediactrl; // Our media control + class wxMediaPlayerListCtrl* m_playlist; // Our playlist + wxSlider* m_slider; // The slider below our media control + wxSlider* m_pbSlider; // Lower-left slider for adjusting speed + wxSlider* m_volSlider; // Lower-right slider for adjusting volume + int m_nLoops; // Number of times media has looped + bool m_bLoop; // Whether we are looping or not + bool m_bIsBeingDragged; // Whether the user is dragging the scroll bar + wxMediaPlayerFrame* m_parentFrame; // Main wxFrame of our sample + wxButton* m_prevButton; // Go to previous file button + wxButton* m_playButton; // Play/pause file button + wxButton* m_stopButton; // Stop playing file button + wxButton* m_nextButton; // Next file button + wxButton* m_vdButton; // Volume down button + wxButton* m_vuButton; // Volume up button + wxGauge* m_gauge; // Gauge to keep in line with slider }; // ---------------------------------------------------------------------------- @@ -272,13 +275,13 @@ public: class wxMediaPlayerTimer : public wxTimer { public: - //Ctor + // Ctor wxMediaPlayerTimer(wxMediaPlayerFrame* frame) {m_frame = frame;} - //Called each time the timer's timeout expires + // Called each time the timer's timeout expires void Notify(); - wxMediaPlayerFrame* m_frame; //The wxMediaPlayerFrame + wxMediaPlayerFrame* m_frame; // The wxMediaPlayerFrame }; // ---------------------------------------------------------------------------- @@ -292,14 +295,13 @@ public: wxListItem kNewItem; kNewItem.SetAlign(wxLIST_FORMAT_LEFT); - int nID; - - kNewItem.SetId(nID = this->GetItemCount()); + int nID = this->GetItemCount(); + kNewItem.SetId(nID); kNewItem.SetMask(wxLIST_MASK_DATA); kNewItem.SetData(new wxString(szString)); this->InsertItem(kNewItem); - this->SetItem(nID, 0, _T("*")); + this->SetItem(nID, 0, wxT("*")); this->SetItem(nID, 1, wxFileName(szString).GetName()); if (nID % 2) @@ -328,15 +330,15 @@ public: listitem.SetId(nLastSelected == -1 ? nLast : nLastSelected); this->GetItem(listitem); } - }; // ---------------------------------------------------------------------------- // wxPlayListDropTarget // -// Drop target for playlist (i.e. user drags a file from explorer unto -// playlist it adds the file) +// Drop target for playlist (i.e. allows users to drag a file from explorer into +// the playlist to add that file) // ---------------------------------------------------------------------------- +#if wxUSE_DRAG_AND_DROP class wxPlayListDropTarget : public wxFileDropTarget { public: @@ -353,6 +355,7 @@ public: } wxMediaPlayerListCtrl& m_list; }; +#endif // ============================================================================ // @@ -401,7 +404,7 @@ const wxChar* wxGetMediaStateText(int nState) // // IMPLEMENT_APP does this, and also implements the platform-specific entry // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do -// not desire this behavior. +// not desire this behaviour. // ---------------------------------------------------------------------------- IMPLEMENT_APP(wxMediaPlayerApp) @@ -415,8 +418,14 @@ IMPLEMENT_APP(wxMediaPlayerApp) // ---------------------------------------------------------------------------- bool wxMediaPlayerApp::OnInit() { + if ( !wxApp::OnInit() ) + return false; + + // SetAppName() lets wxConfig and others know where to write + SetAppName(wxT("wxMediaPlayer")); + wxMediaPlayerFrame *frame = - new wxMediaPlayerFrame(_T("MediaPlayer wxWidgets Sample")); + new wxMediaPlayerFrame(wxT("MediaPlayer wxWidgets Sample")); frame->Show(true); #if wxUSE_CMDLINE_PARSER @@ -428,13 +437,13 @@ bool wxMediaPlayerApp::OnInit() cmdLineDesc[0].kind = wxCMD_LINE_PARAM; cmdLineDesc[0].shortName = NULL; cmdLineDesc[0].longName = NULL; - cmdLineDesc[0].description = wxT("input files"); + cmdLineDesc[0].description = "input files"; cmdLineDesc[0].type = wxCMD_LINE_VAL_STRING; cmdLineDesc[0].flags = wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE; cmdLineDesc[1].kind = wxCMD_LINE_NONE; - //gets the passed media files from cmd line + // gets the passed media files from cmd line wxCmdLineParser parser (cmdLineDesc, argc, argv); // get filenames from the commandline @@ -444,8 +453,8 @@ bool wxMediaPlayerApp::OnInit() { frame->AddToPlayList((parser.GetParam (paramNr))); } - wxCommandEvent emptyevt; - frame->OnNext(emptyevt); + wxCommandEvent theEvent(wxEVT_COMMAND_MENU_SELECTED, wxID_NEXT); + frame->AddPendingEvent(theEvent); } #endif @@ -454,10 +463,10 @@ bool wxMediaPlayerApp::OnInit() #ifdef __WXMAC__ -void wxMediaPlayerApp::MacOpenFile(const wxString & fileName ) +void wxMediaPlayerApp::MacOpenFiles(const wxArrayString & fileNames ) { - //Called when a user drags a file over our app - m_frame->DoOpenFile(fileName, true /* new page */); + // Called when a user drags files over our app + m_frame->DoOpenFile(fileNames[0], true /* new page */); } #endif // __WXMAC__ @@ -479,9 +488,10 @@ void wxMediaPlayerApp::MacOpenFile(const wxString & fileName ) // ---------------------------------------------------------------------------- wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) - : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600,600)), - m_nLastFileId(-1) + : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600,600)) { + SetIcon(wxICON(sample)); + // // Create Menus // @@ -491,50 +501,50 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) wxMenu *helpMenu = new wxMenu; wxMenu *debugMenu = new wxMenu; - fileMenu->Append(wxID_OPENFILESAMEPAGE, _T("&Open File\tCtrl-Shift-O"), - _T("Open a File in the current notebook page")); - fileMenu->Append(wxID_OPENFILENEWPAGE, _T("&Open File in a new page"), - _T("Open a File in a new notebook page")); - fileMenu->Append(wxID_OPENURLSAMEPAGE, _T("&Open URL"), - _T("Open a URL in the current notebook page")); - fileMenu->Append(wxID_OPENURLNEWPAGE, _T("&Open URL in a new page"), - _T("Open a URL in a new notebook page")); + fileMenu->Append(wxID_OPENFILESAMEPAGE, wxT("&Open File\tCtrl-Shift-O"), + wxT("Open a File in the current notebook page")); + fileMenu->Append(wxID_OPENFILENEWPAGE, wxT("&Open File in a new page"), + wxT("Open a File in a new notebook page")); + fileMenu->Append(wxID_OPENURLSAMEPAGE, wxT("&Open URL"), + wxT("Open a URL in the current notebook page")); + fileMenu->Append(wxID_OPENURLNEWPAGE, wxT("&Open URL in a new page"), + wxT("Open a URL in a new notebook page")); fileMenu->AppendSeparator(); - fileMenu->Append(wxID_CLOSECURRENTPAGE, _T("&Close Current Page\tCtrl-C"), - _T("Close current notebook page")); + fileMenu->Append(wxID_CLOSECURRENTPAGE, wxT("&Close Current Page\tCtrl-C"), + wxT("Close current notebook page")); fileMenu->AppendSeparator(); fileMenu->Append(wxID_EXIT, - _T("E&xit\tAlt-X"), - _T("Quit this program")); + wxT("E&xit\tAlt-X"), + wxT("Quit this program")); - controlsMenu->Append(wxID_PLAY, _T("&Play/Pause\tCtrl-P"), _T("Resume/Pause playback")); - controlsMenu->Append(wxID_STOP, _T("&Stop\tCtrl-S"), _T("Stop playback")); + controlsMenu->Append(wxID_PLAY, wxT("&Play/Pause\tCtrl-P"), wxT("Resume/Pause playback")); + controlsMenu->Append(wxID_STOP, wxT("&Stop\tCtrl-S"), wxT("Stop playback")); controlsMenu->AppendSeparator(); - controlsMenu->Append(wxID_PREV, _T("&Previous\tCtrl-B"), _T("Go to previous track")); - controlsMenu->Append(wxID_NEXT, _T("&Next\tCtrl-N"), _T("Skip to next track")); + controlsMenu->Append(wxID_PREV, wxT("&Previous\tCtrl-B"), wxT("Go to previous track")); + controlsMenu->Append(wxID_NEXT, wxT("&Next\tCtrl-N"), wxT("Skip to next track")); optionsMenu->AppendCheckItem(wxID_LOOP, - _T("&Loop\tCtrl-L"), - _T("Loop Selected Media")); + wxT("&Loop\tCtrl-L"), + wxT("Loop Selected Media")); optionsMenu->AppendCheckItem(wxID_SHOWINTERFACE, - _T("&Show Interface\tCtrl-I"), - _T("Show wxMediaCtrl native controls")); + wxT("&Show Interface\tCtrl-I"), + wxT("Show wxMediaCtrl native controls")); debugMenu->Append(wxID_SELECTBACKEND, - _T("&Select Backend...\tCtrl-D"), - _T("Select a backend manually")); + wxT("&Select Backend...\tCtrl-D"), + wxT("Select a backend manually")); helpMenu->Append(wxID_ABOUT, - _T("&About...\tF1"), - _T("Show about dialog")); + wxT("&About\tF1"), + wxT("Show about dialog")); wxMenuBar *menuBar = new wxMenuBar(); - menuBar->Append(fileMenu, _T("&File")); - menuBar->Append(controlsMenu, _T("&Controls")); - menuBar->Append(optionsMenu, _T("&Options")); - menuBar->Append(debugMenu, _T("&Debug")); - menuBar->Append(helpMenu, _T("&Help")); + menuBar->Append(fileMenu, wxT("&File")); + menuBar->Append(controlsMenu, wxT("&Controls")); + menuBar->Append(optionsMenu, wxT("&Options")); + menuBar->Append(debugMenu, wxT("&Debug")); + menuBar->Append(helpMenu, wxT("&Help")); SetMenuBar(menuBar); // @@ -665,12 +675,6 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) this->Connect(wxID_SELECTBACKEND, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend)); - // - // Notebook events - // - this->Connect(wxID_NOTEBOOK, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, - wxNotebookEventHandler(wxMediaPlayerFrame::OnPageChange)); - // // Key events // @@ -692,15 +696,37 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // Create an initial notebook page so the user has something // to work with without having to go file->open every time :). // - m_notebook->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook), + wxMediaPlayerNotebookPage* page = + new wxMediaPlayerNotebookPage(this, m_notebook); + m_notebook->AddPage(page, wxT(""), true); + // + // Here we load the our configuration - + // in our case we load all the files that were left in + // the playlist the last time the user closed our application + // + // As an exercise to the reader try modifying it so that + // it properly loads the playlist for each page without + // conflicting (loading the same data) with the other ones. + // + wxConfig conf; + wxString key, outstring; + for(int i = 0; ; ++i) + { + key.clear(); + key << i; + if(!conf.Read(key, &outstring)) + break; + page->m_playlist->AddToPlayList(outstring); + } + // // Create a timer to update our status bar // m_timer = new wxMediaPlayerTimer(this); - m_timer->Start(100); + m_timer->Start(500); } // ---------------------------------------------------------------------------- @@ -711,15 +737,9 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // ---------------------------------------------------------------------------- wxMediaPlayerFrame::~wxMediaPlayerFrame() { + // Shut down our timer delete m_timer; -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::OnClose -// ---------------------------------------------------------------------------- -void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) -{ // // Here we save our info to the registry or whatever // mechanism the OS uses. @@ -737,22 +757,31 @@ void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) // all you'd need to do is just remove everything after // conf->DeleteAll() here // - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + // As an exercise to the reader, try modifying this so + // that it saves the data for each notebook page + // + wxMediaPlayerListCtrl* playlist = + ((wxMediaPlayerNotebookPage*)m_notebook->GetPage(0))->m_playlist; - wxConfigBase* conf = wxConfigBase::Get(); - conf->DeleteAll(); + wxConfig conf; + conf.DeleteAll(); - for(int i = 0; i < m_playlist->GetItemCount(); ++i) + for(int i = 0; i < playlist->GetItemCount(); ++i) { - wxString* pData = (wxString*) m_playlist->GetItemData(i); + wxString* pData = (wxString*) playlist->GetItemData(i); wxString s; s << i; - conf->Write(s, *(pData)); + conf.Write(s, *(pData)); delete pData; } +} - event.Skip(); //really close the frame +// ---------------------------------------------------------------------------- +// wxMediaPlayerFrame::OnClose +// ---------------------------------------------------------------------------- +void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) +{ + event.Skip(); // really close the frame } // ---------------------------------------------------------------------------- @@ -766,68 +795,6 @@ void wxMediaPlayerFrame::AddToPlayList(const wxString& szString) currentpage->m_playlist->AddToPlayList(szString); } - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::ResetStatus -// -// Here we just make a simple status string with some useful info about -// the media that we won't change later - such as the length of the media. -// -// We then append some other info that changes in wxMediaPlayerTimer::Notify, then -// set the status bar to this text. -// -// In real applications, you'd want to find a better way to do this, -// such as static text controls (wxStaticText). -// -// We display info here in seconds (wxMediaCtrl uses milliseconds - that's why -// we divide by 1000). -// -// We also reset our loop counter here. -// ---------------------------------------------------------------------------- -void wxMediaPlayerFrame::ResetStatus() -{ - wxMediaCtrl* currentMediaCtrl = GetCurrentMediaCtrl(); - - m_basestatus = wxString::Format(_T("Size(x,y):%i,%i ") - _T("Length(Seconds):%u Speed:%1.1fx"), - currentMediaCtrl->GetBestSize().x, - currentMediaCtrl->GetBestSize().y, - (unsigned)((currentMediaCtrl->Length() / 1000)), - currentMediaCtrl->GetPlaybackRate() - ); -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::GetCurrentMediaCtrl -// -// Obtains the media control of the current page, or NULL if there are no -// pages open -// ---------------------------------------------------------------------------- -wxMediaCtrl* wxMediaPlayerFrame::GetCurrentMediaCtrl() -{ - return ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_mediactrl; -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::GetCurrentSlider -// -// Obtains the slider of the current page -// ---------------------------------------------------------------------------- -wxSlider* wxMediaPlayerFrame::GetCurrentSlider() -{ - return ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_slider; -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::GetCurrentGauge -// -// Obtains the gauge of the current page -// ---------------------------------------------------------------------------- -wxGauge* wxMediaPlayerFrame::GetCurrentGauge() -{ - return ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_gauge; -} - // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnQuit // @@ -849,10 +816,25 @@ void wxMediaPlayerFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxString msg; - msg.Printf( _T("This is a test of wxMediaCtrl.\n") - _T("Welcome to %s"), wxVERSION_STRING); + msg.Printf( wxT("This is a test of wxMediaCtrl.\n\n") + + wxT("Instructions:\n") + + wxT("The top slider shows the current the current position, ") + wxT("which you can change by dragging and releasing it.\n") + + wxT("The gauge (progress bar) shows the progress in ") + wxT("downloading data of the current file - it may always be ") + wxT("empty due to lack of support from the current backend.\n") - wxMessageBox(msg, _T("About wxMediaCtrl test"), wxOK | wxICON_INFORMATION, this); + wxT("The lower-left slider controls the volume and the lower-") + wxT("right slider controls the playback rate/speed of the ") + wxT("media\n\n") + + wxT("Currently using: %s"), wxVERSION_STRING); + + wxMessageBox(msg, wxT("About wxMediaCtrl test"), + wxOK | wxICON_INFORMATION, this); } // ---------------------------------------------------------------------------- @@ -863,14 +845,10 @@ void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnLoop(wxCommandEvent& WXUNUSED(event)) { - if(!m_notebook->GetCurrentPage()) - { - wxMessageBox(wxT("No files are currently open!")); - return; - } + wxMediaPlayerNotebookPage* currentpage = + ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage()); - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_bLoop = - !((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_bLoop; + currentpage->m_bLoop = !currentpage->m_bLoop; } // ---------------------------------------------------------------------------- @@ -881,15 +859,23 @@ void wxMediaPlayerFrame::OnLoop(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent& event) { - if(!m_notebook->GetCurrentPage()) - { - wxMessageBox(wxT("No files are currently open!")); - return; - } + wxMediaPlayerNotebookPage* currentpage = + ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage()); - GetCurrentMediaCtrl()->ShowPlayerControls(event.IsChecked() ? + if( !currentpage->m_mediactrl->ShowPlayerControls(event.IsChecked() ? wxMEDIACTRLPLAYERCONTROLS_DEFAULT : - wxMEDIACTRLPLAYERCONTROLS_NONE); + wxMEDIACTRLPLAYERCONTROLS_NONE) ) + { + // error - uncheck and warn user + wxMenuItem* pSIItem = GetMenuBar()->FindItem(wxID_SHOWINTERFACE); + wxASSERT(pSIItem); + pSIItem->Check(!event.IsChecked()); + + if(event.IsChecked()) + wxMessageBox(wxT("Could not show player controls")); + else + wxMessageBox(wxT("Could not hide player controls")); + } } // ---------------------------------------------------------------------------- @@ -946,34 +932,34 @@ void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage) true); } - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if(m_nLastFileId != -1) - m_playlist->SetItemState(m_nLastFileId, 0, wxLIST_STATE_SELECTED); + if(currentpage->m_nLastFileId != -1) + currentpage->m_playlist->SetItemState(currentpage->m_nLastFileId, + 0, wxLIST_STATE_SELECTED); wxListItem newlistitem; newlistitem.SetAlign(wxLIST_FORMAT_LEFT); int nID; - newlistitem.SetId(nID = m_playlist->GetItemCount()); + newlistitem.SetId(nID = currentpage->m_playlist->GetItemCount()); newlistitem.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_STATE); newlistitem.SetState(wxLIST_STATE_SELECTED); newlistitem.SetData(new wxString(path)); - m_playlist->InsertItem(newlistitem); - m_playlist->SetItem(nID, 0, _T("*")); - m_playlist->SetItem(nID, 1, wxFileName(path).GetName()); + currentpage->m_playlist->InsertItem(newlistitem); + currentpage->m_playlist->SetItem(nID, 0, wxT("*")); + currentpage->m_playlist->SetItem(nID, 1, wxFileName(path).GetName()); if (nID % 2) { newlistitem.SetBackgroundColour(wxColour(192,192,192)); - m_playlist->SetItem(newlistitem); + currentpage->m_playlist->SetItem(newlistitem); } DoPlayFile(path); - // m_playlist->Focus(nID); } // ---------------------------------------------------------------------------- @@ -984,69 +970,74 @@ void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::DoPlayFile(const wxString& path) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; - m_playlist->GetSelectedItem(listitem); - - if(listitem.GetData() && - m_szFile.compare(path) == 0 && - m_nLastFileId == listitem.GetId()) + currentpage->m_playlist->GetSelectedItem(listitem); + + if( ( listitem.GetData() && + currentpage->m_nLastFileId == listitem.GetId() && + currentpage->m_szFile.compare(path) == 0 ) || + ( !listitem.GetData() && + currentpage->m_nLastFileId != -1 && + currentpage->m_szFile.compare(path) == 0) + ) { - if(GetCurrentMediaCtrl()->GetState() == wxMEDIASTATE_PLAYING) + if(currentpage->m_mediactrl->GetState() == wxMEDIASTATE_PLAYING) { - if( !GetCurrentMediaCtrl()->Pause() ) + if( !currentpage->m_mediactrl->Pause() ) wxMessageBox(wxT("Couldn't pause movie!")); - else - m_playlist->SetItem(listitem.GetId(), 0, _T("||")); } else { - if( !GetCurrentMediaCtrl()->Play() ) - wxMessageBox(wxT("Couldn't pause movie!")); - else - m_playlist->SetItem(listitem.GetId(), 0, _T(">")); + if( !currentpage->m_mediactrl->Play() ) + wxMessageBox(wxT("Couldn't play movie!")); } } else { + int nNewId = listitem.GetData() ? listitem.GetId() : + currentpage->m_playlist->GetItemCount()-1; m_notebook->SetPageText(m_notebook->GetSelection(), wxFileName(path).GetName()); - if(m_nLastFileId != -1) - m_playlist->SetItem(m_nLastFileId, 0, _T("*")); + if(currentpage->m_nLastFileId != -1) + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 0, wxT("*")); wxURI uripath(path); if( uripath.IsReference() ) { - if( !GetCurrentMediaCtrl()->Load(path) ) + if( !currentpage->m_mediactrl->Load(path) ) { wxMessageBox(wxT("Couldn't load file!")); - m_playlist->SetItem(listitem.GetId(), 0, _T("E")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("E")); } else { - m_playlist->SetItem(listitem.GetId(), 0, _T("O")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("O")); } } else { - if( !GetCurrentMediaCtrl()->Load(uripath) ) + if( !currentpage->m_mediactrl->Load(uripath) ) { - wxMessageBox(wxT("Couldn't load file!")); - m_playlist->SetItem(listitem.GetId(), 0, _T("E")); + wxMessageBox(wxT("Couldn't load URL!")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("E")); } else { - m_playlist->SetItem(listitem.GetId(), 0, _T("O")); + currentpage->m_playlist->SetItem(nNewId, 0, wxT("O")); } } - m_nLastFileId = listitem.GetId(); - m_szFile = path; - m_playlist->SetItem(m_nLastFileId, 1, wxFileName(path).GetName()); - m_playlist->SetItem(m_nLastFileId, 2, wxT("")); + currentpage->m_nLastFileId = nNewId; + currentpage->m_szFile = path; + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + 1, wxFileName(path).GetName()); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + 2, wxT("")); } } @@ -1058,31 +1049,22 @@ void wxMediaPlayerFrame::DoPlayFile(const wxString& path) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent& WXUNUSED(evt)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; - wxListItem listitem; - m_playlist->GetSelectedItem(listitem); + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if( !GetCurrentMediaCtrl()->Play() ) + if( !currentpage->m_mediactrl->Play() ) { wxMessageBox(wxT("Couldn't play movie!")); - m_playlist->SetItem(listitem.GetId(), 0, _T("E")); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT("E")); } else { - m_playlist->SetItem(listitem.GetId(), 0, _T(">")); + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT(">")); } - m_playlist->SetItem(listitem.GetId(), 2, wxString::Format(wxT("%u"), - (unsigned) GetCurrentMediaCtrl()->Length() / 1000) ); - - ResetStatus(); - - GetCurrentSlider()->SetRange(0, - (int)(GetCurrentMediaCtrl()->Length() / 1000)); - GetCurrentGauge()->SetRange((int)(GetCurrentMediaCtrl()->Length() / 1000)); } + // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnSelectBackend // @@ -1094,7 +1076,7 @@ void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent& WXUNUSED(evt)) { wxString sBackend = wxGetTextFromUser(wxT("Enter backend to use")); - if(sBackend.empty() == false) //could have been cancelled by the user + if(sBackend.empty() == false) // could have been cancelled by the user { int sel = m_notebook->GetSelection(); @@ -1106,7 +1088,10 @@ void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent& WXUNUSED(evt)) m_notebook->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook, sBackend ), wxT(""), true); - DoOpenFile(m_szFile, false); + + DoOpenFile( + ((wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage())->m_szFile, + false); } } @@ -1144,7 +1129,7 @@ void wxMediaPlayerFrame::OpenURL(bool bNewPage) wxT("Enter the URL that has the movie to play") ); - if(sUrl.empty() == false) //could have been cancelled by user + if(sUrl.empty() == false) // could have been cancelled by user { DoOpenFile(sUrl, bNewPage); } @@ -1184,35 +1169,36 @@ void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnPlay(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; - m_playlist->GetSelectedItem(listitem); + currentpage->m_playlist->GetSelectedItem(listitem); if ( !listitem.GetData() ) { int nLast = -1; - if ((nLast = m_playlist->GetNextItem(nLast, + if ((nLast = currentpage->m_playlist->GetNextItem(nLast, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE)) == -1) { - //no items in list - wxMessageBox(_T("No items in playlist!")); - return; + // no items in list + wxMessageBox(wxT("No items in playlist!")); } - wxListItem listitem; + else + { listitem.SetId(nLast); - m_playlist->GetItem(listitem); + currentpage->m_playlist->GetItem(listitem); listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE); listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); - m_playlist->SetItem(listitem); - wxListEvent event; - OnChangeSong(event); + currentpage->m_playlist->SetItem(listitem); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); + } } else { - wxListEvent event; - OnChangeSong(event); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); } } @@ -1225,26 +1211,26 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) { if(event.GetKeyCode() == WXK_BACK/*DELETE*/) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; - //delete all selected items + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); + // delete all selected items while(true) { - wxInt32 nSelectedItem = m_playlist->GetNextItem( + wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem( -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (nSelectedItem == -1) break; wxListItem listitem; listitem.SetId(nSelectedItem); - m_playlist->GetItem(listitem); + currentpage->m_playlist->GetItem(listitem); delete (wxString*) listitem.GetData(); - m_playlist->DeleteItem(nSelectedItem); + currentpage->m_playlist->DeleteItem(nSelectedItem); } } - //Could be wxGetTextFromUser or something else important + // Could be wxGetTextFromUser or something else important if(event.GetEventObject() != this) event.Skip(); } @@ -1260,21 +1246,14 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; - - wxListItem listitem; - m_playlist->GetSelectedItem(listitem); - m_playlist->SetItem(listitem.GetId(), 0, _T("[]")); - - if(!m_notebook->GetCurrentPage()) - { - wxMessageBox(wxT("No files are currently open!")); - return; - } + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if( !GetCurrentMediaCtrl()->Stop() ) + if( !currentpage->m_mediactrl->Stop() ) wxMessageBox(wxT("Couldn't stop movie!")); + else + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 0, wxT("[]")); } @@ -1287,12 +1266,15 @@ void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; - m_playlist->GetSelectedItem(listitem); + currentpage->m_playlist->GetSelectedItem(listitem); + if(listitem.GetData()) DoPlayFile((*((wxString*) listitem.GetData()))); + else + wxMessageBox(wxT("No selected item!")); } // ---------------------------------------------------------------------------- @@ -1303,37 +1285,49 @@ void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if (m_playlist->GetItemCount() == 0) + if (currentpage->m_playlist->GetItemCount() == 0) return; wxInt32 nLastSelectedItem = -1; while(true) { - wxInt32 nSelectedItem = m_playlist->GetNextItem(nLastSelectedItem, + wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (nSelectedItem == -1) break; nLastSelectedItem = nSelectedItem; - m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); + currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); } - if (nLastSelectedItem <= 0) - nLastSelectedItem = m_playlist->GetItemCount() - 1; + if (nLastSelectedItem == -1) + { + // nothing selected, default to the file before the currently playing one + if(currentpage->m_nLastFileId == 0) + nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1; + else + nLastSelectedItem = currentpage->m_nLastFileId - 1; + } + else if (nLastSelectedItem == 0) + nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1; else nLastSelectedItem -= 1; + if(nLastSelectedItem == currentpage->m_nLastFileId) + return; // already playing... nothing to do + wxListItem listitem; listitem.SetId(nLastSelectedItem); - m_playlist->GetItem(listitem); + listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA); + currentpage->m_playlist->GetItem(listitem); listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE); listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); - m_playlist->SetItem(listitem); + currentpage->m_playlist->SetItem(listitem); - wxListEvent emptyEvent; - OnChangeSong(emptyEvent); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); } // ---------------------------------------------------------------------------- @@ -1344,76 +1338,77 @@ void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerListCtrl* m_playlist = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_playlist; + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - if (m_playlist->GetItemCount() == 0) + if (currentpage->m_playlist->GetItemCount() == 0) return; wxInt32 nLastSelectedItem = -1; while(true) { - wxInt32 nSelectedItem = m_playlist->GetNextItem(nLastSelectedItem, + wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); if (nSelectedItem == -1) break; nLastSelectedItem = nSelectedItem; - m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); + currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); } if (nLastSelectedItem == -1) + { + if(currentpage->m_nLastFileId == currentpage->m_playlist->GetItemCount() - 1) nLastSelectedItem = 0; else - { - if (nLastSelectedItem == m_playlist->GetItemCount() - 1) + nLastSelectedItem = currentpage->m_nLastFileId + 1; + } + else if (nLastSelectedItem == currentpage->m_playlist->GetItemCount() - 1) nLastSelectedItem = 0; else nLastSelectedItem += 1; - } + + if(nLastSelectedItem == currentpage->m_nLastFileId) + return; // already playing... nothing to do wxListItem listitem; + listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA); listitem.SetId(nLastSelectedItem); - m_playlist->GetItem(listitem); + currentpage->m_playlist->GetItem(listitem); listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE); listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); - m_playlist->SetItem(listitem); + currentpage->m_playlist->SetItem(listitem); - wxListEvent emptyEvent; - OnChangeSong(emptyEvent); + wxASSERT(listitem.GetData()); + DoPlayFile((*((wxString*) listitem.GetData()))); } // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnVolumeDown // -// Lowers the volume of the media control by 10% +// Lowers the volume of the media control by 5% // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event)) { - double dVolume = GetCurrentMediaCtrl()->GetVolume(); - GetCurrentMediaCtrl()->SetVolume(dVolume < 0.1 ? 0.0 : dVolume - .1); + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); + + double dVolume = currentpage->m_mediactrl->GetVolume(); + currentpage->m_mediactrl->SetVolume(dVolume < 0.05 ? 0.0 : dVolume - .05); } // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnVolumeUp // -// Increases the volume of the media control by 10% +// Increases the volume of the media control by 5% // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent& WXUNUSED(event)) { - double dVolume = GetCurrentMediaCtrl()->GetVolume(); - GetCurrentMediaCtrl()->SetVolume(dVolume > 0.9 ? 1.0 : dVolume + .1); -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::OnCloseCurrentPage -// -// Called when the user wants to closes the current notebook page -// ---------------------------------------------------------------------------- + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); -void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event)) -{ - ResetStatus(); + double dVolume = currentpage->m_mediactrl->GetVolume(); + currentpage->m_mediactrl->SetVolume(dVolume > 0.95 ? 1.0 : dVolume + .05); } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1425,47 +1420,91 @@ void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- // wxMediaPlayerTimer::Notify // -// 1) Update our slider with the position were are in in the media -// 2) Update our status bar with the base text from wxMediaPlayerFrame::ResetStatus, -// append some non-static (changing) info to it, then set the -// status bar text to that result +// 1) Updates media information on the status bar +// 2) Sets the max/min length of the slider and guage +// +// Note that the reason we continually do this and don't cache it is because +// some backends such as GStreamer are dynamic change values all the time +// and often don't have things like duration or video size available +// until the media is actually being played // ---------------------------------------------------------------------------- void wxMediaPlayerTimer::Notify() { - if(m_frame->m_notebook->GetCurrentPage()) + wxMediaPlayerNotebookPage* currentpage = + (wxMediaPlayerNotebookPage*) m_frame->m_notebook->GetCurrentPage(); + wxMediaCtrl* currentMediaCtrl = currentpage->m_mediactrl; + + // Number of minutes/seconds total + wxLongLong llLength = currentpage->m_mediactrl->Length(); + int nMinutes = (int) (llLength / 60000).GetValue(); + int nSeconds = (int) ((llLength % 60000)/1000).GetValue(); + + // Duration string (i.e. MM:SS) + wxString sDuration; + sDuration.Printf(wxT("%2i:%02i"), nMinutes, nSeconds); + + + // Number of minutes/seconds total + wxLongLong llTell = currentpage->m_mediactrl->Tell(); + nMinutes = (int) (llTell / 60000).GetValue(); + nSeconds = (int) ((llTell % 60000)/1000).GetValue(); + + // Position string (i.e. MM:SS) + wxString sPosition; + sPosition.Printf(wxT("%2i:%02i"), nMinutes, nSeconds); + + + // Set the third item in the listctrl entry to the duration string + if(currentpage->m_nLastFileId >= 0) + currentpage->m_playlist->SetItem( + currentpage->m_nLastFileId, 2, sDuration); + + // Setup the slider and gauge min/max values + currentpage->m_slider->SetRange(0, (int)(llLength / 1000).GetValue()); + currentpage->m_gauge->SetRange(100); + + + // if the slider is not being dragged then update it with the song position + if(currentpage->IsBeingDragged() == false) + currentpage->m_slider->SetValue((long)(llTell / 1000).GetValue()); + + + // Update the gauge with the download progress + wxLongLong llDownloadProgress = + currentpage->m_mediactrl->GetDownloadProgress(); + wxLongLong llDownloadTotal = + currentpage->m_mediactrl->GetDownloadTotal(); + + if(llDownloadTotal.GetValue() != 0) { - // get some control pointers from current notebook page - wxMediaCtrl* mediactrl = - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_mediactrl; - wxSlider* slider = - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_slider; - wxGauge* gauge = - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_gauge; - - // if the slider is being dragged then update it with the song position - if(((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->IsBeingDragged() == false) - { - long lPosition = (long)( mediactrl->Tell() / 1000 ); - slider->SetValue(lPosition); - } + currentpage->m_gauge->SetValue( + (int) ((llDownloadProgress * 100) / llDownloadTotal).GetValue() + ); + } - // update guage with value from slider - gauge->SetValue(slider->GetValue()); + // GetBestSize holds the original video size + wxSize videoSize = currentMediaCtrl->GetBestSize(); + + // Now the big part - set the status bar text to + // hold various metadata about the media #if wxUSE_STATUSBAR - m_frame->SetStatusText(wxString::Format( - wxT("%s Pos:%u State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"), - m_frame->m_basestatus.c_str(), - slider->GetValue(), - wxGetMediaStateText(mediactrl->GetState()), - ((wxMediaPlayerNotebookPage*)m_frame->m_notebook->GetCurrentPage())->m_nLoops, - (int)mediactrl->GetDownloadProgress(), - (int)mediactrl->GetDownloadTotal(), - (int)(mediactrl->GetVolume() * 100))); + m_frame->SetStatusText(wxString::Format( + wxT("Size(x,y):%i,%i ") + wxT("Position:%s/%s Speed:%1.1fx ") + wxT("State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"), + videoSize.x, + videoSize.y, + sPosition.c_str(), + sDuration.c_str(), + currentMediaCtrl->GetPlaybackRate(), + wxGetMediaStateText(currentpage->m_mediactrl->GetState()), + currentpage->m_nLoops, + (int)llDownloadProgress.GetValue(), + (int)llDownloadTotal.GetValue(), + (int)(currentpage->m_mediactrl->GetVolume() * 100))); #endif // wxUSE_STATUSBAR - } } - // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // // wxMediaPlayerNotebookPage @@ -1478,17 +1517,16 @@ void wxMediaPlayerTimer::Notify() // Creates a media control and slider and adds it to this panel, // along with some sizers for positioning // ---------------------------------------------------------------------------- - wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentFrame, wxNotebook* theBook, const wxString& szBackend) : wxPanel(theBook, wxID_ANY), + m_nLastFileId(-1), m_nLoops(0), m_bLoop(false), m_bIsBeingDragged(false), m_parentFrame(parentFrame) { - // // Layout // @@ -1500,13 +1538,11 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF // // - // Create and attach the sizer + // Create and attach a 2-column grid sizer // - wxFlexGridSizer* sizer = new wxFlexGridSizer(2, 1, 0, 0); - this->SetSizer(sizer); - this->SetAutoLayout(true); - sizer->AddGrowableRow(0); + wxFlexGridSizer* sizer = new wxFlexGridSizer(2); sizer->AddGrowableCol(0); + this->SetSizer(sizer); // // Create our media control @@ -1516,13 +1552,14 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF // Make sure creation was successful bool bOK = m_mediactrl->Create(this, wxID_MEDIACTRL, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, -//you could specify a macrod backend here like -//wxMEDIABACKEND_QUICKTIME); +// you could specify a macro backend here like +// wxMEDIABACKEND_WMP10); +// wxT("wxPDFMediaBackend")); szBackend); -//you could change the cursor here like +// you could change the cursor here like // m_mediactrl->SetCursor(wxCURSOR_BLANK); -//note that this may not effect it if SetPlayerControls -//is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE +// note that this may not effect it if SetPlayerControls +// is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE wxASSERT_MSG(bOK, wxT("Could not create media control!")); wxUnusedVar(bOK); @@ -1534,7 +1571,7 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_playlist = new wxMediaPlayerListCtrl(); m_playlist->Create(this, wxID_LISTCTRL, wxDefaultPosition, wxDefaultSize, - wxLC_REPORT //wxLC_LIST + wxLC_REPORT // wxLC_LIST | wxSUNKEN_BORDER); // Set the background of our listctrl to white @@ -1549,8 +1586,8 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF // > - Currently Playing // [] - Stopped // || - Paused - // (( - Volume Down 10% - // )) - Volume Up 10% + // (( - Volume Down 5% + // )) - Volume Up 5% // // Column two is the name of the file // @@ -1559,32 +1596,11 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_playlist->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT, /*wxLIST_AUTOSIZE_USEHEADER*/305); m_playlist->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER, 75); +#if wxUSE_DRAG_AND_DROP m_playlist->SetDropTarget(new wxPlayListDropTarget(*m_playlist)); - sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5); +#endif - // - // Here we load the our configuration - - // in our case we load all the files that were left in - // the playlist the last time the user closed our application - // - // TODO: This is probably not the best practice since - // the user will load multiple notebook pages with multiple - // wxMediaCtrl elements. - // - // As an exercise to the reader try modifying it so that - // it properly loads the playlist for each page without - // conflicting (loading the same data) with the other ones. - // - wxConfigBase* conf = wxConfigBase::Get(); - wxString key, outstring; - for(int i = 0; ; ++i) - { - key.clear(); - key << i; - if(!conf->Read(key, &outstring)) - break; - m_playlist->AddToPlayList(outstring); - } + sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5); // // Create the control buttons @@ -1601,12 +1617,19 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_vdButton = new wxButton(); m_vuButton = new wxButton(); - m_prevButton->Create(this, wxID_BUTTONPREV, _T("|<")); - m_playButton->Create(this, wxID_BUTTONPLAY, _T(">")); - m_stopButton->Create(this, wxID_BUTTONSTOP, _T("[]")); - m_nextButton->Create(this, wxID_BUTTONNEXT, _T(">|")); - m_vdButton->Create(this, wxID_BUTTONVD, _T("((")); - m_vuButton->Create(this, wxID_BUTTONVU, _T("))")); + m_prevButton->Create(this, wxID_BUTTONPREV, wxT("|<")); + m_prevButton->SetToolTip("Previous"); + m_playButton->Create(this, wxID_BUTTONPLAY, wxT(">")); + m_playButton->SetToolTip("Play"); + m_stopButton->Create(this, wxID_BUTTONSTOP, wxT("[]")); + m_stopButton->SetToolTip("Stop"); + m_nextButton->Create(this, wxID_BUTTONNEXT, wxT(">|")); + m_nextButton->SetToolTip("Next"); + m_vdButton->Create(this, wxID_BUTTONVD, wxT("((")); + m_vdButton->SetToolTip("Volume down"); + m_vuButton->Create(this, wxID_BUTTONVU, wxT("))")); + m_vuButton->SetToolTip("Volume up"); + vertsizer->Add(m_prevButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); vertsizer->Add(m_playButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); vertsizer->Add(m_stopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); @@ -1614,20 +1637,19 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF vertsizer->Add(m_vdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); vertsizer->Add(m_vuButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); horsizer1->Add(vertsizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); - sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5); // // Create our slider // - m_slider = new wxSlider(this, wxID_SLIDER, 0, //init - 0, //start - 0, //end + m_slider = new wxSlider(this, wxID_SLIDER, 0, // init + 0, // start + 1, // end, dummy but must be greater than start wxDefaultPosition, wxDefaultSize, wxSL_HORIZONTAL ); sizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5); - // // Create the gauge // @@ -1636,6 +1658,30 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF wxGA_HORIZONTAL | wxGA_SMOOTH); sizer->Add(m_gauge, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5); + + // + // Create the speed/volume sliders + // + wxBoxSizer* horsizer3 = new wxBoxSizer(wxHORIZONTAL); + + m_volSlider = new wxSlider(this, wxID_VOLSLIDER, 100, // init + 0, // start + 100, // end + wxDefaultPosition, wxSize(250,20), + wxSL_HORIZONTAL ); + horsizer3->Add(m_volSlider, 1, wxALL, 5); + + m_pbSlider = new wxSlider(this, wxID_PBSLIDER, 4, // init + 1, // start + 16, // end + wxDefaultPosition, wxSize(250,20), + wxSL_HORIZONTAL ); + horsizer3->Add(m_pbSlider, 1, wxALL, 5); + sizer->Add(horsizer3, 1, wxCENTRE | wxALL, 5); + + // Now that we have all our rows make some of them growable + sizer->AddGrowableRow(0); + // // ListCtrl events // @@ -1650,10 +1696,20 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek)); this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBRELEASE, wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek)); + this->Connect(wxID_PBSLIDER, wxEVT_SCROLL_THUMBRELEASE, + wxScrollEventHandler(wxMediaPlayerNotebookPage::OnPBChange)); + this->Connect(wxID_VOLSLIDER, wxEVT_SCROLL_THUMBRELEASE, + wxScrollEventHandler(wxMediaPlayerNotebookPage::OnVolChange)); // // Media Control events // + this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PLAY, + wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPlay)); + this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PAUSE, + wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPause)); + this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_STOP, + wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaStop)); this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_FINISHED, wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished)); this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_LOADED, @@ -1723,9 +1779,67 @@ bool wxMediaPlayerNotebookPage::IsBeingDragged() } // ---------------------------------------------------------------------------- -// OnMediaFinished +// wxMediaPlayerNotebookPage::OnVolChange +// +// Called when the user is done dragging the volume-changing slider +// ---------------------------------------------------------------------------- +void wxMediaPlayerNotebookPage::OnVolChange(wxScrollEvent& WXUNUSED(event)) +{ + if( m_mediactrl->SetVolume( + m_volSlider->GetValue() / 100.0 + ) == false ) + wxMessageBox(wxT("Couldn't set volume!")); + +} + +// ---------------------------------------------------------------------------- +// wxMediaPlayerNotebookPage::OnPBChange +// +// Called when the user is done dragging the speed-changing slider +// ---------------------------------------------------------------------------- +void wxMediaPlayerNotebookPage::OnPBChange(wxScrollEvent& WXUNUSED(event)) +{ + if( m_mediactrl->SetPlaybackRate( + m_pbSlider->GetValue() * .25 + ) == false ) + wxMessageBox(wxT("Couldn't set playbackrate!")); + +} + +// ---------------------------------------------------------------------------- +// wxMediaPlayerNotebookPage::OnMediaPlay +// +// Called when the media plays. +// ---------------------------------------------------------------------------- +void wxMediaPlayerNotebookPage::OnMediaPlay(wxMediaEvent& WXUNUSED(event)) +{ + m_playlist->SetItem(m_nLastFileId, 0, wxT(">")); +} + +// ---------------------------------------------------------------------------- +// wxMediaPlayerNotebookPage::OnMediaPause +// +// Called when the media is paused. +// ---------------------------------------------------------------------------- +void wxMediaPlayerNotebookPage::OnMediaPause(wxMediaEvent& WXUNUSED(event)) +{ + m_playlist->SetItem(m_nLastFileId, 0, wxT("||")); +} + +// ---------------------------------------------------------------------------- +// wxMediaPlayerNotebookPage::OnMediaStop +// +// Called when the media stops. +// ---------------------------------------------------------------------------- +void wxMediaPlayerNotebookPage::OnMediaStop(wxMediaEvent& WXUNUSED(event)) +{ + m_playlist->SetItem(m_nLastFileId, 0, wxT("[]")); +} + +// ---------------------------------------------------------------------------- +// wxMediaPlayerNotebookPage::OnMediaFinished // -// Called when the media stops playing. +// Called when the media finishes playing. // Here we loop it if the user wants to (has been selected from file menu) // ---------------------------------------------------------------------------- void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent& WXUNUSED(event)) @@ -1735,14 +1849,14 @@ void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent& WXUNUSED(event)) if ( !m_mediactrl->Play() ) { wxMessageBox(wxT("Couldn't loop movie!")); - m_playlist->SetItem(m_parentFrame->m_nLastFileId, 0, _T("E")); + m_playlist->SetItem(m_nLastFileId, 0, wxT("E")); } else ++m_nLoops; } else { - m_playlist->SetItem(m_parentFrame->m_nLastFileId, 0, _T("[]")); + m_playlist->SetItem(m_nLastFileId, 0, wxT("[]")); } }