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 // SetAppName() lets wxConfig and others know where to write
413 SetAppName(wxT("wxMediaPlayer"));
415 wxMediaPlayerFrame
*frame
=
416 new wxMediaPlayerFrame(wxT("MediaPlayer wxWidgets Sample"));
419 #if wxUSE_CMDLINE_PARSER
421 // What this does is get all the command line arguments
422 // and treat each one as a file to put to the initial playlist
424 wxCmdLineEntryDesc cmdLineDesc
[2];
425 cmdLineDesc
[0].kind
= wxCMD_LINE_PARAM
;
426 cmdLineDesc
[0].shortName
= NULL
;
427 cmdLineDesc
[0].longName
= NULL
;
428 cmdLineDesc
[0].description
= wxT("input files");
429 cmdLineDesc
[0].type
= wxCMD_LINE_VAL_STRING
;
430 cmdLineDesc
[0].flags
= wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
;
432 cmdLineDesc
[1].kind
= wxCMD_LINE_NONE
;
434 //gets the passed media files from cmd line
435 wxCmdLineParser
parser (cmdLineDesc
, argc
, argv
);
437 // get filenames from the commandline
438 if (parser
.Parse() == 0)
440 for (size_t paramNr
=0; paramNr
< parser
.GetParamCount(); ++paramNr
)
442 frame
->AddToPlayList((parser
.GetParam (paramNr
)));
444 wxCommandEvent
theEvent(wxEVT_COMMAND_MENU_SELECTED
, wxID_NEXT
);
445 frame
->AddPendingEvent(theEvent
);
454 void wxMediaPlayerApp::MacOpenFile(const wxString
& fileName
)
456 //Called when a user drags a file over our app
457 m_frame
->DoOpenFile(fileName
, true /* new page */);
462 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
464 // wxMediaPlayerFrame
466 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
468 // ----------------------------------------------------------------------------
469 // wxMediaPlayerFrame Constructor
471 // 1) Create our menus
472 // 2) Create our notebook control and add it to the frame
473 // 3) Create our status bar
474 // 4) Connect our events
475 // 5) Start our timer
476 // ----------------------------------------------------------------------------
478 wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString
& title
)
479 : wxFrame(NULL
, wxID_ANY
, title
, wxDefaultPosition
, wxSize(600,600))
484 wxMenu
*fileMenu
= new wxMenu
;
485 wxMenu
*controlsMenu
= new wxMenu
;
486 wxMenu
*optionsMenu
= new wxMenu
;
487 wxMenu
*helpMenu
= new wxMenu
;
488 wxMenu
*debugMenu
= new wxMenu
;
490 fileMenu
->Append(wxID_OPENFILESAMEPAGE
, wxT("&Open File\tCtrl-Shift-O"),
491 wxT("Open a File in the current notebook page"));
492 fileMenu
->Append(wxID_OPENFILENEWPAGE
, wxT("&Open File in a new page"),
493 wxT("Open a File in a new notebook page"));
494 fileMenu
->Append(wxID_OPENURLSAMEPAGE
, wxT("&Open URL"),
495 wxT("Open a URL in the current notebook page"));
496 fileMenu
->Append(wxID_OPENURLNEWPAGE
, wxT("&Open URL in a new page"),
497 wxT("Open a URL in a new notebook page"));
498 fileMenu
->AppendSeparator();
499 fileMenu
->Append(wxID_CLOSECURRENTPAGE
, wxT("&Close Current Page\tCtrl-C"),
500 wxT("Close current notebook page"));
501 fileMenu
->AppendSeparator();
502 fileMenu
->Append(wxID_EXIT
,
504 wxT("Quit this program"));
506 controlsMenu
->Append(wxID_PLAY
, wxT("&Play/Pause\tCtrl-P"), wxT("Resume/Pause playback"));
507 controlsMenu
->Append(wxID_STOP
, wxT("&Stop\tCtrl-S"), wxT("Stop playback"));
508 controlsMenu
->AppendSeparator();
509 controlsMenu
->Append(wxID_PREV
, wxT("&Previous\tCtrl-B"), wxT("Go to previous track"));
510 controlsMenu
->Append(wxID_NEXT
, wxT("&Next\tCtrl-N"), wxT("Skip to next track"));
512 optionsMenu
->AppendCheckItem(wxID_LOOP
,
513 wxT("&Loop\tCtrl-L"),
514 wxT("Loop Selected Media"));
515 optionsMenu
->AppendCheckItem(wxID_SHOWINTERFACE
,
516 wxT("&Show Interface\tCtrl-I"),
517 wxT("Show wxMediaCtrl native controls"));
519 debugMenu
->Append(wxID_SELECTBACKEND
,
520 wxT("&Select Backend...\tCtrl-D"),
521 wxT("Select a backend manually"));
523 helpMenu
->Append(wxID_ABOUT
,
524 wxT("&About...\tF1"),
525 wxT("Show about dialog"));
528 wxMenuBar
*menuBar
= new wxMenuBar();
529 menuBar
->Append(fileMenu
, wxT("&File"));
530 menuBar
->Append(controlsMenu
, wxT("&Controls"));
531 menuBar
->Append(optionsMenu
, wxT("&Options"));
532 menuBar
->Append(debugMenu
, wxT("&Debug"));
533 menuBar
->Append(helpMenu
, wxT("&Help"));
537 // Create our notebook - using wxNotebook is luckily pretty
538 // simple and self-explanatory in most cases
540 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
543 // Create our status bar
546 // create a status bar just for fun (by default with 1 pane only)
548 #endif // wxUSE_STATUSBAR
553 // There are two ways in wxWidgets to use events -
554 // Message Maps and Connections.
556 // Message Maps are implemented by putting
557 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
558 // class you want to use for events, such as wxMediaPlayerFrame.
560 // Then after your class declaration you put
561 // BEGIN_EVENT_TABLE(wxMediaPlayerFrame, wxFrame)
565 // Where wxMediaPlayerFrame is the class with the DECLARE_MESSAGE_MAP
566 // in it. EVT_XXX(XXX) are each of your handlers, such
567 // as EVT_MENU for menu events and the XXX inside
568 // is the parameters to the event macro - in the case
569 // of EVT_MENU the menu id and then the function to call.
571 // However, with wxEvtHandler::Connect you can avoid a
572 // global message map for your class and those annoying
573 // macros. You can also change the context in which
574 // the call the handler (more later).
576 // The downside is that due to the limitation that
577 // wxWidgets doesn't use templates in certain areas,
578 // You have to triple-cast the event function.
580 // There are five parameters to wxEvtHandler::Connect -
582 // The first is the id of the instance whose events
583 // you want to handle - i.e. a menu id for menus,
584 // a control id for controls (wxControl::GetId())
587 // The second is the event id. This is the same
588 // as the message maps (EVT_MENU) except prefixed
589 // with "wx" (wxEVT_MENU).
591 // The third is the function handler for the event -
592 // You need to cast it to the specific event handler
593 // type, then to a wxEventFunction, then to a
594 // wxObjectEventFunction - I.E.
595 // (wxObjectEventFunction)(wxEventFunction)
596 // (wxCommandEventFunction) &wxMediaPlayerFrame::MyHandler
598 // Or, you can use the new (2.5.5+) event handler
599 // conversion macros - for instance the above could
601 // wxCommandEventHandler(wxMediaPlayerFrame::MyHandler)
602 // pretty simple, eh?
604 // The fourth is an optional userdata param -
605 // this is of historical relevance only and is
606 // there only for backwards compatibility.
608 // The fifth is the context in which to call the
609 // handler - by default (this param is optional)
610 // this. For example in your event handler
611 // if you were to call "this->MyFunc()"
612 // it would literally do this->MyFunc. However,
613 // if you were to pass myHandler as the fifth
614 // parameter, for instance, you would _really_
615 // be calling myHandler->MyFunc, even though
616 // the compiler doesn't really know it.
622 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
623 wxCommandEventHandler(wxMediaPlayerFrame::OnQuit
));
625 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
626 wxCommandEventHandler(wxMediaPlayerFrame::OnAbout
));
628 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
629 wxCommandEventHandler(wxMediaPlayerFrame::OnLoop
));
631 this->Connect(wxID_SHOWINTERFACE
, wxEVT_COMMAND_MENU_SELECTED
,
632 wxCommandEventHandler(wxMediaPlayerFrame::OnShowInterface
));
634 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
635 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileNewPage
));
637 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
638 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileSamePage
));
640 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
641 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLNewPage
));
643 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
644 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLSamePage
));
646 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
647 wxCommandEventHandler(wxMediaPlayerFrame::OnCloseCurrentPage
));
649 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
650 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
));
652 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
653 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
));
655 this->Connect(wxID_NEXT
, wxEVT_COMMAND_MENU_SELECTED
,
656 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
));
658 this->Connect(wxID_PREV
, wxEVT_COMMAND_MENU_SELECTED
,
659 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
));
661 this->Connect(wxID_SELECTBACKEND
, wxEVT_COMMAND_MENU_SELECTED
,
662 wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend
));
667 wxTheApp
->Connect(wxID_ANY
, wxEVT_KEY_DOWN
,
668 wxKeyEventHandler(wxMediaPlayerFrame::OnKeyDown
),
674 this->Connect(wxID_ANY
, wxEVT_CLOSE_WINDOW
,
675 wxCloseEventHandler(wxMediaPlayerFrame::OnClose
));
682 // Create an initial notebook page so the user has something
683 // to work with without having to go file->open every time :).
685 wxMediaPlayerNotebookPage
* page
=
686 new wxMediaPlayerNotebookPage(this, m_notebook
);
687 m_notebook
->AddPage(page
,
692 // Here we load the our configuration -
693 // in our case we load all the files that were left in
694 // the playlist the last time the user closed our application
696 // As an exercise to the reader try modifying it so that
697 // it properly loads the playlist for each page without
698 // conflicting (loading the same data) with the other ones.
701 wxString key
, outstring
;
702 for(int i
= 0; ; ++i
)
706 if(!conf
.Read(key
, &outstring
))
708 page
->m_playlist
->AddToPlayList(outstring
);
712 // Create a timer to update our status bar
714 m_timer
= new wxMediaPlayerTimer(this);
718 // ----------------------------------------------------------------------------
719 // wxMediaPlayerFrame Destructor
721 // 1) Deletes child objects implicitly
722 // 2) Delete our timer explicitly
723 // ----------------------------------------------------------------------------
724 wxMediaPlayerFrame::~wxMediaPlayerFrame()
726 // Shut down our timer
730 // Here we save our info to the registry or whatever
731 // mechanism the OS uses.
733 // This makes it so that when mediaplayer loads up again
734 // it restores the same files that were in the playlist
735 // this time, rather than the user manually re-adding them.
737 // We need to do conf->DeleteAll() here because by default
738 // the config still contains the same files as last time
739 // so we need to clear it before writing our new ones.
741 // TODO: Maybe you could add a menu option to the
742 // options menu to delete the configuration on exit -
743 // all you'd need to do is just remove everything after
744 // conf->DeleteAll() here
746 // As an exercise to the reader, try modifying this so
747 // that it saves the data for each notebook page
749 wxMediaPlayerListCtrl
* playlist
=
750 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetPage(0))->m_playlist
;
755 for(int i
= 0; i
< playlist
->GetItemCount(); ++i
)
757 wxString
* pData
= (wxString
*) playlist
->GetItemData(i
);
760 conf
.Write(s
, *(pData
));
765 // ----------------------------------------------------------------------------
766 // wxMediaPlayerFrame::OnClose
767 // ----------------------------------------------------------------------------
768 void wxMediaPlayerFrame::OnClose(wxCloseEvent
& event
)
770 event
.Skip(); //really close the frame
773 // ----------------------------------------------------------------------------
774 // wxMediaPlayerFrame::AddToPlayList
775 // ----------------------------------------------------------------------------
776 void wxMediaPlayerFrame::AddToPlayList(const wxString
& szString
)
778 wxMediaPlayerNotebookPage
* currentpage
=
779 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
781 currentpage
->m_playlist
->AddToPlayList(szString
);
784 // ----------------------------------------------------------------------------
785 // wxMediaPlayerFrame::OnQuit
787 // Called from file->quit.
788 // Closes this application.
789 // ----------------------------------------------------------------------------
790 void wxMediaPlayerFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
792 // true is to force the frame to close
796 // ----------------------------------------------------------------------------
797 // wxMediaPlayerFrame::OnAbout
799 // Called from help->about.
800 // Gets some info about this application.
801 // ----------------------------------------------------------------------------
802 void wxMediaPlayerFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
805 msg
.Printf( wxT("This is a test of wxMediaCtrl.\n\n")
807 wxT("Intructions:\n")
809 wxT("The top slider shows the current the current position, ")
810 wxT("which you can change by dragging and releasing it.\n")
812 wxT("The gauge (progress bar) shows the progress in ")
813 wxT("downloading data of the current file - it may always be ")
814 wxT("Empty due to lack of support from the current backend.\n")
816 wxT("The lower-left slider controls the volume and the lower-")
817 wxT("right slider controls the playback rate/speed of the ")
820 wxT("Currently using: %s"), wxVERSION_STRING
);
822 wxMessageBox(msg
, wxT("About wxMediaCtrl test"),
823 wxOK
| wxICON_INFORMATION
, this);
826 // ----------------------------------------------------------------------------
827 // wxMediaPlayerFrame::OnLoop
829 // Called from file->loop.
830 // Changes the state of whether we want to loop or not.
831 // ----------------------------------------------------------------------------
832 void wxMediaPlayerFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
834 wxMediaPlayerNotebookPage
* currentpage
=
835 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
837 currentpage
->m_bLoop
= !currentpage
->m_bLoop
;
840 // ----------------------------------------------------------------------------
841 // wxMediaPlayerFrame::OnLoop
843 // Called from file->loop.
844 // Changes the state of whether we want to loop or not.
845 // ----------------------------------------------------------------------------
846 void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent
& event
)
848 wxMediaPlayerNotebookPage
* currentpage
=
849 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
851 if( !currentpage
->m_mediactrl
->ShowPlayerControls(event
.IsChecked() ?
852 wxMEDIACTRLPLAYERCONTROLS_DEFAULT
:
853 wxMEDIACTRLPLAYERCONTROLS_NONE
) )
855 //error - uncheck and warn user
856 wxMenuItem
* pSIItem
= GetMenuBar()->FindItem(wxID_SHOWINTERFACE
);
858 pSIItem
->Check(!event
.IsChecked());
860 if(event
.IsChecked())
861 wxMessageBox(wxT("Could not show player controls"));
863 wxMessageBox(wxT("Could not hide player controls"));
867 // ----------------------------------------------------------------------------
868 // wxMediaPlayerFrame::OnOpenFileSamePage
870 // Called from file->openfile.
871 // Opens and plays a media file in the current notebook page
872 // ----------------------------------------------------------------------------
873 void wxMediaPlayerFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
878 // ----------------------------------------------------------------------------
879 // wxMediaPlayerFrame::OnOpenFileNewPage
881 // Called from file->openfileinnewpage.
882 // Opens and plays a media file in a new notebook page
883 // ----------------------------------------------------------------------------
884 void wxMediaPlayerFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
889 // ----------------------------------------------------------------------------
890 // wxMediaPlayerFrame::OpenFile
892 // Opens a file dialog asking the user for a filename, then
893 // calls DoOpenFile which will add the file to the playlist and play it
894 // ----------------------------------------------------------------------------
895 void wxMediaPlayerFrame::OpenFile(bool bNewPage
)
897 wxFileDialog
fd(this);
899 if(fd
.ShowModal() == wxID_OK
)
901 DoOpenFile(fd
.GetPath(), bNewPage
);
905 // ----------------------------------------------------------------------------
906 // wxMediaPlayerFrame::DoOpenFile
908 // Adds the file to our playlist, selects it in the playlist,
909 // and then calls DoPlayFile to play it
910 // ----------------------------------------------------------------------------
911 void wxMediaPlayerFrame::DoOpenFile(const wxString
& path
, bool bNewPage
)
916 new wxMediaPlayerNotebookPage(this, m_notebook
),
921 wxMediaPlayerNotebookPage
* currentpage
=
922 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
924 if(currentpage
->m_nLastFileId
!= -1)
925 currentpage
->m_playlist
->SetItemState(currentpage
->m_nLastFileId
,
926 0, wxLIST_STATE_SELECTED
);
928 wxListItem newlistitem
;
929 newlistitem
.SetAlign(wxLIST_FORMAT_LEFT
);
933 newlistitem
.SetId(nID
= currentpage
->m_playlist
->GetItemCount());
934 newlistitem
.SetMask(wxLIST_MASK_DATA
| wxLIST_MASK_STATE
);
935 newlistitem
.SetState(wxLIST_STATE_SELECTED
);
936 newlistitem
.SetData(new wxString(path
));
938 currentpage
->m_playlist
->InsertItem(newlistitem
);
939 currentpage
->m_playlist
->SetItem(nID
, 0, wxT("*"));
940 currentpage
->m_playlist
->SetItem(nID
, 1, wxFileName(path
).GetName());
944 newlistitem
.SetBackgroundColour(wxColour(192,192,192));
945 currentpage
->m_playlist
->SetItem(newlistitem
);
951 // ----------------------------------------------------------------------------
952 // wxMediaPlayerFrame::DoPlayFile
954 // Pauses the file if its the currently playing file,
955 // otherwise it plays the file
956 // ----------------------------------------------------------------------------
957 void wxMediaPlayerFrame::DoPlayFile(const wxString
& path
)
959 wxMediaPlayerNotebookPage
* currentpage
=
960 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
963 currentpage
->m_playlist
->GetSelectedItem(listitem
);
965 if( ( listitem
.GetData() &&
966 currentpage
->m_nLastFileId
== listitem
.GetId() &&
967 currentpage
->m_szFile
.compare(path
) == 0 ) ||
968 ( !listitem
.GetData() &&
969 currentpage
->m_nLastFileId
!= -1 &&
970 currentpage
->m_szFile
.compare(path
) == 0)
973 if(currentpage
->m_mediactrl
->GetState() == wxMEDIASTATE_PLAYING
)
975 if( !currentpage
->m_mediactrl
->Pause() )
976 wxMessageBox(wxT("Couldn't pause movie!"));
980 if( !currentpage
->m_mediactrl
->Play() )
981 wxMessageBox(wxT("Couldn't play movie!"));
986 int nNewId
= listitem
.GetData() ? listitem
.GetId() :
987 currentpage
->m_playlist
->GetItemCount()-1;
988 m_notebook
->SetPageText(m_notebook
->GetSelection(),
989 wxFileName(path
).GetName());
991 if(currentpage
->m_nLastFileId
!= -1)
992 currentpage
->m_playlist
->SetItem(
993 currentpage
->m_nLastFileId
, 0, wxT("*"));
996 if( uripath
.IsReference() )
998 if( !currentpage
->m_mediactrl
->Load(path
) )
1000 wxMessageBox(wxT("Couldn't load file!"));
1001 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("E"));
1005 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("O"));
1010 if( !currentpage
->m_mediactrl
->Load(uripath
) )
1012 wxMessageBox(wxT("Couldn't load URL!"));
1013 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("E"));
1017 currentpage
->m_playlist
->SetItem(nNewId
, 0, wxT("O"));
1021 currentpage
->m_nLastFileId
= nNewId
;
1022 currentpage
->m_szFile
= path
;
1023 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
,
1024 1, wxFileName(path
).GetName());
1025 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
,
1030 // ----------------------------------------------------------------------------
1031 // wxMediaPlayerFrame::OnMediaLoaded
1033 // Called when the media is ready to be played - and does
1034 // so, also gets the length of media and shows that in the list control
1035 // ----------------------------------------------------------------------------
1036 void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent
& WXUNUSED(evt
))
1038 wxMediaPlayerNotebookPage
* currentpage
=
1039 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1041 if( !currentpage
->m_mediactrl
->Play() )
1043 wxMessageBox(wxT("Couldn't play movie!"));
1044 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
, 0, wxT("E"));
1048 currentpage
->m_playlist
->SetItem(currentpage
->m_nLastFileId
, 0, wxT(">"));
1054 // ----------------------------------------------------------------------------
1055 // wxMediaPlayerFrame::OnSelectBackend
1057 // Little debugging routine - enter the class name of a backend and it
1058 // will use that instead of letting wxMediaCtrl search the wxMediaBackend
1060 // ----------------------------------------------------------------------------
1061 void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent
& WXUNUSED(evt
))
1063 wxString sBackend
= wxGetTextFromUser(wxT("Enter backend to use"));
1065 if(sBackend
.empty() == false) //could have been cancelled by the user
1067 int sel
= m_notebook
->GetSelection();
1069 if (sel
!= wxNOT_FOUND
)
1071 m_notebook
->DeletePage(sel
);
1074 m_notebook
->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook
,
1079 ((wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage())->m_szFile
,
1084 // ----------------------------------------------------------------------------
1085 // wxMediaPlayerFrame::OnOpenURLSamePage
1087 // Called from file->openurl.
1088 // Opens and plays a media file from a URL in the current notebook page
1089 // ----------------------------------------------------------------------------
1090 void wxMediaPlayerFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
1095 // ----------------------------------------------------------------------------
1096 // wxMediaPlayerFrame::OnOpenURLNewPage
1098 // Called from file->openurlinnewpage.
1099 // Opens and plays a media file from a URL in a new notebook page
1100 // ----------------------------------------------------------------------------
1101 void wxMediaPlayerFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
1106 // ----------------------------------------------------------------------------
1107 // wxMediaPlayerFrame::OpenURL
1109 // Just calls DoOpenFile with the url path - which calls DoPlayFile
1110 // which handles the real dirty work
1111 // ----------------------------------------------------------------------------
1112 void wxMediaPlayerFrame::OpenURL(bool bNewPage
)
1114 wxString sUrl
= wxGetTextFromUser(
1115 wxT("Enter the URL that has the movie to play")
1118 if(sUrl
.empty() == false) //could have been cancelled by user
1120 DoOpenFile(sUrl
, bNewPage
);
1124 // ----------------------------------------------------------------------------
1125 // wxMediaPlayerFrame::OnCloseCurrentPage
1127 // Called when the user wants to close the current notebook page
1129 // 1) Get the current page number (wxControl::GetSelection)
1130 // 2) If there is no current page, break out
1131 // 3) Delete the current page
1132 // ----------------------------------------------------------------------------
1133 void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
1135 if( m_notebook
->GetPageCount() > 1 )
1137 int sel
= m_notebook
->GetSelection();
1139 if (sel
!= wxNOT_FOUND
)
1141 m_notebook
->DeletePage(sel
);
1146 wxMessageBox(wxT("Cannot close main page"));
1150 // ----------------------------------------------------------------------------
1151 // wxMediaPlayerFrame::OnPlay
1153 // Called from file->play.
1154 // Resumes the media if it is paused or stopped.
1155 // ----------------------------------------------------------------------------
1156 void wxMediaPlayerFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
1158 wxMediaPlayerNotebookPage
* currentpage
=
1159 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1161 wxListItem listitem
;
1162 currentpage
->m_playlist
->GetSelectedItem(listitem
);
1163 if ( !listitem
.GetData() )
1166 if ((nLast
= currentpage
->m_playlist
->GetNextItem(nLast
,
1168 wxLIST_STATE_DONTCARE
)) == -1)
1171 wxMessageBox(wxT("No items in playlist!"));
1175 listitem
.SetId(nLast
);
1176 currentpage
->m_playlist
->GetItem(listitem
);
1177 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1178 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1179 currentpage
->m_playlist
->SetItem(listitem
);
1180 wxASSERT(listitem
.GetData());
1181 DoPlayFile((*((wxString
*) listitem
.GetData())));
1186 wxASSERT(listitem
.GetData());
1187 DoPlayFile((*((wxString
*) listitem
.GetData())));
1191 // ----------------------------------------------------------------------------
1192 // wxMediaPlayerFrame::OnKeyDown
1194 // Deletes all selected files from the playlist if the backspace key is pressed
1195 // ----------------------------------------------------------------------------
1196 void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent
& event
)
1198 if(event
.GetKeyCode() == WXK_BACK
/*DELETE*/)
1200 wxMediaPlayerNotebookPage
* currentpage
=
1201 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1202 //delete all selected items
1205 wxInt32 nSelectedItem
= currentpage
->m_playlist
->GetNextItem(
1206 -1, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1207 if (nSelectedItem
== -1)
1210 wxListItem listitem
;
1211 listitem
.SetId(nSelectedItem
);
1212 currentpage
->m_playlist
->GetItem(listitem
);
1213 delete (wxString
*) listitem
.GetData();
1215 currentpage
->m_playlist
->DeleteItem(nSelectedItem
);
1219 //Could be wxGetTextFromUser or something else important
1220 if(event
.GetEventObject() != this)
1224 // ----------------------------------------------------------------------------
1225 // wxMediaPlayerFrame::OnStop
1227 // Called from file->stop.
1228 // Where it stops depends on whether you can seek in the
1229 // media control or not - if you can it stops and seeks to the beginning,
1230 // otherwise it will appear to be at the end - but it will start over again
1231 // when Play() is called
1232 // ----------------------------------------------------------------------------
1233 void wxMediaPlayerFrame::OnStop(wxCommandEvent
& WXUNUSED(evt
))
1235 wxMediaPlayerNotebookPage
* currentpage
=
1236 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1238 if( !currentpage
->m_mediactrl
->Stop() )
1239 wxMessageBox(wxT("Couldn't stop movie!"));
1241 currentpage
->m_playlist
->SetItem(
1242 currentpage
->m_nLastFileId
, 0, wxT("[]"));
1246 // ----------------------------------------------------------------------------
1247 // wxMediaPlayerFrame::OnChangeSong
1249 // Routine that plays the currently selected file in the playlist.
1250 // Called when the user actives the song from the playlist,
1251 // and from other various places in the sample
1252 // ----------------------------------------------------------------------------
1253 void wxMediaPlayerFrame::OnChangeSong(wxListEvent
& WXUNUSED(evt
))
1255 wxMediaPlayerNotebookPage
* currentpage
=
1256 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1258 wxListItem listitem
;
1259 currentpage
->m_playlist
->GetSelectedItem(listitem
);
1260 if(listitem
.GetData())
1261 DoPlayFile((*((wxString
*) listitem
.GetData())));
1263 wxMessageBox(wxT("No selected item!"));
1266 // ----------------------------------------------------------------------------
1267 // wxMediaPlayerFrame::OnPrev
1269 // Tedious wxListCtrl stuff. Goes to prevous song in list, or if at the
1270 // beginning goes to the last in the list.
1271 // ----------------------------------------------------------------------------
1272 void wxMediaPlayerFrame::OnPrev(wxCommandEvent
& WXUNUSED(event
))
1274 wxMediaPlayerNotebookPage
* currentpage
=
1275 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1277 if (currentpage
->m_playlist
->GetItemCount() == 0)
1280 wxInt32 nLastSelectedItem
= -1;
1283 wxInt32 nSelectedItem
= currentpage
->m_playlist
->GetNextItem(nLastSelectedItem
,
1284 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1285 if (nSelectedItem
== -1)
1287 nLastSelectedItem
= nSelectedItem
;
1288 currentpage
->m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1291 if (nLastSelectedItem
== -1)
1293 //nothing selected, default to the file before the currently playing one
1294 if(currentpage
->m_nLastFileId
== 0)
1295 nLastSelectedItem
= currentpage
->m_playlist
->GetItemCount() - 1;
1297 nLastSelectedItem
= currentpage
->m_nLastFileId
- 1;
1299 else if (nLastSelectedItem
== 0)
1300 nLastSelectedItem
= currentpage
->m_playlist
->GetItemCount() - 1;
1302 nLastSelectedItem
-= 1;
1304 if(nLastSelectedItem
== currentpage
->m_nLastFileId
)
1305 return; //already playing... nothing to do
1307 wxListItem listitem
;
1308 listitem
.SetId(nLastSelectedItem
);
1309 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
1310 currentpage
->m_playlist
->GetItem(listitem
);
1311 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1312 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1313 currentpage
->m_playlist
->SetItem(listitem
);
1315 wxASSERT(listitem
.GetData());
1316 DoPlayFile((*((wxString
*) listitem
.GetData())));
1319 // ----------------------------------------------------------------------------
1320 // wxMediaPlayerFrame::OnNext
1322 // Tedious wxListCtrl stuff. Goes to next song in list, or if at the
1323 // end goes to the first in the list.
1324 // ----------------------------------------------------------------------------
1325 void wxMediaPlayerFrame::OnNext(wxCommandEvent
& WXUNUSED(event
))
1327 wxMediaPlayerNotebookPage
* currentpage
=
1328 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1330 if (currentpage
->m_playlist
->GetItemCount() == 0)
1333 wxInt32 nLastSelectedItem
= -1;
1336 wxInt32 nSelectedItem
= currentpage
->m_playlist
->GetNextItem(nLastSelectedItem
,
1337 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1338 if (nSelectedItem
== -1)
1340 nLastSelectedItem
= nSelectedItem
;
1341 currentpage
->m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1344 if (nLastSelectedItem
== -1)
1346 if(currentpage
->m_nLastFileId
== currentpage
->m_playlist
->GetItemCount() - 1)
1347 nLastSelectedItem
= 0;
1349 nLastSelectedItem
= currentpage
->m_nLastFileId
+ 1;
1351 else if (nLastSelectedItem
== currentpage
->m_playlist
->GetItemCount() - 1)
1352 nLastSelectedItem
= 0;
1354 nLastSelectedItem
+= 1;
1356 if(nLastSelectedItem
== currentpage
->m_nLastFileId
)
1357 return; //already playing... nothing to do
1359 wxListItem listitem
;
1360 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
1361 listitem
.SetId(nLastSelectedItem
);
1362 currentpage
->m_playlist
->GetItem(listitem
);
1363 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1364 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1365 currentpage
->m_playlist
->SetItem(listitem
);
1367 wxASSERT(listitem
.GetData());
1368 DoPlayFile((*((wxString
*) listitem
.GetData())));
1372 // ----------------------------------------------------------------------------
1373 // wxMediaPlayerFrame::OnVolumeDown
1375 // Lowers the volume of the media control by 5%
1376 // ----------------------------------------------------------------------------
1377 void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent
& WXUNUSED(event
))
1379 wxMediaPlayerNotebookPage
* currentpage
=
1380 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1382 double dVolume
= currentpage
->m_mediactrl
->GetVolume();
1383 currentpage
->m_mediactrl
->SetVolume(dVolume
< 0.05 ? 0.0 : dVolume
- .05);
1386 // ----------------------------------------------------------------------------
1387 // wxMediaPlayerFrame::OnVolumeUp
1389 // Increases the volume of the media control by 5%
1390 // ----------------------------------------------------------------------------
1391 void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent
& WXUNUSED(event
))
1393 wxMediaPlayerNotebookPage
* currentpage
=
1394 (wxMediaPlayerNotebookPage
*) m_notebook
->GetCurrentPage();
1396 double dVolume
= currentpage
->m_mediactrl
->GetVolume();
1397 currentpage
->m_mediactrl
->SetVolume(dVolume
> 0.95 ? 1.0 : dVolume
+ .05);
1400 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1402 // wxMediaPlayerTimer
1404 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1406 // ----------------------------------------------------------------------------
1407 // wxMediaPlayerTimer::Notify
1409 // 1) Updates media information on the status bar
1410 // 2) Sets the max/min length of the slider and guage
1412 // Note that the reason we continually do this and don't cache it is because
1413 // some backends such as GStreamer are dynamic change values all the time
1414 // and often don't have things like duration or video size available
1415 // until the media is actually being played
1416 // ----------------------------------------------------------------------------
1417 void wxMediaPlayerTimer::Notify()
1419 wxMediaPlayerNotebookPage
* currentpage
=
1420 (wxMediaPlayerNotebookPage
*) m_frame
->m_notebook
->GetCurrentPage();
1421 wxMediaCtrl
* currentMediaCtrl
= currentpage
->m_mediactrl
;
1425 // Number of minutes/seconds total
1426 wxLongLong llLength
= currentpage
->m_mediactrl
->Length();
1427 int nMinutes
= (int) (llLength
/ 60000).GetValue();
1428 int nSeconds
= (int) ((llLength
% 60000)/1000).GetValue();
1430 // Duration string (i.e. MM:SS)
1432 sDuration
.Printf(wxT("%2i:%02i"), nMinutes
, nSeconds
);
1435 // Number of minutes/seconds total
1436 wxLongLong llTell
= currentpage
->m_mediactrl
->Tell();
1437 nMinutes
= (int) (llTell
/ 60000).GetValue();
1438 nSeconds
= (int) ((llTell
% 60000)/1000).GetValue();
1440 // Position string (i.e. MM:SS)
1442 sPosition
.Printf(wxT("%2i:%02i"), nMinutes
, nSeconds
);
1445 // Set the third item in the listctrl entry to the duration string
1446 if(currentpage
->m_nLastFileId
>= 0)
1447 currentpage
->m_playlist
->SetItem(
1448 currentpage
->m_nLastFileId
, 2, sDuration
);
1450 // Setup the slider and gauge min/max values
1451 currentpage
->m_slider
->SetRange(0, (int)(llLength
/ 1000).GetValue());
1452 currentpage
->m_gauge
->SetRange(100);
1455 // if the slider is not being dragged then update it with the song position
1456 if(currentpage
->IsBeingDragged() == false)
1457 currentpage
->m_slider
->SetValue((long)(llTell
/ 1000).GetValue());
1460 // Update the gauge with the download progress
1461 wxLongLong llDownloadProgress
=
1462 currentpage
->m_mediactrl
->GetDownloadProgress();
1463 wxLongLong llDownloadTotal
=
1464 currentpage
->m_mediactrl
->GetDownloadTotal();
1466 if(llDownloadTotal
.GetValue() != 0)
1468 currentpage
->m_gauge
->SetValue(
1469 (int) ((llDownloadProgress
* 100) / llDownloadTotal
).GetValue()
1473 // GetBestSize holds the original video size
1474 wxSize videoSize
= currentMediaCtrl
->GetBestSize();
1476 // Now the big part - set the status bar text to
1477 // hold various metadata about the media
1479 m_frame
->SetStatusText(wxString::Format(
1480 wxT("Size(x,y):%i,%i ")
1481 wxT("Position:%s/%s Speed:%1.1fx ")
1482 wxT("State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
1487 currentMediaCtrl
->GetPlaybackRate(),
1488 wxGetMediaStateText(currentpage
->m_mediactrl
->GetState()),
1489 currentpage
->m_nLoops
,
1490 (int)llDownloadProgress
.GetValue(),
1491 (int)llDownloadTotal
.GetValue(),
1492 (int)(currentpage
->m_mediactrl
->GetVolume() * 100)));
1493 #endif // wxUSE_STATUSBAR
1497 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1499 // wxMediaPlayerNotebookPage
1501 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1503 // ----------------------------------------------------------------------------
1504 // wxMediaPlayerNotebookPage Constructor
1506 // Creates a media control and slider and adds it to this panel,
1507 // along with some sizers for positioning
1508 // ----------------------------------------------------------------------------
1509 wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
1510 wxNotebook
* theBook
,
1511 const wxString
& szBackend
)
1512 : wxPanel(theBook
, wxID_ANY
),
1516 m_bIsBeingDragged(false),
1517 m_parentFrame(parentFrame
)
1524 // [5 control buttons]
1530 // Create and attach the sizer
1532 wxFlexGridSizer
* sizer
= new wxFlexGridSizer(2, 1, 0, 0);
1533 this->SetSizer(sizer
);
1534 this->SetAutoLayout(true);
1535 sizer
->AddGrowableRow(0);
1536 sizer
->AddGrowableCol(0);
1539 // Create our media control
1541 m_mediactrl
= new wxMediaCtrl();
1543 // Make sure creation was successful
1544 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
, wxEmptyString
,
1545 wxDefaultPosition
, wxDefaultSize
, 0,
1546 //you could specify a macrod backend here like
1547 // wxMEDIABACKEND_WMP10);
1548 // wxT("wxPDFMediaBackend"));
1550 //you could change the cursor here like
1551 // m_mediactrl->SetCursor(wxCURSOR_BLANK);
1552 //note that this may not effect it if SetPlayerControls
1553 //is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
1554 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
1557 sizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1560 // Create the playlist/listctrl
1562 m_playlist
= new wxMediaPlayerListCtrl();
1563 m_playlist
->Create(this, wxID_LISTCTRL
, wxDefaultPosition
,
1565 wxLC_REPORT
//wxLC_LIST
1568 // Set the background of our listctrl to white
1569 m_playlist
->SetBackgroundColour(wxColour(255,255,255));
1571 // The layout of the headers of the listctrl are like
1572 // | | File | Length
1574 // Where Column one is a character representing the state the file is in:
1575 // * - not the current file
1576 // E - Error has occured
1577 // > - Currently Playing
1580 // (( - Volume Down 5%
1581 // )) - Volume Up 5%
1583 // Column two is the name of the file
1585 // Column three is the length in seconds of the file
1586 m_playlist
->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER
, 20);
1587 m_playlist
->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT
, /*wxLIST_AUTOSIZE_USEHEADER*/305);
1588 m_playlist
->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER
, 75);
1590 #if wxUSE_DRAG_AND_DROP
1591 m_playlist
->SetDropTarget(new wxPlayListDropTarget(*m_playlist
));
1594 sizer
->Add(m_playlist
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1597 // Create the control buttons
1598 // TODO/FIXME/HACK: This part about sizers is really a nice hack
1599 // and probably isn't proper
1601 wxBoxSizer
* horsizer1
= new wxBoxSizer(wxHORIZONTAL
);
1602 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxHORIZONTAL
);
1604 m_prevButton
= new wxButton();
1605 m_playButton
= new wxButton();
1606 m_stopButton
= new wxButton();
1607 m_nextButton
= new wxButton();
1608 m_vdButton
= new wxButton();
1609 m_vuButton
= new wxButton();
1611 m_prevButton
->Create(this, wxID_BUTTONPREV
, wxT("|<"));
1612 m_playButton
->Create(this, wxID_BUTTONPLAY
, wxT(">"));
1613 m_stopButton
->Create(this, wxID_BUTTONSTOP
, wxT("[]"));
1614 m_nextButton
->Create(this, wxID_BUTTONNEXT
, wxT(">|"));
1615 m_vdButton
->Create(this, wxID_BUTTONVD
, wxT("(("));
1616 m_vuButton
->Create(this, wxID_BUTTONVU
, wxT("))"));
1617 vertsizer
->Add(m_prevButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1618 vertsizer
->Add(m_playButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1619 vertsizer
->Add(m_stopButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1620 vertsizer
->Add(m_nextButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1621 vertsizer
->Add(m_vdButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1622 vertsizer
->Add(m_vuButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1623 horsizer1
->Add(vertsizer
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1624 sizer
->Add(horsizer1
, 0, wxALIGN_CENTER_VERTICAL
|wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
1628 // Create our slider
1630 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
1633 wxDefaultPosition
, wxDefaultSize
,
1635 sizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1640 m_gauge
= new wxGauge();
1641 m_gauge
->Create(this, wxID_GAUGE
, 0, wxDefaultPosition
, wxDefaultSize
,
1642 wxGA_HORIZONTAL
| wxGA_SMOOTH
);
1643 sizer
->Add(m_gauge
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1646 // Create the speed/volume sliders
1648 wxBoxSizer
* horsizer3
= new wxBoxSizer(wxHORIZONTAL
);
1650 m_volSlider
= new wxSlider(this, wxID_VOLSLIDER
, 100, // init
1653 wxDefaultPosition
, wxSize(250,20),
1655 horsizer3
->Add(m_volSlider
, 1, wxALL
, 5);
1657 m_pbSlider
= new wxSlider(this, wxID_PBSLIDER
, 4, // init
1660 wxDefaultPosition
, wxSize(250,20),
1662 horsizer3
->Add(m_pbSlider
, 1, wxALL
, 5);
1663 sizer
->Add(horsizer3
, 1, wxCENTRE
| wxALL
, 5);
1668 this->Connect( wxID_LISTCTRL
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED
,
1669 wxListEventHandler(wxMediaPlayerFrame::OnChangeSong
),
1670 (wxObject
*)0, parentFrame
);
1675 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBTRACK
,
1676 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek
));
1677 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1678 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek
));
1679 this->Connect(wxID_PBSLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1680 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnPBChange
));
1681 this->Connect(wxID_VOLSLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1682 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnVolChange
));
1685 // Media Control events
1687 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_PLAY
,
1688 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPlay
));
1689 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_PAUSE
,
1690 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPause
));
1691 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_STOP
,
1692 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaStop
));
1693 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
1694 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished
));
1695 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_LOADED
,
1696 wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded
),
1697 (wxObject
*)0, parentFrame
);
1702 this->Connect( wxID_BUTTONPREV
, wxEVT_COMMAND_BUTTON_CLICKED
,
1703 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
),
1704 (wxObject
*)0, parentFrame
);
1705 this->Connect( wxID_BUTTONPLAY
, wxEVT_COMMAND_BUTTON_CLICKED
,
1706 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
),
1707 (wxObject
*)0, parentFrame
);
1708 this->Connect( wxID_BUTTONSTOP
, wxEVT_COMMAND_BUTTON_CLICKED
,
1709 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
),
1710 (wxObject
*)0, parentFrame
);
1711 this->Connect( wxID_BUTTONNEXT
, wxEVT_COMMAND_BUTTON_CLICKED
,
1712 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
),
1713 (wxObject
*)0, parentFrame
);
1714 this->Connect( wxID_BUTTONVD
, wxEVT_COMMAND_BUTTON_CLICKED
,
1715 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown
),
1716 (wxObject
*)0, parentFrame
);
1717 this->Connect( wxID_BUTTONVU
, wxEVT_COMMAND_BUTTON_CLICKED
,
1718 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp
),
1719 (wxObject
*)0, parentFrame
);
1722 // ----------------------------------------------------------------------------
1723 // MyNotebook::OnBeginSeek
1725 // Sets m_bIsBeingDragged to true to stop the timer from changing the position
1727 // ----------------------------------------------------------------------------
1728 void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent
& WXUNUSED(event
))
1730 m_bIsBeingDragged
= true;
1733 // ----------------------------------------------------------------------------
1734 // MyNotebook::OnEndSeek
1736 // Called from file->seek.
1737 // Called when the user moves the slider -
1738 // seeks to a position within the media
1739 // then sets m_bIsBeingDragged to false to ok the timer to change the position
1740 // ----------------------------------------------------------------------------
1741 void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent
& WXUNUSED(event
))
1743 if( m_mediactrl
->Seek(
1744 m_slider
->GetValue() * 1000
1745 ) == wxInvalidOffset
)
1746 wxMessageBox(wxT("Couldn't seek in movie!"));
1748 m_bIsBeingDragged
= false;
1751 // ----------------------------------------------------------------------------
1752 // wxMediaPlayerNotebookPage::IsBeingDragged
1754 // Returns true if the user is dragging the slider
1755 // ----------------------------------------------------------------------------
1756 bool wxMediaPlayerNotebookPage::IsBeingDragged()
1758 return m_bIsBeingDragged
;
1761 // ----------------------------------------------------------------------------
1762 // wxMediaPlayerNotebookPage::OnVolChange
1764 // Called when the user is done dragging the volume-changing slider
1765 // ----------------------------------------------------------------------------
1766 void wxMediaPlayerNotebookPage::OnVolChange(wxScrollEvent
& WXUNUSED(event
))
1768 if( m_mediactrl
->SetVolume(
1769 m_volSlider
->GetValue() / 100.0
1771 wxMessageBox(wxT("Couldn't set volume!"));
1775 // ----------------------------------------------------------------------------
1776 // wxMediaPlayerNotebookPage::OnPBChange
1778 // Called when the user is done dragging the speed-changing slider
1779 // ----------------------------------------------------------------------------
1780 void wxMediaPlayerNotebookPage::OnPBChange(wxScrollEvent
& WXUNUSED(event
))
1782 if( m_mediactrl
->SetPlaybackRate(
1783 m_pbSlider
->GetValue() * .25
1785 wxMessageBox(wxT("Couldn't set playbackrate!"));
1789 // ----------------------------------------------------------------------------
1790 // wxMediaPlayerNotebookPage::OnMediaPlay
1792 // Called when the media plays.
1793 // ----------------------------------------------------------------------------
1794 void wxMediaPlayerNotebookPage::OnMediaPlay(wxMediaEvent
& WXUNUSED(event
))
1796 m_playlist
->SetItem(m_nLastFileId
, 0, wxT(">"));
1799 // ----------------------------------------------------------------------------
1800 // wxMediaPlayerNotebookPage::OnMediaPause
1802 // Called when the media is paused.
1803 // ----------------------------------------------------------------------------
1804 void wxMediaPlayerNotebookPage::OnMediaPause(wxMediaEvent
& WXUNUSED(event
))
1806 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("||"));
1809 // ----------------------------------------------------------------------------
1810 // wxMediaPlayerNotebookPage::OnMediaStop
1812 // Called when the media stops.
1813 // ----------------------------------------------------------------------------
1814 void wxMediaPlayerNotebookPage::OnMediaStop(wxMediaEvent
& WXUNUSED(event
))
1816 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("[]"));
1819 // ----------------------------------------------------------------------------
1820 // wxMediaPlayerNotebookPage::OnMediaFinished
1822 // Called when the media finishes playing.
1823 // Here we loop it if the user wants to (has been selected from file menu)
1824 // ----------------------------------------------------------------------------
1825 void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
1829 if ( !m_mediactrl
->Play() )
1831 wxMessageBox(wxT("Couldn't loop movie!"));
1832 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("E"));
1839 m_playlist
->SetItem(m_nLastFileId
, 0, wxT("[]"));
1844 // End of MediaPlayer sample