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
);
142 virtual bool OnInit();
145 class wxMediaPlayerFrame
* m_frame
;
148 // ----------------------------------------------------------------------------
149 // wxMediaPlayerFrame
150 // ----------------------------------------------------------------------------
152 class wxMediaPlayerFrame
: public wxFrame
156 wxMediaPlayerFrame(const wxString
& title
);
157 ~wxMediaPlayerFrame();
159 // Menu event handlers
160 void OnQuit(wxCommandEvent
& event
);
161 void OnAbout(wxCommandEvent
& event
);
163 void OnOpenFileSamePage(wxCommandEvent
& event
);
164 void OnOpenFileNewPage(wxCommandEvent
& event
);
165 void OnOpenURLSamePage(wxCommandEvent
& event
);
166 void OnOpenURLNewPage(wxCommandEvent
& event
);
167 void OnCloseCurrentPage(wxCommandEvent
& event
);
169 void OnPlay(wxCommandEvent
& event
);
170 void OnPause(wxCommandEvent
& event
);
171 void OnStop(wxCommandEvent
& event
);
172 void OnNext(wxCommandEvent
& event
);
173 void OnPrev(wxCommandEvent
& event
);
174 void OnVolumeDown(wxCommandEvent
& event
);
175 void OnVolumeUp(wxCommandEvent
& event
);
177 void OnLoop(wxCommandEvent
& event
);
178 void OnShowInterface(wxCommandEvent
& event
);
180 void OnSelectBackend(wxCommandEvent
& event
);
182 // Notebook event handlers
183 void OnPageChange(wxNotebookEvent
& event
);
185 // Key event handlers
186 void OnKeyDown(wxKeyEvent
& event
);
188 // Quickie for playing from command line
189 void AddToPlayList(const wxString
& szString
);
191 // ListCtrl event handlers
192 void OnChangeSong(wxListEvent
& event
);
194 // Media event handlers
195 void OnMediaLoaded(wxMediaEvent
& event
);
197 // Close event handlers
198 void OnClose(wxCloseEvent
& event
);
201 // Rebuild base status string (see Implementation)
204 // Common open file code
205 void OpenFile(bool bNewPage
);
206 void OpenURL(bool bNewPage
);
207 void DoOpenFile(const wxString
& path
, bool bNewPage
);
208 void DoPlayFile(const wxString
& path
);
210 // Get the controls of current notebook page
211 wxMediaCtrl
* GetCurrentMediaCtrl();
212 wxSlider
* GetCurrentSlider();
213 wxGauge
* GetCurrentGauge();
215 int m_nLastFileId
; //List ID of played file in listctrl
216 wxString m_szFile
; //Name of currently playing file/location
217 class wxMediaPlayerTimer
* m_timer
; //Timer to write info to status bar
218 wxString m_basestatus
; //Base status string (see ResetStatus())
219 wxNotebook
* m_notebook
; //Notebook containing our pages
221 // Maybe I should use more accessors, but for simplicity
222 // I'll allow the other classes access to our members
223 friend class wxMediaPlayerApp
;
224 friend class wxMediaPlayerNotebookPage
;
225 friend class wxMediaPlayerTimer
;
230 // ----------------------------------------------------------------------------
231 // wxMediaPlayerNotebookPage
232 // ----------------------------------------------------------------------------
234 class wxMediaPlayerNotebookPage
: public wxPanel
236 wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
237 wxNotebook
* book
, const wxString
& be
= wxEmptyString
);
239 // Slider event handlers
240 void OnBeginSeek(wxScrollEvent
& event
);
241 void OnEndSeek(wxScrollEvent
& event
);
243 // Media event handlers
244 void OnMediaFinished(wxMediaEvent
& event
);
247 bool IsBeingDragged(); //accessor for m_bIsBeingDragged
249 //make wxMediaPlayerFrame able to access the private members
250 friend class wxMediaPlayerFrame
;
252 wxMediaCtrl
* m_mediactrl
; //Our media control
253 class wxMediaPlayerListCtrl
* m_playlist
; //Our playlist
254 wxSlider
* m_slider
; //The slider below our media control
255 int m_nLoops
; //Number of times media has looped
256 bool m_bLoop
; //Whether we are looping or not
257 bool m_bIsBeingDragged
; //Whether the user is dragging the scroll bar
258 wxMediaPlayerFrame
* m_parentFrame
; //Main wxFrame of our sample
259 wxButton
* m_prevButton
; //Go to previous file button
260 wxButton
* m_playButton
; //Play/pause file button
261 wxButton
* m_stopButton
; //Stop playing file button
262 wxButton
* m_nextButton
; //Next file button
263 wxButton
* m_vdButton
; //Volume down button
264 wxButton
* m_vuButton
; //Volume up button
265 wxGauge
* m_gauge
; //Gauge to keep in line with slider
268 // ----------------------------------------------------------------------------
269 // wxMediaPlayerTimer
270 // ----------------------------------------------------------------------------
272 class wxMediaPlayerTimer
: public wxTimer
276 wxMediaPlayerTimer(wxMediaPlayerFrame
* frame
) {m_frame
= frame
;}
278 //Called each time the timer's timeout expires
281 wxMediaPlayerFrame
* m_frame
; //The wxMediaPlayerFrame
284 // ----------------------------------------------------------------------------
285 // wxMediaPlayerListCtrl
286 // ----------------------------------------------------------------------------
287 class wxMediaPlayerListCtrl
: public wxListCtrl
290 void AddToPlayList(const wxString
& szString
)
293 kNewItem
.SetAlign(wxLIST_FORMAT_LEFT
);
297 kNewItem
.SetId(nID
= this->GetItemCount());
298 kNewItem
.SetMask(wxLIST_MASK_DATA
);
299 kNewItem
.SetData(new wxString(szString
));
301 this->InsertItem(kNewItem
);
302 this->SetItem(nID
, 0, _T("*"));
303 this->SetItem(nID
, 1, wxFileName(szString
).GetName());
307 kNewItem
.SetBackgroundColour(wxColour(192,192,192));
308 this->SetItem(kNewItem
);
312 void GetSelectedItem(wxListItem
& listitem
)
314 listitem
.SetMask(wxLIST_MASK_TEXT
| wxLIST_MASK_DATA
);
315 int nLast
= -1, nLastSelected
= -1;
316 while ((nLast
= this->GetNextItem(nLast
,
318 wxLIST_STATE_SELECTED
)) != -1)
320 listitem
.SetId(nLast
);
321 this->GetItem(listitem
);
322 if ((listitem
.GetState() & wxLIST_STATE_FOCUSED
) )
324 nLastSelected
= nLast
;
326 if (nLast
== -1 && nLastSelected
== -1)
328 listitem
.SetId(nLastSelected
== -1 ? nLast
: nLastSelected
);
329 this->GetItem(listitem
);
334 // ----------------------------------------------------------------------------
335 // wxPlayListDropTarget
337 // Drop target for playlist (i.e. user drags a file from explorer unto
338 // playlist it adds the file)
339 // ----------------------------------------------------------------------------
340 class wxPlayListDropTarget
: public wxFileDropTarget
343 wxPlayListDropTarget(wxMediaPlayerListCtrl
& list
) : m_list(list
) {}
344 ~wxPlayListDropTarget(){}
345 virtual bool OnDropFiles(wxCoord
WXUNUSED(x
), wxCoord
WXUNUSED(y
),
346 const wxArrayString
& files
)
348 for (size_t i
= 0; i
< files
.GetCount(); ++i
)
350 m_list
.AddToPlayList(files
[i
]);
354 wxMediaPlayerListCtrl
& m_list
;
357 // ============================================================================
361 // ============================================================================
363 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
367 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
369 // ----------------------------------------------------------------------------
370 // wxGetMediaStateText
372 // Converts a wxMediaCtrl state into something useful that we can display
374 // ----------------------------------------------------------------------------
375 const wxChar
* wxGetMediaStateText(int nState
)
379 case wxMEDIASTATE_PLAYING
:
380 return wxT("Playing");
381 case wxMEDIASTATE_STOPPED
:
382 return wxT("Stopped");
383 ///case wxMEDIASTATE_PAUSED:
385 return wxT("Paused");
389 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
393 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
395 // ----------------------------------------------------------------------------
396 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
397 // use. For example, if you were to be in windows and use a file dialog,
398 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
399 // handle of the application. These routines in wx _DO NOT_ check to see if
400 // the wxApp exists, and thus will crash the application if you try it.
402 // IMPLEMENT_APP does this, and also implements the platform-specific entry
403 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
404 // not desire this behavior.
405 // ----------------------------------------------------------------------------
406 IMPLEMENT_APP(wxMediaPlayerApp
)
408 // ----------------------------------------------------------------------------
409 // wxMediaPlayerApp::OnInit
411 // Where execution starts - akin to a main or WinMain.
412 // 1) Create the frame and show it to the user
413 // 2) Process filenames from the commandline
414 // 3) return true specifying that we want execution to continue past OnInit
415 // ----------------------------------------------------------------------------
416 bool wxMediaPlayerApp::OnInit()
418 wxMediaPlayerFrame
*frame
=
419 new wxMediaPlayerFrame(_T("MediaPlayer wxWidgets Sample"));
422 #if wxUSE_CMDLINE_PARSER
424 // What this does is get all the command line arguments
425 // and treat each one as a file to put to the initial playlist
427 wxCmdLineEntryDesc cmdLineDesc
[2];
428 cmdLineDesc
[0].kind
= wxCMD_LINE_PARAM
;
429 cmdLineDesc
[0].shortName
= NULL
;
430 cmdLineDesc
[0].longName
= NULL
;
431 cmdLineDesc
[0].description
= wxT("input files");
432 cmdLineDesc
[0].type
= wxCMD_LINE_VAL_STRING
;
433 cmdLineDesc
[0].flags
= wxCMD_LINE_PARAM_OPTIONAL
| wxCMD_LINE_PARAM_MULTIPLE
;
435 cmdLineDesc
[1].kind
= wxCMD_LINE_NONE
;
437 //gets the passed media files from cmd line
438 wxCmdLineParser
parser (cmdLineDesc
, argc
, argv
);
440 // get filenames from the commandline
441 if (parser
.Parse() == 0)
443 for (size_t paramNr
=0; paramNr
< parser
.GetParamCount(); ++paramNr
)
445 frame
->AddToPlayList((parser
.GetParam (paramNr
)));
447 wxCommandEvent emptyevt
;
448 frame
->OnNext(emptyevt
);
457 void wxMediaPlayerApp::MacOpenFile(const wxString
& fileName
)
459 //Called when a user drags a file over our app
460 m_frame
->DoOpenFile(fileName
, true /* new page */);
465 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
467 // wxMediaPlayerFrame
469 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
471 // ----------------------------------------------------------------------------
472 // wxMediaPlayerFrame Constructor
474 // 1) Create our menus
475 // 2) Create our notebook control and add it to the frame
476 // 3) Create our status bar
477 // 4) Connect our events
478 // 5) Start our timer
479 // ----------------------------------------------------------------------------
481 wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString
& title
)
482 : wxFrame(NULL
, wxID_ANY
, title
, wxDefaultPosition
, wxSize(600,600)),
488 wxMenu
*fileMenu
= new wxMenu
;
489 wxMenu
*controlsMenu
= new wxMenu
;
490 wxMenu
*optionsMenu
= new wxMenu
;
491 wxMenu
*helpMenu
= new wxMenu
;
492 wxMenu
*debugMenu
= new wxMenu
;
494 fileMenu
->Append(wxID_OPENFILESAMEPAGE
, _T("&Open File\tCtrl-Shift-O"),
495 _T("Open a File in the current notebook page"));
496 fileMenu
->Append(wxID_OPENFILENEWPAGE
, _T("&Open File in a new page"),
497 _T("Open a File in a new notebook page"));
498 fileMenu
->Append(wxID_OPENURLSAMEPAGE
, _T("&Open URL"),
499 _T("Open a URL in the current notebook page"));
500 fileMenu
->Append(wxID_OPENURLNEWPAGE
, _T("&Open URL in a new page"),
501 _T("Open a URL in a new notebook page"));
502 fileMenu
->AppendSeparator();
503 fileMenu
->Append(wxID_CLOSECURRENTPAGE
, _T("&Close Current Page\tCtrl-C"),
504 _T("Close current notebook page"));
505 fileMenu
->AppendSeparator();
506 fileMenu
->Append(wxID_EXIT
,
508 _T("Quit this program"));
510 controlsMenu
->Append(wxID_PLAY
, _T("&Play/Pause\tCtrl-P"), _T("Resume/Pause playback"));
511 controlsMenu
->Append(wxID_STOP
, _T("&Stop\tCtrl-S"), _T("Stop playback"));
512 controlsMenu
->AppendSeparator();
513 controlsMenu
->Append(wxID_PREV
, _T("&Previous\tCtrl-B"), _T("Go to previous track"));
514 controlsMenu
->Append(wxID_NEXT
, _T("&Next\tCtrl-N"), _T("Skip to next track"));
516 optionsMenu
->AppendCheckItem(wxID_LOOP
,
518 _T("Loop Selected Media"));
519 optionsMenu
->AppendCheckItem(wxID_SHOWINTERFACE
,
520 _T("&Show Interface\tCtrl-I"),
521 _T("Show wxMediaCtrl native controls"));
523 debugMenu
->Append(wxID_SELECTBACKEND
,
524 _T("&Select Backend...\tCtrl-D"),
525 _T("Select a backend manually"));
527 helpMenu
->Append(wxID_ABOUT
,
529 _T("Show about dialog"));
532 wxMenuBar
*menuBar
= new wxMenuBar();
533 menuBar
->Append(fileMenu
, _T("&File"));
534 menuBar
->Append(controlsMenu
, _T("&Controls"));
535 menuBar
->Append(optionsMenu
, _T("&Options"));
536 menuBar
->Append(debugMenu
, _T("&Debug"));
537 menuBar
->Append(helpMenu
, _T("&Help"));
541 // Create our notebook - using wxNotebook is luckily pretty
542 // simple and self-explanatory in most cases
544 m_notebook
= new wxNotebook(this, wxID_NOTEBOOK
);
547 // Create our status bar
550 // create a status bar just for fun (by default with 1 pane only)
552 #endif // wxUSE_STATUSBAR
557 // There are two ways in wxWidgets to use events -
558 // Message Maps and Connections.
560 // Message Maps are implemented by putting
561 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
562 // class you want to use for events, such as wxMediaPlayerFrame.
564 // Then after your class declaration you put
565 // BEGIN_EVENT_TABLE(wxMediaPlayerFrame, wxFrame)
569 // Where wxMediaPlayerFrame is the class with the DECLARE_MESSAGE_MAP
570 // in it. EVT_XXX(XXX) are each of your handlers, such
571 // as EVT_MENU for menu events and the XXX inside
572 // is the parameters to the event macro - in the case
573 // of EVT_MENU the menu id and then the function to call.
575 // However, with wxEvtHandler::Connect you can avoid a
576 // global message map for your class and those annoying
577 // macros. You can also change the context in which
578 // the call the handler (more later).
580 // The downside is that due to the limitation that
581 // wxWidgets doesn't use templates in certain areas,
582 // You have to triple-cast the event function.
584 // There are five parameters to wxEvtHandler::Connect -
586 // The first is the id of the instance whose events
587 // you want to handle - i.e. a menu id for menus,
588 // a control id for controls (wxControl::GetId())
591 // The second is the event id. This is the same
592 // as the message maps (EVT_MENU) except prefixed
593 // with "wx" (wxEVT_MENU).
595 // The third is the function handler for the event -
596 // You need to cast it to the specific event handler
597 // type, then to a wxEventFunction, then to a
598 // wxObjectEventFunction - I.E.
599 // (wxObjectEventFunction)(wxEventFunction)
600 // (wxCommandEventFunction) &wxMediaPlayerFrame::MyHandler
602 // Or, you can use the new (2.5.5+) event handler
603 // conversion macros - for instance the above could
605 // wxCommandEventHandler(wxMediaPlayerFrame::MyHandler)
606 // pretty simple, eh?
608 // The fourth is an optional userdata param -
609 // this is of historical relevance only and is
610 // there only for backwards compatibility.
612 // The fifth is the context in which to call the
613 // handler - by default (this param is optional)
614 // this. For example in your event handler
615 // if you were to call "this->MyFunc()"
616 // it would literally do this->MyFunc. However,
617 // if you were to pass myHandler as the fifth
618 // parameter, for instance, you would _really_
619 // be calling myHandler->MyFunc, even though
620 // the compiler doesn't really know it.
626 this->Connect(wxID_EXIT
, wxEVT_COMMAND_MENU_SELECTED
,
627 wxCommandEventHandler(wxMediaPlayerFrame::OnQuit
));
629 this->Connect(wxID_ABOUT
, wxEVT_COMMAND_MENU_SELECTED
,
630 wxCommandEventHandler(wxMediaPlayerFrame::OnAbout
));
632 this->Connect(wxID_LOOP
, wxEVT_COMMAND_MENU_SELECTED
,
633 wxCommandEventHandler(wxMediaPlayerFrame::OnLoop
));
635 this->Connect(wxID_SHOWINTERFACE
, wxEVT_COMMAND_MENU_SELECTED
,
636 wxCommandEventHandler(wxMediaPlayerFrame::OnShowInterface
));
638 this->Connect(wxID_OPENFILENEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
639 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileNewPage
));
641 this->Connect(wxID_OPENFILESAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
642 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileSamePage
));
644 this->Connect(wxID_OPENURLNEWPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
645 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLNewPage
));
647 this->Connect(wxID_OPENURLSAMEPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
648 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLSamePage
));
650 this->Connect(wxID_CLOSECURRENTPAGE
, wxEVT_COMMAND_MENU_SELECTED
,
651 wxCommandEventHandler(wxMediaPlayerFrame::OnCloseCurrentPage
));
653 this->Connect(wxID_PLAY
, wxEVT_COMMAND_MENU_SELECTED
,
654 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
));
656 this->Connect(wxID_STOP
, wxEVT_COMMAND_MENU_SELECTED
,
657 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
));
659 this->Connect(wxID_NEXT
, wxEVT_COMMAND_MENU_SELECTED
,
660 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
));
662 this->Connect(wxID_PREV
, wxEVT_COMMAND_MENU_SELECTED
,
663 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
));
665 this->Connect(wxID_SELECTBACKEND
, wxEVT_COMMAND_MENU_SELECTED
,
666 wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend
));
671 this->Connect(wxID_NOTEBOOK
, wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED
,
672 wxNotebookEventHandler(wxMediaPlayerFrame::OnPageChange
));
677 wxTheApp
->Connect(wxID_ANY
, wxEVT_KEY_DOWN
,
678 wxKeyEventHandler(wxMediaPlayerFrame::OnKeyDown
),
684 this->Connect(wxID_ANY
, wxEVT_CLOSE_WINDOW
,
685 wxCloseEventHandler(wxMediaPlayerFrame::OnClose
));
692 // Create an initial notebook page so the user has something
693 // to work with without having to go file->open every time :).
695 m_notebook
->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook
),
700 // Create a timer to update our status bar
702 m_timer
= new wxMediaPlayerTimer(this);
706 // ----------------------------------------------------------------------------
707 // wxMediaPlayerFrame Destructor
709 // 1) Deletes child objects implicitly
710 // 2) Delete our timer explicitly
711 // ----------------------------------------------------------------------------
712 wxMediaPlayerFrame::~wxMediaPlayerFrame()
718 // ----------------------------------------------------------------------------
719 // wxMediaPlayerFrame::OnClose
720 // ----------------------------------------------------------------------------
721 void wxMediaPlayerFrame::OnClose(wxCloseEvent
& event
)
724 // Here we save our info to the registry or whatever
725 // mechanism the OS uses.
727 // This makes it so that when mediaplayer loads up again
728 // it restores the same files that were in the playlist
729 // this time, rather than the user manually re-adding them.
731 // We need to do conf->DeleteAll() here because by default
732 // the config still contains the same files as last time
733 // so we need to clear it before writing our new ones.
735 // TODO: Maybe you could add a menu option to the
736 // options menu to delete the configuration on exit -
737 // all you'd need to do is just remove everything after
738 // conf->DeleteAll() here
740 wxMediaPlayerListCtrl
* m_playlist
=
741 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
743 wxConfigBase
* conf
= wxConfigBase::Get();
746 for(int i
= 0; i
< m_playlist
->GetItemCount(); ++i
)
748 wxString
* pData
= (wxString
*) m_playlist
->GetItemData(i
);
751 conf
->Write(s
, *(pData
));
755 event
.Skip(); //really close the frame
758 // ----------------------------------------------------------------------------
759 // wxMediaPlayerFrame::AddToPlayList
760 // ----------------------------------------------------------------------------
761 void wxMediaPlayerFrame::AddToPlayList(const wxString
& szString
)
763 wxMediaPlayerNotebookPage
* currentpage
=
764 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage());
766 currentpage
->m_playlist
->AddToPlayList(szString
);
770 // ----------------------------------------------------------------------------
771 // wxMediaPlayerFrame::ResetStatus
773 // Here we just make a simple status string with some useful info about
774 // the media that we won't change later - such as the length of the media.
776 // We then append some other info that changes in wxMediaPlayerTimer::Notify, then
777 // set the status bar to this text.
779 // In real applications, you'd want to find a better way to do this,
780 // such as static text controls (wxStaticText).
782 // We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
783 // we divide by 1000).
785 // We also reset our loop counter here.
786 // ----------------------------------------------------------------------------
787 void wxMediaPlayerFrame::ResetStatus()
789 wxMediaCtrl
* currentMediaCtrl
= GetCurrentMediaCtrl();
791 m_basestatus
= wxString::Format(_T("Size(x,y):%i,%i ")
792 _T("Length(Seconds):%u Speed:%1.1fx"),
793 currentMediaCtrl
->GetBestSize().x
,
794 currentMediaCtrl
->GetBestSize().y
,
795 (unsigned)((currentMediaCtrl
->Length() / 1000)),
796 currentMediaCtrl
->GetPlaybackRate()
800 // ----------------------------------------------------------------------------
801 // wxMediaPlayerFrame::GetCurrentMediaCtrl
803 // Obtains the media control of the current page, or NULL if there are no
805 // ----------------------------------------------------------------------------
806 wxMediaCtrl
* wxMediaPlayerFrame::GetCurrentMediaCtrl()
808 return ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_mediactrl
;
811 // ----------------------------------------------------------------------------
812 // wxMediaPlayerFrame::GetCurrentSlider
814 // Obtains the slider of the current page
815 // ----------------------------------------------------------------------------
816 wxSlider
* wxMediaPlayerFrame::GetCurrentSlider()
818 return ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_slider
;
821 // ----------------------------------------------------------------------------
822 // wxMediaPlayerFrame::GetCurrentGauge
824 // Obtains the gauge of the current page
825 // ----------------------------------------------------------------------------
826 wxGauge
* wxMediaPlayerFrame::GetCurrentGauge()
828 return ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_gauge
;
831 // ----------------------------------------------------------------------------
832 // wxMediaPlayerFrame::OnQuit
834 // Called from file->quit.
835 // Closes this application.
836 // ----------------------------------------------------------------------------
837 void wxMediaPlayerFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
839 // true is to force the frame to close
843 // ----------------------------------------------------------------------------
844 // wxMediaPlayerFrame::OnAbout
846 // Called from help->about.
847 // Gets some info about this application.
848 // ----------------------------------------------------------------------------
849 void wxMediaPlayerFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
852 msg
.Printf( _T("This is a test of wxMediaCtrl.\n")
853 _T("Welcome to %s"), wxVERSION_STRING
);
855 wxMessageBox(msg
, _T("About wxMediaCtrl test"), wxOK
| wxICON_INFORMATION
, this);
858 // ----------------------------------------------------------------------------
859 // wxMediaPlayerFrame::OnLoop
861 // Called from file->loop.
862 // Changes the state of whether we want to loop or not.
863 // ----------------------------------------------------------------------------
864 void wxMediaPlayerFrame::OnLoop(wxCommandEvent
& WXUNUSED(event
))
866 if(!m_notebook
->GetCurrentPage())
868 wxMessageBox(wxT("No files are currently open!"));
872 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
=
873 !((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_bLoop
;
876 // ----------------------------------------------------------------------------
877 // wxMediaPlayerFrame::OnLoop
879 // Called from file->loop.
880 // Changes the state of whether we want to loop or not.
881 // ----------------------------------------------------------------------------
882 void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent
& event
)
884 if(!m_notebook
->GetCurrentPage())
886 wxMessageBox(wxT("No files are currently open!"));
890 GetCurrentMediaCtrl()->ShowPlayerControls(event
.IsChecked() ?
891 wxMEDIACTRLPLAYERCONTROLS_DEFAULT
:
892 wxMEDIACTRLPLAYERCONTROLS_NONE
);
895 // ----------------------------------------------------------------------------
896 // wxMediaPlayerFrame::OnOpenFileSamePage
898 // Called from file->openfile.
899 // Opens and plays a media file in the current notebook page
900 // ----------------------------------------------------------------------------
901 void wxMediaPlayerFrame::OnOpenFileSamePage(wxCommandEvent
& WXUNUSED(event
))
906 // ----------------------------------------------------------------------------
907 // wxMediaPlayerFrame::OnOpenFileNewPage
909 // Called from file->openfileinnewpage.
910 // Opens and plays a media file in a new notebook page
911 // ----------------------------------------------------------------------------
912 void wxMediaPlayerFrame::OnOpenFileNewPage(wxCommandEvent
& WXUNUSED(event
))
917 // ----------------------------------------------------------------------------
918 // wxMediaPlayerFrame::OpenFile
920 // Opens a file dialog asking the user for a filename, then
921 // calls DoOpenFile which will add the file to the playlist and play it
922 // ----------------------------------------------------------------------------
923 void wxMediaPlayerFrame::OpenFile(bool bNewPage
)
925 wxFileDialog
fd(this);
927 if(fd
.ShowModal() == wxID_OK
)
929 DoOpenFile(fd
.GetPath(), bNewPage
);
933 // ----------------------------------------------------------------------------
934 // wxMediaPlayerFrame::DoOpenFile
936 // Adds the file to our playlist, selects it in the playlist,
937 // and then calls DoPlayFile to play it
938 // ----------------------------------------------------------------------------
939 void wxMediaPlayerFrame::DoOpenFile(const wxString
& path
, bool bNewPage
)
944 new wxMediaPlayerNotebookPage(this, m_notebook
),
949 wxMediaPlayerListCtrl
* m_playlist
=
950 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
952 if(m_nLastFileId
!= -1)
953 m_playlist
->SetItemState(m_nLastFileId
, 0, wxLIST_STATE_SELECTED
);
955 wxListItem newlistitem
;
956 newlistitem
.SetAlign(wxLIST_FORMAT_LEFT
);
960 newlistitem
.SetId(nID
= m_playlist
->GetItemCount());
961 newlistitem
.SetMask(wxLIST_MASK_DATA
| wxLIST_MASK_STATE
);
962 newlistitem
.SetState(wxLIST_STATE_SELECTED
);
963 newlistitem
.SetData(new wxString(path
));
965 m_playlist
->InsertItem(newlistitem
);
966 m_playlist
->SetItem(nID
, 0, _T("*"));
967 m_playlist
->SetItem(nID
, 1, wxFileName(path
).GetName());
971 newlistitem
.SetBackgroundColour(wxColour(192,192,192));
972 m_playlist
->SetItem(newlistitem
);
976 // m_playlist->Focus(nID);
979 // ----------------------------------------------------------------------------
980 // wxMediaPlayerFrame::DoPlayFile
982 // Pauses the file if its the currently playing file,
983 // otherwise it plays the file
984 // ----------------------------------------------------------------------------
985 void wxMediaPlayerFrame::DoPlayFile(const wxString
& path
)
987 wxMediaPlayerListCtrl
* m_playlist
=
988 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
991 m_playlist
->GetSelectedItem(listitem
);
993 if(listitem
.GetData() &&
994 m_szFile
.compare(path
) == 0 &&
995 m_nLastFileId
== listitem
.GetId())
997 if(GetCurrentMediaCtrl()->GetState() == wxMEDIASTATE_PLAYING
)
999 if( !GetCurrentMediaCtrl()->Pause() )
1000 wxMessageBox(wxT("Couldn't pause movie!"));
1002 m_playlist
->SetItem(listitem
.GetId(), 0, _T("||"));
1006 if( !GetCurrentMediaCtrl()->Play() )
1007 wxMessageBox(wxT("Couldn't pause movie!"));
1009 m_playlist
->SetItem(listitem
.GetId(), 0, _T(">"));
1014 m_notebook
->SetPageText(m_notebook
->GetSelection(),
1015 wxFileName(path
).GetName());
1017 if(m_nLastFileId
!= -1)
1018 m_playlist
->SetItem(m_nLastFileId
, 0, _T("*"));
1020 wxURI
uripath(path
);
1021 if( uripath
.IsReference() )
1023 if( !GetCurrentMediaCtrl()->Load(path
) )
1025 wxMessageBox(wxT("Couldn't load file!"));
1026 m_playlist
->SetItem(listitem
.GetId(), 0, _T("E"));
1030 m_playlist
->SetItem(listitem
.GetId(), 0, _T("O"));
1035 if( !GetCurrentMediaCtrl()->Load(uripath
) )
1037 wxMessageBox(wxT("Couldn't load file!"));
1038 m_playlist
->SetItem(listitem
.GetId(), 0, _T("E"));
1042 m_playlist
->SetItem(listitem
.GetId(), 0, _T("O"));
1046 m_nLastFileId
= listitem
.GetId();
1048 m_playlist
->SetItem(m_nLastFileId
, 1, wxFileName(path
).GetName());
1049 m_playlist
->SetItem(m_nLastFileId
, 2, wxT(""));
1053 // ----------------------------------------------------------------------------
1054 // wxMediaPlayerFrame::OnMediaLoaded
1056 // Called when the media is ready to be played - and does
1057 // so, also gets the length of media and shows that in the list control
1058 // ----------------------------------------------------------------------------
1059 void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent
& WXUNUSED(evt
))
1061 wxMediaPlayerListCtrl
* m_playlist
=
1062 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1063 wxListItem listitem
;
1064 m_playlist
->GetSelectedItem(listitem
);
1066 if( !GetCurrentMediaCtrl()->Play() )
1068 wxMessageBox(wxT("Couldn't play movie!"));
1069 m_playlist
->SetItem(listitem
.GetId(), 0, _T("E"));
1073 m_playlist
->SetItem(listitem
.GetId(), 0, _T(">"));
1076 m_playlist
->SetItem(listitem
.GetId(), 2, wxString::Format(wxT("%u"),
1077 (unsigned) GetCurrentMediaCtrl()->Length() / 1000) );
1081 GetCurrentSlider()->SetRange(0,
1082 (int)(GetCurrentMediaCtrl()->Length() / 1000));
1083 GetCurrentGauge()->SetRange((int)(GetCurrentMediaCtrl()->Length() / 1000));
1086 // ----------------------------------------------------------------------------
1087 // wxMediaPlayerFrame::OnSelectBackend
1089 // Little debugging routine - enter the class name of a backend and it
1090 // will use that instead of letting wxMediaCtrl search the wxMediaBackend
1092 // ----------------------------------------------------------------------------
1093 void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent
& WXUNUSED(evt
))
1095 wxString sBackend
= wxGetTextFromUser(wxT("Enter backend to use"));
1097 if(sBackend
.empty() == false) //could have been cancelled by the user
1099 int sel
= m_notebook
->GetSelection();
1101 if (sel
!= wxNOT_FOUND
)
1103 m_notebook
->DeletePage(sel
);
1106 m_notebook
->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook
,
1109 DoOpenFile(m_szFile
, false);
1113 // ----------------------------------------------------------------------------
1114 // wxMediaPlayerFrame::OnOpenURLSamePage
1116 // Called from file->openurl.
1117 // Opens and plays a media file from a URL in the current notebook page
1118 // ----------------------------------------------------------------------------
1119 void wxMediaPlayerFrame::OnOpenURLSamePage(wxCommandEvent
& WXUNUSED(event
))
1124 // ----------------------------------------------------------------------------
1125 // wxMediaPlayerFrame::OnOpenURLNewPage
1127 // Called from file->openurlinnewpage.
1128 // Opens and plays a media file from a URL in a new notebook page
1129 // ----------------------------------------------------------------------------
1130 void wxMediaPlayerFrame::OnOpenURLNewPage(wxCommandEvent
& WXUNUSED(event
))
1135 // ----------------------------------------------------------------------------
1136 // wxMediaPlayerFrame::OpenURL
1138 // Just calls DoOpenFile with the url path - which calls DoPlayFile
1139 // which handles the real dirty work
1140 // ----------------------------------------------------------------------------
1141 void wxMediaPlayerFrame::OpenURL(bool bNewPage
)
1143 wxString sUrl
= wxGetTextFromUser(
1144 wxT("Enter the URL that has the movie to play")
1147 if(sUrl
.empty() == false) //could have been cancelled by user
1149 DoOpenFile(sUrl
, bNewPage
);
1153 // ----------------------------------------------------------------------------
1154 // wxMediaPlayerFrame::OnCloseCurrentPage
1156 // Called when the user wants to close the current notebook page
1158 // 1) Get the current page number (wxControl::GetSelection)
1159 // 2) If there is no current page, break out
1160 // 3) Delete the current page
1161 // ----------------------------------------------------------------------------
1162 void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent
& WXUNUSED(event
))
1164 if( m_notebook
->GetPageCount() > 1 )
1166 int sel
= m_notebook
->GetSelection();
1168 if (sel
!= wxNOT_FOUND
)
1170 m_notebook
->DeletePage(sel
);
1175 wxMessageBox(wxT("Cannot close main page"));
1179 // ----------------------------------------------------------------------------
1180 // wxMediaPlayerFrame::OnPlay
1182 // Called from file->play.
1183 // Resumes the media if it is paused or stopped.
1184 // ----------------------------------------------------------------------------
1185 void wxMediaPlayerFrame::OnPlay(wxCommandEvent
& WXUNUSED(event
))
1187 wxMediaPlayerListCtrl
* m_playlist
=
1188 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1190 wxListItem listitem
;
1191 m_playlist
->GetSelectedItem(listitem
);
1192 if ( !listitem
.GetData() )
1195 if ((nLast
= m_playlist
->GetNextItem(nLast
,
1197 wxLIST_STATE_DONTCARE
)) == -1)
1200 wxMessageBox(_T("No items in playlist!"));
1203 wxListItem listitem
;
1204 listitem
.SetId(nLast
);
1205 m_playlist
->GetItem(listitem
);
1206 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1207 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1208 m_playlist
->SetItem(listitem
);
1210 OnChangeSong(event
);
1215 OnChangeSong(event
);
1219 // ----------------------------------------------------------------------------
1220 // wxMediaPlayerFrame::OnKeyDown
1222 // Deletes all selected files from the playlist if the backspace key is pressed
1223 // ----------------------------------------------------------------------------
1224 void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent
& event
)
1226 if(event
.GetKeyCode() == WXK_BACK
/*DELETE*/)
1228 wxMediaPlayerListCtrl
* m_playlist
=
1229 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1230 //delete all selected items
1233 wxInt32 nSelectedItem
= m_playlist
->GetNextItem(
1234 -1, wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1235 if (nSelectedItem
== -1)
1238 wxListItem listitem
;
1239 listitem
.SetId(nSelectedItem
);
1240 m_playlist
->GetItem(listitem
);
1241 delete (wxString
*) listitem
.GetData();
1243 m_playlist
->DeleteItem(nSelectedItem
);
1247 //Could be wxGetTextFromUser or something else important
1248 if(event
.GetEventObject() != this)
1252 // ----------------------------------------------------------------------------
1253 // wxMediaPlayerFrame::OnStop
1255 // Called from file->stop.
1256 // Where it stops depends on whether you can seek in the
1257 // media control or not - if you can it stops and seeks to the beginning,
1258 // otherwise it will appear to be at the end - but it will start over again
1259 // when Play() is called
1260 // ----------------------------------------------------------------------------
1261 void wxMediaPlayerFrame::OnStop(wxCommandEvent
& WXUNUSED(evt
))
1263 wxMediaPlayerListCtrl
* m_playlist
=
1264 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1266 wxListItem listitem
;
1267 m_playlist
->GetSelectedItem(listitem
);
1268 m_playlist
->SetItem(listitem
.GetId(), 0, _T("[]"));
1270 if(!m_notebook
->GetCurrentPage())
1272 wxMessageBox(wxT("No files are currently open!"));
1276 if( !GetCurrentMediaCtrl()->Stop() )
1277 wxMessageBox(wxT("Couldn't stop movie!"));
1281 // ----------------------------------------------------------------------------
1282 // wxMediaPlayerFrame::OnChangeSong
1284 // Routine that plays the currently selected file in the playlist.
1285 // Called when the user actives the song from the playlist,
1286 // and from other various places in the sample
1287 // ----------------------------------------------------------------------------
1288 void wxMediaPlayerFrame::OnChangeSong(wxListEvent
& WXUNUSED(evt
))
1290 wxMediaPlayerListCtrl
* m_playlist
=
1291 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1293 wxListItem listitem
;
1294 m_playlist
->GetSelectedItem(listitem
);
1295 DoPlayFile((*((wxString
*) listitem
.GetData())));
1298 // ----------------------------------------------------------------------------
1299 // wxMediaPlayerFrame::OnPrev
1301 // Tedious wxListCtrl stuff. Goes to prevous song in list, or if at the
1302 // beginning goes to the last in the list.
1303 // ----------------------------------------------------------------------------
1304 void wxMediaPlayerFrame::OnPrev(wxCommandEvent
& WXUNUSED(event
))
1306 wxMediaPlayerListCtrl
* m_playlist
=
1307 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1309 if (m_playlist
->GetItemCount() == 0)
1312 wxInt32 nLastSelectedItem
= -1;
1315 wxInt32 nSelectedItem
= m_playlist
->GetNextItem(nLastSelectedItem
,
1316 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1317 if (nSelectedItem
== -1)
1319 nLastSelectedItem
= nSelectedItem
;
1320 m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1323 if (nLastSelectedItem
<= 0)
1324 nLastSelectedItem
= m_playlist
->GetItemCount() - 1;
1326 nLastSelectedItem
-= 1;
1328 wxListItem listitem
;
1329 listitem
.SetId(nLastSelectedItem
);
1330 m_playlist
->GetItem(listitem
);
1331 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1332 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1333 m_playlist
->SetItem(listitem
);
1335 wxListEvent emptyEvent
;
1336 OnChangeSong(emptyEvent
);
1339 // ----------------------------------------------------------------------------
1340 // wxMediaPlayerFrame::OnNext
1342 // Tedious wxListCtrl stuff. Goes to next song in list, or if at the
1343 // end goes to the first in the list.
1344 // ----------------------------------------------------------------------------
1345 void wxMediaPlayerFrame::OnNext(wxCommandEvent
& WXUNUSED(event
))
1347 wxMediaPlayerListCtrl
* m_playlist
=
1348 ((wxMediaPlayerNotebookPage
*)m_notebook
->GetCurrentPage())->m_playlist
;
1350 if (m_playlist
->GetItemCount() == 0)
1353 wxInt32 nLastSelectedItem
= -1;
1356 wxInt32 nSelectedItem
= m_playlist
->GetNextItem(nLastSelectedItem
,
1357 wxLIST_NEXT_ALL
, wxLIST_STATE_SELECTED
);
1358 if (nSelectedItem
== -1)
1360 nLastSelectedItem
= nSelectedItem
;
1361 m_playlist
->SetItemState(nSelectedItem
, 0, wxLIST_STATE_SELECTED
);
1364 if (nLastSelectedItem
== -1)
1365 nLastSelectedItem
= 0;
1368 if (nLastSelectedItem
== m_playlist
->GetItemCount() - 1)
1369 nLastSelectedItem
= 0;
1371 nLastSelectedItem
+= 1;
1374 wxListItem listitem
;
1375 listitem
.SetId(nLastSelectedItem
);
1376 m_playlist
->GetItem(listitem
);
1377 listitem
.SetMask(listitem
.GetMask() | wxLIST_MASK_STATE
);
1378 listitem
.SetState(listitem
.GetState() | wxLIST_STATE_SELECTED
);
1379 m_playlist
->SetItem(listitem
);
1381 wxListEvent emptyEvent
;
1382 OnChangeSong(emptyEvent
);
1386 // ----------------------------------------------------------------------------
1387 // wxMediaPlayerFrame::OnVolumeDown
1389 // Lowers the volume of the media control by 10%
1390 // ----------------------------------------------------------------------------
1391 void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent
& WXUNUSED(event
))
1393 double dVolume
= GetCurrentMediaCtrl()->GetVolume();
1394 GetCurrentMediaCtrl()->SetVolume(dVolume
< 0.1 ? 0.0 : dVolume
- .1);
1397 // ----------------------------------------------------------------------------
1398 // wxMediaPlayerFrame::OnVolumeUp
1400 // Increases the volume of the media control by 10%
1401 // ----------------------------------------------------------------------------
1402 void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent
& WXUNUSED(event
))
1404 double dVolume
= GetCurrentMediaCtrl()->GetVolume();
1405 GetCurrentMediaCtrl()->SetVolume(dVolume
> 0.9 ? 1.0 : dVolume
+ .1);
1408 // ----------------------------------------------------------------------------
1409 // wxMediaPlayerFrame::OnCloseCurrentPage
1411 // Called when the user wants to closes the current notebook page
1412 // ----------------------------------------------------------------------------
1414 void wxMediaPlayerFrame::OnPageChange(wxNotebookEvent
& WXUNUSED(event
))
1419 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1421 // wxMediaPlayerTimer
1423 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1425 // ----------------------------------------------------------------------------
1426 // wxMediaPlayerTimer::Notify
1428 // 1) Update our slider with the position were are in in the media
1429 // 2) Update our status bar with the base text from wxMediaPlayerFrame::ResetStatus,
1430 // append some non-static (changing) info to it, then set the
1431 // status bar text to that result
1432 // ----------------------------------------------------------------------------
1433 void wxMediaPlayerTimer::Notify()
1435 if(m_frame
->m_notebook
->GetCurrentPage())
1437 // get some control pointers from current notebook page
1438 wxMediaCtrl
* mediactrl
=
1439 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_mediactrl
;
1441 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_slider
;
1443 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_gauge
;
1445 // if the slider is being dragged then update it with the song position
1446 if(((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->IsBeingDragged() == false)
1448 long lPosition
= (long)( mediactrl
->Tell() / 1000 );
1449 slider
->SetValue(lPosition
);
1452 // update guage with value from slider
1453 gauge
->SetValue(slider
->GetValue());
1455 m_frame
->SetStatusText(wxString::Format(
1456 wxT("%s Pos:%u State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
1457 m_frame
->m_basestatus
.c_str(),
1459 wxGetMediaStateText(mediactrl
->GetState()),
1460 ((wxMediaPlayerNotebookPage
*)m_frame
->m_notebook
->GetCurrentPage())->m_nLoops
,
1461 (int)mediactrl
->GetDownloadProgress(),
1462 (int)mediactrl
->GetDownloadTotal(),
1463 (int)(mediactrl
->GetVolume() * 100)));
1464 #endif // wxUSE_STATUSBAR
1469 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1471 // wxMediaPlayerNotebookPage
1473 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1475 // ----------------------------------------------------------------------------
1476 // wxMediaPlayerNotebookPage Constructor
1478 // Creates a media control and slider and adds it to this panel,
1479 // along with some sizers for positioning
1480 // ----------------------------------------------------------------------------
1482 wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame
* parentFrame
,
1483 wxNotebook
* theBook
,
1484 const wxString
& szBackend
)
1485 : wxPanel(theBook
, wxID_ANY
),
1488 m_bIsBeingDragged(false),
1489 m_parentFrame(parentFrame
)
1497 // [5 control buttons]
1503 // Create and attach the sizer
1505 wxFlexGridSizer
* sizer
= new wxFlexGridSizer(2, 1, 0, 0);
1506 this->SetSizer(sizer
);
1507 this->SetAutoLayout(true);
1508 sizer
->AddGrowableRow(0);
1509 sizer
->AddGrowableCol(0);
1512 // Create our media control
1514 m_mediactrl
= new wxMediaCtrl();
1516 // Make sure creation was successful
1517 bool bOK
= m_mediactrl
->Create(this, wxID_MEDIACTRL
, wxEmptyString
,
1518 wxDefaultPosition
, wxDefaultSize
, 0,
1519 //you could specify a macrod backend here like
1520 //wxMEDIABACKEND_QUICKTIME);
1522 //you could change the cursor here like
1523 // m_mediactrl->SetCursor(wxCURSOR_BLANK);
1524 //note that this may not effect it if SetPlayerControls
1525 //is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
1526 wxASSERT_MSG(bOK
, wxT("Could not create media control!"));
1529 sizer
->Add(m_mediactrl
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1532 // Create the playlist/listctrl
1534 m_playlist
= new wxMediaPlayerListCtrl();
1535 m_playlist
->Create(this, wxID_LISTCTRL
, wxDefaultPosition
,
1537 wxLC_REPORT
//wxLC_LIST
1540 // Set the background of our listctrl to white
1541 m_playlist
->SetBackgroundColour(wxColour(255,255,255));
1543 // The layout of the headers of the listctrl are like
1544 // | | File | Length
1546 // Where Column one is a character representing the state the file is in:
1547 // * - not the current file
1548 // E - Error has occured
1549 // > - Currently Playing
1552 // (( - Volume Down 10%
1553 // )) - Volume Up 10%
1555 // Column two is the name of the file
1557 // Column three is the length in seconds of the file
1558 m_playlist
->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER
, 20);
1559 m_playlist
->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT
, /*wxLIST_AUTOSIZE_USEHEADER*/305);
1560 m_playlist
->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER
, 75);
1562 m_playlist
->SetDropTarget(new wxPlayListDropTarget(*m_playlist
));
1563 sizer
->Add(m_playlist
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1566 // Here we load the our configuration -
1567 // in our case we load all the files that were left in
1568 // the playlist the last time the user closed our application
1570 // TODO: This is probably not the best practice since
1571 // the user will load multiple notebook pages with multiple
1572 // wxMediaCtrl elements.
1574 // As an exercise to the reader try modifying it so that
1575 // it properly loads the playlist for each page without
1576 // conflicting (loading the same data) with the other ones.
1578 wxConfigBase
* conf
= wxConfigBase::Get();
1579 wxString key
, outstring
;
1580 for(int i
= 0; ; ++i
)
1584 if(!conf
->Read(key
, &outstring
))
1586 m_playlist
->AddToPlayList(outstring
);
1590 // Create the control buttons
1591 // TODO/FIXME/HACK: This part about sizers is really a nice hack
1592 // and probably isn't proper
1594 wxBoxSizer
* horsizer1
= new wxBoxSizer(wxHORIZONTAL
);
1595 wxBoxSizer
* vertsizer
= new wxBoxSizer(wxHORIZONTAL
);
1597 m_prevButton
= new wxButton();
1598 m_playButton
= new wxButton();
1599 m_stopButton
= new wxButton();
1600 m_nextButton
= new wxButton();
1601 m_vdButton
= new wxButton();
1602 m_vuButton
= new wxButton();
1604 m_prevButton
->Create(this, wxID_BUTTONPREV
, _T("|<"));
1605 m_playButton
->Create(this, wxID_BUTTONPLAY
, _T(">"));
1606 m_stopButton
->Create(this, wxID_BUTTONSTOP
, _T("[]"));
1607 m_nextButton
->Create(this, wxID_BUTTONNEXT
, _T(">|"));
1608 m_vdButton
->Create(this, wxID_BUTTONVD
, _T("(("));
1609 m_vuButton
->Create(this, wxID_BUTTONVU
, _T("))"));
1610 vertsizer
->Add(m_prevButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1611 vertsizer
->Add(m_playButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1612 vertsizer
->Add(m_stopButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1613 vertsizer
->Add(m_nextButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1614 vertsizer
->Add(m_vdButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1615 vertsizer
->Add(m_vuButton
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1616 horsizer1
->Add(vertsizer
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1617 sizer
->Add(horsizer1
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, 5);
1621 // Create our slider
1623 m_slider
= new wxSlider(this, wxID_SLIDER
, 0, //init
1626 wxDefaultPosition
, wxDefaultSize
,
1628 sizer
->Add(m_slider
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1634 m_gauge
= new wxGauge();
1635 m_gauge
->Create(this, wxID_GAUGE
, 0, wxDefaultPosition
, wxDefaultSize
,
1636 wxGA_HORIZONTAL
| wxGA_SMOOTH
);
1637 sizer
->Add(m_gauge
, 0, wxALIGN_CENTER_HORIZONTAL
|wxALL
|wxEXPAND
, 5);
1642 this->Connect( wxID_LISTCTRL
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED
,
1643 wxListEventHandler(wxMediaPlayerFrame::OnChangeSong
),
1644 (wxObject
*)0, parentFrame
);
1649 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBTRACK
,
1650 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek
));
1651 this->Connect(wxID_SLIDER
, wxEVT_SCROLL_THUMBRELEASE
,
1652 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek
));
1655 // Media Control events
1657 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_FINISHED
,
1658 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished
));
1659 this->Connect(wxID_MEDIACTRL
, wxEVT_MEDIA_LOADED
,
1660 wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded
),
1661 (wxObject
*)0, parentFrame
);
1666 this->Connect( wxID_BUTTONPREV
, wxEVT_COMMAND_BUTTON_CLICKED
,
1667 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev
),
1668 (wxObject
*)0, parentFrame
);
1669 this->Connect( wxID_BUTTONPLAY
, wxEVT_COMMAND_BUTTON_CLICKED
,
1670 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay
),
1671 (wxObject
*)0, parentFrame
);
1672 this->Connect( wxID_BUTTONSTOP
, wxEVT_COMMAND_BUTTON_CLICKED
,
1673 wxCommandEventHandler(wxMediaPlayerFrame::OnStop
),
1674 (wxObject
*)0, parentFrame
);
1675 this->Connect( wxID_BUTTONNEXT
, wxEVT_COMMAND_BUTTON_CLICKED
,
1676 wxCommandEventHandler(wxMediaPlayerFrame::OnNext
),
1677 (wxObject
*)0, parentFrame
);
1678 this->Connect( wxID_BUTTONVD
, wxEVT_COMMAND_BUTTON_CLICKED
,
1679 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown
),
1680 (wxObject
*)0, parentFrame
);
1681 this->Connect( wxID_BUTTONVU
, wxEVT_COMMAND_BUTTON_CLICKED
,
1682 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp
),
1683 (wxObject
*)0, parentFrame
);
1686 // ----------------------------------------------------------------------------
1687 // MyNotebook::OnBeginSeek
1689 // Sets m_bIsBeingDragged to true to stop the timer from changing the position
1691 // ----------------------------------------------------------------------------
1692 void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent
& WXUNUSED(event
))
1694 m_bIsBeingDragged
= true;
1697 // ----------------------------------------------------------------------------
1698 // MyNotebook::OnEndSeek
1700 // Called from file->seek.
1701 // Called when the user moves the slider -
1702 // seeks to a position within the media
1703 // then sets m_bIsBeingDragged to false to ok the timer to change the position
1704 // ----------------------------------------------------------------------------
1705 void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent
& WXUNUSED(event
))
1707 if( m_mediactrl
->Seek(
1708 m_slider
->GetValue() * 1000
1709 ) == wxInvalidOffset
)
1710 wxMessageBox(wxT("Couldn't seek in movie!"));
1712 m_bIsBeingDragged
= false;
1715 // ----------------------------------------------------------------------------
1716 // wxMediaPlayerNotebookPage::IsBeingDragged
1718 // Returns true if the user is dragging the slider
1719 // ----------------------------------------------------------------------------
1720 bool wxMediaPlayerNotebookPage::IsBeingDragged()
1722 return m_bIsBeingDragged
;
1725 // ----------------------------------------------------------------------------
1728 // Called when the media stops playing.
1729 // Here we loop it if the user wants to (has been selected from file menu)
1730 // ----------------------------------------------------------------------------
1731 void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent
& WXUNUSED(event
))
1735 if ( !m_mediactrl
->Play() )
1737 wxMessageBox(wxT("Couldn't loop movie!"));
1738 m_playlist
->SetItem(m_parentFrame
->m_nLastFileId
, 0, _T("E"));
1745 m_playlist
->SetItem(m_parentFrame
->m_nLastFileId
, 0, _T("[]"));
1750 // End of MediaPlayer sample