1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mediaplayer.cpp
3 // Purpose: wxMediaCtrl sample
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 // This is a somewhat comprehensive example of how to use all the funtionality
16 // of the wxMediaCtrl class in wxWidgets.
18 // To use this sample, simply select Open File from the file menu,
19 // select the file you want to play - and MediaPlayer will play the file in a
20 // the current notebook page, showing video if necessary.
22 // You can select one of the menu options, or move the slider around
23 // to manipulate what is playing.
24 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27 // Known bugs with wxMediaCtrl:
29 // 1) Certain backends can't play the same media file at the same time (MCI,
30 // Cocoa NSMovieView-Quicktime).
31 // 2) Positioning on Mac Carbon is messed up if put in a sub-control like a
32 // Notebook (like this sample does).
33 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 // ============================================================================
37 // ============================================================================
39 // ----------------------------------------------------------------------------
40 // Pre-compiled header stuff
41 // ----------------------------------------------------------------------------
43 #include "wx/wxprec.h"
53 // ----------------------------------------------------------------------------
55 // ----------------------------------------------------------------------------
57 #include "wx/mediactrl.h" //for wxMediaCtrl
58 #include "wx/filedlg.h" //for opening files from OpenFile
59 #include "wx/slider.h" //for a slider for seeking within media
60 #include "wx/sizer.h" //for positioning controls/wxBoxSizer
61 #include "wx/timer.h" //timer for updating status bar
62 #include "wx/textdlg.h" //for getting user text from OpenURL/Debug
63 #include "wx/notebook.h" //for wxNotebook and putting movies in pages
64 #include "wx/cmdline.h" //for wxCmdLineParser (optional)
65 #include "wx/listctrl.h" //for wxListCtrl
66 #include "wx/dnd.h" //drag and drop for the playlist
67 #include "wx/filename.h" //For wxFileName::GetName()
68 #include "wx/config.h" //for native wxConfig
70 // ----------------------------------------------------------------------------
71 // Bail out if the user doesn't want one of the
73 // ----------------------------------------------------------------------------
75 // RN: I'm not sure why this is here - even minimal doesn't check for
76 // wxUSE_GUI. I may have added it myself though...
78 #error "This is a GUI sample"
81 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || \
82 !wxUSE_NOTEBOOK || !wxUSE_LISTCTRL
83 #error "Not all required elements are enabled. Please modify setup.h!"
86 // ============================================================================
88 // ============================================================================
90 // ----------------------------------------------------------------------------
92 // ----------------------------------------------------------------------------
94 // IDs for the controls and the menu commands
99 wxID_OPENFILESAMEPAGE
,
100 wxID_OPENFILENEWPAGE
,
101 wxID_OPENURLSAMEPAGE
,
103 wxID_CLOSECURRENTPAGE
,
110 // wxID_STOP, [built-in to wxWidgets]
111 // wxID_ABOUT, [built-in to wxWidgets]
112 // wxID_EXIT, [built-in to wxWidgets]
129 // ----------------------------------------------------------------------------
131 // ----------------------------------------------------------------------------
133 class wxMediaPlayerApp
: public wxApp
137 virtual void MacOpenFile(const wxString
& fileName
);
140 virtual bool OnInit();
143 class wxMediaPlayerFrame
* m_frame
;
146 // ----------------------------------------------------------------------------
147 // wxMediaPlayerFrame
148 // ----------------------------------------------------------------------------
150 class wxMediaPlayerFrame
: public wxFrame
154 wxMediaPlayerFrame(const wxString
& title
);
155 ~wxMediaPlayerFrame();
157 // Menu event handlers
158 void OnQuit(wxCommandEvent
& event
);
159 void OnAbout(wxCommandEvent
& event
);
161 void OnOpenFileSamePage(wxCommandEvent
& event
);
162 void OnOpenFileNewPage(wxCommandEvent
& event
);
163 void OnOpenURLSamePage(wxCommandEvent
& event
);
164 void OnOpenURLNewPage(wxCommandEvent
& event
);
165 void OnCloseCurrentPage(wxCommandEvent
& event
);
167 void OnPlay(wxCommandEvent
& event
);
168 void OnPause(wxCommandEvent
& event
);
169 void OnStop(wxCommandEvent
& event
);
170 void OnNext(wxCommandEvent
& event
);
171 void OnPrev(wxCommandEvent
& event
);
172 void OnVolumeDown(wxCommandEvent
& event
);
173 void OnVolumeUp(wxCommandEvent
& event
);
175 void OnLoop(wxCommandEvent
& event
);
176 void OnShowInterface(wxCommandEvent
& event
);
178 void OnSelectBackend(wxCommandEvent
& event
);
180 // Key event handlers
181 void OnKeyDown(wxKeyEvent
& event
);
183 // Quickie for playing from command line
184 void AddToPlayList(const wxString
& szString
);
186 // ListCtrl event handlers
187 void OnChangeSong(wxListEvent
& event
);
189 // Media event handlers
190 void OnMediaLoaded(wxMediaEvent
& event
);
192 // Close event handlers
193 void OnClose(wxCloseEvent
& event
);
196 // Common open file code
197 void OpenFile(bool bNewPage
);
198 void OpenURL(bool bNewPage
);
199 void DoOpenFile(const wxString
& path
, bool bNewPage
);
200 void DoPlayFile(const wxString
& path
);
202 class wxMediaPlayerTimer
* m_timer
; //Timer to write info to status bar
203 wxNotebook
* m_notebook
; //Notebook containing our pages
205 // Maybe I should use more accessors, but for simplicity
206 // I'll allow the other classes access to our members
207 friend class wxMediaPlayerApp
;
208 friend class wxMediaPlayerNotebookPage
;
209 friend class wxMediaPlayerTimer
;
214 // ----------------------------------------------------------------------------
215 // wxMediaPlayerNotebookPage
216 // ----------------------------------------------------------------------------
218 class wxMediaPlayerNotebookPage
: public wxPanel
220 wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
221 wxNotebook
* book
, const wxString
& be
= wxEmptyString
);
223 // Slider event handlers
224 void OnBeginSeek(wxScrollEvent
& event
);
225 void OnEndSeek(wxScrollEvent
& event
);
226 void OnPBChange(wxScrollEvent
& event
);
227 void OnVolChange(wxScrollEvent
& event
);
229 // Media event handlers
230 void OnMediaPlay(wxMediaEvent
& event
);
231 void OnMediaPause(wxMediaEvent
& event
);
232 void OnMediaStop(wxMediaEvent
& event
);
233 void OnMediaFinished(wxMediaEvent
& event
);
236 bool IsBeingDragged(); //accessor for m_bIsBeingDragged
238 //make wxMediaPlayerFrame able to access the private members
239 friend class wxMediaPlayerFrame
;
241 int m_nLastFileId
; //List ID of played file in listctrl
242 wxString m_szFile
; //Name of currently playing file/location
244 wxMediaCtrl
* m_mediactrl
; //Our media control
245 class wxMediaPlayerListCtrl
* m_playlist
; //Our playlist
246 wxSlider
* m_slider
; //The slider below our media control
247 wxSlider
* m_pbSlider
; //Lower-left slider for adjusting speed
248 wxSlider
* m_volSlider
; //Lower-right slider for adjusting volume
249 int m_nLoops
; //Number of times media has looped
250 bool m_bLoop
; //Whether we are looping or not
251 bool m_bIsBeingDragged
; //Whether the user is dragging the scroll bar
252 wxMediaPlayerFrame
* m_parentFrame
; //Main wxFrame of our sample
253 wxButton
* m_prevButton
; //Go to previous file button
254 wxButton
* m_playButton
; //Play/pause file button
255 wxButton
* m_stopButton
; //Stop playing file button
256 wxButton
* m_nextButton
; //Next file button
257 wxButton
* m_vdButton
; //Volume down button
258 wxButton
* m_vuButton
; //Volume up button
259 wxGauge
* m_gauge
; //Gauge to keep in line with slider
262 // ----------------------------------------------------------------------------
263 // wxMediaPlayerTimer
264 // ----------------------------------------------------------------------------
266 class wxMediaPlayerTimer
: public wxTimer
270 wxMediaPlayerTimer(wxMediaPlayerFrame
* frame
) {m_frame
= frame
;}
272 //Called each time the timer's timeout expires
275 wxMediaPlayerFrame
* m_frame
; //The wxMediaPlayerFrame
278 // ----------------------------------------------------------------------------
279 // wxMediaPlayerListCtrl
280 // ----------------------------------------------------------------------------
281 class wxMediaPlayerListCtrl
: public wxListCtrl
284 void AddToPlayList(const wxString
& szString
)
287 kNewItem
.SetAlign(wxLIST_FORMAT_LEFT
);
289 int nID
= this->GetItemCount();
291 kNewItem
.SetMask(wxLIST_MASK_DATA
);
292 kNewItem
.SetData(new wxString(szString
));
294 this->InsertItem(kNewItem
);
295 this->SetItem(nID
, 0, wxT("*"));
296 this->SetItem(nID
, 1, wxFileName(szString
).GetName());
300 kNewItem
.SetBackgroundColour(wxColour(192,192,192));
301 this->SetItem(kNewItem
);
305 void GetSelectedItem(wxListItem
& listitem
)
307 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
308 int nLast
= -1, nLastSelected
= -1;
309 while ((nLast
= this->GetNextItem(nLast
,
311 wxLIST_STATE_SELECTED
)) != -1)
313 listitem
.SetId(nLast
);
314 this->GetItem(listitem
);
315 if ((listitem
.GetState() & wxLIST_STATE_FOCUSED
) )
317 nLastSelected
= nLast
;
319 if (nLast
== -1 && nLastSelected
== -1)
321 listitem
.SetId(nLastSelected
== -1 ? nLast
: nLastSelected
);
322 this->GetItem(listitem
);
326 // ----------------------------------------------------------------------------
327 // wxPlayListDropTarget
329 // Drop target for playlist (i.e. user drags a file from explorer unto
330 // playlist it adds the file)
331 // ----------------------------------------------------------------------------
332 #if wxUSE_DRAG_AND_DROP
333 class wxPlayListDropTarget
: public wxFileDropTarget
336 wxPlayListDropTarget(wxMediaPlayerListCtrl
& list
) : m_list(list
) {}
337 ~wxPlayListDropTarget(){}
338 virtual bool OnDropFiles(wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
339 const wxArrayString
& files
)
341 for (size_t i
= 0; i
< files
.GetCount(); ++i
)
343 m_list
.AddToPlayList(files
[i
]);
347 wxMediaPlayerListCtrl
& m_list
;
351 // ============================================================================
355 // ============================================================================
357 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
361 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
363 // ----------------------------------------------------------------------------
364 // wxGetMediaStateText
366 // Converts a wxMediaCtrl state into something useful that we can display
368 // ----------------------------------------------------------------------------
369 const wxChar
* wxGetMediaStateText(int nState
)
373 case wxMEDIASTATE_PLAYING
:
374 return wxT("Playing");
375 case wxMEDIASTATE_STOPPED
:
376 return wxT("Stopped");
377 ///case wxMEDIASTATE_PAUSED:
379 return wxT("Paused");
383 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
387 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
389 // ----------------------------------------------------------------------------
390 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
391 // use. For example, if you were to be in windows and use a file dialog,
392 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
393 // handle of the application. These routines in wx _DO NOT_ check to see if
394 // the wxApp exists, and thus will crash the application if you try it.
396 // IMPLEMENT_APP does this, and also implements the platform-specific entry
397 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
398 // not desire this behavior.
399 // ----------------------------------------------------------------------------
400 IMPLEMENT_APP(wxMediaPlayerApp
)
402 // ----------------------------------------------------------------------------
403 // wxMediaPlayerApp::OnInit
405 // Where execution starts - akin to a main or WinMain.
406 // 1) Create the frame and show it to the user
407 // 2) Process filenames from the commandline
408 // 3) return true specifying that we want execution to continue past OnInit
409 // ----------------------------------------------------------------------------
410 bool wxMediaPlayerApp::OnInit()
412 if ( !wxApp::OnInit() )
415 // SetAppName() lets wxConfig and others know where to write
416 SetAppName(wxT("wxMediaPlayer"));
418 wxMediaPlayerFrame
*frame
=
419 new wxMediaPlayerFrame(wxT("MediaPlayer wxWidgets Sample"));
422 #if wxUSE_CMDLINE_PARSER
424 // What this does is get all the command line arguments
425 // and treat each one as a file to put to the initial playlist
427 wxCmdLineEntryDesc cmdLineDesc
[2];
428 cmdLineDesc
[0].kind
= wxCMD_LINE_PARAM
;
429 cmdLineDesc
[0].shortName
= NULL
;
430 cmdLineDesc
[0].longName
= NULL
;
431 cmdLineDesc
[0].description
= "input files";
432 cmdLineDesc
[0].type
= wxCMD_LINE_VAL_STRING
;
433 cmdLineDesc
[0].flags
= wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
;
435 cmdLineDesc
[1].kind
= wxCMD_LINE_NONE
;
437 //gets the passed media files from cmd line
438 wxCmdLineParser
parser (cmdLineDesc
, argc
, argv
);
440 // get filenames from the commandline
441 if (parser
.Parse() == 0)
443 for (size_t paramNr
=0; paramNr
< parser
.GetParamCount(); ++paramNr
)
445 frame
->AddToPlayList((parser
.GetParam (paramNr
)));
447 wxCommandEvent
theEvent(wxEVT_COMMAND_MENU_SELECTED
, wxID_NEXT
);
448 frame
->AddPendingEvent(theEvent
);
457 void wxMediaPlayerApp::MacOpenFile(const wxString
& fileName
)
459 //Called when a user drags a file over our app
460 m_frame
->DoOpenFile(fileName
, true /* new page */);
465 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
467 // wxMediaPlayerFrame
469 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
471 // ----------------------------------------------------------------------------
472 // wxMediaPlayerFrame Constructor
474 // 1) Create our menus
475 // 2) Create our notebook control and add it to the frame
476 // 3) Create our status bar
477 // 4) Connect our events
478 // 5) Start our timer
479 // ----------------------------------------------------------------------------
481 wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString
& title
)
482 : wxFrame(NULL
, wxID_ANY
, title
, wxDefaultPosition
, wxSize(600,600))
487 wxMenu
*fileMenu
= new wxMenu
;
488 wxMenu
*controlsMenu
= new wxMenu
;
489 wxMenu
*optionsMenu
= new wxMenu
;
490 wxMenu
*helpMenu
= new wxMenu
;
491 wxMenu
*debugMenu
= new wxMenu
;
493 fileMenu
->Append(wxID_OPENFILESAMEPAGE
, wxT("&Open File\tCtrl-Shift-O"),
494 wxT("Open a File in the current notebook page"));
495 fileMenu
->Append(wxID_OPENFILENEWPAGE
, wxT("&Open File in a new page"),
496 wxT("Open a File in a new notebook page"));
497 fileMenu
->Append(wxID_OPENURLSAMEPAGE
, wxT("&Open URL"),
498 wxT("Open a URL in the current notebook page"));
499 fileMenu
->Append(wxID_OPENURLNEWPAGE
, wxT("&Open URL in a new page"),
500 wxT("Open a URL in a new notebook page"));
501 fileMenu
->AppendSeparator();
502 fileMenu
->Append(wxID_CLOSECURRENTPAGE
, wxT("&Close Current Page\tCtrl-C"),
503 wxT("Close current notebook page"));
504 fileMenu
->AppendSeparator();
505 fileMenu
->Append(wxID_EXIT
,
507 wxT("Quit this program"));
509 controlsMenu
->Append(wxID_PLAY
, wxT("&Play/Pause\tCtrl-P"), wxT("Resume/Pause playback"));
510 controlsMenu
->Append(wxID_STOP
, wxT("&Stop\tCtrl-S"), wxT("Stop playback"));
511 controlsMenu
->AppendSeparator();
512 controlsMenu
->Append(wxID_PREV
, wxT("&Previous\tCtrl-B"), wxT("Go to previous track"));
513 controlsMenu
->Append(wxID_NEXT
, wxT("&Next\tCtrl-N"), wxT("Skip to next track"));
515 optionsMenu
->AppendCheckItem(wxID_LOOP
,
516 wxT("&Loop\tCtrl-L"),
517 wxT("Loop Selected Media"));
518 optionsMenu
->AppendCheckItem(wxID_SHOWINTERFACE
,
519 wxT("&Show Interface\tCtrl-I"),
520 wxT("Show wxMediaCtrl native controls"));
522 debugMenu
->Append(wxID_SELECTBACKEND
,
523 wxT("&Select Backend...\tCtrl-D"),
524 wxT("Select a backend manually"));
526 helpMenu
->Append(wxID_ABOUT
,
527 wxT("&About...\tF1"),
528 wxT("Show about dialog"));
531 wxMenuBar
*menuBar
= new wxMenuBar();
532 menuBar
->Append(fileMenu
, wxT("&File"));
533 menuBar
->Append(controlsMenu
, wxT("&Controls"));
534 menuBar
->Append(optionsMenu
, wxT("&Options"));
535 menuBar
->Append(debugMenu
, wxT("&Debug"));
536 menuBar
->Append(helpMenu
, wxT("&Help"));
540 // Create our notebook - using wxNotebook is luckily pretty
541 // simple and self-explanatory in most cases
543 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
546 // Create our status bar
549 // create a status bar just for fun (by default with 1 pane only)
551 #endif // wxUSE_STATUSBAR
556 // There are two ways in wxWidgets to use events -
557 // Message Maps and Connections.
559 // Message Maps are implemented by putting
560 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
561 // class you want to use for events, such as wxMediaPlayerFrame.
563 // Then after your class declaration you put
564 // BEGIN_EVENT_TABLE(wxMediaPlayerFrame, wxFrame)
568 // Where wxMediaPlayerFrame is the class with the DECLARE_MESSAGE_MAP
569 // in it. EVT_XXX(XXX) are each of your handlers, such
570 // as EVT_MENU for menu events and the XXX inside
571 // is the parameters to the event macro - in the case
572 // of EVT_MENU the menu id and then the function to call.
574 // However, with wxEvtHandler::Connect you can avoid a
575 // global message map for your class and those annoying
576 // macros. You can also change the context in which
577 // the call the handler (more later).
579 // The downside is that due to the limitation that
580 // wxWidgets doesn't use templates in certain areas,
581 // You have to triple-cast the event function.
583 // There are five parameters to wxEvtHandler::Connect -
585 // The first is the id of the instance whose events
586 // you want to handle - i.e. a menu id for menus,
587 // a control id for controls (wxControl::GetId())
590 // The second is the event id. This is the same
591 // as the message maps (EVT_MENU) except prefixed
592 // with "wx" (wxEVT_MENU).
594 // The third is the function handler for the event -
595 // You need to cast it to the specific event handler
596 // type, then to a wxEventFunction, then to a
597 // wxObjectEventFunction - I.E.
598 // (wxObjectEventFunction)(wxEventFunction)
599 // (wxCommandEventFunction) &wxMediaPlayerFrame::MyHandler
601 // Or, you can use the new (2.5.5+) event handler
602 // conversion macros - for instance the above could
604 // wxCommandEventHandler(wxMediaPlayerFrame::MyHandler)
605 // pretty simple, eh?
607 // The fourth is an optional userdata param -
608 // this is of historical relevance only and is
609 // there only for backwards compatibility.
611 // The fifth is the context in which to call the
612 // handler - by default (this param is optional)
613 // this. For example in your event handler
614 // if you were to call "this->MyFunc()"
615 // it would literally do this->MyFunc. However,
616 // if you were to pass myHandler as the fifth
617 // parameter, for instance, you would _really_
618 // be calling myHandler->MyFunc, even though
619 // the compiler doesn't really know it.
625 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
626 wxCommandEventHandler(wxMediaPlayerFrame::OnQuit
));
628 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
629 wxCommandEventHandler(wxMediaPlayerFrame::OnAbout
));
631 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
632 wxCommandEventHandler(wxMediaPlayerFrame::OnLoop
));
634 this->Connect(wxID_SHOWINTERFACE
, wxEVT_COMMAND_MENU_SELECTED
,
635 wxCommandEventHandler(wxMediaPlayerFrame::OnShowInterface
));
637 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
638 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileNewPage
));
640 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
641 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileSamePage
));
643 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
644 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLNewPage
));
646 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
647 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLSamePage
));
649 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
650 wxCommandEventHandler(wxMediaPlayerFrame::OnCloseCurrentPage
));
652 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
653 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
));
655 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
656 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
));
658 this->Connect(wxID_NEXT
, wxEVT_COMMAND_MENU_SELECTED
,
659 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
));
661 this->Connect(wxID_PREV
, wxEVT_COMMAND_MENU_SELECTED
,
662 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
));
664 this->Connect(wxID_SELECTBACKEND
, wxEVT_COMMAND_MENU_SELECTED
,
665 wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend
));
670 wxTheApp
->Connect(wxID_ANY
, wxEVT_KEY_DOWN
,
671 wxKeyEventHandler(wxMediaPlayerFrame::OnKeyDown
),
677 this->Connect(wxID_ANY
, wxEVT_CLOSE_WINDOW
,
678 wxCloseEventHandler(wxMediaPlayerFrame::OnClose
));
685 // Create an initial notebook page so the user has something
686 // to work with without having to go file->open every time :).
688 wxMediaPlayerNotebookPage
* page
=
689 new wxMediaPlayerNotebookPage(this, m_notebook
);
690 m_notebook
->AddPage(page
,
695 // Here we load the our configuration -
696 // in our case we load all the files that were left in
697 // the playlist the last time the user closed our application
699 // As an exercise to the reader try modifying it so that
700 // it properly loads the playlist for each page without
701 // conflicting (loading the same data) with the other ones.
704 wxString key
, outstring
;
705 for(int i
= 0; ; ++i
)
709 if(!conf
.Read(key
, &outstring
))
711 page
->m_playlist
->AddToPlayList(outstring
);
715 // Create a timer to update our status bar
717 m_timer
= new wxMediaPlayerTimer(this);
721 // ----------------------------------------------------------------------------
722 // wxMediaPlayerFrame Destructor
724 // 1) Deletes child objects implicitly
725 // 2) Delete our timer explicitly
726 // ----------------------------------------------------------------------------
727 wxMediaPlayerFrame::~wxMediaPlayerFrame()
729 // Shut down our timer
733 // Here we save our info to the registry or whatever
734 // mechanism the OS uses.
736 // This makes it so that when mediaplayer loads up again
737 // it restores the same files that were in the playlist
738 // this time, rather than the user manually re-adding them.
740 // We need to do conf->DeleteAll() here because by default
741 // the config still contains the same files as last time
742 // so we need to clear it before writing our new ones.
744 // TODO: Maybe you could add a menu option to the
745 // options menu to delete the configuration on exit -
746 // all you'd need to do is just remove everything after
747 // conf->DeleteAll() here
749 // As an exercise to the reader, try modifying this so
750 // that it saves the data for each notebook page
752 wxMediaPlayerListCtrl
* playlist
=
753 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetPage(0))->m_playlist
;
758 for(int i
= 0; i
< playlist
->GetItemCount(); ++i
)
760 wxString
* pData
= (wxString
*) playlist
->GetItemData(i
);
763 conf
.Write(s
, *(pData
));
768 // ----------------------------------------------------------------------------
769 // wxMediaPlayerFrame::OnClose
770 // ----------------------------------------------------------------------------
771 void wxMediaPlayerFrame::OnClose(wxCloseEvent
& event
)
773 event
.Skip(); //really close the frame
776 // ----------------------------------------------------------------------------
777 // wxMediaPlayerFrame::AddToPlayList
778 // ----------------------------------------------------------------------------
779 void wxMediaPlayerFrame::AddToPlayList(const wxString
& szString
)
781 wxMediaPlayerNotebookPage
* currentpage
=
782 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
784 currentpage
->m_playlist
->AddToPlayList(szString
);
787 // ----------------------------------------------------------------------------
788 // wxMediaPlayerFrame::OnQuit
790 // Called from file->quit.
791 // Closes this application.
792 // ----------------------------------------------------------------------------
793 void wxMediaPlayerFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
795 // true is to force the frame to close
799 // ----------------------------------------------------------------------------
800 // wxMediaPlayerFrame::OnAbout
802 // Called from help->about.
803 // Gets some info about this application.
804 // ----------------------------------------------------------------------------
805 void wxMediaPlayerFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
808 msg
.Printf( wxT("This is a test of wxMediaCtrl.\n\n")
810 wxT("Intructions:\n")
812 wxT("The top slider shows the current the current position, ")
813 wxT("which you can change by dragging and releasing it.\n")
815 wxT("The gauge (progress bar) shows the progress in ")
816 wxT("downloading data of the current file - it may always be ")
817 wxT("Empty due to lack of support from the current backend.\n")
819 wxT("The lower-left slider controls the volume and the lower-")
820 wxT("right slider controls the playback rate/speed of the ")
823 wxT("Currently using: %s"), wxVERSION_STRING
);
825 wxMessageBox(msg
, wxT("About wxMediaCtrl test"),
826 wxOK
| wxICON_INFORMATION
, this);
829 // ----------------------------------------------------------------------------
830 // wxMediaPlayerFrame::OnLoop
832 // Called from file->loop.
833 // Changes the state of whether we want to loop or not.
834 // ----------------------------------------------------------------------------
835 void wxMediaPlayerFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
837 wxMediaPlayerNotebookPage
* currentpage
=
838 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
840 currentpage
->m_bLoop
= !currentpage
->m_bLoop
;
843 // ----------------------------------------------------------------------------
844 // wxMediaPlayerFrame::OnLoop
846 // Called from file->loop.
847 // Changes the state of whether we want to loop or not.
848 // ----------------------------------------------------------------------------
849 void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent
& event
)
851 wxMediaPlayerNotebookPage
* currentpage
=
852 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
854 if( !currentpage
->m_mediactrl
->ShowPlayerControls(event
.IsChecked() ?
855 wxMEDIACTRLPLAYERCONTROLS_DEFAULT
:
856 wxMEDIACTRLPLAYERCONTROLS_NONE
) )
858 //error - uncheck and warn user
859 wxMenuItem
* pSIItem
= GetMenuBar()->FindItem(wxID_SHOWINTERFACE
);
861 pSIItem
->Check(!event
.IsChecked());
863 if(event
.IsChecked())
864 wxMessageBox(wxT("Could not show player controls"));
866 wxMessageBox(wxT("Could not hide player controls"));
870 // ----------------------------------------------------------------------------
871 // wxMediaPlayerFrame::OnOpenFileSamePage
873 // Called from file->openfile.
874 // Opens and plays a media file in the current notebook page
875 // ----------------------------------------------------------------------------
876 void wxMediaPlayerFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
881 // ----------------------------------------------------------------------------
882 // wxMediaPlayerFrame::OnOpenFileNewPage
884 // Called from file->openfileinnewpage.
885 // Opens and plays a media file in a new notebook page
886 // ----------------------------------------------------------------------------
887 void wxMediaPlayerFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
892 // ----------------------------------------------------------------------------
893 // wxMediaPlayerFrame::OpenFile
895 // Opens a file dialog asking the user for a filename, then
896 // calls DoOpenFile which will add the file to the playlist and play it
897 // ----------------------------------------------------------------------------
898 void wxMediaPlayerFrame::OpenFile(bool bNewPage
)
900 wxFileDialog
fd(this);
902 if(fd
.ShowModal() == wxID_OK
)
904 DoOpenFile(fd
.GetPath(), bNewPage
);
908 // ----------------------------------------------------------------------------
909 // wxMediaPlayerFrame::DoOpenFile
911 // Adds the file to our playlist, selects it in the playlist,
912 // and then calls DoPlayFile to play it
913 // ----------------------------------------------------------------------------
914 void wxMediaPlayerFrame::DoOpenFile(const wxString
& path
, bool bNewPage
)
919 new wxMediaPlayerNotebookPage(this, m_notebook
),
924 wxMediaPlayerNotebookPage
* currentpage
=
925 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
927 if(currentpage
->m_nLastFileId
!= -1)
928 currentpage
->m_playlist
->SetItemState(currentpage
->m_nLastFileId
,
929 0, wxLIST_STATE_SELECTED
);
931 wxListItem newlistitem
;
932 newlistitem
.SetAlign(wxLIST_FORMAT_LEFT
);
936 newlistitem
.SetId(nID
= currentpage
->m_playlist
->GetItemCount());
937 newlistitem
.SetMask(wxLIST_MASK_DATA
| wxLIST_MASK_STATE
);
938 newlistitem
.SetState(wxLIST_STATE_SELECTED
);
939 newlistitem
.SetData(new wxString(path
));
941 currentpage
->m_playlist
->InsertItem(newlistitem
);
942 currentpage
->m_playlist
->SetItem(nID
, 0, wxT("*"));
943 currentpage
->m_playlist
->SetItem(nID
, 1, wxFileName(path
).GetName());
947 newlistitem
.SetBackgroundColour(wxColour(192,192,192));
948 currentpage
->m_playlist
->SetItem(newlistitem
);
954 // ----------------------------------------------------------------------------
955 // wxMediaPlayerFrame::DoPlayFile
957 // Pauses the file if its the currently playing file,
958 // otherwise it plays the file
959 // ----------------------------------------------------------------------------
960 void wxMediaPlayerFrame::DoPlayFile(const wxString
& path
)
962 wxMediaPlayerNotebookPage
* currentpage
=
963 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
966 currentpage
->m_playlist
->GetSelectedItem(listitem
);
968 if( ( listitem
.GetData() &&
969 currentpage
->m_nLastFileId
== listitem
.GetId() &&
970 currentpage
->m_szFile
.compare(path
) == 0 ) ||
971 ( !listitem
.GetData() &&
972 currentpage
->m_nLastFileId
!= -1 &&
973 currentpage
->m_szFile
.compare(path
) == 0)
976 if(currentpage
->m_mediactrl
->GetState() == wxMEDIASTATE_PLAYING
)
978 if( !currentpage
->m_mediactrl
->Pause() )
979 wxMessageBox(wxT("Couldn't pause movie!"));
983 if( !currentpage
->m_mediactrl
->Play() )
984 wxMessageBox(wxT("Couldn't play movie!"));
989 int nNewId
= listitem
.GetData() ? listitem
.GetId() :
990 currentpage
->m_playlist
->GetItemCount()-1;
991 m_notebook
->SetPageText(m_notebook
->GetSelection(),
992 wxFileName(path
).GetName());
994 if(currentpage
->m_nLastFileId
!= -1)
995 currentpage
->m_playlist
->SetItem(
996 currentpage
->m_nLastFileId
, 0, wxT("*"));
999 if( uripath
.IsReference() )
1001 if( !currentpage
->m_mediactrl
->Load(path
) )
1003 wxMessageBox(wxT("Couldn't load file!"));
1004 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("E"));
1008 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("O"));
1013 if( !currentpage
->m_mediactrl
->Load(uripath
) )
1015 wxMessageBox(wxT("Couldn't load URL!"));
1016 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("E"));
1020 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("O"));
1024 currentpage
->m_nLastFileId
= nNewId
;
1025 currentpage
->m_szFile
= path
;
1026 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
,
1027 1, wxFileName(path
).GetName());
1028 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
,
1033 // ----------------------------------------------------------------------------
1034 // wxMediaPlayerFrame::OnMediaLoaded
1036 // Called when the media is ready to be played - and does
1037 // so, also gets the length of media and shows that in the list control
1038 // ----------------------------------------------------------------------------
1039 void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent
& WXUNUSED(evt
))
1041 wxMediaPlayerNotebookPage
* currentpage
=
1042 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1044 if( !currentpage
->m_mediactrl
->Play() )
1046 wxMessageBox(wxT("Couldn't play movie!"));
1047 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
, 0, wxT("E"));
1051 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
, 0, wxT(">"));
1057 // ----------------------------------------------------------------------------
1058 // wxMediaPlayerFrame::OnSelectBackend
1060 // Little debugging routine - enter the class name of a backend and it
1061 // will use that instead of letting wxMediaCtrl search the wxMediaBackend
1063 // ----------------------------------------------------------------------------
1064 void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent
& WXUNUSED(evt
))
1066 wxString sBackend
= wxGetTextFromUser(wxT("Enter backend to use"));
1068 if(sBackend
.empty() == false) //could have been cancelled by the user
1070 int sel
= m_notebook
->GetSelection();
1072 if (sel
!= wxNOT_FOUND
)
1074 m_notebook
->DeletePage(sel
);
1077 m_notebook
->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook
,
1082 ((wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage())->m_szFile
,
1087 // ----------------------------------------------------------------------------
1088 // wxMediaPlayerFrame::OnOpenURLSamePage
1090 // Called from file->openurl.
1091 // Opens and plays a media file from a URL in the current notebook page
1092 // ----------------------------------------------------------------------------
1093 void wxMediaPlayerFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
1098 // ----------------------------------------------------------------------------
1099 // wxMediaPlayerFrame::OnOpenURLNewPage
1101 // Called from file->openurlinnewpage.
1102 // Opens and plays a media file from a URL in a new notebook page
1103 // ----------------------------------------------------------------------------
1104 void wxMediaPlayerFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
1109 // ----------------------------------------------------------------------------
1110 // wxMediaPlayerFrame::OpenURL
1112 // Just calls DoOpenFile with the url path - which calls DoPlayFile
1113 // which handles the real dirty work
1114 // ----------------------------------------------------------------------------
1115 void wxMediaPlayerFrame::OpenURL(bool bNewPage
)
1117 wxString sUrl
= wxGetTextFromUser(
1118 wxT("Enter the URL that has the movie to play")
1121 if(sUrl
.empty() == false) //could have been cancelled by user
1123 DoOpenFile(sUrl
, bNewPage
);
1127 // ----------------------------------------------------------------------------
1128 // wxMediaPlayerFrame::OnCloseCurrentPage
1130 // Called when the user wants to close the current notebook page
1132 // 1) Get the current page number (wxControl::GetSelection)
1133 // 2) If there is no current page, break out
1134 // 3) Delete the current page
1135 // ----------------------------------------------------------------------------
1136 void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
1138 if( m_notebook
->GetPageCount() > 1 )
1140 int sel
= m_notebook
->GetSelection();
1142 if (sel
!= wxNOT_FOUND
)
1144 m_notebook
->DeletePage(sel
);
1149 wxMessageBox(wxT("Cannot close main page"));
1153 // ----------------------------------------------------------------------------
1154 // wxMediaPlayerFrame::OnPlay
1156 // Called from file->play.
1157 // Resumes the media if it is paused or stopped.
1158 // ----------------------------------------------------------------------------
1159 void wxMediaPlayerFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
1161 wxMediaPlayerNotebookPage
* currentpage
=
1162 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1164 wxListItem listitem
;
1165 currentpage
->m_playlist
->GetSelectedItem(listitem
);
1166 if ( !listitem
.GetData() )
1169 if ((nLast
= currentpage
->m_playlist
->GetNextItem(nLast
,
1171 wxLIST_STATE_DONTCARE
)) == -1)
1174 wxMessageBox(wxT("No items in playlist!"));
1178 listitem
.SetId(nLast
);
1179 currentpage
->m_playlist
->GetItem(listitem
);
1180 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1181 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1182 currentpage
->m_playlist
->SetItem(listitem
);
1183 wxASSERT(listitem
.GetData());
1184 DoPlayFile((*((wxString
*) listitem
.GetData())));
1189 wxASSERT(listitem
.GetData());
1190 DoPlayFile((*((wxString
*) listitem
.GetData())));
1194 // ----------------------------------------------------------------------------
1195 // wxMediaPlayerFrame::OnKeyDown
1197 // Deletes all selected files from the playlist if the backspace key is pressed
1198 // ----------------------------------------------------------------------------
1199 void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent
& event
)
1201 if(event
.GetKeyCode() == WXK_BACK
/*DELETE*/)
1203 wxMediaPlayerNotebookPage
* currentpage
=
1204 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1205 //delete all selected items
1208 wxInt32 nSelectedItem
= currentpage
->m_playlist
->GetNextItem(
1209 -1, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1210 if (nSelectedItem
== -1)
1213 wxListItem listitem
;
1214 listitem
.SetId(nSelectedItem
);
1215 currentpage
->m_playlist
->GetItem(listitem
);
1216 delete (wxString
*) listitem
.GetData();
1218 currentpage
->m_playlist
->DeleteItem(nSelectedItem
);
1222 //Could be wxGetTextFromUser or something else important
1223 if(event
.GetEventObject() != this)
1227 // ----------------------------------------------------------------------------
1228 // wxMediaPlayerFrame::OnStop
1230 // Called from file->stop.
1231 // Where it stops depends on whether you can seek in the
1232 // media control or not - if you can it stops and seeks to the beginning,
1233 // otherwise it will appear to be at the end - but it will start over again
1234 // when Play() is called
1235 // ----------------------------------------------------------------------------
1236 void wxMediaPlayerFrame::OnStop(wxCommandEvent
& WXUNUSED(evt
))
1238 wxMediaPlayerNotebookPage
* currentpage
=
1239 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1241 if( !currentpage
->m_mediactrl
->Stop() )
1242 wxMessageBox(wxT("Couldn't stop movie!"));
1244 currentpage
->m_playlist
->SetItem(
1245 currentpage
->m_nLastFileId
, 0, wxT("[]"));
1249 // ----------------------------------------------------------------------------
1250 // wxMediaPlayerFrame::OnChangeSong
1252 // Routine that plays the currently selected file in the playlist.
1253 // Called when the user actives the song from the playlist,
1254 // and from other various places in the sample
1255 // ----------------------------------------------------------------------------
1256 void wxMediaPlayerFrame::OnChangeSong(wxListEvent
& WXUNUSED(evt
))
1258 wxMediaPlayerNotebookPage
* currentpage
=
1259 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1261 wxListItem listitem
;
1262 currentpage
->m_playlist
->GetSelectedItem(listitem
);
1263 if(listitem
.GetData())
1264 DoPlayFile((*((wxString
*) listitem
.GetData())));
1266 wxMessageBox(wxT("No selected item!"));
1269 // ----------------------------------------------------------------------------
1270 // wxMediaPlayerFrame::OnPrev
1272 // Tedious wxListCtrl stuff. Goes to prevous song in list, or if at the
1273 // beginning goes to the last in the list.
1274 // ----------------------------------------------------------------------------
1275 void wxMediaPlayerFrame::OnPrev(wxCommandEvent
& WXUNUSED(event
))
1277 wxMediaPlayerNotebookPage
* currentpage
=
1278 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1280 if (currentpage
->m_playlist
->GetItemCount() == 0)
1283 wxInt32 nLastSelectedItem
= -1;
1286 wxInt32 nSelectedItem
= currentpage
->m_playlist
->GetNextItem(nLastSelectedItem
,
1287 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1288 if (nSelectedItem
== -1)
1290 nLastSelectedItem
= nSelectedItem
;
1291 currentpage
->m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1294 if (nLastSelectedItem
== -1)
1296 //nothing selected, default to the file before the currently playing one
1297 if(currentpage
->m_nLastFileId
== 0)
1298 nLastSelectedItem
= currentpage
->m_playlist
->GetItemCount() - 1;
1300 nLastSelectedItem
= currentpage
->m_nLastFileId
- 1;
1302 else if (nLastSelectedItem
== 0)
1303 nLastSelectedItem
= currentpage
->m_playlist
->GetItemCount() - 1;
1305 nLastSelectedItem
-= 1;
1307 if(nLastSelectedItem
== currentpage
->m_nLastFileId
)
1308 return; //already playing... nothing to do
1310 wxListItem listitem
;
1311 listitem
.SetId(nLastSelectedItem
);
1312 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
1313 currentpage
->m_playlist
->GetItem(listitem
);
1314 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1315 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1316 currentpage
->m_playlist
->SetItem(listitem
);
1318 wxASSERT(listitem
.GetData());
1319 DoPlayFile((*((wxString
*) listitem
.GetData())));
1322 // ----------------------------------------------------------------------------
1323 // wxMediaPlayerFrame::OnNext
1325 // Tedious wxListCtrl stuff. Goes to next song in list, or if at the
1326 // end goes to the first in the list.
1327 // ----------------------------------------------------------------------------
1328 void wxMediaPlayerFrame::OnNext(wxCommandEvent
& WXUNUSED(event
))
1330 wxMediaPlayerNotebookPage
* currentpage
=
1331 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1333 if (currentpage
->m_playlist
->GetItemCount() == 0)
1336 wxInt32 nLastSelectedItem
= -1;
1339 wxInt32 nSelectedItem
= currentpage
->m_playlist
->GetNextItem(nLastSelectedItem
,
1340 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1341 if (nSelectedItem
== -1)
1343 nLastSelectedItem
= nSelectedItem
;
1344 currentpage
->m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1347 if (nLastSelectedItem
== -1)
1349 if(currentpage
->m_nLastFileId
== currentpage
->m_playlist
->GetItemCount() - 1)
1350 nLastSelectedItem
= 0;
1352 nLastSelectedItem
= currentpage
->m_nLastFileId
+ 1;
1354 else if (nLastSelectedItem
== currentpage
->m_playlist
->GetItemCount() - 1)
1355 nLastSelectedItem
= 0;
1357 nLastSelectedItem
+= 1;
1359 if(nLastSelectedItem
== currentpage
->m_nLastFileId
)
1360 return; //already playing... nothing to do
1362 wxListItem listitem
;
1363 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
1364 listitem
.SetId(nLastSelectedItem
);
1365 currentpage
->m_playlist
->GetItem(listitem
);
1366 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1367 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1368 currentpage
->m_playlist
->SetItem(listitem
);
1370 wxASSERT(listitem
.GetData());
1371 DoPlayFile((*((wxString
*) listitem
.GetData())));
1375 // ----------------------------------------------------------------------------
1376 // wxMediaPlayerFrame::OnVolumeDown
1378 // Lowers the volume of the media control by 5%
1379 // ----------------------------------------------------------------------------
1380 void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent
& WXUNUSED(event
))
1382 wxMediaPlayerNotebookPage
* currentpage
=
1383 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1385 double dVolume
= currentpage
->m_mediactrl
->GetVolume();
1386 currentpage
->m_mediactrl
->SetVolume(dVolume
< 0.05 ? 0.0 : dVolume
- .05);
1389 // ----------------------------------------------------------------------------
1390 // wxMediaPlayerFrame::OnVolumeUp
1392 // Increases the volume of the media control by 5%
1393 // ----------------------------------------------------------------------------
1394 void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent
& WXUNUSED(event
))
1396 wxMediaPlayerNotebookPage
* currentpage
=
1397 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1399 double dVolume
= currentpage
->m_mediactrl
->GetVolume();
1400 currentpage
->m_mediactrl
->SetVolume(dVolume
> 0.95 ? 1.0 : dVolume
+ .05);
1403 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1405 // wxMediaPlayerTimer
1407 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1409 // ----------------------------------------------------------------------------
1410 // wxMediaPlayerTimer::Notify
1412 // 1) Updates media information on the status bar
1413 // 2) Sets the max/min length of the slider and guage
1415 // Note that the reason we continually do this and don't cache it is because
1416 // some backends such as GStreamer are dynamic change values all the time
1417 // and often don't have things like duration or video size available
1418 // until the media is actually being played
1419 // ----------------------------------------------------------------------------
1420 void wxMediaPlayerTimer::Notify()
1422 wxMediaPlayerNotebookPage
* currentpage
=
1423 (wxMediaPlayerNotebookPage
*) m_frame
->m_notebook
->GetCurrentPage();
1424 wxMediaCtrl
* currentMediaCtrl
= currentpage
->m_mediactrl
;
1428 // Number of minutes/seconds total
1429 wxLongLong llLength
= currentpage
->m_mediactrl
->Length();
1430 int nMinutes
= (int) (llLength
/ 60000).GetValue();
1431 int nSeconds
= (int) ((llLength
% 60000)/1000).GetValue();
1433 // Duration string (i.e. MM:SS)
1435 sDuration
.Printf(wxT("%2i:%02i"), nMinutes
, nSeconds
);
1438 // Number of minutes/seconds total
1439 wxLongLong llTell
= currentpage
->m_mediactrl
->Tell();
1440 nMinutes
= (int) (llTell
/ 60000).GetValue();
1441 nSeconds
= (int) ((llTell
% 60000)/1000).GetValue();
1443 // Position string (i.e. MM:SS)
1445 sPosition
.Printf(wxT("%2i:%02i"), nMinutes
, nSeconds
);
1448 // Set the third item in the listctrl entry to the duration string
1449 if(currentpage
->m_nLastFileId
>= 0)
1450 currentpage
->m_playlist
->SetItem(
1451 currentpage
->m_nLastFileId
, 2, sDuration
);
1453 // Setup the slider and gauge min/max values
1454 currentpage
->m_slider
->SetRange(0, (int)(llLength
/ 1000).GetValue());
1455 currentpage
->m_gauge
->SetRange(100);
1458 // if the slider is not being dragged then update it with the song position
1459 if(currentpage
->IsBeingDragged() == false)
1460 currentpage
->m_slider
->SetValue((long)(llTell
/ 1000).GetValue());
1463 // Update the gauge with the download progress
1464 wxLongLong llDownloadProgress
=
1465 currentpage
->m_mediactrl
->GetDownloadProgress();
1466 wxLongLong llDownloadTotal
=
1467 currentpage
->m_mediactrl
->GetDownloadTotal();
1469 if(llDownloadTotal
.GetValue() != 0)
1471 currentpage
->m_gauge
->SetValue(
1472 (int) ((llDownloadProgress
* 100) / llDownloadTotal
).GetValue()
1476 // GetBestSize holds the original video size
1477 wxSize videoSize
= currentMediaCtrl
->GetBestSize();
1479 // Now the big part - set the status bar text to
1480 // hold various metadata about the media
1482 m_frame
->SetStatusText(wxString::Format(
1483 wxT("Size(x,y):%i,%i ")
1484 wxT("Position:%s/%s Speed:%1.1fx ")
1485 wxT("State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
1490 currentMediaCtrl
->GetPlaybackRate(),
1491 wxGetMediaStateText(currentpage
->m_mediactrl
->GetState()),
1492 currentpage
->m_nLoops
,
1493 (int)llDownloadProgress
.GetValue(),
1494 (int)llDownloadTotal
.GetValue(),
1495 (int)(currentpage
->m_mediactrl
->GetVolume() * 100)));
1496 #endif // wxUSE_STATUSBAR
1500 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1502 // wxMediaPlayerNotebookPage
1504 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1506 // ----------------------------------------------------------------------------
1507 // wxMediaPlayerNotebookPage Constructor
1509 // Creates a media control and slider and adds it to this panel,
1510 // along with some sizers for positioning
1511 // ----------------------------------------------------------------------------
1512 wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
1513 wxNotebook
* theBook
,
1514 const wxString
& szBackend
)
1515 : wxPanel(theBook
, wxID_ANY
),
1519 m_bIsBeingDragged(false),
1520 m_parentFrame(parentFrame
)
1527 // [5 control buttons]
1533 // Create and attach the sizer
1535 wxFlexGridSizer
* sizer
= new wxFlexGridSizer(2, 1, 0, 0);
1536 this->SetSizer(sizer
);
1537 sizer
->AddGrowableRow(0);
1538 sizer
->AddGrowableCol(0);
1541 // Create our media control
1543 m_mediactrl
= new wxMediaCtrl();
1545 // Make sure creation was successful
1546 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
, wxEmptyString
,
1547 wxDefaultPosition
, wxDefaultSize
, 0,
1548 //you could specify a macrod backend here like
1549 // wxMEDIABACKEND_WMP10);
1550 // wxT("wxPDFMediaBackend"));
1552 //you could change the cursor here like
1553 // m_mediactrl->SetCursor(wxCURSOR_BLANK);
1554 //note that this may not effect it if SetPlayerControls
1555 //is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
1556 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
1559 sizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1562 // Create the playlist/listctrl
1564 m_playlist
= new wxMediaPlayerListCtrl();
1565 m_playlist
->Create(this, wxID_LISTCTRL
, wxDefaultPosition
,
1567 wxLC_REPORT
//wxLC_LIST
1570 // Set the background of our listctrl to white
1571 m_playlist
->SetBackgroundColour(wxColour(255,255,255));
1573 // The layout of the headers of the listctrl are like
1574 // | | File | Length
1576 // Where Column one is a character representing the state the file is in:
1577 // * - not the current file
1578 // E - Error has occured
1579 // > - Currently Playing
1582 // (( - Volume Down 5%
1583 // )) - Volume Up 5%
1585 // Column two is the name of the file
1587 // Column three is the length in seconds of the file
1588 m_playlist
->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER
, 20);
1589 m_playlist
->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT
, /*wxLIST_AUTOSIZE_USEHEADER*/305);
1590 m_playlist
->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER
, 75);
1592 #if wxUSE_DRAG_AND_DROP
1593 m_playlist
->SetDropTarget(new wxPlayListDropTarget(*m_playlist
));
1596 sizer
->Add(m_playlist
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1599 // Create the control buttons
1600 // TODO/FIXME/HACK: This part about sizers is really a nice hack
1601 // and probably isn't proper
1603 wxBoxSizer
* horsizer1
= new wxBoxSizer(wxHORIZONTAL
);
1604 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxHORIZONTAL
);
1606 m_prevButton
= new wxButton();
1607 m_playButton
= new wxButton();
1608 m_stopButton
= new wxButton();
1609 m_nextButton
= new wxButton();
1610 m_vdButton
= new wxButton();
1611 m_vuButton
= new wxButton();
1613 m_prevButton
->Create(this, wxID_BUTTONPREV
, wxT("|<"));
1614 m_playButton
->Create(this, wxID_BUTTONPLAY
, wxT(">"));
1615 m_stopButton
->Create(this, wxID_BUTTONSTOP
, wxT("[]"));
1616 m_nextButton
->Create(this, wxID_BUTTONNEXT
, wxT(">|"));
1617 m_vdButton
->Create(this, wxID_BUTTONVD
, wxT("(("));
1618 m_vuButton
->Create(this, wxID_BUTTONVU
, wxT("))"));
1619 vertsizer
->Add(m_prevButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1620 vertsizer
->Add(m_playButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1621 vertsizer
->Add(m_stopButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1622 vertsizer
->Add(m_nextButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1623 vertsizer
->Add(m_vdButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1624 vertsizer
->Add(m_vuButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1625 horsizer1
->Add(vertsizer
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1626 sizer
->Add(horsizer1
, 0, wxALIGN_CENTER_VERTICAL
|wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
1630 // Create our slider
1632 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
1635 wxDefaultPosition
, wxDefaultSize
,
1637 sizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1642 m_gauge
= new wxGauge();
1643 m_gauge
->Create(this, wxID_GAUGE
, 0, wxDefaultPosition
, wxDefaultSize
,
1644 wxGA_HORIZONTAL
| wxGA_SMOOTH
);
1645 sizer
->Add(m_gauge
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1649 // Create the speed/volume sliders
1651 wxBoxSizer
* horsizer3
= new wxBoxSizer(wxHORIZONTAL
);
1653 m_volSlider
= new wxSlider(this, wxID_VOLSLIDER
, 100, // init
1656 wxDefaultPosition
, wxSize(250,20),
1658 horsizer3
->Add(m_volSlider
, 1, wxALL
, 5);
1660 m_pbSlider
= new wxSlider(this, wxID_PBSLIDER
, 4, // init
1663 wxDefaultPosition
, wxSize(250,20),
1665 horsizer3
->Add(m_pbSlider
, 1, wxALL
, 5);
1666 sizer
->Add(horsizer3
, 1, wxCENTRE
| wxALL
, 5);
1671 this->Connect( wxID_LISTCTRL
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED
,
1672 wxListEventHandler(wxMediaPlayerFrame::OnChangeSong
),
1673 (wxObject
*)0, parentFrame
);
1678 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBTRACK
,
1679 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek
));
1680 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1681 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek
));
1682 this->Connect(wxID_PBSLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1683 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnPBChange
));
1684 this->Connect(wxID_VOLSLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1685 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnVolChange
));
1688 // Media Control events
1690 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_PLAY
,
1691 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPlay
));
1692 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_PAUSE
,
1693 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPause
));
1694 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_STOP
,
1695 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaStop
));
1696 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
1697 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished
));
1698 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_LOADED
,
1699 wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded
),
1700 (wxObject
*)0, parentFrame
);
1705 this->Connect( wxID_BUTTONPREV
, wxEVT_COMMAND_BUTTON_CLICKED
,
1706 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
),
1707 (wxObject
*)0, parentFrame
);
1708 this->Connect( wxID_BUTTONPLAY
, wxEVT_COMMAND_BUTTON_CLICKED
,
1709 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
),
1710 (wxObject
*)0, parentFrame
);
1711 this->Connect( wxID_BUTTONSTOP
, wxEVT_COMMAND_BUTTON_CLICKED
,
1712 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
),
1713 (wxObject
*)0, parentFrame
);
1714 this->Connect( wxID_BUTTONNEXT
, wxEVT_COMMAND_BUTTON_CLICKED
,
1715 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
),
1716 (wxObject
*)0, parentFrame
);
1717 this->Connect( wxID_BUTTONVD
, wxEVT_COMMAND_BUTTON_CLICKED
,
1718 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown
),
1719 (wxObject
*)0, parentFrame
);
1720 this->Connect( wxID_BUTTONVU
, wxEVT_COMMAND_BUTTON_CLICKED
,
1721 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp
),
1722 (wxObject
*)0, parentFrame
);
1725 // ----------------------------------------------------------------------------
1726 // MyNotebook::OnBeginSeek
1728 // Sets m_bIsBeingDragged to true to stop the timer from changing the position
1730 // ----------------------------------------------------------------------------
1731 void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent
& WXUNUSED(event
))
1733 m_bIsBeingDragged
= true;
1736 // ----------------------------------------------------------------------------
1737 // MyNotebook::OnEndSeek
1739 // Called from file->seek.
1740 // Called when the user moves the slider -
1741 // seeks to a position within the media
1742 // then sets m_bIsBeingDragged to false to ok the timer to change the position
1743 // ----------------------------------------------------------------------------
1744 void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent
& WXUNUSED(event
))
1746 if( m_mediactrl
->Seek(
1747 m_slider
->GetValue() * 1000
1748 ) == wxInvalidOffset
)
1749 wxMessageBox(wxT("Couldn't seek in movie!"));
1751 m_bIsBeingDragged
= false;
1754 // ----------------------------------------------------------------------------
1755 // wxMediaPlayerNotebookPage::IsBeingDragged
1757 // Returns true if the user is dragging the slider
1758 // ----------------------------------------------------------------------------
1759 bool wxMediaPlayerNotebookPage::IsBeingDragged()
1761 return m_bIsBeingDragged
;
1764 // ----------------------------------------------------------------------------
1765 // wxMediaPlayerNotebookPage::OnVolChange
1767 // Called when the user is done dragging the volume-changing slider
1768 // ----------------------------------------------------------------------------
1769 void wxMediaPlayerNotebookPage::OnVolChange(wxScrollEvent
& WXUNUSED(event
))
1771 if( m_mediactrl
->SetVolume(
1772 m_volSlider
->GetValue() / 100.0
1774 wxMessageBox(wxT("Couldn't set volume!"));
1778 // ----------------------------------------------------------------------------
1779 // wxMediaPlayerNotebookPage::OnPBChange
1781 // Called when the user is done dragging the speed-changing slider
1782 // ----------------------------------------------------------------------------
1783 void wxMediaPlayerNotebookPage::OnPBChange(wxScrollEvent
& WXUNUSED(event
))
1785 if( m_mediactrl
->SetPlaybackRate(
1786 m_pbSlider
->GetValue() * .25
1788 wxMessageBox(wxT("Couldn't set playbackrate!"));
1792 // ----------------------------------------------------------------------------
1793 // wxMediaPlayerNotebookPage::OnMediaPlay
1795 // Called when the media plays.
1796 // ----------------------------------------------------------------------------
1797 void wxMediaPlayerNotebookPage::OnMediaPlay(wxMediaEvent
& WXUNUSED(event
))
1799 m_playlist
->SetItem(m_nLastFileId
, 0, wxT(">"));
1802 // ----------------------------------------------------------------------------
1803 // wxMediaPlayerNotebookPage::OnMediaPause
1805 // Called when the media is paused.
1806 // ----------------------------------------------------------------------------
1807 void wxMediaPlayerNotebookPage::OnMediaPause(wxMediaEvent
& WXUNUSED(event
))
1809 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("||"));
1812 // ----------------------------------------------------------------------------
1813 // wxMediaPlayerNotebookPage::OnMediaStop
1815 // Called when the media stops.
1816 // ----------------------------------------------------------------------------
1817 void wxMediaPlayerNotebookPage::OnMediaStop(wxMediaEvent
& WXUNUSED(event
))
1819 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("[]"));
1822 // ----------------------------------------------------------------------------
1823 // wxMediaPlayerNotebookPage::OnMediaFinished
1825 // Called when the media finishes playing.
1826 // Here we loop it if the user wants to (has been selected from file menu)
1827 // ----------------------------------------------------------------------------
1828 void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
1832 if ( !m_mediactrl
->Play() )
1834 wxMessageBox(wxT("Couldn't loop movie!"));
1835 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("E"));
1842 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("[]"));
1847 // End of MediaPlayer sample