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 // ----------------------------------------------------------------------------
70 // Bail out if the user doesn't want one of the
72 // ----------------------------------------------------------------------------
75 #error "This is a GUI sample"
78 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || !wxUSE_NOTEBOOK
79 #error "menus, slider, mediactrl, notebook, and timers must all be enabled for this sample!"
82 // ============================================================================
84 // ============================================================================
86 // ----------------------------------------------------------------------------
88 // ----------------------------------------------------------------------------
90 // IDs for the controls and the menu commands
95 wxID_OPENFILESAMEPAGE
,
99 wxID_CLOSECURRENTPAGE
,
102 // wxID_STOP, [built-in to wxWidgets]
103 // wxID_ABOUT, [built-in to wxWidgets]
104 // wxID_EXIT, [built-in to wxWidgets]
105 wxID_SLIDER
, // event id for our slider
106 wxID_NOTEBOOK
, // event id for our notebook
107 wxID_MEDIACTRL
// event id for our wxMediaCtrl
110 // ----------------------------------------------------------------------------
112 // ----------------------------------------------------------------------------
114 class MyApp
: public wxApp
117 virtual bool OnInit();
120 // ----------------------------------------------------------------------------
122 // ----------------------------------------------------------------------------
124 class MyFrame
: public wxFrame
128 MyFrame(const wxString
& title
);
131 // Menu event handlers
132 void OnQuit(wxCommandEvent
& event
);
133 void OnAbout(wxCommandEvent
& event
);
134 void OnLoop(wxCommandEvent
& event
);
136 void OnOpenFileSamePage(wxCommandEvent
& event
);
137 void OnOpenFileNewPage(wxCommandEvent
& event
);
138 void OnOpenURLSamePage(wxCommandEvent
& event
);
139 void OnOpenURLNewPage(wxCommandEvent
& event
);
140 void OnCloseCurrentPage(wxCommandEvent
& event
);
142 void OnPlay(wxCommandEvent
& event
);
143 void OnPause(wxCommandEvent
& event
);
144 void OnStop(wxCommandEvent
& event
);
146 // Notebook event handlers
147 void OnPageChange(wxNotebookEvent
& event
);
150 // Rebuild base status string (see Implementation)
153 // Common open file code
154 void OpenFile(bool bNewPage
);
155 void OpenURL(bool bNewPage
);
157 // Get the media control and slider of current notebook page
158 wxMediaCtrl
* GetCurrentMediaCtrl();
159 wxSlider
* GetCurrentSlider();
161 class MyTimer
* m_timer
; //Timer to write info to status bar
162 wxString m_basestatus
; //Base status string (see ResetStatus())
163 wxNotebook
* m_notebook
; //Notebook containing our pages
165 // So that mytimer can access MyFrame's members
166 friend class MyTimer
;
171 // ----------------------------------------------------------------------------
173 // ----------------------------------------------------------------------------
175 class MyNotebookPage
: public wxPanel
177 MyNotebookPage(wxNotebook
* book
);
179 // Slider event handlers
180 void OnSeek(wxCommandEvent
& event
);
182 // Media event handlers
183 void OnMediaFinished(wxMediaEvent
& event
);
186 friend class MyFrame
; //make MyFrame able to access private members
187 wxMediaCtrl
* m_mediactrl
; //Our media control
188 wxSlider
* m_slider
; //The slider below our media control
189 int m_nLoops
; //Number of times media has looped
190 bool m_bLoop
; //Whether we are looping or not
193 // ----------------------------------------------------------------------------
195 // ----------------------------------------------------------------------------
197 class MyTimer
: public wxTimer
201 MyTimer(MyFrame
* frame
) {m_frame
= frame
;}
203 //Called each time the timer's timeout expires
206 MyFrame
* m_frame
; //The MyFrame
209 // ============================================================================
213 // ============================================================================
215 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
219 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
221 // ----------------------------------------------------------------------------
222 // wxGetMediaStateText
224 // Converts a wxMediaCtrl state into something useful that we can display
226 // ----------------------------------------------------------------------------
227 const wxChar
* wxGetMediaStateText(int nState
)
231 case wxMEDIASTATE_PLAYING
:
232 return wxT("Playing");
233 case wxMEDIASTATE_STOPPED
:
234 return wxT("Stopped");
235 ///case wxMEDIASTATE_PAUSED:
237 return wxT("Paused");
241 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
245 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
247 // ----------------------------------------------------------------------------
248 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
249 // use. For example, if you were to be in windows and use a file dialog,
250 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
251 // handle of the application. These routines in wx _DO NOT_ check to see if
252 // the wxApp exists, and thus will crash the application if you try it.
254 // IMPLEMENT_APP does this, and also implements the platform-specific entry
255 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
256 // not desire this behavior.
257 // ----------------------------------------------------------------------------
261 // ----------------------------------------------------------------------------
264 // Where execution starts - akin to a main or WinMain.
265 // 1) Create the frame and show it to the user
266 // 2) return true specifying that we want execution to continue past OnInit
267 // ----------------------------------------------------------------------------
270 MyFrame
*frame
= new MyFrame(_T("MediaPlayer wxWidgets Sample"));
277 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
281 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
283 // ----------------------------------------------------------------------------
284 // MyFrame Constructor
286 // 1) Create our menus
287 // 2) Create our notebook control and add it to the frame
288 // 3) Create our status bar
289 // 4) Connect our events
290 // 5) Start our timer
291 // ----------------------------------------------------------------------------
293 MyFrame::MyFrame(const wxString
& title
)
294 : wxFrame(NULL
, wxID_ANY
, title
)
299 wxMenu
*menuFile
= new wxMenu
;
301 wxMenu
*helpMenu
= new wxMenu
;
302 helpMenu
->Append(wxID_ABOUT
,
304 _T("Show about dialog"));
306 menuFile
->Append(wxID_OPENFILESAMEPAGE
, _T("&Open File"),
307 _T("Open a File in the current notebook page"));
308 menuFile
->Append(wxID_OPENFILENEWPAGE
, _T("&Open File in a new page"),
309 _T("Open a File in a new notebook page"));
310 #if wxUSE_UNOFFICIALSTUFF
311 menuFile
->Append(wxID_OPENURLSAMEPAGE
, _T("&Open URL"),
312 _T("Open a URL in the current notebook page"));
313 menuFile
->Append(wxID_OPENURLNEWPAGE
, _T("&Open URL in a new page"),
314 _T("Open a URL in a new notebook page"));
316 menuFile
->AppendSeparator();
317 menuFile
->Append(wxID_CLOSECURRENTPAGE
, _T("&Close Current Page"),
318 _T("Close current notebook page"));
319 menuFile
->AppendSeparator();
320 menuFile
->Append(wxID_PLAY
, _T("&Play"), _T("Resume playback"));
321 menuFile
->Append(wxID_PAUSE
, _T("P&ause"), _T("Pause playback"));
322 menuFile
->Append(wxID_STOP
, _T("&Stop"), _T("Stop playback"));
323 menuFile
->AppendSeparator();
324 menuFile
->AppendCheckItem(wxID_LOOP
,
326 _T("Loop Selected Media"));
327 menuFile
->AppendSeparator();
328 menuFile
->Append(wxID_EXIT
,
330 _T("Quit this program"));
332 wxMenuBar
*menuBar
= new wxMenuBar();
333 menuBar
->Append(menuFile
, _T("&File"));
334 menuBar
->Append(helpMenu
, _T("&Help"));
339 // Create our notebook - using wxNotebook is luckily pretty
340 // simple and self-explanatory in most cases
342 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
345 // Create our status bar
348 // create a status bar just for fun (by default with 1 pane only)
350 #endif // wxUSE_STATUSBAR
355 // There are two ways in wxWidgets to use events -
356 // Message Maps and Connections.
358 // Message Maps are implemented by putting
359 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
360 // class you want to use for events, such as MyFrame.
362 // Then after your class declaration you put
363 // BEGIN_EVENT_TABLE(MyFrame, wxFrame)
367 // Where MyFrame is the class with the DECLARE_MESSAGE_MAP
368 // in it. EVT_XXX(XXX) are each of your handlers, such
369 // as EVT_MENU for menu events and the XXX inside
370 // is the parameters to the event macro - in the case
371 // of EVT_MENU the menu id and then the function to call.
373 // However, with wxEvtHandler::Connect you can avoid a
374 // global message map for your class and those annoying
375 // macros. You can also change the context in which
376 // the call the handler (more later).
378 // The downside is that due to the limitation that
379 // wxWidgets doesn't use templates in certain areas,
380 // You have to triple-cast the event function.
382 // There are five parameters to wxEvtHandler::Connect -
384 // The first is the id of the instance whose events
385 // you want to handle - i.e. a menu id for menus,
386 // a control id for controls (wxControl::GetId())
389 // The second is the event id. This is the same
390 // as the message maps (EVT_MENU) except prefixed
391 // with "wx" (wxEVT_MENU).
393 // The third is the function handler for the event -
394 // You need to cast it to the specific event handler
395 // type, then to a wxEventFunction, then to a
396 // wxObjectEventFunction - I.E.
397 // (wxObjectEventFunction)(wxEventFunction)
398 // (wxCommandEventFunction) &MyFrame::MyHandler
400 // Or, you can use the new (2.5.5+) event handler
401 // conversion macros - for instance the above could
403 // wxCommandEventHandler(MyFrame::MyHandler)
404 // pretty simple, eh?
406 // The fourth is an optional userdata param -
407 // this is of historical relevance only and is
408 // there only for backwards compatibility.
410 // The fifth is the context in which to call the
411 // handler - by default (this param is optional)
412 // this. For example in your event handler
413 // if you were to call "this->MyFunc()"
414 // it would literally do this->MyFunc. However,
415 // if you were to pass myHandler as the fifth
416 // parameter, for instance, you would _really_
417 // be calling myHandler->MyFunc, even though
418 // the compiler doesn't really know it.
424 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
425 wxCommandEventHandler(MyFrame::OnQuit
));
427 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
428 wxCommandEventHandler(MyFrame::OnAbout
));
430 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
431 wxCommandEventHandler(MyFrame::OnLoop
));
433 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
434 wxCommandEventHandler(MyFrame::OnOpenFileNewPage
));
436 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
437 wxCommandEventHandler(MyFrame::OnOpenFileSamePage
));
439 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
440 wxCommandEventHandler(MyFrame::OnOpenURLNewPage
));
442 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
443 wxCommandEventHandler(MyFrame::OnOpenURLSamePage
));
445 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
446 wxCommandEventHandler(MyFrame::OnCloseCurrentPage
));
448 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
449 wxCommandEventHandler(MyFrame::OnPlay
));
451 this->Connect(wxID_PAUSE
, wxEVT_COMMAND_MENU_SELECTED
,
452 wxCommandEventHandler(MyFrame::OnPause
));
454 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
455 wxCommandEventHandler(MyFrame::OnStop
));
460 this->Connect(wxID_NOTEBOOK
, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
,
461 wxNotebookEventHandler(MyFrame::OnPageChange
));
468 // Create a timer to update our status bar
470 m_timer
= new MyTimer(this);
474 // ----------------------------------------------------------------------------
475 // MyFrame Destructor
477 // 1) Deletes child objects implicitly
478 // 2) Delete our timer explicitly
479 // ----------------------------------------------------------------------------
485 // ----------------------------------------------------------------------------
486 // MyFrame::ResetStatus
488 // Here we just make a simple status string with some useful info about
489 // the media that we won't change later - such as the length of the media.
491 // We then append some other info that changes in MyTimer::Notify, then
492 // set the status bar to this text.
494 // In real applications, you'd want to find a better way to do this,
495 // such as static text controls (wxStaticText).
497 // We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
498 // we divide by 1000).
500 // We also reset our loop counter here.
501 // ----------------------------------------------------------------------------
502 void MyFrame::ResetStatus()
504 wxMediaCtrl
* currentMediaCtrl
= GetCurrentMediaCtrl();
506 m_basestatus
= wxString::Format(_T("Size(x,y):%i,%i ")
507 _T("Length(Seconds):%u Speed:%1.1fx"),
508 currentMediaCtrl
->GetBestSize().x
,
509 currentMediaCtrl
->GetBestSize().y
,
510 (unsigned)((currentMediaCtrl
->Length() / 1000)),
511 currentMediaCtrl
->GetPlaybackRate()
515 // ----------------------------------------------------------------------------
516 // MyFrame::GetCurrentMediaCtrl
518 // Obtains the media control of the current page, or NULL if there are no
520 // ----------------------------------------------------------------------------
521 wxMediaCtrl
* MyFrame::GetCurrentMediaCtrl()
523 wxASSERT(m_notebook
->GetCurrentPage() != NULL
);
524 return ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_mediactrl
;
527 // ----------------------------------------------------------------------------
528 // MyFrame::GetCurrentSlider
530 // Obtains the slider of the current page, or NULL if there are no
532 // ----------------------------------------------------------------------------
533 wxSlider
* MyFrame::GetCurrentSlider()
535 wxASSERT(m_notebook
->GetCurrentPage() != NULL
);
536 return ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_slider
;
539 // ----------------------------------------------------------------------------
542 // Called from file->quit.
543 // Closes this application.
544 // ----------------------------------------------------------------------------
545 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
547 // true is to force the frame to close
551 // ----------------------------------------------------------------------------
554 // Called from help->about.
555 // Gets some info about this application.
556 // ----------------------------------------------------------------------------
557 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
560 msg
.Printf( _T("This is a test of wxMediaCtrl.\n")
561 _T("Welcome to %s"), wxVERSION_STRING
);
563 wxMessageBox(msg
, _T("About wxMediaCtrl test"), wxOK
| wxICON_INFORMATION
, this);
566 // ----------------------------------------------------------------------------
569 // Called from file->loop.
570 // Changes the state of whether we want to loop or not.
571 // ----------------------------------------------------------------------------
572 void MyFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
574 if(!m_notebook
->GetCurrentPage())
576 wxMessageBox(wxT("No files are currently open!"));
580 ((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
=
581 !((MyNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
;
584 // ----------------------------------------------------------------------------
585 // MyFrame::OnOpenFileSamePage
587 // Called from file->openfile.
588 // Opens and plays a media file in the current notebook page
589 // ----------------------------------------------------------------------------
590 void MyFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
595 // ----------------------------------------------------------------------------
596 // MyFrame::OnOpenFileNewPage
598 // Called from file->openfileinnewpage.
599 // Opens and plays a media file in a new notebook page
600 // ----------------------------------------------------------------------------
601 void MyFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
606 // ----------------------------------------------------------------------------
609 // Code to actually open the media file
611 // 1) Create file dialog and ask the user for input file
612 // 2) If the user didn't want anything, break out
613 // 3) Create a new page if the user wanted one or there isn't a current page
616 // 6) Reset the text on the status bar
617 // 7) Set the slider of the current page to accurately reflect media length
618 // ----------------------------------------------------------------------------
619 void MyFrame::OpenFile(bool bNewPage
)
621 wxFileDialog
fd(this);
623 if(fd
.ShowModal() == wxID_OK
)
625 if(bNewPage
|| !m_notebook
->GetCurrentPage())
626 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), fd
.GetPath(), true);
627 else //don't forget to update notebook page title
628 m_notebook
->SetPageText(m_notebook
->GetSelection(), fd
.GetPath());
630 if( !GetCurrentMediaCtrl()->Load(fd
.GetPath()) )
631 wxMessageBox(wxT("Couldn't load file!"));
633 if( !GetCurrentMediaCtrl()->Play() )
634 wxMessageBox(wxT("Couldn't play movie!"));
638 GetCurrentSlider()->SetRange(0,
639 (int)(GetCurrentMediaCtrl()->Length() / 1000));
643 // ----------------------------------------------------------------------------
644 // MyFrame::OnOpenURLSamePage
646 // Called from file->openurl.
647 // Opens and plays a media file from a URL in the current notebook page
648 // ----------------------------------------------------------------------------
649 void MyFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
654 // ----------------------------------------------------------------------------
655 // MyFrame::OnOpenURLNewPage
657 // Called from file->openurlinnewpage.
658 // Opens and plays a media file from a URL in a new notebook page
659 // ----------------------------------------------------------------------------
660 void MyFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
665 // ----------------------------------------------------------------------------
668 // Code to actually open the media file from a URL
670 // 1) Create text input dialog and ask the user for an input URL
671 // 2) If the user didn't want anything, break out
672 // 3) Create a new page if the user wanted one or there isn't a current page
675 // 6) Reset the text on the status bar
676 // 7) Set the slider of the current page to accurately reflect media length
677 // ----------------------------------------------------------------------------
678 void MyFrame::OpenURL(bool bNewPage
)
680 wxString theURL
= wxGetTextFromUser(wxT("Enter the URL that has the movie to play"));
684 if(bNewPage
|| !m_notebook
->GetCurrentPage())
685 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), theURL
, true);
686 else //don't forget to update notebook page title
687 m_notebook
->SetPageText(m_notebook
->GetSelection(), theURL
);
689 if( !GetCurrentMediaCtrl()->Load(wxURI(theURL
)) )
690 wxMessageBox(wxT("Couldn't load URL!"));
692 if( !GetCurrentMediaCtrl()->Play() )
693 wxMessageBox(wxT("Couldn't play movie!"));
697 GetCurrentSlider()->SetRange(0,
698 (int)(GetCurrentMediaCtrl()->Length() / 1000));
702 // ----------------------------------------------------------------------------
703 // MyFrame::OnCloseCurrentPage
705 // Called when the user wants to close the current notebook page
707 // 1) Get the current page number (wxControl::GetSelection)
708 // 2) If there is no current page, break out
709 // 3) Delete the current page
710 // ----------------------------------------------------------------------------
711 void MyFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
713 int sel
= m_notebook
->GetSelection();
715 if (sel
!= wxNOT_FOUND
)
717 m_notebook
->DeletePage(sel
);
721 // ----------------------------------------------------------------------------
724 // Called from file->play.
725 // Resumes the media if it is paused or stopped.
726 // ----------------------------------------------------------------------------
727 void MyFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
729 if(!m_notebook
->GetCurrentPage())
731 wxMessageBox(wxT("No files are currently open!"));
735 if( !GetCurrentMediaCtrl()->Play() )
736 wxMessageBox(wxT("Couldn't play movie!"));
739 // ----------------------------------------------------------------------------
742 // Called from file->pause.
743 // Pauses the media in-place.
744 // ----------------------------------------------------------------------------
745 void MyFrame::OnPause(wxCommandEvent
& WXUNUSED(event
))
747 if(!m_notebook
->GetCurrentPage())
749 wxMessageBox(wxT("No files are currently open!"));
753 if( !GetCurrentMediaCtrl()->Pause() )
754 wxMessageBox(wxT("Couldn't pause movie!"));
757 // ----------------------------------------------------------------------------
760 // Called from file->stop.
761 // Where it stops depends on whether you can seek in the
762 // media control or not - if you can it stops and seeks to the beginning,
763 // otherwise it will appear to be at the end - but it will start over again
764 // when Play() is called
765 // ----------------------------------------------------------------------------
766 void MyFrame::OnStop(wxCommandEvent
& WXUNUSED(event
))
768 if(!m_notebook
->GetCurrentPage())
770 wxMessageBox(wxT("No files are currently open!"));
774 if( !GetCurrentMediaCtrl()->Stop() )
775 wxMessageBox(wxT("Couldn't stop movie!"));
778 // ----------------------------------------------------------------------------
779 // MyFrame::OnCloseCurrentPage
781 // Called when the user wants to closes the current notebook page
782 // ----------------------------------------------------------------------------
784 void MyFrame::OnPageChange(wxNotebookEvent
& WXUNUSED(event
))
789 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
793 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
795 // ----------------------------------------------------------------------------
798 // 1) Update our slider with the position were are in in the media
799 // 2) Update our status bar with the base text from MyFrame::ResetStatus,
800 // append some non-static (changing) info to it, then set the
801 // status bar text to that result
802 // ----------------------------------------------------------------------------
803 void MyTimer::Notify()
805 if (!m_frame
->m_notebook
->GetCurrentPage()) return;
806 wxMediaCtrl
* m_mediactrl
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_mediactrl
;
807 wxSlider
* m_slider
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_slider
;
808 if (!m_mediactrl
) return;
810 long lPosition
= (long)( m_mediactrl
->Tell() / 1000 );
811 m_slider
->SetValue(lPosition
);
814 m_frame
->SetStatusText(wxString::Format(
815 _T("%s Pos:%u State:%s Loops:%i"),
816 m_frame
->m_basestatus
.c_str(),
817 (unsigned int)lPosition
,
818 wxGetMediaStateText(m_mediactrl
->GetState()),
819 ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_nLoops
828 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
832 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
834 // ----------------------------------------------------------------------------
835 // MyNotebookPage Constructor
837 // Creates a media control and slider and adds it to this panel,
838 // along with some sizers for positioning
839 // ----------------------------------------------------------------------------
841 MyNotebookPage::MyNotebookPage(wxNotebook
* theBook
) :
842 wxPanel(theBook
, wxID_ANY
), m_nLoops(0), m_bLoop(false)
845 // Create and attach the first/main sizer
847 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxVERTICAL
);
848 this->SetSizer(vertsizer
);
849 this->SetAutoLayout(true);
852 // Create our media control
854 m_mediactrl
= new wxMediaCtrl();
856 // Make sure creation was successful
857 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
);
858 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
861 vertsizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
866 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
869 wxDefaultPosition
, wxDefaultSize
,
871 vertsizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
875 // Create the second sizer which will position things
878 // -------Menu----------
883 wxBoxSizer
* horzsizer
= new wxBoxSizer(wxHORIZONTAL
);
884 vertsizer
->Add(horzsizer
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
889 this->Connect(wxID_SLIDER
, wxEVT_COMMAND_SLIDER_UPDATED
,
890 wxCommandEventHandler(MyNotebookPage::OnSeek
));
893 // Media Control events
895 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
896 wxMediaEventHandler(MyNotebookPage::OnMediaFinished
));
899 // ----------------------------------------------------------------------------
900 // MyNotebook::OnSeek
902 // Called from file->seek.
903 // Called when the user moves the slider -
904 // seeks to a position within the media
905 // ----------------------------------------------------------------------------
906 void MyNotebookPage::OnSeek(wxCommandEvent
& WXUNUSED(event
))
908 if( m_mediactrl
->Seek(
909 m_slider
->GetValue() * 1000
910 ) == wxInvalidOffset
)
911 wxMessageBox(wxT("Couldn't seek in movie!"));
914 // ----------------------------------------------------------------------------
917 // Called when the media stops playing.
918 // Here we loop it if the user wants to (has been selected from file menu)
919 // ----------------------------------------------------------------------------
920 void MyNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
924 if ( !m_mediactrl
->Play() )
925 wxMessageBox(wxT("Couldn't loop movie!"));
932 // End of MediaPlayer sample