1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mediaplayer.cpp
3 // Purpose: wxMediaCtrl sample
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 // This is a simple example of how to use all the funtionality of
16 // 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 // new notebook page, showing video if neccessary.
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) on OS versions < 10.2.
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
63 #include "wx/notebook.h" //for wxNotebook and putting movies in pages
65 // Use some stuff that's not part of the current API, such as loading
66 // media from a URL, etc.
67 #define wxUSE_UNOFFICIALSTUFF 0
69 //Libraries for MSVC with optional backends
72 #pragma comment(lib,"qtmlClient.lib")
76 // ----------------------------------------------------------------------------
77 // Bail out if the user doesn't want one of the
79 // ----------------------------------------------------------------------------
82 #error "This is a GUI sample"
85 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || !wxUSE_NOTEBOOK
86 #error "menus, slider, mediactrl, notebook, and timers must all be enabled for this sample!"
89 // ============================================================================
91 // ============================================================================
93 // ----------------------------------------------------------------------------
95 // ----------------------------------------------------------------------------
97 // IDs for the controls and the menu commands
102 wxID_OPENFILESAMEPAGE
,
103 wxID_OPENFILENEWPAGE
,
104 wxID_OPENURLSAMEPAGE
,
106 wxID_CLOSECURRENTPAGE
,
109 // wxID_STOP, [built-in to wxWidgets]
110 // wxID_ABOUT, [built-in to wxWidgets]
111 // wxID_EXIT, [built-in to wxWidgets]
112 wxID_SLIDER
, // event id for our slider
113 wxID_NOTEBOOK
, // event id for our notebook
114 wxID_MEDIACTRL
// event id for our wxMediaCtrl
117 // ----------------------------------------------------------------------------
119 // ----------------------------------------------------------------------------
121 class MyApp
: public wxApp
124 virtual bool OnInit();
127 // ----------------------------------------------------------------------------
129 // ----------------------------------------------------------------------------
131 class MyFrame
: public wxFrame
135 MyFrame(const wxString
& title
);
138 // Menu event handlers
139 void OnQuit(wxCommandEvent
& event
);
140 void OnAbout(wxCommandEvent
& event
);
141 void OnLoop(wxCommandEvent
& event
);
143 void OnOpenFileSamePage(wxCommandEvent
& event
);
144 void OnOpenFileNewPage(wxCommandEvent
& event
);
145 void OnOpenURLSamePage(wxCommandEvent
& event
);
146 void OnOpenURLNewPage(wxCommandEvent
& event
);
147 void OnCloseCurrentPage(wxCommandEvent
& event
);
149 void OnPlay(wxCommandEvent
& event
);
150 void OnPause(wxCommandEvent
& event
);
151 void OnStop(wxCommandEvent
& event
);
153 // Notebook event handlers
154 void OnPageChange(wxNotebookEvent
& event
);
157 // Rebuild base status string (see Implementation)
160 // Common open file code
161 void OpenFile(bool bNewPage
);
162 void OpenURL(bool bNewPage
);
164 // Get the media control and slider of current notebook page
165 wxMediaCtrl
* GetCurrentMediaCtrl();
166 wxSlider
* GetCurrentSlider();
168 class MyTimer
* m_timer
; //Timer to write info to status bar
169 wxString m_basestatus
; //Base status string (see ResetStatus())
170 wxNotebook
* m_notebook
; //Notebook containing our pages
172 // So that mytimer can access MyFrame's members
173 friend class MyTimer
;
178 // ----------------------------------------------------------------------------
180 // ----------------------------------------------------------------------------
182 class MyNotebookPage
: public wxPanel
184 MyNotebookPage(wxNotebook
* book
);
186 // Slider event handlers
187 void OnSeek(wxCommandEvent
& event
);
189 // Media event handlers
190 void OnMediaFinished(wxMediaEvent
& event
);
193 friend class MyFrame
; //make MyFrame able to access private members
194 wxMediaCtrl
* m_mediactrl
; //Our media control
195 wxSlider
* m_slider
; //The slider below our media control
196 int m_nLoops
; //Number of times media has looped
197 bool m_bLoop
; //Whether we are looping or not
200 // ----------------------------------------------------------------------------
202 // ----------------------------------------------------------------------------
204 class MyTimer
: public wxTimer
208 MyTimer(MyFrame
* frame
) {m_frame
= frame
;}
210 //Called each time the timer's timeout expires
213 MyFrame
* m_frame
; //The MyFrame
216 // ============================================================================
220 // ============================================================================
222 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
226 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
228 // ----------------------------------------------------------------------------
229 // wxGetMediaStateText
231 // Converts a wxMediaCtrl state into something useful that we can display
233 // ----------------------------------------------------------------------------
234 const wxChar
* wxGetMediaStateText(int nState
)
238 case wxMEDIASTATE_PLAYING
:
239 return wxT("Playing");
240 case wxMEDIASTATE_STOPPED
:
241 return wxT("Stopped");
242 ///case wxMEDIASTATE_PAUSED:
244 return wxT("Paused");
248 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
252 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
254 // ----------------------------------------------------------------------------
255 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
256 // use. For example, if you were to be in windows and use a file dialog,
257 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
258 // handle of the application. These routines in wx _DO NOT_ check to see if
259 // the wxApp exists, and thus will crash the application if you try it.
261 // IMPLEMENT_APP does this, and also implements the platform-specific entry
262 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
263 // not desire this behavior.
264 // ----------------------------------------------------------------------------
268 // ----------------------------------------------------------------------------
271 // Where execution starts - akin to a main or WinMain.
272 // 1) Create the frame and show it to the user
273 // 2) return true specifying that we want execution to continue past OnInit
274 // ----------------------------------------------------------------------------
277 MyFrame
*frame
= new MyFrame(_T("MediaPlayer wxWidgets Sample"));
284 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
288 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
290 // ----------------------------------------------------------------------------
291 // MyFrame Constructor
293 // 1) Create our menus
294 // 2) Create our notebook control and add it to the frame
295 // 3) Create our status bar
296 // 4) Connect our events
297 // 5) Start our timer
298 // ----------------------------------------------------------------------------
300 MyFrame::MyFrame(const wxString
& title
)
301 : wxFrame(NULL
, wxID_ANY
, title
)
306 wxMenu
*menuFile
= new wxMenu
;
308 wxMenu
*helpMenu
= new wxMenu
;
309 helpMenu
->Append(wxID_ABOUT
,
311 _T("Show about dialog"));
313 menuFile
->Append(wxID_OPENFILESAMEPAGE
, _T("&Open File"),
314 _T("Open a File in the current notebook page"));
315 menuFile
->Append(wxID_OPENFILENEWPAGE
, _T("&Open File in a new page"),
316 _T("Open a File in a new notebook page"));
317 #if wxUSE_UNOFFICIALSTUFF
318 menuFile
->Append(wxID_OPENURLSAMEPAGE
, _T("&Open URL"),
319 _T("Open a URL in the current notebook page"));
320 menuFile
->Append(wxID_OPENURLNEWPAGE
, _T("&Open URL in a new page"),
321 _T("Open a URL in a new notebook page"));
323 menuFile
->AppendSeparator();
324 menuFile
->Append(wxID_CLOSECURRENTPAGE
, _T("&Close Current Page"),
325 _T("Close current notebook page"));
326 menuFile
->AppendSeparator();
327 menuFile
->Append(wxID_PLAY
, _T("&Play"), _T("Resume playback"));
328 menuFile
->Append(wxID_PAUSE
, _T("P&ause"), _T("Pause playback"));
329 menuFile
->Append(wxID_STOP
, _T("&Stop"), _T("Stop playback"));
330 menuFile
->AppendSeparator();
331 menuFile
->AppendCheckItem(wxID_LOOP
,
333 _T("Loop Selected Media"));
334 menuFile
->AppendSeparator();
335 menuFile
->Append(wxID_EXIT
,
337 _T("Quit this program"));
339 wxMenuBar
*menuBar
= new wxMenuBar();
340 menuBar
->Append(menuFile
, _T("&File"));
341 menuBar
->Append(helpMenu
, _T("&Help"));
346 // Create our notebook - using wxNotebook is luckily pretty
347 // simple and self-explanatory in most cases
349 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
352 // Create our status bar
355 // create a status bar just for fun (by default with 1 pane only)
357 #endif // wxUSE_STATUSBAR
362 // There are two ways in wxWidgets to use events -
363 // Message Maps and Connections.
365 // Message Maps are implemented by putting
366 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
367 // class you want to use for events, such as MyFrame.
369 // Then after your class declaration you put
370 // BEGIN_EVENT_TABLE(MyFrame, wxFrame)
374 // Where MyFrame is the class with the DECLARE_MESSAGE_MAP
375 // in it. EVT_XXX(XXX) are each of your handlers, such
376 // as EVT_MENU for menu events and the XXX inside
377 // is the parameters to the event macro - in the case
378 // of EVT_MENU the menu id and then the function to call.
380 // However, with wxEvtHandler::Connect you can avoid a
381 // global message map for your class and those annoying
382 // macros. You can also change the context in which
383 // the call the handler (more later).
385 // The downside is that due to the limitation that
386 // wxWidgets doesn't use templates in certain areas,
387 // You have to triple-cast the event function.
389 // There are five parameters to wxEvtHandler::Connect -
391 // The first is the id of the instance whose events
392 // you want to handle - i.e. a menu id for menus,
393 // a control id for controls (wxControl::GetId())
396 // The second is the event id. This is the same
397 // as the message maps (EVT_MENU) except prefixed
398 // with "wx" (wxEVT_MENU).
400 // The third is the function handler for the event -
401 // You need to cast it to the specific event handler
402 // type, then to a wxEventFunction, then to a
403 // wxObjectEventFunction - I.E.
404 // (wxObjectEventFunction)(wxEventFunction)
405 // (wxCommandEventFunction) &MyFrame::MyHandler
407 // Or, you can use the new (2.5.5+) event handler
408 // conversion macros - for instance the above could
410 // wxCommandEventHandler(MyFrame::MyHandler)
411 // pretty simple, eh?
413 // The fourth is an optional userdata param -
414 // this is of historical relevance only and is
415 // there only for backwards compatibility.
417 // The fifth is the context in which to call the
418 // handler - by default (this param is optional)
419 // this. For example in your event handler
420 // if you were to call "this->MyFunc()"
421 // it would literally do this->MyFunc. However,
422 // if you were to pass myHandler as the fifth
423 // parameter, for instance, you would _really_
424 // be calling myHandler->MyFunc, even though
425 // the compiler doesn't really know it.
431 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
432 wxCommandEventHandler(MyFrame::OnQuit
));
434 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
435 wxCommandEventHandler(MyFrame::OnAbout
));
437 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
438 wxCommandEventHandler(MyFrame::OnLoop
));
440 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
441 wxCommandEventHandler(MyFrame::OnOpenFileNewPage
));
443 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
444 wxCommandEventHandler(MyFrame::OnOpenFileSamePage
));
446 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
447 wxCommandEventHandler(MyFrame::OnOpenURLNewPage
));
449 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
450 wxCommandEventHandler(MyFrame::OnOpenURLSamePage
));
452 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
453 wxCommandEventHandler(MyFrame::OnCloseCurrentPage
));
455 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
456 wxCommandEventHandler(MyFrame::OnPlay
));
458 this->Connect(wxID_PAUSE
, wxEVT_COMMAND_MENU_SELECTED
,
459 wxCommandEventHandler(MyFrame::OnPause
));
461 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
462 wxCommandEventHandler(MyFrame::OnStop
));
467 this->Connect(wxID_NOTEBOOK
, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
,
468 wxNotebookEventHandler(MyFrame::OnPageChange
));
475 // Create a timer to update our status bar
477 m_timer
= new MyTimer(this);
481 // ----------------------------------------------------------------------------
482 // MyFrame Destructor
484 // 1) Deletes child objects implicitly
485 // 2) Delete our timer explicitly
486 // ----------------------------------------------------------------------------
492 // ----------------------------------------------------------------------------
493 // MyFrame::ResetStatus
495 // Here we just make a simple status string with some useful info about
496 // the media that we won't change later - such as the length of the media.
498 // We then append some other info that changes in MyTimer::Notify, then
499 // set the status bar to this text.
501 // In real applications, you'd want to find a better way to do this,
502 // such as static text controls (wxStaticText).
504 // We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
505 // we divide by 1000).
507 // We also reset our loop counter here.
508 // ----------------------------------------------------------------------------
509 void MyFrame::ResetStatus()
511 wxMediaCtrl
* currentMediaCtrl
= GetCurrentMediaCtrl();
513 m_basestatus
= wxString::Format(_T("Size(x,y):%i,%i ")
514 _T("Length(Seconds):%u Speed:%1.1fx"),
515 currentMediaCtrl
->GetBestSize().x
,
516 currentMediaCtrl
->GetBestSize().y
,
517 (unsigned)((currentMediaCtrl
->Length() / 1000)),
518 currentMediaCtrl
->GetPlaybackRate()
522 // ----------------------------------------------------------------------------
523 // MyFrame::GetCurrentMediaCtrl
525 // Obtains the media control of the current page, or NULL if there are no
527 // ----------------------------------------------------------------------------
528 wxMediaCtrl
* MyFrame::GetCurrentMediaCtrl()
530 wxASSERT(m_notebook
->GetCurrentPage() != NULL
);
531 return ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_mediactrl
;
534 // ----------------------------------------------------------------------------
535 // MyFrame::GetCurrentSlider
537 // Obtains the slider of the current page, or NULL if there are no
539 // ----------------------------------------------------------------------------
540 wxSlider
* MyFrame::GetCurrentSlider()
542 wxASSERT(m_notebook
->GetCurrentPage() != NULL
);
543 return ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_slider
;
546 // ----------------------------------------------------------------------------
549 // Called from file->quit.
550 // Closes this application.
551 // ----------------------------------------------------------------------------
552 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
554 // true is to force the frame to close
558 // ----------------------------------------------------------------------------
561 // Called from help->about.
562 // Gets some info about this application.
563 // ----------------------------------------------------------------------------
564 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
567 msg
.Printf( _T("This is a test of wxMediaCtrl.\n")
568 _T("Welcome to %s"), wxVERSION_STRING
);
570 wxMessageBox(msg
, _T("About wxMediaCtrl test"), wxOK
| wxICON_INFORMATION
, this);
573 // ----------------------------------------------------------------------------
576 // Called from file->loop.
577 // Changes the state of whether we want to loop or not.
578 // ----------------------------------------------------------------------------
579 void MyFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
581 if(!m_notebook
->GetCurrentPage())
583 wxMessageBox(wxT("No files are currently open!"));
587 ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
=
588 !((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
;
591 // ----------------------------------------------------------------------------
592 // MyFrame::OnOpenFileSamePage
594 // Called from file->openfile.
595 // Opens and plays a media file in the current notebook page
596 // ----------------------------------------------------------------------------
597 void MyFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
602 // ----------------------------------------------------------------------------
603 // MyFrame::OnOpenFileNewPage
605 // Called from file->openfileinnewpage.
606 // Opens and plays a media file in a new notebook page
607 // ----------------------------------------------------------------------------
608 void MyFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
613 // ----------------------------------------------------------------------------
616 // Code to actually open the media file
618 // 1) Create file dialog and ask the user for input file
619 // 2) If the user didn't want anything, break out
620 // 3) Create a new page if the user wanted one or there isn't a current page
623 // 6) Reset the text on the status bar
624 // 7) Set the slider of the current page to accurately reflect media length
625 // ----------------------------------------------------------------------------
626 void MyFrame::OpenFile(bool bNewPage
)
628 wxFileDialog
fd(this);
630 if(fd
.ShowModal() == wxID_OK
)
632 if(bNewPage
|| !m_notebook
->GetCurrentPage())
633 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), fd
.GetPath(), true);
634 else //don't forget to update notebook page title
635 m_notebook
->SetPageText(m_notebook
->GetSelection(), fd
.GetPath());
637 if( !GetCurrentMediaCtrl()->Load(fd
.GetPath()) )
638 wxMessageBox(wxT("Couldn't load file!"));
640 if( !GetCurrentMediaCtrl()->Play() )
641 wxMessageBox(wxT("Couldn't play movie!"));
645 GetCurrentSlider()->SetRange(0,
646 (int)(GetCurrentMediaCtrl()->Length() / 1000));
650 // ----------------------------------------------------------------------------
651 // MyFrame::OnOpenURLSamePage
653 // Called from file->openurl.
654 // Opens and plays a media file from a URL in the current notebook page
655 // ----------------------------------------------------------------------------
656 void MyFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
661 // ----------------------------------------------------------------------------
662 // MyFrame::OnOpenURLNewPage
664 // Called from file->openurlinnewpage.
665 // Opens and plays a media file from a URL in a new notebook page
666 // ----------------------------------------------------------------------------
667 void MyFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
672 // ----------------------------------------------------------------------------
675 // Code to actually open the media file from a URL
677 // 1) Create text input dialog and ask the user for an input URL
678 // 2) If the user didn't want anything, break out
679 // 3) Create a new page if the user wanted one or there isn't a current page
682 // 6) Reset the text on the status bar
683 // 7) Set the slider of the current page to accurately reflect media length
684 // ----------------------------------------------------------------------------
685 void MyFrame::OpenURL(bool bNewPage
)
687 wxString theURL
= wxGetTextFromUser(wxT("Enter the URL that has the movie to play"));
691 if(bNewPage
|| !m_notebook
->GetCurrentPage())
692 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), theURL
, true);
693 else //don't forget to update notebook page title
694 m_notebook
->SetPageText(m_notebook
->GetSelection(), theURL
);
696 if( !GetCurrentMediaCtrl()->Load(wxURI(theURL
)) )
697 wxMessageBox(wxT("Couldn't load URL!"));
699 if( !GetCurrentMediaCtrl()->Play() )
700 wxMessageBox(wxT("Couldn't play movie!"));
704 GetCurrentSlider()->SetRange(0,
705 (int)(GetCurrentMediaCtrl()->Length() / 1000));
709 // ----------------------------------------------------------------------------
710 // MyFrame::OnCloseCurrentPage
712 // Called when the user wants to close the current notebook page
714 // 1) Get the current page number (wxControl::GetSelection)
715 // 2) If there is no current page, break out
716 // 3) Delete the current page
717 // ----------------------------------------------------------------------------
718 void MyFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
720 int sel
= m_notebook
->GetSelection();
722 if (sel
!= wxNOT_FOUND
)
724 m_notebook
->DeletePage(sel
);
728 // ----------------------------------------------------------------------------
731 // Called from file->play.
732 // Resumes the media if it is paused or stopped.
733 // ----------------------------------------------------------------------------
734 void MyFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
736 if(!m_notebook
->GetCurrentPage())
738 wxMessageBox(wxT("No files are currently open!"));
742 if( !GetCurrentMediaCtrl()->Play() )
743 wxMessageBox(wxT("Couldn't play movie!"));
746 // ----------------------------------------------------------------------------
749 // Called from file->pause.
750 // Pauses the media in-place.
751 // ----------------------------------------------------------------------------
752 void MyFrame::OnPause(wxCommandEvent
& WXUNUSED(event
))
754 if(!m_notebook
->GetCurrentPage())
756 wxMessageBox(wxT("No files are currently open!"));
760 if( !GetCurrentMediaCtrl()->Pause() )
761 wxMessageBox(wxT("Couldn't pause movie!"));
764 // ----------------------------------------------------------------------------
767 // Called from file->stop.
768 // Where it stops depends on whether you can seek in the
769 // media control or not - if you can it stops and seeks to the beginning,
770 // otherwise it will appear to be at the end - but it will start over again
771 // when Play() is called
772 // ----------------------------------------------------------------------------
773 void MyFrame::OnStop(wxCommandEvent
& WXUNUSED(event
))
775 if(!m_notebook
->GetCurrentPage())
777 wxMessageBox(wxT("No files are currently open!"));
781 if( !GetCurrentMediaCtrl()->Stop() )
782 wxMessageBox(wxT("Couldn't stop movie!"));
785 // ----------------------------------------------------------------------------
786 // MyFrame::OnCloseCurrentPage
788 // Called when the user wants to closes the current notebook page
789 // ----------------------------------------------------------------------------
791 void MyFrame::OnPageChange(wxNotebookEvent
& WXUNUSED(event
))
796 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
800 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
802 // ----------------------------------------------------------------------------
805 // 1) Update our slider with the position were are in in the media
806 // 2) Update our status bar with the base text from MyFrame::ResetStatus,
807 // append some non-static (changing) info to it, then set the
808 // status bar text to that result
809 // ----------------------------------------------------------------------------
810 void MyTimer::Notify()
812 if (!m_frame
->m_notebook
->GetCurrentPage()) return;
813 wxMediaCtrl
* m_mediactrl
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_mediactrl
;
814 wxSlider
* m_slider
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_slider
;
815 if (!m_mediactrl
) return;
817 long lPosition
= (long)( m_mediactrl
->Tell() / 1000 );
818 m_slider
->SetValue(lPosition
);
821 m_frame
->SetStatusText(wxString::Format(
822 _T("%s Pos:%u State:%s Loops:%i"),
823 m_frame
->m_basestatus
.c_str(),
824 (unsigned int)lPosition
,
825 wxGetMediaStateText(m_mediactrl
->GetState()),
826 ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_nLoops
835 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
839 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
841 // ----------------------------------------------------------------------------
842 // MyNotebookPage Constructor
844 // Creates a media control and slider and adds it to this panel,
845 // along with some sizers for positioning
846 // ----------------------------------------------------------------------------
848 MyNotebookPage::MyNotebookPage(wxNotebook
* theBook
) :
849 wxPanel(theBook
, wxID_ANY
), m_nLoops(0), m_bLoop(false)
852 // Create and attach the first/main sizer
854 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxVERTICAL
);
855 this->SetSizer(vertsizer
);
856 this->SetAutoLayout(true);
859 // Create our media control
861 m_mediactrl
= new wxMediaCtrl();
863 // Make sure creation was successful
864 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
);
865 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
868 vertsizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
873 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
876 wxDefaultPosition
, wxDefaultSize
,
878 vertsizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
882 // Create the second sizer which will position things
885 // -------Menu----------
890 wxBoxSizer
* horzsizer
= new wxBoxSizer(wxHORIZONTAL
);
891 vertsizer
->Add(horzsizer
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
896 this->Connect(wxID_SLIDER
, wxEVT_COMMAND_SLIDER_UPDATED
,
897 wxCommandEventHandler(MyNotebookPage::OnSeek
));
900 // Media Control events
902 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
903 wxMediaEventHandler(MyNotebookPage::OnMediaFinished
));
906 // ----------------------------------------------------------------------------
907 // MyNotebook::OnSeek
909 // Called from file->seek.
910 // Called when the user moves the slider -
911 // seeks to a position within the media
912 // ----------------------------------------------------------------------------
913 void MyNotebookPage::OnSeek(wxCommandEvent
& WXUNUSED(event
))
915 if( m_mediactrl
->Seek(
916 m_slider
->GetValue() * 1000
917 ) == wxInvalidOffset
)
918 wxMessageBox(wxT("Couldn't seek in movie!"));
921 // ----------------------------------------------------------------------------
924 // Called when the media stops playing.
925 // Here we loop it if the user wants to (has been selected from file menu)
926 // ----------------------------------------------------------------------------
927 void MyNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
931 if ( !m_mediactrl
->Play() )
932 wxMessageBox(wxT("Couldn't loop movie!"));
939 // End of MediaPlayer sample