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) Not available on Unix :\.
30 // 2) Certain backends can't play the same media file at the same time (MCI,
31 // Cocoa NSMovieView/Quicktime).
32 // 3) Positioning on Mac Carbon is messed up if put in a sub-control like a
33 // Notebook (like this sample does).
34 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36 // ============================================================================
38 // ============================================================================
40 // ----------------------------------------------------------------------------
41 // Pre-compiled header stuff
42 // ----------------------------------------------------------------------------
44 #include "wx/wxprec.h"
54 // ----------------------------------------------------------------------------
56 // ----------------------------------------------------------------------------
58 #include "wx/mediactrl.h" //for wxMediaCtrl
59 #include "wx/filedlg.h" //for opening files from OpenFile
60 #include "wx/slider.h" //for a slider for seeking within media
61 #include "wx/sizer.h" //for positioning controls/wxBoxSizer
62 #include "wx/timer.h" //timer for updating status bar
63 #include "wx/textdlg.h" //for getting user text from OpenURL
64 #include "wx/notebook.h" //for wxNotebook and putting movies in pages
66 // Use some stuff that's not part of the current API, such as loading
67 // media from a URL, etc.
68 #define wxUSE_UNOFFICIALSTUFF 0
70 //Libraries for MSVC with optional backends
73 #pragma comment(lib,"strmiids.lib")
76 #pragma comment(lib,"qtmlClient.lib")
80 // ----------------------------------------------------------------------------
81 // Bail out if the user doesn't want one of the
83 // ----------------------------------------------------------------------------
86 #error "This is a GUI sample"
89 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || !wxUSE_NOTEBOOK
90 #error "menus, slider, mediactrl, notebook, and timers must all be enabled for this sample!"
93 // ============================================================================
95 // ============================================================================
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
101 // IDs for the controls and the menu commands
106 wxID_OPENFILESAMEPAGE
,
107 wxID_OPENFILENEWPAGE
,
108 wxID_OPENURLSAMEPAGE
,
110 wxID_CLOSECURRENTPAGE
,
113 // wxID_STOP, [built-in to wxWidgets]
114 // wxID_ABOUT, [built-in to wxWidgets]
115 // wxID_EXIT, [built-in to wxWidgets]
117 // event id for our slider
120 // event id for our notebook
123 // event id for our wxMediaCtrl
127 // ----------------------------------------------------------------------------
129 // ----------------------------------------------------------------------------
131 class MyApp
: public wxApp
134 virtual bool OnInit();
137 // ----------------------------------------------------------------------------
139 // ----------------------------------------------------------------------------
141 class MyFrame
: public wxFrame
145 MyFrame(const wxString
& title
);
148 // Menu event handlers
149 void OnQuit(wxCommandEvent
& event
);
150 void OnAbout(wxCommandEvent
& event
);
151 void OnLoop(wxCommandEvent
& event
);
153 void OnOpenFileSamePage(wxCommandEvent
& event
);
154 void OnOpenFileNewPage(wxCommandEvent
& event
);
155 void OnOpenURLSamePage(wxCommandEvent
& event
);
156 void OnOpenURLNewPage(wxCommandEvent
& event
);
157 void OnCloseCurrentPage(wxCommandEvent
& event
);
159 void OnPlay(wxCommandEvent
& event
);
160 void OnPause(wxCommandEvent
& event
);
161 void OnStop(wxCommandEvent
& event
);
163 // Notebook event handlers
164 void OnPageChange(wxNotebookEvent
& event
);
167 // Rebuild base status string (see Implementation)
170 // Common open file code
171 void OpenFile(bool bNewPage
);
172 void OpenURL(bool bNewPage
);
174 // Get the media control and slider of current notebook page
175 wxMediaCtrl
* GetCurrentMediaCtrl();
176 wxSlider
* GetCurrentSlider();
178 class MyTimer
* m_timer
; //Timer to write info to status bar
179 wxString m_basestatus
; //Base status string (see ResetStatus())
180 wxNotebook
* m_notebook
;
182 // So that mytimer can access MyFrame's members
183 friend class MyTimer
;
188 // ----------------------------------------------------------------------------
190 // ----------------------------------------------------------------------------
192 class MyNotebookPage
: public wxPanel
194 MyNotebookPage(wxNotebook
* book
);
196 // Slider event handlers
197 void OnSeek(wxCommandEvent
& event
);
199 // Media event handlers
200 void OnMediaStop(wxMediaEvent
& event
);
203 friend class MyFrame
; //make MyFrame able to access private members
204 wxMediaCtrl
* m_mediactrl
; //Our media control
205 wxSlider
* m_slider
; //The slider below our media control
206 int m_nLoops
; //Number of times media has looped
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 compatability.
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!"));
601 GetCurrentMediaCtrl()->Loop( !GetCurrentMediaCtrl()->IsLooped() );
604 // ----------------------------------------------------------------------------
605 // MyFrame::OnOpenFileSamePage
607 // Called from file->openfile.
608 // Opens and plays a media file in the current notebook page
609 // ----------------------------------------------------------------------------
610 void MyFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
615 // ----------------------------------------------------------------------------
616 // MyFrame::OnOpenFileNewPage
618 // Called from file->openfileinnewpage.
619 // Opens and plays a media file in a new notebook page
620 // ----------------------------------------------------------------------------
621 void MyFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
626 // ----------------------------------------------------------------------------
629 // Code to actually open the media file
631 // 1) Create file dialog and ask the user for input file
632 // 2) If the user didn't want anything, break out
633 // 3) Create a new page if the user wanted one or there isn't a current page
636 // 6) Reset the text on the status bar
637 // 7) Set the slider of the current page to accurately reflect media length
638 // ----------------------------------------------------------------------------
639 void MyFrame::OpenFile(bool bNewPage
)
641 wxFileDialog
fd(this);
643 if(fd
.ShowModal() == wxID_OK
)
645 if(bNewPage
|| !m_notebook
->GetCurrentPage())
646 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), fd
.GetPath(), true);
648 if( !GetCurrentMediaCtrl()->Load(fd
.GetPath()) )
649 wxMessageBox(wxT("Couldn't load file!"));
651 if( !GetCurrentMediaCtrl()->Play() )
652 wxMessageBox(wxT("Couldn't play movie!"));
656 GetCurrentSlider()->SetRange(0,
657 (int)(GetCurrentMediaCtrl()->Length() / 1000));
662 // ----------------------------------------------------------------------------
663 // MyFrame::OnOpenURLSamePage
665 // Called from file->openurl.
666 // Opens and plays a media file from a URL in the current notebook page
667 // ----------------------------------------------------------------------------
668 void MyFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
673 // ----------------------------------------------------------------------------
674 // MyFrame::OnOpenURLNewPage
676 // Called from file->openurlinnewpage.
677 // Opens and plays a media file from a URL in a new notebook page
678 // ----------------------------------------------------------------------------
679 void MyFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
684 // ----------------------------------------------------------------------------
687 // Code to actually open the media file from a URL
689 // 1) Create text input dialog and ask the user for an input URL
690 // 2) If the user didn't want anything, break out
691 // 3) Create a new page if the user wanted one or there isn't a current page
694 // 6) Reset the text on the status bar
695 // 7) Set the slider of the current page to accurately reflect media length
696 // ----------------------------------------------------------------------------
697 void MyFrame::OpenURL(bool bNewPage
)
699 wxString theURL
= wxGetTextFromUser(wxT("Enter the URL that has the movie to play"));
703 if(bNewPage
|| !m_notebook
->GetCurrentPage())
704 m_notebook
->AddPage(new MyNotebookPage(m_notebook
), theURL
, true);
706 if( !GetCurrentMediaCtrl()->Load(wxURI(theURL
)) )
707 wxMessageBox(wxT("Couldn't load URL!"));
709 if( !GetCurrentMediaCtrl()->Play() )
710 wxMessageBox(wxT("Couldn't play movie!"));
714 GetCurrentSlider()->SetRange(0,
715 (int)(GetCurrentMediaCtrl()->Length() / 1000));
719 // ----------------------------------------------------------------------------
720 // MyFrame::OnCloseCurrentPage
722 // Called when the user wants to close the current notebook page
724 // 1) Get the current page number (wxControl::GetSelection)
725 // 2) If there is no current page, break out
726 // 3) Delete the current page
727 // ----------------------------------------------------------------------------
728 void MyFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
730 int sel
= m_notebook
->GetSelection();
732 if (sel
!= wxNOT_FOUND
)
734 m_notebook
->DeletePage(sel
);
738 // ----------------------------------------------------------------------------
741 // Called from file->play.
742 // Resumes the media if it is paused or stopped.
743 // ----------------------------------------------------------------------------
744 void MyFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
746 if(!m_notebook
->GetCurrentPage())
748 wxMessageBox(wxT("No files are currently open!"));
752 if( !GetCurrentMediaCtrl()->Play() )
753 wxMessageBox(wxT("Couldn't play movie!"));
756 // ----------------------------------------------------------------------------
759 // Called from file->pause.
760 // Pauses the media in-place.
761 // ----------------------------------------------------------------------------
762 void MyFrame::OnPause(wxCommandEvent
& WXUNUSED(event
))
764 if(!m_notebook
->GetCurrentPage())
766 wxMessageBox(wxT("No files are currently open!"));
770 if( !GetCurrentMediaCtrl()->Pause() )
771 wxMessageBox(wxT("Couldn't pause movie!"));
774 // ----------------------------------------------------------------------------
777 // Called from file->stop.
778 // Where it stops depends on whether you can seek in the
779 // media control or not - if you can it stops and seeks to the beginning,
780 // otherwise it will appear to be at the end - but it will start over again
781 // when Play() is called
782 // ----------------------------------------------------------------------------
783 void MyFrame::OnStop(wxCommandEvent
& WXUNUSED(event
))
785 if(!m_notebook
->GetCurrentPage())
787 wxMessageBox(wxT("No files are currently open!"));
791 if( !GetCurrentMediaCtrl()->Stop() )
792 wxMessageBox(wxT("Couldn't stop movie!"));
795 // ----------------------------------------------------------------------------
796 // MyFrame::OnCloseCurrentPage
798 // Called when the user wants to closes the current notebook page
799 // ----------------------------------------------------------------------------
801 void MyFrame::OnPageChange(wxNotebookEvent
& WXUNUSED(event
))
806 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
810 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
812 // ----------------------------------------------------------------------------
815 // 1) Update our slider with the position were are in in the media
816 // 2) Update our status bar with the base text from MyFrame::ResetStatus,
817 // append some non-static (changing) info to it, then set the
818 // status bar text to that result
819 // ----------------------------------------------------------------------------
820 void MyTimer::Notify()
822 if (!m_frame
->m_notebook
->GetCurrentPage()) return;
823 wxMediaCtrl
* m_mediactrl
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_mediactrl
;
824 wxSlider
* m_slider
= ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_slider
;
825 if (!m_mediactrl
) return;
827 long lPosition
= (long)( m_mediactrl
->Tell() / 1000 );
828 m_slider
->SetValue(lPosition
);
831 m_frame
->SetStatusText(wxString::Format(
832 _T("%s Pos:%u State:%s Loops:%i"),
833 m_frame
->m_basestatus
.c_str(),
834 (unsigned int)lPosition
,
835 wxGetMediaStateText(m_mediactrl
->GetState()),
836 ((MyNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_nLoops
845 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
849 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
851 // ----------------------------------------------------------------------------
852 // MyNotebookPage Constructor
854 // Creates a media control and slider and adds it to this panel,
855 // along with some sizers for positioning
856 // ----------------------------------------------------------------------------
858 MyNotebookPage::MyNotebookPage(wxNotebook
* theBook
) :
859 wxPanel(theBook
, wxID_ANY
), m_nLoops(0)
862 // Create and attach the first/main sizer
864 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxVERTICAL
);
865 this->SetSizer(vertsizer
);
866 this->SetAutoLayout(true);
869 // Create our media control
871 m_mediactrl
= new wxMediaCtrl(this, wxID_MEDIACTRL
);
872 vertsizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
877 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
880 wxDefaultPosition
, wxDefaultSize
,
882 vertsizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
886 // Create the second sizer which will position things
889 // -------Menu----------
894 wxBoxSizer
* horzsizer
= new wxBoxSizer(wxHORIZONTAL
);
895 vertsizer
->Add(horzsizer
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
, 5);
900 this->Connect(wxID_SLIDER
, wxEVT_COMMAND_SLIDER_UPDATED
,
901 (wxObjectEventFunction
) (wxEventFunction
)
902 (wxCommandEventFunction
) &MyNotebookPage::OnSeek
);
905 // Media Control events
907 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_STOP
,
908 (wxObjectEventFunction
) (wxEventFunction
)
909 (wxMediaEventFunction
) &MyNotebookPage::OnMediaStop
);
912 // ----------------------------------------------------------------------------
913 // MyNotebook::OnSeek
915 // Called from file->seek.
916 // Called when the user moves the slider -
917 // seeks to a position within the media
918 // ----------------------------------------------------------------------------
919 void MyNotebookPage::OnSeek(wxCommandEvent
& WXUNUSED(event
))
921 if( m_mediactrl
->Seek(
922 m_slider
->GetValue() * 1000
923 ) == wxInvalidOffset
)
924 wxMessageBox(wxT("Couldn't seek in movie!"));
927 // ----------------------------------------------------------------------------
928 // MyNotebookPage::OnMediaStop
930 // Called when the media is about to stop playing.
931 // ----------------------------------------------------------------------------
932 void MyNotebookPage::OnMediaStop(wxMediaEvent
& WXUNUSED(event
))
934 if(m_mediactrl
->IsLooped())
939 // End of MediaPlayer sample