1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mediaplayer.cpp
3 // Purpose: wxMediaCtrl sample
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
15 // This is a somewhat comprehensive example of how to use all the funtionality
16 // of the wxMediaCtrl class in wxWidgets.
18 // To use this sample, simply select Open File from the file menu,
19 // select the file you want to play - and MediaPlayer will play the file in a
20 // the current notebook page, showing video if necessary.
22 // You can select one of the menu options, or move the slider around
23 // to manipulate what is playing.
24 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
26 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27 // Known bugs with wxMediaCtrl:
29 // 1) Certain backends can't play the same media file at the same time (MCI,
30 // Cocoa NSMovieView-Quicktime).
31 // 2) Positioning on Mac Carbon is messed up if put in a sub-control like a
32 // Notebook (like this sample does) on OS versions < 10.2.
33 // 3) On unix the video may not work - it only checks for a few video
34 // sinks - xvimagesink, ximagesink and whatever gnome preferences has -
35 // if gnome preferences is not available or you have a different video
36 // sink then those two (such as sdlvideosink) then you'll get black video
37 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39 // ============================================================================
41 // ============================================================================
43 // ----------------------------------------------------------------------------
44 // Pre-compiled header stuff
45 // ----------------------------------------------------------------------------
47 #include "wx/wxprec.h"
57 // ----------------------------------------------------------------------------
59 // ----------------------------------------------------------------------------
61 #include "wx/mediactrl.h" //for wxMediaCtrl
62 #include "wx/filedlg.h" //for opening files from OpenFile
63 #include "wx/slider.h" //for a slider for seeking within media
64 #include "wx/sizer.h" //for positioning controls/wxBoxSizer
65 #include "wx/timer.h" //timer for updating status bar
66 #include "wx/textdlg.h" //for getting user text from OpenURL/Debug
67 #include "wx/notebook.h" //for wxNotebook and putting movies in pages
68 #include "wx/cmdline.h" //for wxCmdLineParser (optional)
69 #include "wx/listctrl.h" //for wxListCtrl
70 #include "wx/dnd.h" //drag and drop for the playlist
71 #include "wx/filename.h" //For wxFileName::GetName()
72 #include "wx/config.h" //for native wxConfig
74 // ----------------------------------------------------------------------------
75 // Bail out if the user doesn't want one of the
77 // ----------------------------------------------------------------------------
79 // RN: I'm not sure why this is here - even minimal doesn't check for
80 // wxUSE_GUI. I may have added it myself though...
82 #error "This is a GUI sample"
85 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || \
86 !wxUSE_NOTEBOOK || !wxUSE_LISTCTRL || !wxUSE_DRAG_AND_DROP
87 #error "Not all required elements are enabled. Please modify setup.h!"
90 // ============================================================================
92 // ============================================================================
94 // ----------------------------------------------------------------------------
96 // ----------------------------------------------------------------------------
98 // IDs for the controls and the menu commands
103 wxID_OPENFILESAMEPAGE
,
104 wxID_OPENFILENEWPAGE
,
105 wxID_OPENURLSAMEPAGE
,
107 wxID_CLOSECURRENTPAGE
,
114 // wxID_STOP, [built-in to wxWidgets]
115 // wxID_ABOUT, [built-in to wxWidgets]
116 // wxID_EXIT, [built-in to wxWidgets]
131 // ----------------------------------------------------------------------------
133 // ----------------------------------------------------------------------------
135 class wxMediaPlayerApp
: public wxApp
139 virtual void MacOpenFile(const wxString
& fileName
)
141 //Called when a user drags a file over our app
142 m_frame
->DoOpenFile(fileName
);
145 virtual bool OnInit();
148 class wxMediaPlayerFrame
* m_frame
;
151 // ----------------------------------------------------------------------------
152 // wxMediaPlayerFrame
153 // ----------------------------------------------------------------------------
155 class wxMediaPlayerFrame
: public wxFrame
159 wxMediaPlayerFrame(const wxString
& title
);
160 ~wxMediaPlayerFrame();
162 // Menu event handlers
163 void OnQuit(wxCommandEvent
& event
);
164 void OnAbout(wxCommandEvent
& event
);
166 void OnOpenFileSamePage(wxCommandEvent
& event
);
167 void OnOpenFileNewPage(wxCommandEvent
& event
);
168 void OnOpenURLSamePage(wxCommandEvent
& event
);
169 void OnOpenURLNewPage(wxCommandEvent
& event
);
170 void OnCloseCurrentPage(wxCommandEvent
& event
);
172 void OnPlay(wxCommandEvent
& event
);
173 void OnPause(wxCommandEvent
& event
);
174 void OnStop(wxCommandEvent
& event
);
175 void OnNext(wxCommandEvent
& event
);
176 void OnPrev(wxCommandEvent
& event
);
177 void OnVolumeDown(wxCommandEvent
& event
);
178 void OnVolumeUp(wxCommandEvent
& event
);
180 void OnLoop(wxCommandEvent
& event
);
181 void OnShowInterface(wxCommandEvent
& event
);
183 void OnSelectBackend(wxCommandEvent
& event
);
185 // Notebook event handlers
186 void OnPageChange(wxNotebookEvent
& event
);
188 // Key event handlers
189 void OnKeyDown(wxKeyEvent
& event
);
191 // Quickie for playing from command line
192 void AddToPlayList(const wxString
& szString
);
194 // ListCtrl event handlers
195 void OnChangeSong(wxListEvent
& event
);
197 // Media event handlers
198 void OnMediaLoaded(wxMediaEvent
& event
);
200 // Close event handlers
201 void OnClose(wxCloseEvent
& event
);
204 // Rebuild base status string (see Implementation)
207 // Common open file code
208 void OpenFile(bool bNewPage
);
209 void OpenURL(bool bNewPage
);
210 void DoOpenFile(const wxString
& path
, bool bNewPage
);
211 void DoPlayFile(const wxString
& path
);
213 // Get the controls of current notebook page
214 wxMediaCtrl
* GetCurrentMediaCtrl();
215 wxSlider
* GetCurrentSlider();
216 wxGauge
* GetCurrentGauge();
218 int m_nLastFileId
; //List ID of played file in listctrl
219 wxString m_szFile
; //Name of currently playing file/location
220 class wxMediaPlayerTimer
* m_timer
; //Timer to write info to status bar
221 wxString m_basestatus
; //Base status string (see ResetStatus())
222 wxNotebook
* m_notebook
; //Notebook containing our pages
224 // Maybe I should use more accessors, but for simplicity
225 // I'll allow the other classes access to our members
226 friend class wxMediaPlayerApp
;
227 friend class wxMediaPlayerNotebookPage
;
228 friend class wxMediaPlayerTimer
;
233 // ----------------------------------------------------------------------------
234 // wxMediaPlayerNotebookPage
235 // ----------------------------------------------------------------------------
237 class wxMediaPlayerNotebookPage
: public wxPanel
239 wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
240 wxNotebook
* book
, const wxString
& be
= wxEmptyString
);
242 // Slider event handlers
243 void OnBeginSeek(wxScrollEvent
& event
);
244 void OnEndSeek(wxScrollEvent
& event
);
246 // Media event handlers
247 void OnMediaFinished(wxMediaEvent
& event
);
250 bool IsBeingDragged(); //accessor for m_bIsBeingDragged
252 //make wxMediaPlayerFrame able to access the private members
253 friend class wxMediaPlayerFrame
;
255 wxMediaCtrl
* m_mediactrl
; //Our media control
256 class wxMediaPlayerListCtrl
* m_playlist
; //Our playlist
257 wxSlider
* m_slider
; //The slider below our media control
258 int m_nLoops
; //Number of times media has looped
259 bool m_bLoop
; //Whether we are looping or not
260 bool m_bIsBeingDragged
; //Whether the user is dragging the scroll bar
261 wxMediaPlayerFrame
* m_parentFrame
; //Main wxFrame of our sample
262 wxButton
* m_prevButton
; //Go to previous file button
263 wxButton
* m_playButton
; //Play/pause file button
264 wxButton
* m_stopButton
; //Stop playing file button
265 wxButton
* m_nextButton
; //Next file button
266 wxButton
* m_vdButton
; //Volume down button
267 wxButton
* m_vuButton
; //Volume up button
268 wxGauge
* m_gauge
; //Gauge to keep in line with slider
271 // ----------------------------------------------------------------------------
272 // wxMediaPlayerTimer
273 // ----------------------------------------------------------------------------
275 class wxMediaPlayerTimer
: public wxTimer
279 wxMediaPlayerTimer(wxMediaPlayerFrame
* frame
) {m_frame
= frame
;}
281 //Called each time the timer's timeout expires
284 wxMediaPlayerFrame
* m_frame
; //The wxMediaPlayerFrame
287 // ----------------------------------------------------------------------------
288 // wxMediaPlayerListCtrl
289 // ----------------------------------------------------------------------------
290 class wxMediaPlayerListCtrl
: public wxListCtrl
293 void AddToPlayList(const wxString
& szString
)
296 kNewItem
.SetAlign(wxLIST_FORMAT_LEFT
);
300 kNewItem
.SetId(nID
= this->GetItemCount());
301 kNewItem
.SetMask(wxLIST_MASK_DATA
);
302 kNewItem
.SetData(new wxString(szString
));
304 this->InsertItem(kNewItem
);
305 this->SetItem(nID
, 0, _T("*"));
306 this->SetItem(nID
, 1, wxFileName(szString
).GetName());
310 kNewItem
.SetBackgroundColour(wxColour(192,192,192));
311 this->SetItem(kNewItem
);
315 void GetSelectedItem(wxListItem
& listitem
)
317 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
318 int nLast
= -1, nLastSelected
= -1;
319 while ((nLast
= this->GetNextItem(nLast
,
321 wxLIST_STATE_SELECTED
)) != -1)
323 listitem
.SetId(nLast
);
324 this->GetItem(listitem
);
325 if ((listitem
.GetState() & wxLIST_STATE_FOCUSED
) )
327 nLastSelected
= nLast
;
329 if (nLast
== -1 && nLastSelected
== -1)
331 listitem
.SetId(nLastSelected
== -1 ? nLast
: nLastSelected
);
332 this->GetItem(listitem
);
337 // ----------------------------------------------------------------------------
338 // wxPlayListDropTarget
340 // Drop target for playlist (i.e. user drags a file from explorer unto
341 // playlist it adds the file)
342 // ----------------------------------------------------------------------------
343 class wxPlayListDropTarget
: public wxFileDropTarget
346 wxPlayListDropTarget(wxMediaPlayerListCtrl
& list
) : m_list(list
) {}
347 ~wxPlayListDropTarget(){}
348 virtual bool OnDropFiles(wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
349 const wxArrayString
& files
)
351 for (size_t i
= 0; i
< files
.GetCount(); ++i
)
353 m_list
.AddToPlayList(files
[i
]);
357 wxMediaPlayerListCtrl
& m_list
;
360 // ============================================================================
364 // ============================================================================
366 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
370 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
372 // ----------------------------------------------------------------------------
373 // wxGetMediaStateText
375 // Converts a wxMediaCtrl state into something useful that we can display
377 // ----------------------------------------------------------------------------
378 const wxChar
* wxGetMediaStateText(int nState
)
382 case wxMEDIASTATE_PLAYING
:
383 return wxT("Playing");
384 case wxMEDIASTATE_STOPPED
:
385 return wxT("Stopped");
386 ///case wxMEDIASTATE_PAUSED:
388 return wxT("Paused");
392 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
396 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
398 // ----------------------------------------------------------------------------
399 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
400 // use. For example, if you were to be in windows and use a file dialog,
401 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
402 // handle of the application. These routines in wx _DO NOT_ check to see if
403 // the wxApp exists, and thus will crash the application if you try it.
405 // IMPLEMENT_APP does this, and also implements the platform-specific entry
406 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
407 // not desire this behavior.
408 // ----------------------------------------------------------------------------
409 IMPLEMENT_APP(wxMediaPlayerApp
)
411 // ----------------------------------------------------------------------------
412 // wxMediaPlayerApp::OnInit
414 // Where execution starts - akin to a main or WinMain.
415 // 1) Create the frame and show it to the user
416 // 2) Process filenames from the commandline
417 // 3) return true specifying that we want execution to continue past OnInit
418 // ----------------------------------------------------------------------------
419 bool wxMediaPlayerApp::OnInit()
421 wxMediaPlayerFrame
*frame
=
422 new wxMediaPlayerFrame(_T("MediaPlayer wxWidgets Sample"));
425 #if wxUSE_CMDLINE_PARSER
427 // What this does is get all the command line arguments
428 // and treat each one as a file to put to the initial playlist
430 wxCmdLineEntryDesc cmdLineDesc
[2];
431 cmdLineDesc
[0].kind
= wxCMD_LINE_PARAM
;
432 cmdLineDesc
[0].shortName
= NULL
;
433 cmdLineDesc
[0].longName
= NULL
;
434 cmdLineDesc
[0].description
= wxT("input files");
435 cmdLineDesc
[0].type
= wxCMD_LINE_VAL_STRING
;
436 cmdLineDesc
[0].flags
= wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
;
438 cmdLineDesc
[1].kind
= wxCMD_LINE_NONE
;
440 //gets the passed media files from cmd line
441 wxCmdLineParser
parser (cmdLineDesc
, argc
, argv
);
443 // get filenames from the commandline
444 if (parser
.Parse() == 0)
446 for (size_t paramNr
=0; paramNr
< parser
.GetParamCount(); ++paramNr
)
448 frame
->AddToPlayList((parser
.GetParam (paramNr
)));
450 wxCommandEvent emptyevt
;
451 frame
->OnNext(emptyevt
);
459 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
461 // wxMediaPlayerFrame
463 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
465 // ----------------------------------------------------------------------------
466 // wxMediaPlayerFrame Constructor
468 // 1) Create our menus
469 // 2) Create our notebook control and add it to the frame
470 // 3) Create our status bar
471 // 4) Connect our events
472 // 5) Start our timer
473 // ----------------------------------------------------------------------------
475 wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString
& title
)
476 : wxFrame(NULL
, wxID_ANY
, title
, wxDefaultPosition
, wxSize(600,600)),
482 wxMenu
*fileMenu
= new wxMenu
;
483 wxMenu
*controlsMenu
= new wxMenu
;
484 wxMenu
*optionsMenu
= new wxMenu
;
485 wxMenu
*helpMenu
= new wxMenu
;
486 wxMenu
*debugMenu
= new wxMenu
;
488 fileMenu
->Append(wxID_OPENFILESAMEPAGE
, _T("&Open File\tCtrl-Shift-O"),
489 _T("Open a File in the current notebook page"));
490 fileMenu
->Append(wxID_OPENFILENEWPAGE
, _T("&Open File in a new page"),
491 _T("Open a File in a new notebook page"));
492 fileMenu
->Append(wxID_OPENURLSAMEPAGE
, _T("&Open URL"),
493 _T("Open a URL in the current notebook page"));
494 fileMenu
->Append(wxID_OPENURLNEWPAGE
, _T("&Open URL in a new page"),
495 _T("Open a URL in a new notebook page"));
496 fileMenu
->AppendSeparator();
497 fileMenu
->Append(wxID_CLOSECURRENTPAGE
, _T("&Close Current Page\tCtrl-C"),
498 _T("Close current notebook page"));
499 fileMenu
->AppendSeparator();
500 fileMenu
->Append(wxID_EXIT
,
502 _T("Quit this program"));
504 controlsMenu
->Append(wxID_PLAY
, _T("&Play/Pause\tCtrl-P"), _T("Resume/Pause playback"));
505 controlsMenu
->Append(wxID_STOP
, _T("&Stop\tCtrl-S"), _T("Stop playback"));
506 controlsMenu
->AppendSeparator();
507 controlsMenu
->Append(wxID_PREV
, _T("&Previous\tCtrl-B"), _T("Go to previous track"));
508 controlsMenu
->Append(wxID_NEXT
, _T("&Next\tCtrl-N"), _T("Skip to next track"));
510 optionsMenu
->AppendCheckItem(wxID_LOOP
,
512 _T("Loop Selected Media"));
513 optionsMenu
->AppendCheckItem(wxID_SHOWINTERFACE
,
514 _T("&Show Interface\tCtrl-I"),
515 _T("Show wxMediaCtrl native controls"));
517 debugMenu
->Append(wxID_SELECTBACKEND
,
518 _T("&Select Backend...\tCtrl-D"),
519 _T("Select a backend manually"));
521 helpMenu
->Append(wxID_ABOUT
,
523 _T("Show about dialog"));
526 wxMenuBar
*menuBar
= new wxMenuBar();
527 menuBar
->Append(fileMenu
, _T("&File"));
528 menuBar
->Append(controlsMenu
, _T("&Controls"));
529 menuBar
->Append(optionsMenu
, _T("&Options"));
530 menuBar
->Append(debugMenu
, _T("&Debug"));
531 menuBar
->Append(helpMenu
, _T("&Help"));
535 // Create our notebook - using wxNotebook is luckily pretty
536 // simple and self-explanatory in most cases
538 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
541 // Create our status bar
544 // create a status bar just for fun (by default with 1 pane only)
546 #endif // wxUSE_STATUSBAR
551 // There are two ways in wxWidgets to use events -
552 // Message Maps and Connections.
554 // Message Maps are implemented by putting
555 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
556 // class you want to use for events, such as wxMediaPlayerFrame.
558 // Then after your class declaration you put
559 // BEGIN_EVENT_TABLE(wxMediaPlayerFrame, wxFrame)
563 // Where wxMediaPlayerFrame is the class with the DECLARE_MESSAGE_MAP
564 // in it. EVT_XXX(XXX) are each of your handlers, such
565 // as EVT_MENU for menu events and the XXX inside
566 // is the parameters to the event macro - in the case
567 // of EVT_MENU the menu id and then the function to call.
569 // However, with wxEvtHandler::Connect you can avoid a
570 // global message map for your class and those annoying
571 // macros. You can also change the context in which
572 // the call the handler (more later).
574 // The downside is that due to the limitation that
575 // wxWidgets doesn't use templates in certain areas,
576 // You have to triple-cast the event function.
578 // There are five parameters to wxEvtHandler::Connect -
580 // The first is the id of the instance whose events
581 // you want to handle - i.e. a menu id for menus,
582 // a control id for controls (wxControl::GetId())
585 // The second is the event id. This is the same
586 // as the message maps (EVT_MENU) except prefixed
587 // with "wx" (wxEVT_MENU).
589 // The third is the function handler for the event -
590 // You need to cast it to the specific event handler
591 // type, then to a wxEventFunction, then to a
592 // wxObjectEventFunction - I.E.
593 // (wxObjectEventFunction)(wxEventFunction)
594 // (wxCommandEventFunction) &wxMediaPlayerFrame::MyHandler
596 // Or, you can use the new (2.5.5+) event handler
597 // conversion macros - for instance the above could
599 // wxCommandEventHandler(wxMediaPlayerFrame::MyHandler)
600 // pretty simple, eh?
602 // The fourth is an optional userdata param -
603 // this is of historical relevance only and is
604 // there only for backwards compatibility.
606 // The fifth is the context in which to call the
607 // handler - by default (this param is optional)
608 // this. For example in your event handler
609 // if you were to call "this->MyFunc()"
610 // it would literally do this->MyFunc. However,
611 // if you were to pass myHandler as the fifth
612 // parameter, for instance, you would _really_
613 // be calling myHandler->MyFunc, even though
614 // the compiler doesn't really know it.
620 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
621 wxCommandEventHandler(wxMediaPlayerFrame::OnQuit
));
623 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
624 wxCommandEventHandler(wxMediaPlayerFrame::OnAbout
));
626 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
627 wxCommandEventHandler(wxMediaPlayerFrame::OnLoop
));
629 this->Connect(wxID_SHOWINTERFACE
, wxEVT_COMMAND_MENU_SELECTED
,
630 wxCommandEventHandler(wxMediaPlayerFrame::OnShowInterface
));
632 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
633 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileNewPage
));
635 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
636 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileSamePage
));
638 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
639 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLNewPage
));
641 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
642 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLSamePage
));
644 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
645 wxCommandEventHandler(wxMediaPlayerFrame::OnCloseCurrentPage
));
647 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
648 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
));
650 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
651 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
));
653 this->Connect(wxID_NEXT
, wxEVT_COMMAND_MENU_SELECTED
,
654 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
));
656 this->Connect(wxID_PREV
, wxEVT_COMMAND_MENU_SELECTED
,
657 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
));
659 this->Connect(wxID_SELECTBACKEND
, wxEVT_COMMAND_MENU_SELECTED
,
660 wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend
));
665 this->Connect(wxID_NOTEBOOK
, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
,
666 wxNotebookEventHandler(wxMediaPlayerFrame::OnPageChange
));
671 wxTheApp
->Connect(wxID_ANY
, wxEVT_KEY_DOWN
,
672 wxKeyEventHandler(wxMediaPlayerFrame::OnKeyDown
),
678 this->Connect(wxID_ANY
, wxEVT_CLOSE_WINDOW
,
679 wxCloseEventHandler(wxMediaPlayerFrame::OnClose
));
686 // Create an initial notebook page so the user has something
687 // to work with without having to go file->open every time :).
689 m_notebook
->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook
),
694 // Create a timer to update our status bar
696 m_timer
= new wxMediaPlayerTimer(this);
700 // ----------------------------------------------------------------------------
701 // wxMediaPlayerFrame Destructor
703 // 1) Deletes child objects implicitly
704 // 2) Delete our timer explicitly
705 // ----------------------------------------------------------------------------
706 wxMediaPlayerFrame::~wxMediaPlayerFrame()
712 // ----------------------------------------------------------------------------
713 // wxMediaPlayerFrame::OnClose
714 // ----------------------------------------------------------------------------
715 void wxMediaPlayerFrame::OnClose(wxCloseEvent
& event
)
718 // Here we save our info to the registry or whatever
719 // mechanism the OS uses.
721 // This makes it so that when mediaplayer loads up again
722 // it restores the same files that were in the playlist
723 // this time, rather than the user manually re-adding them.
725 // We need to do conf->DeleteAll() here because by default
726 // the config still contains the same files as last time
727 // so we need to clear it before writing our new ones.
729 // TODO: Maybe you could add a menu option to the
730 // options menu to delete the configuration on exit -
731 // all you'd need to do is just remove everything after
732 // conf->DeleteAll() here
734 wxMediaPlayerListCtrl
* m_playlist
=
735 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
737 wxConfigBase
* conf
= wxConfigBase::Get();
740 for(int i
= 0; i
< m_playlist
->GetItemCount(); ++i
)
742 wxString
* pData
= (wxString
*) m_playlist
->GetItemData(i
);
745 conf
->Write(s
, *(pData
));
749 event
.Skip(); //really close the frame
752 // ----------------------------------------------------------------------------
753 // wxMediaPlayerFrame::AddToPlayList
754 // ----------------------------------------------------------------------------
755 void wxMediaPlayerFrame::AddToPlayList(const wxString
& szString
)
757 wxMediaPlayerNotebookPage
* currentpage
=
758 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
760 currentpage
->m_playlist
->AddToPlayList(szString
);
764 // ----------------------------------------------------------------------------
765 // wxMediaPlayerFrame::ResetStatus
767 // Here we just make a simple status string with some useful info about
768 // the media that we won't change later - such as the length of the media.
770 // We then append some other info that changes in wxMediaPlayerTimer::Notify, then
771 // set the status bar to this text.
773 // In real applications, you'd want to find a better way to do this,
774 // such as static text controls (wxStaticText).
776 // We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
777 // we divide by 1000).
779 // We also reset our loop counter here.
780 // ----------------------------------------------------------------------------
781 void wxMediaPlayerFrame::ResetStatus()
783 wxMediaCtrl
* currentMediaCtrl
= GetCurrentMediaCtrl();
785 m_basestatus
= wxString::Format(_T("Size(x,y):%i,%i ")
786 _T("Length(Seconds):%u Speed:%1.1fx"),
787 currentMediaCtrl
->GetBestSize().x
,
788 currentMediaCtrl
->GetBestSize().y
,
789 (unsigned)((currentMediaCtrl
->Length() / 1000)),
790 currentMediaCtrl
->GetPlaybackRate()
794 // ----------------------------------------------------------------------------
795 // wxMediaPlayerFrame::GetCurrentMediaCtrl
797 // Obtains the media control of the current page, or NULL if there are no
799 // ----------------------------------------------------------------------------
800 wxMediaCtrl
* wxMediaPlayerFrame::GetCurrentMediaCtrl()
802 return ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_mediactrl
;
805 // ----------------------------------------------------------------------------
806 // wxMediaPlayerFrame::GetCurrentSlider
808 // Obtains the slider of the current page
809 // ----------------------------------------------------------------------------
810 wxSlider
* wxMediaPlayerFrame::GetCurrentSlider()
812 return ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_slider
;
815 // ----------------------------------------------------------------------------
816 // wxMediaPlayerFrame::GetCurrentGauge
818 // Obtains the gauge of the current page
819 // ----------------------------------------------------------------------------
820 wxGauge
* wxMediaPlayerFrame::GetCurrentGauge()
822 return ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_gauge
;
825 // ----------------------------------------------------------------------------
826 // wxMediaPlayerFrame::OnQuit
828 // Called from file->quit.
829 // Closes this application.
830 // ----------------------------------------------------------------------------
831 void wxMediaPlayerFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
833 // true is to force the frame to close
837 // ----------------------------------------------------------------------------
838 // wxMediaPlayerFrame::OnAbout
840 // Called from help->about.
841 // Gets some info about this application.
842 // ----------------------------------------------------------------------------
843 void wxMediaPlayerFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
846 msg
.Printf( _T("This is a test of wxMediaCtrl.\n")
847 _T("Welcome to %s"), wxVERSION_STRING
);
849 wxMessageBox(msg
, _T("About wxMediaCtrl test"), wxOK
| wxICON_INFORMATION
, this);
852 // ----------------------------------------------------------------------------
853 // wxMediaPlayerFrame::OnLoop
855 // Called from file->loop.
856 // Changes the state of whether we want to loop or not.
857 // ----------------------------------------------------------------------------
858 void wxMediaPlayerFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
860 if(!m_notebook
->GetCurrentPage())
862 wxMessageBox(wxT("No files are currently open!"));
866 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
=
867 !((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
;
870 // ----------------------------------------------------------------------------
871 // wxMediaPlayerFrame::OnLoop
873 // Called from file->loop.
874 // Changes the state of whether we want to loop or not.
875 // ----------------------------------------------------------------------------
876 void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent
& event
)
878 if(!m_notebook
->GetCurrentPage())
880 wxMessageBox(wxT("No files are currently open!"));
884 GetCurrentMediaCtrl()->ShowPlayerControls(event
.IsChecked() ?
885 wxMEDIACTRLPLAYERCONTROLS_DEFAULT
:
886 wxMEDIACTRLPLAYERCONTROLS_NONE
);
889 // ----------------------------------------------------------------------------
890 // wxMediaPlayerFrame::OnOpenFileSamePage
892 // Called from file->openfile.
893 // Opens and plays a media file in the current notebook page
894 // ----------------------------------------------------------------------------
895 void wxMediaPlayerFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
900 // ----------------------------------------------------------------------------
901 // wxMediaPlayerFrame::OnOpenFileNewPage
903 // Called from file->openfileinnewpage.
904 // Opens and plays a media file in a new notebook page
905 // ----------------------------------------------------------------------------
906 void wxMediaPlayerFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
911 // ----------------------------------------------------------------------------
912 // wxMediaPlayerFrame::OpenFile
914 // Opens a file dialog asking the user for a filename, then
915 // calls DoOpenFile which will add the file to the playlist and play it
916 // ----------------------------------------------------------------------------
917 void wxMediaPlayerFrame::OpenFile(bool bNewPage
)
919 wxFileDialog
fd(this);
921 if(fd
.ShowModal() == wxID_OK
)
923 DoOpenFile(fd
.GetPath(), bNewPage
);
927 // ----------------------------------------------------------------------------
928 // wxMediaPlayerFrame::DoOpenFile
930 // Adds the file to our playlist, selects it in the playlist,
931 // and then calls DoPlayFile to play it
932 // ----------------------------------------------------------------------------
933 void wxMediaPlayerFrame::DoOpenFile(const wxString
& path
, bool bNewPage
)
938 new wxMediaPlayerNotebookPage(this, m_notebook
),
943 wxMediaPlayerListCtrl
* m_playlist
=
944 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
946 if(m_nLastFileId
!= -1)
947 m_playlist
->SetItemState(m_nLastFileId
, 0, wxLIST_STATE_SELECTED
);
949 wxListItem newlistitem
;
950 newlistitem
.SetAlign(wxLIST_FORMAT_LEFT
);
954 newlistitem
.SetId(nID
= m_playlist
->GetItemCount());
955 newlistitem
.SetMask(wxLIST_MASK_DATA
| wxLIST_MASK_STATE
);
956 newlistitem
.SetState(wxLIST_STATE_SELECTED
);
957 newlistitem
.SetData(new wxString(path
));
959 m_playlist
->InsertItem(newlistitem
);
960 m_playlist
->SetItem(nID
, 0, _T("*"));
961 m_playlist
->SetItem(nID
, 1, wxFileName(path
).GetName());
965 newlistitem
.SetBackgroundColour(wxColour(192,192,192));
966 m_playlist
->SetItem(newlistitem
);
970 // m_playlist->Focus(nID);
973 // ----------------------------------------------------------------------------
974 // wxMediaPlayerFrame::DoPlayFile
976 // Pauses the file if its the currently playing file,
977 // otherwise it plays the file
978 // ----------------------------------------------------------------------------
979 void wxMediaPlayerFrame::DoPlayFile(const wxString
& path
)
981 wxMediaPlayerListCtrl
* m_playlist
=
982 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
985 m_playlist
->GetSelectedItem(listitem
);
987 if(listitem
.GetData() != NULL
&&
988 m_szFile
.compare(path
) == 0 &&
989 m_nLastFileId
== listitem
.GetId())
991 if(GetCurrentMediaCtrl()->GetState() == wxMEDIASTATE_PLAYING
)
993 if( !GetCurrentMediaCtrl()->Pause() )
994 wxMessageBox(wxT("Couldn't pause movie!"));
996 m_playlist
->SetItem(listitem
.GetId(), 0, _T("||"));
1000 if( !GetCurrentMediaCtrl()->Play() )
1001 wxMessageBox(wxT("Couldn't pause movie!"));
1003 m_playlist
->SetItem(listitem
.GetId(), 0, _T(">"));
1008 m_notebook
->SetPageText(m_notebook
->GetSelection(),
1009 wxFileName(path
).GetName());
1011 if(m_nLastFileId
!= -1)
1012 m_playlist
->SetItem(m_nLastFileId
, 0, _T("*"));
1014 wxURI
uripath(path
);
1015 if( uripath
.IsReference() )
1017 if( !GetCurrentMediaCtrl()->Load(path
) )
1019 wxMessageBox(wxT("Couldn't load file!"));
1020 m_playlist
->SetItem(listitem
.GetId(), 0, _T("E"));
1024 m_playlist
->SetItem(listitem
.GetId(), 0, _T("O"));
1029 if( !GetCurrentMediaCtrl()->Load(uripath
) )
1031 wxMessageBox(wxT("Couldn't load file!"));
1032 m_playlist
->SetItem(listitem
.GetId(), 0, _T("E"));
1036 m_playlist
->SetItem(listitem
.GetId(), 0, _T("O"));
1040 m_nLastFileId
= listitem
.GetId();
1042 m_playlist
->SetItem(m_nLastFileId
, 1, wxFileName(path
).GetName());
1043 m_playlist
->SetItem(m_nLastFileId
, 2, wxT(""));
1047 // ----------------------------------------------------------------------------
1048 // wxMediaPlayerFrame::OnMediaLoaded
1050 // Called when the media is ready to be played - and does
1051 // so, also gets the length of media and shows that in the list control
1052 // ----------------------------------------------------------------------------
1053 void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent
& WXUNUSED(evt
))
1055 wxMediaPlayerListCtrl
* m_playlist
=
1056 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1057 wxListItem listitem
;
1058 m_playlist
->GetSelectedItem(listitem
);
1060 if( !GetCurrentMediaCtrl()->Play() )
1062 wxMessageBox(wxT("Couldn't play movie!"));
1063 m_playlist
->SetItem(listitem
.GetId(), 0, _T("E"));
1067 m_playlist
->SetItem(listitem
.GetId(), 0, _T(">"));
1070 m_playlist
->SetItem(listitem
.GetId(), 2, wxString::Format(wxT("%u"),
1071 (unsigned) GetCurrentMediaCtrl()->Length() / 1000) );
1075 GetCurrentSlider()->SetRange(0,
1076 (int)(GetCurrentMediaCtrl()->Length() / 1000));
1077 GetCurrentGauge()->SetRange((int)(GetCurrentMediaCtrl()->Length() / 1000));
1080 // ----------------------------------------------------------------------------
1081 // wxMediaPlayerFrame::OnSelectBackend
1083 // Little debugging routine - enter the class name of a backend and it
1084 // will use that instead of letting wxMediaCtrl search the wxMediaBackend
1086 // ----------------------------------------------------------------------------
1087 void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent
& WXUNUSED(evt
))
1089 wxString sBackend
= wxGetTextFromUser(wxT("Enter backend to use"));
1091 if(sBackend
.empty() == false) //could have been cancelled by the user
1093 int sel
= m_notebook
->GetSelection();
1095 if (sel
!= wxNOT_FOUND
)
1097 m_notebook
->DeletePage(sel
);
1100 m_notebook
->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook
,
1103 DoOpenFile(m_szFile
, false);
1107 // ----------------------------------------------------------------------------
1108 // wxMediaPlayerFrame::OnOpenURLSamePage
1110 // Called from file->openurl.
1111 // Opens and plays a media file from a URL in the current notebook page
1112 // ----------------------------------------------------------------------------
1113 void wxMediaPlayerFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
1118 // ----------------------------------------------------------------------------
1119 // wxMediaPlayerFrame::OnOpenURLNewPage
1121 // Called from file->openurlinnewpage.
1122 // Opens and plays a media file from a URL in a new notebook page
1123 // ----------------------------------------------------------------------------
1124 void wxMediaPlayerFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
1129 // ----------------------------------------------------------------------------
1130 // wxMediaPlayerFrame::OpenURL
1132 // Just calls DoOpenFile with the url path - which calls DoPlayFile
1133 // which handles the real dirty work
1134 // ----------------------------------------------------------------------------
1135 void wxMediaPlayerFrame::OpenURL(bool bNewPage
)
1137 wxString sUrl
= wxGetTextFromUser(
1138 wxT("Enter the URL that has the movie to play")
1141 if(sUrl
.empty() == false) //could have been cancelled by user
1143 DoOpenFile(sUrl
, bNewPage
);
1147 // ----------------------------------------------------------------------------
1148 // wxMediaPlayerFrame::OnCloseCurrentPage
1150 // Called when the user wants to close the current notebook page
1152 // 1) Get the current page number (wxControl::GetSelection)
1153 // 2) If there is no current page, break out
1154 // 3) Delete the current page
1155 // ----------------------------------------------------------------------------
1156 void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
1158 if( m_notebook
->GetPageCount() > 1 )
1160 int sel
= m_notebook
->GetSelection();
1162 if (sel
!= wxNOT_FOUND
)
1164 m_notebook
->DeletePage(sel
);
1169 wxMessageBox(wxT("Cannot close main page"));
1173 // ----------------------------------------------------------------------------
1174 // wxMediaPlayerFrame::OnPlay
1176 // Called from file->play.
1177 // Resumes the media if it is paused or stopped.
1178 // ----------------------------------------------------------------------------
1179 void wxMediaPlayerFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
1181 wxMediaPlayerListCtrl
* m_playlist
=
1182 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1184 wxListItem listitem
;
1185 m_playlist
->GetSelectedItem(listitem
);
1186 if (listitem
.GetData() == NULL
)
1189 if ((nLast
= m_playlist
->GetNextItem(nLast
,
1191 wxLIST_STATE_DONTCARE
)) == -1)
1194 wxMessageBox(_T("No items in playlist!"));
1197 wxListItem listitem
;
1198 listitem
.SetId(nLast
);
1199 m_playlist
->GetItem(listitem
);
1200 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1201 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1202 m_playlist
->SetItem(listitem
);
1204 OnChangeSong(event
);
1209 OnChangeSong(event
);
1213 // ----------------------------------------------------------------------------
1214 // wxMediaPlayerFrame::OnKeyDown
1216 // Deletes all selected files from the playlist if the backspace key is pressed
1217 // ----------------------------------------------------------------------------
1218 void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent
& event
)
1220 if(event
.GetKeyCode() == WXK_BACK
/*DELETE*/)
1222 wxMediaPlayerListCtrl
* m_playlist
=
1223 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1224 //delete all selected items
1227 wxInt32 nSelectedItem
= m_playlist
->GetNextItem(
1228 -1, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1229 if (nSelectedItem
== -1)
1232 wxListItem listitem
;
1233 listitem
.SetId(nSelectedItem
);
1234 m_playlist
->GetItem(listitem
);
1235 delete (wxString
*) listitem
.GetData();
1237 m_playlist
->DeleteItem(nSelectedItem
);
1241 //Could be wxGetTextFromUser or something else important
1242 if(event
.GetEventObject() != this)
1246 // ----------------------------------------------------------------------------
1247 // wxMediaPlayerFrame::OnStop
1249 // Called from file->stop.
1250 // Where it stops depends on whether you can seek in the
1251 // media control or not - if you can it stops and seeks to the beginning,
1252 // otherwise it will appear to be at the end - but it will start over again
1253 // when Play() is called
1254 // ----------------------------------------------------------------------------
1255 void wxMediaPlayerFrame::OnStop(wxCommandEvent
& WXUNUSED(evt
))
1257 wxMediaPlayerListCtrl
* m_playlist
=
1258 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1260 wxListItem listitem
;
1261 m_playlist
->GetSelectedItem(listitem
);
1262 m_playlist
->SetItem(listitem
.GetId(), 0, _T("[]"));
1264 if(!m_notebook
->GetCurrentPage())
1266 wxMessageBox(wxT("No files are currently open!"));
1270 if( !GetCurrentMediaCtrl()->Stop() )
1271 wxMessageBox(wxT("Couldn't stop movie!"));
1275 // ----------------------------------------------------------------------------
1276 // wxMediaPlayerFrame::OnChangeSong
1278 // Routine that plays the currently selected file in the playlist.
1279 // Called when the user actives the song from the playlist,
1280 // and from other various places in the sample
1281 // ----------------------------------------------------------------------------
1282 void wxMediaPlayerFrame::OnChangeSong(wxListEvent
& WXUNUSED(evt
))
1284 wxMediaPlayerListCtrl
* m_playlist
=
1285 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1287 wxListItem listitem
;
1288 m_playlist
->GetSelectedItem(listitem
);
1289 DoPlayFile((*((wxString
*) listitem
.GetData())));
1292 // ----------------------------------------------------------------------------
1293 // wxMediaPlayerFrame::OnPrev
1295 // Tedious wxListCtrl stuff. Goes to prevous song in list, or if at the
1296 // beginning goes to the last in the list.
1297 // ----------------------------------------------------------------------------
1298 void wxMediaPlayerFrame::OnPrev(wxCommandEvent
& WXUNUSED(event
))
1300 wxMediaPlayerListCtrl
* m_playlist
=
1301 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1303 if (m_playlist
->GetItemCount() == 0)
1306 wxInt32 nLastSelectedItem
= -1;
1309 wxInt32 nSelectedItem
= m_playlist
->GetNextItem(nLastSelectedItem
,
1310 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1311 if (nSelectedItem
== -1)
1313 nLastSelectedItem
= nSelectedItem
;
1314 m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1317 if (nLastSelectedItem
<= 0)
1318 nLastSelectedItem
= m_playlist
->GetItemCount() - 1;
1320 nLastSelectedItem
-= 1;
1322 wxListItem listitem
;
1323 listitem
.SetId(nLastSelectedItem
);
1324 m_playlist
->GetItem(listitem
);
1325 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1326 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1327 m_playlist
->SetItem(listitem
);
1329 wxListEvent emptyEvent
;
1330 OnChangeSong(emptyEvent
);
1333 // ----------------------------------------------------------------------------
1334 // wxMediaPlayerFrame::OnNext
1336 // Tedious wxListCtrl stuff. Goes to next song in list, or if at the
1337 // end goes to the first in the list.
1338 // ----------------------------------------------------------------------------
1339 void wxMediaPlayerFrame::OnNext(wxCommandEvent
& WXUNUSED(event
))
1341 wxMediaPlayerListCtrl
* m_playlist
=
1342 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1344 if (m_playlist
->GetItemCount() == 0)
1347 wxInt32 nLastSelectedItem
= -1;
1350 wxInt32 nSelectedItem
= m_playlist
->GetNextItem(nLastSelectedItem
,
1351 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1352 if (nSelectedItem
== -1)
1354 nLastSelectedItem
= nSelectedItem
;
1355 m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1358 if (nLastSelectedItem
== -1)
1359 nLastSelectedItem
= 0;
1362 if (nLastSelectedItem
== m_playlist
->GetItemCount() - 1)
1363 nLastSelectedItem
= 0;
1365 nLastSelectedItem
+= 1;
1368 wxListItem listitem
;
1369 listitem
.SetId(nLastSelectedItem
);
1370 m_playlist
->GetItem(listitem
);
1371 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1372 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1373 m_playlist
->SetItem(listitem
);
1375 wxListEvent emptyEvent
;
1376 OnChangeSong(emptyEvent
);
1380 // ----------------------------------------------------------------------------
1381 // wxMediaPlayerFrame::OnVolumeDown
1383 // Lowers the volume of the media control by 10%
1384 // ----------------------------------------------------------------------------
1385 void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent
& WXUNUSED(event
))
1387 double dVolume
= GetCurrentMediaCtrl()->GetVolume();
1388 GetCurrentMediaCtrl()->SetVolume(dVolume
< 0.1 ? 0.0 : dVolume
- .1);
1391 // ----------------------------------------------------------------------------
1392 // wxMediaPlayerFrame::OnVolumeUp
1394 // Increases the volume of the media control by 10%
1395 // ----------------------------------------------------------------------------
1396 void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent
& WXUNUSED(event
))
1398 double dVolume
= GetCurrentMediaCtrl()->GetVolume();
1399 GetCurrentMediaCtrl()->SetVolume(dVolume
> 0.9 ? 1.0 : dVolume
+ .1);
1402 // ----------------------------------------------------------------------------
1403 // wxMediaPlayerFrame::OnCloseCurrentPage
1405 // Called when the user wants to closes the current notebook page
1406 // ----------------------------------------------------------------------------
1408 void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent
& WXUNUSED(event
))
1413 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1415 // wxMediaPlayerTimer
1417 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1419 // ----------------------------------------------------------------------------
1420 // wxMediaPlayerTimer::Notify
1422 // 1) Update our slider with the position were are in in the media
1423 // 2) Update our status bar with the base text from wxMediaPlayerFrame::ResetStatus,
1424 // append some non-static (changing) info to it, then set the
1425 // status bar text to that result
1426 // ----------------------------------------------------------------------------
1427 void wxMediaPlayerTimer::Notify()
1429 if(m_frame
->m_notebook
->GetCurrentPage())
1431 // get some control pointers from current notebook page
1432 wxMediaCtrl
* mediactrl
=
1433 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_mediactrl
;
1435 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_slider
;
1437 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_gauge
;
1439 // if the slider is being dragged then update it with the song position
1440 if(((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->IsBeingDragged() == false)
1442 long lPosition
= (long)( mediactrl
->Tell() / 1000 );
1443 slider
->SetValue(lPosition
);
1446 // update guage with value from slider
1447 gauge
->SetValue(slider
->GetValue());
1449 m_frame
->SetStatusText(wxString::Format(
1450 wxT("%s Pos:%u State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
1451 m_frame
->m_basestatus
.c_str(),
1453 wxGetMediaStateText(mediactrl
->GetState()),
1454 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_nLoops
,
1455 (int)mediactrl
->GetDownloadProgress(),
1456 (int)mediactrl
->GetDownloadTotal(),
1457 (int)(mediactrl
->GetVolume() * 100)));
1458 #endif // wxUSE_STATUSBAR
1463 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1465 // wxMediaPlayerNotebookPage
1467 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1469 // ----------------------------------------------------------------------------
1470 // wxMediaPlayerNotebookPage Constructor
1472 // Creates a media control and slider and adds it to this panel,
1473 // along with some sizers for positioning
1474 // ----------------------------------------------------------------------------
1476 wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
1477 wxNotebook
* theBook
,
1478 const wxString
& szBackend
) :
1479 wxPanel(theBook
, wxID_ANY
), m_bIsBeingDragged(false),
1480 m_nLoops(0), m_bLoop(false), m_parentFrame(parentFrame
)
1488 // [5 control buttons]
1494 // Create and attach the sizer
1496 wxFlexGridSizer
* sizer
= new wxFlexGridSizer(2, 1, 0, 0);
1497 this->SetSizer(sizer
);
1498 this->SetAutoLayout(true);
1499 sizer
->AddGrowableRow(0);
1500 sizer
->AddGrowableCol(0);
1503 // Create our media control
1505 m_mediactrl
= new wxMediaCtrl();
1507 // Make sure creation was successful
1508 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
, wxEmptyString
,
1509 wxDefaultPosition
, wxDefaultSize
, 0,
1510 //you could specify a macrod backend here like
1511 //wxMEDIABACKEND_QUICKTIME);
1513 //you could change the cursor here like
1514 // m_mediactrl->SetCursor(wxCURSOR_BLANK);
1515 //note that this may not effect it if SetPlayerControls
1516 //is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
1517 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
1520 sizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1523 // Create the playlist/listctrl
1525 m_playlist
= new wxMediaPlayerListCtrl();
1526 m_playlist
->Create(this, wxID_LISTCTRL
, wxDefaultPosition
,
1528 wxLC_REPORT
//wxLC_LIST
1531 // Set the background of our listctrl to white
1532 m_playlist
->SetBackgroundColour(wxColour(255,255,255));
1534 // The layout of the headers of the listctrl are like
1535 // | | File | Length
1537 // Where Column one is a character representing the state the file is in:
1538 // * - not the current file
1539 // E - Error has occured
1540 // > - Currently Playing
1543 // (( - Volume Down 10%
1544 // )) - Volume Up 10%
1546 // Column two is the name of the file
1548 // Column three is the length in seconds of the file
1549 m_playlist
->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER
, 20);
1550 m_playlist
->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT
, /*wxLIST_AUTOSIZE_USEHEADER*/305);
1551 m_playlist
->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER
, 75);
1553 m_playlist
->SetDropTarget(new wxPlayListDropTarget(*m_playlist
));
1554 sizer
->Add(m_playlist
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1557 // Here we load the our configuration -
1558 // in our case we load all the files that were left in
1559 // the playlist the last time the user closed our application
1561 // TODO: This is probably not the best practice since
1562 // the user will load multiple notebook pages with multiple
1563 // wxMediaCtrl elements.
1565 // As an exercise to the reader try modifying it so that
1566 // it properly loads the playlist for each page without
1567 // conflicting (loading the same data) with the other ones.
1569 wxConfigBase
* conf
= wxConfigBase::Get();
1570 wxString key
, outstring
;
1571 for(int i
= 0; ; ++i
)
1575 if(!conf
->Read(key
, &outstring
))
1577 m_playlist
->AddToPlayList(outstring
);
1581 // Create the control buttons
1582 // TODO/FIXME/HACK: This part about sizers is really a nice hack
1583 // and probably isn't proper
1585 wxBoxSizer
* horsizer1
= new wxBoxSizer(wxHORIZONTAL
);
1586 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxHORIZONTAL
);
1588 m_prevButton
= new wxButton();
1589 m_playButton
= new wxButton();
1590 m_stopButton
= new wxButton();
1591 m_nextButton
= new wxButton();
1592 m_vdButton
= new wxButton();
1593 m_vuButton
= new wxButton();
1595 m_prevButton
->Create(this, wxID_BUTTONPREV
, _T("|<"));
1596 m_playButton
->Create(this, wxID_BUTTONPLAY
, _T(">"));
1597 m_stopButton
->Create(this, wxID_BUTTONSTOP
, _T("[]"));
1598 m_nextButton
->Create(this, wxID_BUTTONNEXT
, _T(">|"));
1599 m_vdButton
->Create(this, wxID_BUTTONVD
, _T("(("));
1600 m_vuButton
->Create(this, wxID_BUTTONVU
, _T("))"));
1601 vertsizer
->Add(m_prevButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1602 vertsizer
->Add(m_playButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1603 vertsizer
->Add(m_stopButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1604 vertsizer
->Add(m_nextButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1605 vertsizer
->Add(m_vdButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1606 vertsizer
->Add(m_vuButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1607 horsizer1
->Add(vertsizer
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1608 sizer
->Add(horsizer1
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1612 // Create our slider
1614 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
1617 wxDefaultPosition
, wxDefaultSize
,
1619 sizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1625 m_gauge
= new wxGauge();
1626 m_gauge
->Create(this, wxID_GAUGE
, 0, wxDefaultPosition
, wxDefaultSize
,
1627 wxGA_HORIZONTAL
| wxGA_SMOOTH
);
1628 sizer
->Add(m_gauge
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1633 this->Connect( wxID_LISTCTRL
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED
,
1634 wxListEventHandler(wxMediaPlayerFrame::OnChangeSong
),
1635 (wxObject
*)0, parentFrame
);
1640 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBTRACK
,
1641 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek
));
1642 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1643 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek
));
1646 // Media Control events
1648 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
1649 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished
));
1650 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_LOADED
,
1651 wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded
),
1652 (wxObject
*)0, parentFrame
);
1657 this->Connect( wxID_BUTTONPREV
, wxEVT_COMMAND_BUTTON_CLICKED
,
1658 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
),
1659 (wxObject
*)0, parentFrame
);
1660 this->Connect( wxID_BUTTONPLAY
, wxEVT_COMMAND_BUTTON_CLICKED
,
1661 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
),
1662 (wxObject
*)0, parentFrame
);
1663 this->Connect( wxID_BUTTONSTOP
, wxEVT_COMMAND_BUTTON_CLICKED
,
1664 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
),
1665 (wxObject
*)0, parentFrame
);
1666 this->Connect( wxID_BUTTONNEXT
, wxEVT_COMMAND_BUTTON_CLICKED
,
1667 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
),
1668 (wxObject
*)0, parentFrame
);
1669 this->Connect( wxID_BUTTONVD
, wxEVT_COMMAND_BUTTON_CLICKED
,
1670 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown
),
1671 (wxObject
*)0, parentFrame
);
1672 this->Connect( wxID_BUTTONVU
, wxEVT_COMMAND_BUTTON_CLICKED
,
1673 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp
),
1674 (wxObject
*)0, parentFrame
);
1677 // ----------------------------------------------------------------------------
1678 // MyNotebook::OnBeginSeek
1680 // Sets m_bIsBeingDragged to true to stop the timer from changing the position
1682 // ----------------------------------------------------------------------------
1683 void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent
& WXUNUSED(event
))
1685 m_bIsBeingDragged
= true;
1688 // ----------------------------------------------------------------------------
1689 // MyNotebook::OnEndSeek
1691 // Called from file->seek.
1692 // Called when the user moves the slider -
1693 // seeks to a position within the media
1694 // then sets m_bIsBeingDragged to false to ok the timer to change the position
1695 // ----------------------------------------------------------------------------
1696 void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent
& WXUNUSED(event
))
1698 if( m_mediactrl
->Seek(
1699 m_slider
->GetValue() * 1000
1700 ) == wxInvalidOffset
)
1701 wxMessageBox(wxT("Couldn't seek in movie!"));
1703 m_bIsBeingDragged
= false;
1706 // ----------------------------------------------------------------------------
1707 // wxMediaPlayerNotebookPage::IsBeingDragged
1709 // Returns true if the user is dragging the slider
1710 // ----------------------------------------------------------------------------
1711 bool wxMediaPlayerNotebookPage::IsBeingDragged()
1713 return m_bIsBeingDragged
;
1716 // ----------------------------------------------------------------------------
1719 // Called when the media stops playing.
1720 // Here we loop it if the user wants to (has been selected from file menu)
1721 // ----------------------------------------------------------------------------
1722 void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
1726 if ( !m_mediactrl
->Play() )
1728 wxMessageBox(wxT("Couldn't loop movie!"));
1729 m_playlist
->SetItem(m_parentFrame
->m_nLastFileId
, 0, _T("E"));
1736 m_playlist
->SetItem(m_parentFrame
->m_nLastFileId
, 0, _T("[]"));
1741 // End of MediaPlayer sample