X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bf354396f61a2e1bd5544b67ecde341b6ff9bf35..7f6cf37004ce42bba674e577b8a39b853aa08254:/samples/mediaplayer/mediaplayer.cpp diff --git a/samples/mediaplayer/mediaplayer.cpp b/samples/mediaplayer/mediaplayer.cpp index 19e337583b..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,18 +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); - 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 @@ -232,33 +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; - 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 - 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 }; // ---------------------------------------------------------------------------- @@ -268,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 }; // ---------------------------------------------------------------------------- @@ -328,9 +335,10 @@ public: // ---------------------------------------------------------------------------- // 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: @@ -347,6 +355,7 @@ public: } wxMediaPlayerListCtrl& m_list; }; +#endif // ============================================================================ // @@ -395,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) @@ -409,6 +418,12 @@ 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(wxT("MediaPlayer wxWidgets Sample")); frame->Show(true); @@ -422,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 @@ -438,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 @@ -448,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__ @@ -475,6 +490,8 @@ void wxMediaPlayerApp::MacOpenFile(const wxString & fileName ) wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600,600)) { + SetIcon(wxICON(sample)); + // // Create Menus // @@ -518,7 +535,7 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) wxT("Select a backend manually")); helpMenu->Append(wxID_ABOUT, - wxT("&About...\tF1"), + wxT("&About\tF1"), wxT("Show about dialog")); @@ -658,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 // @@ -685,7 +696,7 @@ 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 :). // - wxMediaPlayerNotebookPage* page = + wxMediaPlayerNotebookPage* page = new wxMediaPlayerNotebookPage(this, m_notebook); m_notebook->AddPage(page, wxT(""), @@ -700,13 +711,13 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // it properly loads the playlist for each page without // conflicting (loading the same data) with the other ones. // - wxConfigBase* conf = wxConfigBase::Get(); + wxConfig conf; wxString key, outstring; for(int i = 0; ; ++i) { key.clear(); key << i; - if(!conf->Read(key, &outstring)) + if(!conf.Read(key, &outstring)) break; page->m_playlist->AddToPlayList(outstring); } @@ -715,7 +726,7 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // Create a timer to update our status bar // m_timer = new wxMediaPlayerTimer(this); - m_timer->Start(100); + m_timer->Start(500); } // ---------------------------------------------------------------------------- @@ -726,6 +737,9 @@ wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title) // ---------------------------------------------------------------------------- wxMediaPlayerFrame::~wxMediaPlayerFrame() { + // Shut down our timer + delete m_timer; + // // Here we save our info to the registry or whatever // mechanism the OS uses. @@ -749,19 +763,17 @@ wxMediaPlayerFrame::~wxMediaPlayerFrame() wxMediaPlayerListCtrl* playlist = ((wxMediaPlayerNotebookPage*)m_notebook->GetPage(0))->m_playlist; - wxConfigBase* conf = wxConfigBase::Get(); - conf->DeleteAll(); + wxConfig conf; + conf.DeleteAll(); for(int i = 0; i < playlist->GetItemCount(); ++i) { wxString* pData = (wxString*) playlist->GetItemData(i); wxString s; s << i; - conf->Write(s, *(pData)); + conf.Write(s, *(pData)); delete pData; } - - delete m_timer; } // ---------------------------------------------------------------------------- @@ -769,7 +781,7 @@ wxMediaPlayerFrame::~wxMediaPlayerFrame() // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnClose(wxCloseEvent& event) { - event.Skip(); //really close the frame + event.Skip(); // really close the frame } // ---------------------------------------------------------------------------- @@ -783,38 +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 = - ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage())->m_mediactrl; - - m_basestatus = wxString::Format(wxT("Size(x,y):%i,%i ") - wxT("Length(Seconds):%u Speed:%1.1fx"), - currentMediaCtrl->GetBestSize().x, - currentMediaCtrl->GetBestSize().y, - (unsigned)((currentMediaCtrl->Length() / 1000)), - currentMediaCtrl->GetPlaybackRate() - ); -} - // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnQuit // @@ -836,10 +816,25 @@ void wxMediaPlayerFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxString msg; - msg.Printf( wxT("This is a test of wxMediaCtrl.\n") - wxT("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") + + 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); + wxMessageBox(msg, wxT("About wxMediaCtrl test"), + wxOK | wxICON_INFORMATION, this); } // ---------------------------------------------------------------------------- @@ -871,11 +866,11 @@ void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent& event) wxMEDIACTRLPLAYERCONTROLS_DEFAULT : wxMEDIACTRLPLAYERCONTROLS_NONE) ) { - //error - uncheck and warn user + // 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 @@ -937,11 +932,11 @@ void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage) true); } - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); if(currentpage->m_nLastFileId != -1) - currentpage->m_playlist->SetItemState(currentpage->m_nLastFileId, + currentpage->m_playlist->SetItemState(currentpage->m_nLastFileId, 0, wxLIST_STATE_SELECTED); wxListItem newlistitem; @@ -975,7 +970,7 @@ void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::DoPlayFile(const wxString& path) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; @@ -993,22 +988,16 @@ void wxMediaPlayerFrame::DoPlayFile(const wxString& path) { if( !currentpage->m_mediactrl->Pause() ) wxMessageBox(wxT("Couldn't pause movie!")); - else - currentpage->m_playlist->SetItem( - currentpage->m_nLastFileId, 0, wxT("||")); } else { if( !currentpage->m_mediactrl->Play() ) wxMessageBox(wxT("Couldn't play movie!")); - else - currentpage->m_playlist->SetItem( - currentpage->m_nLastFileId, 0, wxT(">")); } } else { - int nNewId = listitem.GetData() ? listitem.GetId() : + int nNewId = listitem.GetData() ? listitem.GetId() : currentpage->m_playlist->GetItemCount()-1; m_notebook->SetPageText(m_notebook->GetSelection(), wxFileName(path).GetName()); @@ -1045,9 +1034,9 @@ void wxMediaPlayerFrame::DoPlayFile(const wxString& path) currentpage->m_nLastFileId = nNewId; currentpage->m_szFile = path; - currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 1, wxFileName(path).GetName()); - currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, + currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 2, wxT("")); } } @@ -1060,7 +1049,7 @@ void wxMediaPlayerFrame::DoPlayFile(const wxString& path) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent& WXUNUSED(evt)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); if( !currentpage->m_mediactrl->Play() ) @@ -1073,18 +1062,9 @@ void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent& WXUNUSED(evt)) currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT(">")); } - currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, - 2, wxString::Format(wxT("%u"), - (unsigned) currentpage->m_mediactrl->Length() / 1000) - ); - - ResetStatus(); - - currentpage->m_slider->SetRange(0, - (int)(currentpage->m_mediactrl->Length() / 1000)); - currentpage->m_gauge->SetRange((int)(currentpage->m_mediactrl->Length() / 1000)); } + // ---------------------------------------------------------------------------- // wxMediaPlayerFrame::OnSelectBackend // @@ -1096,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(); @@ -1110,7 +1090,7 @@ void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent& WXUNUSED(evt)) ), wxT(""), true); DoOpenFile( - ((wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage())->m_szFile, + ((wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage())->m_szFile, false); } } @@ -1149,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); } @@ -1189,7 +1169,7 @@ void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnPlay(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; @@ -1201,7 +1181,7 @@ void wxMediaPlayerFrame::OnPlay(wxCommandEvent& WXUNUSED(event)) wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE)) == -1) { - //no items in list + // no items in list wxMessageBox(wxT("No items in playlist!")); } else @@ -1212,7 +1192,7 @@ void wxMediaPlayerFrame::OnPlay(wxCommandEvent& WXUNUSED(event)) listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED); currentpage->m_playlist->SetItem(listitem); wxASSERT(listitem.GetData()); - DoPlayFile((*((wxString*) listitem.GetData()))); + DoPlayFile((*((wxString*) listitem.GetData()))); } } else @@ -1231,9 +1211,9 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) { if(event.GetKeyCode() == WXK_BACK/*DELETE*/) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); - //delete all selected items + // delete all selected items while(true) { wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem( @@ -1250,7 +1230,7 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) } } - //Could be wxGetTextFromUser or something else important + // Could be wxGetTextFromUser or something else important if(event.GetEventObject() != this) event.Skip(); } @@ -1266,7 +1246,7 @@ void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); if( !currentpage->m_mediactrl->Stop() ) @@ -1286,7 +1266,7 @@ void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); wxListItem listitem; @@ -1305,7 +1285,7 @@ void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); if (currentpage->m_playlist->GetItemCount() == 0) @@ -1322,21 +1302,21 @@ void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED); } - if (nLastSelectedItem == -1) + if (nLastSelectedItem == -1) { - //nothing selected, default to the file before the currently playing one + // 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) + else if (nLastSelectedItem == 0) nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1; else nLastSelectedItem -= 1; if(nLastSelectedItem == currentpage->m_nLastFileId) - return; //already playing... nothing to do + return; // already playing... nothing to do wxListItem listitem; listitem.SetId(nLastSelectedItem); @@ -1358,7 +1338,7 @@ void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); if (currentpage->m_playlist->GetItemCount() == 0) @@ -1380,7 +1360,7 @@ void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) if(currentpage->m_nLastFileId == currentpage->m_playlist->GetItemCount() - 1) nLastSelectedItem = 0; else - nLastSelectedItem = currentpage->m_nLastFileId + 1; + nLastSelectedItem = currentpage->m_nLastFileId + 1; } else if (nLastSelectedItem == currentpage->m_playlist->GetItemCount() - 1) nLastSelectedItem = 0; @@ -1388,7 +1368,7 @@ void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) nLastSelectedItem += 1; if(nLastSelectedItem == currentpage->m_nLastFileId) - return; //already playing... nothing to do + return; // already playing... nothing to do wxListItem listitem; listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA); @@ -1406,39 +1386,29 @@ void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event)) // ---------------------------------------------------------------------------- // 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)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); double dVolume = currentpage->m_mediactrl->GetVolume(); - currentpage->m_mediactrl->SetVolume(dVolume < 0.1 ? 0.0 : dVolume - .1); + 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)) { - wxMediaPlayerNotebookPage* currentpage = + wxMediaPlayerNotebookPage* currentpage = (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage(); double dVolume = currentpage->m_mediactrl->GetVolume(); - currentpage->m_mediactrl->SetVolume(dVolume > 0.9 ? 1.0 : dVolume + .1); -} - -// ---------------------------------------------------------------------------- -// wxMediaPlayerFrame::OnPageChange -// -// Called when the user changes the current notebook page shown -// ---------------------------------------------------------------------------- -void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent& WXUNUSED(event)) -{ - ResetStatus(); + currentpage->m_mediactrl->SetVolume(dVolume > 0.95 ? 1.0 : dVolume + .05); } // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1450,42 +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() { - wxMediaPlayerNotebookPage* currentpage = + 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); + - if(currentpage) + // 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) { - // if the slider is being dragged then update it with the song position - if(currentpage->IsBeingDragged() == false) - { - long lPosition = (long)( currentpage->m_mediactrl->Tell() / 1000 ); - currentpage->m_slider->SetValue(lPosition); - } + currentpage->m_gauge->SetValue( + (int) ((llDownloadProgress * 100) / llDownloadTotal).GetValue() + ); + } - // update guage with value from slider - currentpage->m_gauge->SetValue(currentpage->m_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(), - currentpage->m_slider->GetValue(), - wxGetMediaStateText(currentpage->m_mediactrl->GetState()), - currentpage->m_nLoops, - (int)currentpage->m_mediactrl->GetDownloadProgress(), - (int)currentpage->m_mediactrl->GetDownloadTotal(), - (int)(currentpage->m_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 @@ -1508,7 +1527,6 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_bIsBeingDragged(false), m_parentFrame(parentFrame) { - // // Layout // @@ -1520,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 @@ -1536,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); @@ -1554,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 @@ -1569,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 // @@ -1579,7 +1596,10 @@ 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)); +#endif + sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5); // @@ -1598,11 +1618,18 @@ wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentF m_vuButton = new wxButton(); 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); @@ -1610,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 // @@ -1632,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 // @@ -1646,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, @@ -1719,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))