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,"strmiids.lib")
75 #pragma comment(lib,"qtmlClient.lib")
79 // ----------------------------------------------------------------------------
80 // Bail out if the user doesn't want one of the
82 // ----------------------------------------------------------------------------
85 #error "This is a GUI sample"
88 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || !wxUSE_NOTEBOOK
89 #error "menus, slider, mediactrl, notebook, and timers must all be enabled for this sample!"
92 // ============================================================================
94 // ============================================================================
96 // ----------------------------------------------------------------------------
98 // ----------------------------------------------------------------------------
100 // IDs for the controls and the menu commands
105 wxID_OPENFILESAMEPAGE
,
106 wxID_OPENFILENEWPAGE
,
107 wxID_OPENURLSAMEPAGE
,
109 wxID_CLOSECURRENTPAGE
,
112 // wxID_STOP, [built-in to wxWidgets]
113 // wxID_ABOUT, [built-in to wxWidgets]
114 // wxID_EXIT, [built-in to wxWidgets]
116 // event id for our slider
119 // event id for our notebook
122 // event id for our wxMediaCtrl
126 // ----------------------------------------------------------------------------
128 // ----------------------------------------------------------------------------
130 class MyApp
: public wxApp
133 virtual bool OnInit();
136 // ----------------------------------------------------------------------------
138 // ----------------------------------------------------------------------------
140 class MyFrame
: public wxFrame
144 MyFrame(const wxString
& title
);
147 // Menu event handlers
148 void OnQuit(wxCommandEvent
& event
);
149 void OnAbout(wxCommandEvent
& event
);
150 void OnLoop(wxCommandEvent
& event
);
152 void OnOpenFileSamePage(wxCommandEvent
& event
);
153 void OnOpenFileNewPage(wxCommandEvent
& event
);
154 void OnOpenURLSamePage(wxCommandEvent
& event
);
155 void OnOpenURLNewPage(wxCommandEvent
& event
);
156 void OnCloseCurrentPage(wxCommandEvent
& event
);
158 void OnPlay(wxCommandEvent
& event
);
159 void OnPause(wxCommandEvent
& event
);
160 void OnStop(wxCommandEvent
& event
);
162 // Notebook event handlers
163 void OnPageChange(wxNotebookEvent
& event
);
166 // Rebuild base status string (see Implementation)
169 // Common open file code
170 void OpenFile(bool bNewPage
);
171 void OpenURL(bool bNewPage
);
173 // Get the media control and slider of current notebook page
174 wxMediaCtrl
* GetCurrentMediaCtrl();
175 wxSlider
* GetCurrentSlider();
177 class MyTimer
* m_timer
; //Timer to write info to status bar
178 wxString m_basestatus
; //Base status string (see ResetStatus())
179 wxNotebook
* m_notebook
;
181 // So that mytimer can access MyFrame's members
182 friend class MyTimer
;
187 // ----------------------------------------------------------------------------
189 // ----------------------------------------------------------------------------
191 class MyNotebookPage
: public wxPanel
193 MyNotebookPage(wxNotebook
* book
);
195 // Slider event handlers
196 void OnSeek(wxCommandEvent
& event
);
198 // Media event handlers
199 void OnMediaFinished(wxMediaEvent
& event
);
202 friend class MyFrame
; //make MyFrame able to access private members
203 wxMediaCtrl
* m_mediactrl
; //Our media control
204 wxSlider
* m_slider
; //The slider below our media control
205 int m_nLoops
; //Number of times media has looped
206 bool m_bLoop
; //Whether we are looping or not
209 // ----------------------------------------------------------------------------
211 // ----------------------------------------------------------------------------
213 class MyTimer
: public wxTimer
217 MyTimer(MyFrame
* frame
) {m_frame
= frame
;}
219 //Called each time the timer's timeout expires
222 MyFrame
* m_frame
; //The MyFrame
225 // ============================================================================
229 // ============================================================================
231 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
235 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
237 // ----------------------------------------------------------------------------
238 // wxGetMediaStateText
240 // Converts a wxMediaCtrl state into something useful that we can display
242 // ----------------------------------------------------------------------------
243 const wxChar
* wxGetMediaStateText(int nState
)
247 case wxMEDIASTATE_PLAYING
:
248 return wxT("Playing");
249 case wxMEDIASTATE_STOPPED
:
250 return wxT("Stopped");
251 ///case wxMEDIASTATE_PAUSED:
253 return wxT("Paused");
257 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
261 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
263 // ----------------------------------------------------------------------------
264 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
265 // use. For example, if you were to be in windows and use a file dialog,
266 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
267 // handle of the application. These routines in wx _DO NOT_ check to see if
268 // the wxApp exists, and thus will crash the application if you try it.
270 // IMPLEMENT_APP does this, and also implements the platform-specific entry
271 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
272 // not desire this behavior.
273 // ----------------------------------------------------------------------------
277 // ----------------------------------------------------------------------------
280 // Where execution starts - akin to a main or WinMain.
281 // 1) Create the frame and show it to the user
282 // 2) return true specifying that we want execution to continue past OnInit
283 // ----------------------------------------------------------------------------
286 MyFrame
*frame
= new MyFrame(_T("MediaPlayer wxWidgets Sample"));
293 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
297 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
299 // ----------------------------------------------------------------------------
300 // MyFrame Constructor
302 // 1) Create our menus
303 // 2) Create our notebook control and add it to the frame
304 // 3) Create our status bar
305 // 4) Connect our events
306 // 5) Start our timer
307 // ----------------------------------------------------------------------------
309 MyFrame::MyFrame(const wxString
& title
)
310 : wxFrame(NULL
, wxID_ANY
, title
)
315 wxMenu
*menuFile
= new wxMenu
;
317 wxMenu
*helpMenu
= new wxMenu
;
318 helpMenu
->Append(wxID_ABOUT
,
320 _T("Show about dialog"));
322 menuFile
->Append(wxID_OPENFILESAMEPAGE
, _T("&Open File"),
323 _T("Open a File in the current notebook page"));
324 menuFile
->Append(wxID_OPENFILENEWPAGE
, _T("&Open File in a new page"),
325 _T("Open a File in a new notebook page"));
326 #if wxUSE_UNOFFICIALSTUFF
327 menuFile
->Append(wxID_OPENURLSAMEPAGE
, _T("&Open URL"),
328 _T("Open a URL in the current notebook page"));
329 menuFile
->Append(wxID_OPENURLNEWPAGE
, _T("&Open URL in a new page"),
330 _T("Open a URL in a new notebook page"));
332 menuFile
->AppendSeparator();
333 menuFile
->Append(wxID_CLOSECURRENTPAGE
, _T("&Close Current Page"),
334 _T("Close current notebook page"));
335 menuFile
->AppendSeparator();
336 menuFile
->Append(wxID_PLAY
, _T("&Play"), _T("Resume playback"));
337 menuFile
->Append(wxID_PAUSE
, _T("P&ause"), _T("Pause playback"));
338 menuFile
->Append(wxID_STOP
, _T("&Stop"), _T("Stop playback"));
339 menuFile
->AppendSeparator();
340 menuFile
->AppendCheckItem(wxID_LOOP
,
342 _T("Loop Selected Media"));
343 menuFile
->AppendSeparator();
344 menuFile
->Append(wxID_EXIT
,
346 _T("Quit this program"));
348 wxMenuBar
*menuBar
= new wxMenuBar();
349 menuBar
->Append(menuFile
, _T("&File"));
350 menuBar
->Append(helpMenu
, _T("&Help"));
355 // Create our notebook - using wxNotebook is luckily pretty
356 // simple and self-explanatory in most cases
358 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
361 // Create our status bar
364 // create a status bar just for fun (by default with 1 pane only)
366 #endif // wxUSE_STATUSBAR
371 // There are two ways in wxWidgets to use events -
372 // Message Maps and Connections.
374 // Message Maps are implemented by putting
375 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
376 // class you want to use for events, such as MyFrame.
378 // Then after your class declaration you put
379 // BEGIN_EVENT_TABLE(MyFrame, wxFrame)
383 // Where MyFrame is the class with the DECLARE_MESSAGE_MAP
384 // in it. EVT_XXX(XXX) are each of your handlers, such
385 // as EVT_MENU for menu events and the XXX inside
386 // is the parameters to the event macro - in the case
387 // of EVT_MENU the menu id and then the function to call.
389 // However, with wxEvtHandler::Connect you can avoid a
390 // global message map for your class and those annoying
391 // macros. You can also change the context in which
392 // the call the handler (more later).
394 // The downside is that due to the limitation that
395 // wxWidgets doesn't use templates in certain areas,
396 // You have to triple-cast the event function.
398 // There are five parameters to wxEvtHandler::Connect -
400 // The first is the id of the instance whose events
401 // you want to handle - i.e. a menu id for menus,
402 // a control id for controls (wxControl::GetId())
405 // The second is the event id. This is the same
406 // as the message maps (EVT_MENU) except prefixed
407 // with "wx" (wxEVT_MENU).
409 // The third is the function handler for the event -
410 // You need to cast it to the specific event handler
411 // type, then to a wxEventFunction, then to a
412 // wxObjectEventFunction - I.E.
413 // (wxObjectEventFunction)(wxEventFunction)
414 // (wxCommandEventFunction) &MyFrame::MyHandler
416 // The fourth is an optional userdata param -
417 // this is of historical relevance only and is
418 // there only for backwards compatibility.
420 // The fifth is the context in which to call the
421 // handler - by default (this param is optional)
422 // this. For example in your event handler
423 // if you were to call "this->MyFunc()"
424 // it would literally do this->MyFunc. However,
425 // if you were to pass myHandler as the fifth
426 // parameter, for instance, you would _really_
427 // be calling myHandler->MyFunc, even though
428 // the compiler doesn't really know it.
434 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
435 (wxObjectEventFunction
) (wxEventFunction
)
436 (wxCommandEventFunction
) &MyFrame::OnQuit
);
438 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
439 (wxObjectEventFunction
) (wxEventFunction
)
440 (wxCommandEventFunction
) &MyFrame::OnAbout
);
442 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
443 (wxObjectEventFunction
) (wxEventFunction
)
444 (wxCommandEventFunction
) &MyFrame::OnLoop
);
446 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
447 (wxObjectEventFunction
) (wxEventFunction
)
448 (wxCommandEventFunction
) &MyFrame::OnOpenFileNewPage
);
450 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
451 (wxObjectEventFunction
) (wxEventFunction
)
452 (wxCommandEventFunction
) &MyFrame::OnOpenFileSamePage
);
454 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
455 (wxObjectEventFunction
) (wxEventFunction
)
456 (wxCommandEventFunction
) &MyFrame::OnOpenURLNewPage
);
458 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
459 (wxObjectEventFunction
) (wxEventFunction
)
460 (wxCommandEventFunction
) &MyFrame::OnOpenURLSamePage
);
462 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
463 (wxObjectEventFunction
) (wxEventFunction
)
464 (wxCommandEventFunction
) &MyFrame::OnCloseCurrentPage
);
466 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
467 (wxObjectEventFunction
) (wxEventFunction
)
468 (wxCommandEventFunction
) &MyFrame::OnPlay
);
470 this->Connect(wxID_PAUSE
, wxEVT_COMMAND_MENU_SELECTED
,
471 (wxObjectEventFunction
) (wxEventFunction
)
472 (wxCommandEventFunction
) &MyFrame::OnPause
);
474 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
475 (wxObjectEventFunction
) (wxEventFunction
)
476 (wxCommandEventFunction
) &MyFrame::OnStop
);
481 this->Connect(wxID_NOTEBOOK
, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
,
482 (wxObjectEventFunction
) (wxEventFunction
)
483 (wxNotebookEventFunction
) &MyFrame::OnPageChange
);
490 // Create a timer to update our status bar
492 m_timer
= new MyTimer(this);
496 // ----------------------------------------------------------------------------
497 // MyFrame Destructor
499 // 1) Deletes child objects implicitly
500 // 2) Delete our timer explicitly
501 // ----------------------------------------------------------------------------
507 // ----------------------------------------------------------------------------
508 // MyFrame::ResetStatus
510 // Here we just make a simple status string with some useful info about
511 // the media that we won't change later - such as the length of the media.
513 // We then append some other info that changes in MyTimer::Notify, then
514 // set the status bar to this text.
516 // In real applications, you'd want to find a better way to do this,
517 // such as static text controls (wxStaticText).
519 // We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
520 // we divide by 1000).
522 // We also reset our loop counter here.
523 // ----------------------------------------------------------------------------
524 void MyFrame::ResetStatus()
526 wxMediaCtrl
* currentMediaCtrl
= GetCurrentMediaCtrl();
528 m_basestatus
= wxString::Format(_T("Size(x,y):%i,%i ")
529 _T("Length(Seconds):%u Speed:%1.1fx"),
530 currentMediaCtrl
->GetBestSize().x
,
531 currentMediaCtrl
->GetBestSize().y
,
532 (unsigned)((currentMediaCtrl
->Length() / 1000)),
533 currentMediaCtrl
->GetPlaybackRate()
537 // ----------------------------------------------------------------------------
538 // MyFrame::GetCurrentMediaCtrl
540 // Obtains the media control of the current page, or NULL if there are no
542 // ----------------------------------------------------------------------------
543 wxMediaCtrl
* MyFrame::GetCurrentMediaCtrl()
545 wxASSERT(m_notebook
->GetCurrentPage() != NULL
);
546 return ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_mediactrl
;
549 // ----------------------------------------------------------------------------
550 // MyFrame::GetCurrentSlider
552 // Obtains the slider of the current page, or NULL if there are no
554 // ----------------------------------------------------------------------------
555 wxSlider
* MyFrame::GetCurrentSlider()
557 wxASSERT(m_notebook
->GetCurrentPage() != NULL
);
558 return ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_slider
;
561 // ----------------------------------------------------------------------------
564 // Called from file->quit.
565 // Closes this application.
566 // ----------------------------------------------------------------------------
567 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
569 // true is to force the frame to close
573 // ----------------------------------------------------------------------------
576 // Called from help->about.
577 // Gets some info about this application.
578 // ----------------------------------------------------------------------------
579 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
582 msg
.Printf( _T("This is a test of wxMediaCtrl.\n")
583 _T("Welcome to %s"), wxVERSION_STRING
);
585 wxMessageBox(msg
, _T("About wxMediaCtrl test"), wxOK
| wxICON_INFORMATION
, this);
588 // ----------------------------------------------------------------------------
591 // Called from file->loop.
592 // Changes the state of whether we want to loop or not.
593 // ----------------------------------------------------------------------------
594 void MyFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
596 if(!m_notebook
->GetCurrentPage())
598 wxMessageBox(wxT("No files are currently open!"));
602 ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
=
603 !((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
;
606 // ----------------------------------------------------------------------------
607 // MyFrame::OnOpenFileSamePage
609 // Called from file->openfile.
610 // Opens and plays a media file in the current notebook page
611 // ----------------------------------------------------------------------------
612 void MyFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
617 // ----------------------------------------------------------------------------
618 // MyFrame::OnOpenFileNewPage
620 // Called from file->openfileinnewpage.
621 // Opens and plays a media file in a new notebook page
622 // ----------------------------------------------------------------------------
623 void MyFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
628 // ----------------------------------------------------------------------------
631 // Code to actually open the media file
633 // 1) Create file dialog and ask the user for input file
634 // 2) If the user didn't want anything, break out
635 // 3) Create a new page if the user wanted one or there isn't a current page
638 // 6) Reset the text on the status bar
639 // 7) Set the slider of the current page to accurately reflect media length
640 // ----------------------------------------------------------------------------
641 void MyFrame::OpenFile(bool bNewPage
)
643 wxFileDialog
fd(this);
645 if(fd
.ShowModal() == wxID_OK
)
647 if(bNewPage
|| !m_notebook
->GetCurrentPage())
648 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), fd
.GetPath(), true);
650 if( !GetCurrentMediaCtrl()->Load(fd
.GetPath()) )
651 wxMessageBox(wxT("Couldn't load file!"));
653 if( !GetCurrentMediaCtrl()->Play() )
654 wxMessageBox(wxT("Couldn't play movie!"));
658 GetCurrentSlider()->SetRange(0,
659 (int)(GetCurrentMediaCtrl()->Length() / 1000));
664 // ----------------------------------------------------------------------------
665 // MyFrame::OnOpenURLSamePage
667 // Called from file->openurl.
668 // Opens and plays a media file from a URL in the current notebook page
669 // ----------------------------------------------------------------------------
670 void MyFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
675 // ----------------------------------------------------------------------------
676 // MyFrame::OnOpenURLNewPage
678 // Called from file->openurlinnewpage.
679 // Opens and plays a media file from a URL in a new notebook page
680 // ----------------------------------------------------------------------------
681 void MyFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
686 // ----------------------------------------------------------------------------
689 // Code to actually open the media file from a URL
691 // 1) Create text input dialog and ask the user for an input URL
692 // 2) If the user didn't want anything, break out
693 // 3) Create a new page if the user wanted one or there isn't a current page
696 // 6) Reset the text on the status bar
697 // 7) Set the slider of the current page to accurately reflect media length
698 // ----------------------------------------------------------------------------
699 void MyFrame::OpenURL(bool bNewPage
)
701 wxString theURL
= wxGetTextFromUser(wxT("Enter the URL that has the movie to play"));
705 if(bNewPage
|| !m_notebook
->GetCurrentPage())
706 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), theURL
, true);
708 if( !GetCurrentMediaCtrl()->Load(wxURI(theURL
)) )
709 wxMessageBox(wxT("Couldn't load URL!"));
711 if( !GetCurrentMediaCtrl()->Play() )
712 wxMessageBox(wxT("Couldn't play movie!"));
716 GetCurrentSlider()->SetRange(0,
717 (int)(GetCurrentMediaCtrl()->Length() / 1000));
721 // ----------------------------------------------------------------------------
722 // MyFrame::OnCloseCurrentPage
724 // Called when the user wants to close the current notebook page
726 // 1) Get the current page number (wxControl::GetSelection)
727 // 2) If there is no current page, break out
728 // 3) Delete the current page
729 // ----------------------------------------------------------------------------
730 void MyFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
732 int sel
= m_notebook
->GetSelection();
734 if (sel
!= wxNOT_FOUND
)
736 m_notebook
->DeletePage(sel
);
740 // ----------------------------------------------------------------------------
743 // Called from file->play.
744 // Resumes the media if it is paused or stopped.
745 // ----------------------------------------------------------------------------
746 void MyFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
748 if(!m_notebook
->GetCurrentPage())
750 wxMessageBox(wxT("No files are currently open!"));
754 if( !GetCurrentMediaCtrl()->Play() )
755 wxMessageBox(wxT("Couldn't play movie!"));
758 // ----------------------------------------------------------------------------
761 // Called from file->pause.
762 // Pauses the media in-place.
763 // ----------------------------------------------------------------------------
764 void MyFrame::OnPause(wxCommandEvent
& WXUNUSED(event
))
766 if(!m_notebook
->GetCurrentPage())
768 wxMessageBox(wxT("No files are currently open!"));
772 if( !GetCurrentMediaCtrl()->Pause() )
773 wxMessageBox(wxT("Couldn't pause movie!"));
776 // ----------------------------------------------------------------------------
779 // Called from file->stop.
780 // Where it stops depends on whether you can seek in the
781 // media control or not - if you can it stops and seeks to the beginning,
782 // otherwise it will appear to be at the end - but it will start over again
783 // when Play() is called
784 // ----------------------------------------------------------------------------
785 void MyFrame::OnStop(wxCommandEvent
& WXUNUSED(event
))
787 if(!m_notebook
->GetCurrentPage())
789 wxMessageBox(wxT("No files are currently open!"));
793 if( !GetCurrentMediaCtrl()->Stop() )
794 wxMessageBox(wxT("Couldn't stop movie!"));
797 // ----------------------------------------------------------------------------
798 // MyFrame::OnCloseCurrentPage
800 // Called when the user wants to closes the current notebook page
801 // ----------------------------------------------------------------------------
803 void MyFrame::OnPageChange(wxNotebookEvent
& WXUNUSED(event
))
808 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
812 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
814 // ----------------------------------------------------------------------------
817 // 1) Update our slider with the position were are in in the media
818 // 2) Update our status bar with the base text from MyFrame::ResetStatus,
819 // append some non-static (changing) info to it, then set the
820 // status bar text to that result
821 // ----------------------------------------------------------------------------
822 void MyTimer::Notify()
824 if (!m_frame
->m_notebook
->GetCurrentPage()) return;
825 wxMediaCtrl
* m_mediactrl
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_mediactrl
;
826 wxSlider
* m_slider
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_slider
;
827 if (!m_mediactrl
) return;
829 long lPosition
= (long)( m_mediactrl
->Tell() / 1000 );
830 m_slider
->SetValue(lPosition
);
833 m_frame
->SetStatusText(wxString::Format(
834 _T("%s Pos:%u State:%s Loops:%i"),
835 m_frame
->m_basestatus
.c_str(),
836 (unsigned int)lPosition
,
837 wxGetMediaStateText(m_mediactrl
->GetState()),
838 ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_nLoops
847 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
851 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
853 // ----------------------------------------------------------------------------
854 // MyNotebookPage Constructor
856 // Creates a media control and slider and adds it to this panel,
857 // along with some sizers for positioning
858 // ----------------------------------------------------------------------------
860 MyNotebookPage::MyNotebookPage(wxNotebook
* theBook
) :
861 wxPanel(theBook
, wxID_ANY
), m_nLoops(0), m_bLoop(false)
864 // Create and attach the first/main sizer
866 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxVERTICAL
);
867 this->SetSizer(vertsizer
);
868 this->SetAutoLayout(true);
871 // Create our media control
873 m_mediactrl
= new wxMediaCtrl();
875 // Make sure creation was successful
876 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
);
877 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
879 vertsizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
884 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
887 wxDefaultPosition
, wxDefaultSize
,
889 vertsizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
893 // Create the second sizer which will position things
896 // -------Menu----------
901 wxBoxSizer
* horzsizer
= new wxBoxSizer(wxHORIZONTAL
);
902 vertsizer
->Add(horzsizer
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
907 this->Connect(wxID_SLIDER
, wxEVT_COMMAND_SLIDER_UPDATED
,
908 (wxObjectEventFunction
) (wxEventFunction
)
909 (wxCommandEventFunction
) &MyNotebookPage::OnSeek
);
912 // Media Control events
914 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
915 (wxObjectEventFunction
) (wxEventFunction
)
916 (wxMediaEventFunction
) &MyNotebookPage::OnMediaFinished
);
919 // ----------------------------------------------------------------------------
920 // MyNotebook::OnSeek
922 // Called from file->seek.
923 // Called when the user moves the slider -
924 // seeks to a position within the media
925 // ----------------------------------------------------------------------------
926 void MyNotebookPage::OnSeek(wxCommandEvent
& WXUNUSED(event
))
928 if( m_mediactrl
->Seek(
929 m_slider
->GetValue() * 1000
930 ) == wxInvalidOffset
)
931 wxMessageBox(wxT("Couldn't seek in movie!"));
934 // ----------------------------------------------------------------------------
937 // Called when the media stops playing.
938 // Here we loop it if the user wants to (has been selected from file menu)
939 // ----------------------------------------------------------------------------
940 void MyNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
944 if ( !m_mediactrl
->Play() )
945 wxMessageBox(wxT("Couldn't loop movie!"));
952 // End of MediaPlayer sample