]> git.saurik.com Git - wxWidgets.git/blob - samples/mediaplayer/mediaplayer.cpp
added a period at the end of a sentence (test commit, really)
[wxWidgets.git] / samples / mediaplayer / mediaplayer.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: mediaplayer.cpp
3 // Purpose: wxMediaCtrl sample
4 // Author: Ryan Norton
5 // Modified by:
6 // Created: 11/10/04
7 // RCS-ID: $Id$
8 // Copyright: (c) Ryan Norton
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11
12 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 // MediaPlayer
14 //
15 // This is a somewhat comprehensive example of how to use all the funtionality
16 // of the wxMediaCtrl class in wxWidgets.
17 //
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.
21 //
22 // You can select one of the menu options, or move the slider around
23 // to manipulate what is playing.
24 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
25
26 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
27 // Known bugs with wxMediaCtrl:
28 //
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).
33 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34
35 // ============================================================================
36 // Definitions
37 // ============================================================================
38
39 // ----------------------------------------------------------------------------
40 // Pre-compiled header stuff
41 // ----------------------------------------------------------------------------
42
43 #include "wx/wxprec.h"
44
45 #ifdef __BORLANDC__
46 #pragma hdrstop
47 #endif
48
49 #ifndef WX_PRECOMP
50 #include "wx/wx.h"
51 #endif
52
53 // ----------------------------------------------------------------------------
54 // Headers
55 // ----------------------------------------------------------------------------
56
57 #include "wx/mediactrl.h" //for wxMediaCtrl
58 #include "wx/filedlg.h" //for opening files from OpenFile
59 #include "wx/slider.h" //for a slider for seeking within media
60 #include "wx/sizer.h" //for positioning controls/wxBoxSizer
61 #include "wx/timer.h" //timer for updating status bar
62 #include "wx/textdlg.h" //for getting user text from OpenURL/Debug
63 #include "wx/notebook.h" //for wxNotebook and putting movies in pages
64 #include "wx/cmdline.h" //for wxCmdLineParser (optional)
65 #include "wx/listctrl.h" //for wxListCtrl
66 #include "wx/dnd.h" //drag and drop for the playlist
67 #include "wx/filename.h" //For wxFileName::GetName()
68 #include "wx/config.h" //for native wxConfig
69
70 #ifndef __WXMSW__
71 #include "../sample.xpm"
72 #endif
73
74 // ----------------------------------------------------------------------------
75 // Bail out if the user doesn't want one of the
76 // things we need
77 // ----------------------------------------------------------------------------
78
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...
81 #if !wxUSE_GUI
82 #error "This is a GUI sample"
83 #endif
84
85 #if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER || \
86 !wxUSE_NOTEBOOK || !wxUSE_LISTCTRL
87 #error "Not all required elements are enabled. Please modify setup.h!"
88 #endif
89
90 // ============================================================================
91 // Declarations
92 // ============================================================================
93
94 // ----------------------------------------------------------------------------
95 // Enumurations
96 // ----------------------------------------------------------------------------
97
98 // IDs for the controls and the menu commands
99 enum
100 {
101 // Menu event IDs
102 wxID_LOOP = 1,
103 wxID_OPENFILESAMEPAGE,
104 wxID_OPENFILENEWPAGE,
105 wxID_OPENURLSAMEPAGE,
106 wxID_OPENURLNEWPAGE,
107 wxID_CLOSECURRENTPAGE,
108 wxID_PLAY,
109 wxID_PAUSE,
110 wxID_NEXT,
111 wxID_PREV,
112 wxID_SELECTBACKEND,
113 wxID_SHOWINTERFACE,
114 // wxID_STOP, [built-in to wxWidgets]
115 // wxID_ABOUT, [built-in to wxWidgets]
116 // wxID_EXIT, [built-in to wxWidgets]
117 // Control event IDs
118 wxID_SLIDER,
119 wxID_PBSLIDER,
120 wxID_VOLSLIDER,
121 wxID_NOTEBOOK,
122 wxID_MEDIACTRL,
123 wxID_BUTTONNEXT,
124 wxID_BUTTONPREV,
125 wxID_BUTTONSTOP,
126 wxID_BUTTONPLAY,
127 wxID_BUTTONVD,
128 wxID_BUTTONVU,
129 wxID_LISTCTRL,
130 wxID_GAUGE
131 };
132
133 // ----------------------------------------------------------------------------
134 // wxMediaPlayerApp
135 // ----------------------------------------------------------------------------
136
137 class wxMediaPlayerApp : public wxApp
138 {
139 public:
140 #ifdef __WXMAC__
141 virtual void MacOpenFile(const wxString & fileName );
142 #endif
143
144 virtual bool OnInit();
145
146 protected:
147 class wxMediaPlayerFrame* m_frame;
148 };
149
150 // ----------------------------------------------------------------------------
151 // wxMediaPlayerFrame
152 // ----------------------------------------------------------------------------
153
154 class wxMediaPlayerFrame : public wxFrame
155 {
156 public:
157 // Ctor/Dtor
158 wxMediaPlayerFrame(const wxString& title);
159 ~wxMediaPlayerFrame();
160
161 // Menu event handlers
162 void OnQuit(wxCommandEvent& event);
163 void OnAbout(wxCommandEvent& event);
164
165 void OnOpenFileSamePage(wxCommandEvent& event);
166 void OnOpenFileNewPage(wxCommandEvent& event);
167 void OnOpenURLSamePage(wxCommandEvent& event);
168 void OnOpenURLNewPage(wxCommandEvent& event);
169 void OnCloseCurrentPage(wxCommandEvent& event);
170
171 void OnPlay(wxCommandEvent& event);
172 void OnPause(wxCommandEvent& event);
173 void OnStop(wxCommandEvent& event);
174 void OnNext(wxCommandEvent& event);
175 void OnPrev(wxCommandEvent& event);
176 void OnVolumeDown(wxCommandEvent& event);
177 void OnVolumeUp(wxCommandEvent& event);
178
179 void OnLoop(wxCommandEvent& event);
180 void OnShowInterface(wxCommandEvent& event);
181
182 void OnSelectBackend(wxCommandEvent& event);
183
184 // Key event handlers
185 void OnKeyDown(wxKeyEvent& event);
186
187 // Quickie for playing from command line
188 void AddToPlayList(const wxString& szString);
189
190 // ListCtrl event handlers
191 void OnChangeSong(wxListEvent& event);
192
193 // Media event handlers
194 void OnMediaLoaded(wxMediaEvent& event);
195
196 // Close event handlers
197 void OnClose(wxCloseEvent& event);
198
199 private:
200 // Common open file code
201 void OpenFile(bool bNewPage);
202 void OpenURL(bool bNewPage);
203 void DoOpenFile(const wxString& path, bool bNewPage);
204 void DoPlayFile(const wxString& path);
205
206 class wxMediaPlayerTimer* m_timer; //Timer to write info to status bar
207 wxNotebook* m_notebook; //Notebook containing our pages
208
209 // Maybe I should use more accessors, but for simplicity
210 // I'll allow the other classes access to our members
211 friend class wxMediaPlayerApp;
212 friend class wxMediaPlayerNotebookPage;
213 friend class wxMediaPlayerTimer;
214 };
215
216
217
218 // ----------------------------------------------------------------------------
219 // wxMediaPlayerNotebookPage
220 // ----------------------------------------------------------------------------
221
222 class wxMediaPlayerNotebookPage : public wxPanel
223 {
224 wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentFrame,
225 wxNotebook* book, const wxString& be = wxEmptyString);
226
227 // Slider event handlers
228 void OnBeginSeek(wxScrollEvent& event);
229 void OnEndSeek(wxScrollEvent& event);
230 void OnPBChange(wxScrollEvent& event);
231 void OnVolChange(wxScrollEvent& event);
232
233 // Media event handlers
234 void OnMediaPlay(wxMediaEvent& event);
235 void OnMediaPause(wxMediaEvent& event);
236 void OnMediaStop(wxMediaEvent& event);
237 void OnMediaFinished(wxMediaEvent& event);
238
239 public:
240 bool IsBeingDragged(); //accessor for m_bIsBeingDragged
241
242 //make wxMediaPlayerFrame able to access the private members
243 friend class wxMediaPlayerFrame;
244
245 int m_nLastFileId; //List ID of played file in listctrl
246 wxString m_szFile; //Name of currently playing file/location
247
248 wxMediaCtrl* m_mediactrl; //Our media control
249 class wxMediaPlayerListCtrl* m_playlist; //Our playlist
250 wxSlider* m_slider; //The slider below our media control
251 wxSlider* m_pbSlider; //Lower-left slider for adjusting speed
252 wxSlider* m_volSlider; //Lower-right slider for adjusting volume
253 int m_nLoops; //Number of times media has looped
254 bool m_bLoop; //Whether we are looping or not
255 bool m_bIsBeingDragged; //Whether the user is dragging the scroll bar
256 wxMediaPlayerFrame* m_parentFrame; //Main wxFrame of our sample
257 wxButton* m_prevButton; //Go to previous file button
258 wxButton* m_playButton; //Play/pause file button
259 wxButton* m_stopButton; //Stop playing file button
260 wxButton* m_nextButton; //Next file button
261 wxButton* m_vdButton; //Volume down button
262 wxButton* m_vuButton; //Volume up button
263 wxGauge* m_gauge; //Gauge to keep in line with slider
264 };
265
266 // ----------------------------------------------------------------------------
267 // wxMediaPlayerTimer
268 // ----------------------------------------------------------------------------
269
270 class wxMediaPlayerTimer : public wxTimer
271 {
272 public:
273 //Ctor
274 wxMediaPlayerTimer(wxMediaPlayerFrame* frame) {m_frame = frame;}
275
276 //Called each time the timer's timeout expires
277 void Notify();
278
279 wxMediaPlayerFrame* m_frame; //The wxMediaPlayerFrame
280 };
281
282 // ----------------------------------------------------------------------------
283 // wxMediaPlayerListCtrl
284 // ----------------------------------------------------------------------------
285 class wxMediaPlayerListCtrl : public wxListCtrl
286 {
287 public:
288 void AddToPlayList(const wxString& szString)
289 {
290 wxListItem kNewItem;
291 kNewItem.SetAlign(wxLIST_FORMAT_LEFT);
292
293 int nID = this->GetItemCount();
294 kNewItem.SetId(nID);
295 kNewItem.SetMask(wxLIST_MASK_DATA);
296 kNewItem.SetData(new wxString(szString));
297
298 this->InsertItem(kNewItem);
299 this->SetItem(nID, 0, wxT("*"));
300 this->SetItem(nID, 1, wxFileName(szString).GetName());
301
302 if (nID % 2)
303 {
304 kNewItem.SetBackgroundColour(wxColour(192,192,192));
305 this->SetItem(kNewItem);
306 }
307 }
308
309 void GetSelectedItem(wxListItem& listitem)
310 {
311 listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA);
312 int nLast = -1, nLastSelected = -1;
313 while ((nLast = this->GetNextItem(nLast,
314 wxLIST_NEXT_ALL,
315 wxLIST_STATE_SELECTED)) != -1)
316 {
317 listitem.SetId(nLast);
318 this->GetItem(listitem);
319 if ((listitem.GetState() & wxLIST_STATE_FOCUSED) )
320 break;
321 nLastSelected = nLast;
322 }
323 if (nLast == -1 && nLastSelected == -1)
324 return;
325 listitem.SetId(nLastSelected == -1 ? nLast : nLastSelected);
326 this->GetItem(listitem);
327 }
328 };
329
330 // ----------------------------------------------------------------------------
331 // wxPlayListDropTarget
332 //
333 // Drop target for playlist (i.e. user drags a file from explorer unto
334 // playlist it adds the file)
335 // ----------------------------------------------------------------------------
336 #if wxUSE_DRAG_AND_DROP
337 class wxPlayListDropTarget : public wxFileDropTarget
338 {
339 public:
340 wxPlayListDropTarget(wxMediaPlayerListCtrl& list) : m_list(list) {}
341 ~wxPlayListDropTarget(){}
342 virtual bool OnDropFiles(wxCoord WXUNUSED(x), wxCoord WXUNUSED(y),
343 const wxArrayString& files)
344 {
345 for (size_t i = 0; i < files.GetCount(); ++i)
346 {
347 m_list.AddToPlayList(files[i]);
348 }
349 return true;
350 }
351 wxMediaPlayerListCtrl& m_list;
352 };
353 #endif
354
355 // ============================================================================
356 //
357 // Implementation
358 //
359 // ============================================================================
360
361 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
362 //
363 // [Functions]
364 //
365 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
366
367 // ----------------------------------------------------------------------------
368 // wxGetMediaStateText
369 //
370 // Converts a wxMediaCtrl state into something useful that we can display
371 // to the user
372 // ----------------------------------------------------------------------------
373 const wxChar* wxGetMediaStateText(int nState)
374 {
375 switch(nState)
376 {
377 case wxMEDIASTATE_PLAYING:
378 return wxT("Playing");
379 case wxMEDIASTATE_STOPPED:
380 return wxT("Stopped");
381 ///case wxMEDIASTATE_PAUSED:
382 default:
383 return wxT("Paused");
384 }
385 }
386
387 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
388 //
389 // wxMediaPlayerApp
390 //
391 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
392
393 // ----------------------------------------------------------------------------
394 // This sets up this wxApp as the global wxApp that gui calls in wxWidgets
395 // use. For example, if you were to be in windows and use a file dialog,
396 // wxWidgets would use wxTheApp->GetHInstance() which would get the instance
397 // handle of the application. These routines in wx _DO NOT_ check to see if
398 // the wxApp exists, and thus will crash the application if you try it.
399 //
400 // IMPLEMENT_APP does this, and also implements the platform-specific entry
401 // routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
402 // not desire this behavior.
403 // ----------------------------------------------------------------------------
404 IMPLEMENT_APP(wxMediaPlayerApp)
405
406 // ----------------------------------------------------------------------------
407 // wxMediaPlayerApp::OnInit
408 //
409 // Where execution starts - akin to a main or WinMain.
410 // 1) Create the frame and show it to the user
411 // 2) Process filenames from the commandline
412 // 3) return true specifying that we want execution to continue past OnInit
413 // ----------------------------------------------------------------------------
414 bool wxMediaPlayerApp::OnInit()
415 {
416 if ( !wxApp::OnInit() )
417 return false;
418
419 // SetAppName() lets wxConfig and others know where to write
420 SetAppName(wxT("wxMediaPlayer"));
421
422 wxMediaPlayerFrame *frame =
423 new wxMediaPlayerFrame(wxT("MediaPlayer wxWidgets Sample"));
424 frame->Show(true);
425
426 #if wxUSE_CMDLINE_PARSER
427 //
428 // What this does is get all the command line arguments
429 // and treat each one as a file to put to the initial playlist
430 //
431 wxCmdLineEntryDesc cmdLineDesc[2];
432 cmdLineDesc[0].kind = wxCMD_LINE_PARAM;
433 cmdLineDesc[0].shortName = NULL;
434 cmdLineDesc[0].longName = NULL;
435 cmdLineDesc[0].description = "input files";
436 cmdLineDesc[0].type = wxCMD_LINE_VAL_STRING;
437 cmdLineDesc[0].flags = wxCMD_LINE_PARAM_OPTIONAL | wxCMD_LINE_PARAM_MULTIPLE;
438
439 cmdLineDesc[1].kind = wxCMD_LINE_NONE;
440
441 //gets the passed media files from cmd line
442 wxCmdLineParser parser (cmdLineDesc, argc, argv);
443
444 // get filenames from the commandline
445 if (parser.Parse() == 0)
446 {
447 for (size_t paramNr=0; paramNr < parser.GetParamCount(); ++paramNr)
448 {
449 frame->AddToPlayList((parser.GetParam (paramNr)));
450 }
451 wxCommandEvent theEvent(wxEVT_COMMAND_MENU_SELECTED, wxID_NEXT);
452 frame->AddPendingEvent(theEvent);
453 }
454 #endif
455
456 return true;
457 }
458
459 #ifdef __WXMAC__
460
461 void wxMediaPlayerApp::MacOpenFile(const wxString & fileName )
462 {
463 //Called when a user drags a file over our app
464 m_frame->DoOpenFile(fileName, true /* new page */);
465 }
466
467 #endif // __WXMAC__
468
469 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
470 //
471 // wxMediaPlayerFrame
472 //
473 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
474
475 // ----------------------------------------------------------------------------
476 // wxMediaPlayerFrame Constructor
477 //
478 // 1) Create our menus
479 // 2) Create our notebook control and add it to the frame
480 // 3) Create our status bar
481 // 4) Connect our events
482 // 5) Start our timer
483 // ----------------------------------------------------------------------------
484
485 wxMediaPlayerFrame::wxMediaPlayerFrame(const wxString& title)
486 : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(600,600))
487 {
488 SetIcon(wxICON(sample));
489
490 //
491 // Create Menus
492 //
493 wxMenu *fileMenu = new wxMenu;
494 wxMenu *controlsMenu = new wxMenu;
495 wxMenu *optionsMenu = new wxMenu;
496 wxMenu *helpMenu = new wxMenu;
497 wxMenu *debugMenu = new wxMenu;
498
499 fileMenu->Append(wxID_OPENFILESAMEPAGE, wxT("&Open File\tCtrl-Shift-O"),
500 wxT("Open a File in the current notebook page"));
501 fileMenu->Append(wxID_OPENFILENEWPAGE, wxT("&Open File in a new page"),
502 wxT("Open a File in a new notebook page"));
503 fileMenu->Append(wxID_OPENURLSAMEPAGE, wxT("&Open URL"),
504 wxT("Open a URL in the current notebook page"));
505 fileMenu->Append(wxID_OPENURLNEWPAGE, wxT("&Open URL in a new page"),
506 wxT("Open a URL in a new notebook page"));
507 fileMenu->AppendSeparator();
508 fileMenu->Append(wxID_CLOSECURRENTPAGE, wxT("&Close Current Page\tCtrl-C"),
509 wxT("Close current notebook page"));
510 fileMenu->AppendSeparator();
511 fileMenu->Append(wxID_EXIT,
512 wxT("E&xit\tAlt-X"),
513 wxT("Quit this program"));
514
515 controlsMenu->Append(wxID_PLAY, wxT("&Play/Pause\tCtrl-P"), wxT("Resume/Pause playback"));
516 controlsMenu->Append(wxID_STOP, wxT("&Stop\tCtrl-S"), wxT("Stop playback"));
517 controlsMenu->AppendSeparator();
518 controlsMenu->Append(wxID_PREV, wxT("&Previous\tCtrl-B"), wxT("Go to previous track"));
519 controlsMenu->Append(wxID_NEXT, wxT("&Next\tCtrl-N"), wxT("Skip to next track"));
520
521 optionsMenu->AppendCheckItem(wxID_LOOP,
522 wxT("&Loop\tCtrl-L"),
523 wxT("Loop Selected Media"));
524 optionsMenu->AppendCheckItem(wxID_SHOWINTERFACE,
525 wxT("&Show Interface\tCtrl-I"),
526 wxT("Show wxMediaCtrl native controls"));
527
528 debugMenu->Append(wxID_SELECTBACKEND,
529 wxT("&Select Backend...\tCtrl-D"),
530 wxT("Select a backend manually"));
531
532 helpMenu->Append(wxID_ABOUT,
533 wxT("&About...\tF1"),
534 wxT("Show about dialog"));
535
536
537 wxMenuBar *menuBar = new wxMenuBar();
538 menuBar->Append(fileMenu, wxT("&File"));
539 menuBar->Append(controlsMenu, wxT("&Controls"));
540 menuBar->Append(optionsMenu, wxT("&Options"));
541 menuBar->Append(debugMenu, wxT("&Debug"));
542 menuBar->Append(helpMenu, wxT("&Help"));
543 SetMenuBar(menuBar);
544
545 //
546 // Create our notebook - using wxNotebook is luckily pretty
547 // simple and self-explanatory in most cases
548 //
549 m_notebook = new wxNotebook(this, wxID_NOTEBOOK);
550
551 //
552 // Create our status bar
553 //
554 #if wxUSE_STATUSBAR
555 // create a status bar just for fun (by default with 1 pane only)
556 CreateStatusBar(1);
557 #endif // wxUSE_STATUSBAR
558
559 //
560 // Connect events.
561 //
562 // There are two ways in wxWidgets to use events -
563 // Message Maps and Connections.
564 //
565 // Message Maps are implemented by putting
566 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
567 // class you want to use for events, such as wxMediaPlayerFrame.
568 //
569 // Then after your class declaration you put
570 // BEGIN_EVENT_TABLE(wxMediaPlayerFrame, wxFrame)
571 // EVT_XXX(XXX)...
572 // END_EVENT_TABLE()
573 //
574 // Where wxMediaPlayerFrame is the class with the DECLARE_MESSAGE_MAP
575 // in it. EVT_XXX(XXX) are each of your handlers, such
576 // as EVT_MENU for menu events and the XXX inside
577 // is the parameters to the event macro - in the case
578 // of EVT_MENU the menu id and then the function to call.
579 //
580 // However, with wxEvtHandler::Connect you can avoid a
581 // global message map for your class and those annoying
582 // macros. You can also change the context in which
583 // the call the handler (more later).
584 //
585 // The downside is that due to the limitation that
586 // wxWidgets doesn't use templates in certain areas,
587 // You have to triple-cast the event function.
588 //
589 // There are five parameters to wxEvtHandler::Connect -
590 //
591 // The first is the id of the instance whose events
592 // you want to handle - i.e. a menu id for menus,
593 // a control id for controls (wxControl::GetId())
594 // and so on.
595 //
596 // The second is the event id. This is the same
597 // as the message maps (EVT_MENU) except prefixed
598 // with "wx" (wxEVT_MENU).
599 //
600 // The third is the function handler for the event -
601 // You need to cast it to the specific event handler
602 // type, then to a wxEventFunction, then to a
603 // wxObjectEventFunction - I.E.
604 // (wxObjectEventFunction)(wxEventFunction)
605 // (wxCommandEventFunction) &wxMediaPlayerFrame::MyHandler
606 //
607 // Or, you can use the new (2.5.5+) event handler
608 // conversion macros - for instance the above could
609 // be done as
610 // wxCommandEventHandler(wxMediaPlayerFrame::MyHandler)
611 // pretty simple, eh?
612 //
613 // The fourth is an optional userdata param -
614 // this is of historical relevance only and is
615 // there only for backwards compatibility.
616 //
617 // The fifth is the context in which to call the
618 // handler - by default (this param is optional)
619 // this. For example in your event handler
620 // if you were to call "this->MyFunc()"
621 // it would literally do this->MyFunc. However,
622 // if you were to pass myHandler as the fifth
623 // parameter, for instance, you would _really_
624 // be calling myHandler->MyFunc, even though
625 // the compiler doesn't really know it.
626 //
627
628 //
629 // Menu events
630 //
631 this->Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
632 wxCommandEventHandler(wxMediaPlayerFrame::OnQuit));
633
634 this->Connect(wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED,
635 wxCommandEventHandler(wxMediaPlayerFrame::OnAbout));
636
637 this->Connect(wxID_LOOP, wxEVT_COMMAND_MENU_SELECTED,
638 wxCommandEventHandler(wxMediaPlayerFrame::OnLoop));
639
640 this->Connect(wxID_SHOWINTERFACE, wxEVT_COMMAND_MENU_SELECTED,
641 wxCommandEventHandler(wxMediaPlayerFrame::OnShowInterface));
642
643 this->Connect(wxID_OPENFILENEWPAGE, wxEVT_COMMAND_MENU_SELECTED,
644 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileNewPage));
645
646 this->Connect(wxID_OPENFILESAMEPAGE, wxEVT_COMMAND_MENU_SELECTED,
647 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenFileSamePage));
648
649 this->Connect(wxID_OPENURLNEWPAGE, wxEVT_COMMAND_MENU_SELECTED,
650 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLNewPage));
651
652 this->Connect(wxID_OPENURLSAMEPAGE, wxEVT_COMMAND_MENU_SELECTED,
653 wxCommandEventHandler(wxMediaPlayerFrame::OnOpenURLSamePage));
654
655 this->Connect(wxID_CLOSECURRENTPAGE, wxEVT_COMMAND_MENU_SELECTED,
656 wxCommandEventHandler(wxMediaPlayerFrame::OnCloseCurrentPage));
657
658 this->Connect(wxID_PLAY, wxEVT_COMMAND_MENU_SELECTED,
659 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay));
660
661 this->Connect(wxID_STOP, wxEVT_COMMAND_MENU_SELECTED,
662 wxCommandEventHandler(wxMediaPlayerFrame::OnStop));
663
664 this->Connect(wxID_NEXT, wxEVT_COMMAND_MENU_SELECTED,
665 wxCommandEventHandler(wxMediaPlayerFrame::OnNext));
666
667 this->Connect(wxID_PREV, wxEVT_COMMAND_MENU_SELECTED,
668 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev));
669
670 this->Connect(wxID_SELECTBACKEND, wxEVT_COMMAND_MENU_SELECTED,
671 wxCommandEventHandler(wxMediaPlayerFrame::OnSelectBackend));
672
673 //
674 // Key events
675 //
676 wxTheApp->Connect(wxID_ANY, wxEVT_KEY_DOWN,
677 wxKeyEventHandler(wxMediaPlayerFrame::OnKeyDown),
678 (wxObject*)0, this);
679
680 //
681 // Close events
682 //
683 this->Connect(wxID_ANY, wxEVT_CLOSE_WINDOW,
684 wxCloseEventHandler(wxMediaPlayerFrame::OnClose));
685
686 //
687 // End of Events
688 //
689
690 //
691 // Create an initial notebook page so the user has something
692 // to work with without having to go file->open every time :).
693 //
694 wxMediaPlayerNotebookPage* page =
695 new wxMediaPlayerNotebookPage(this, m_notebook);
696 m_notebook->AddPage(page,
697 wxT(""),
698 true);
699
700 //
701 // Here we load the our configuration -
702 // in our case we load all the files that were left in
703 // the playlist the last time the user closed our application
704 //
705 // As an exercise to the reader try modifying it so that
706 // it properly loads the playlist for each page without
707 // conflicting (loading the same data) with the other ones.
708 //
709 wxConfig conf;
710 wxString key, outstring;
711 for(int i = 0; ; ++i)
712 {
713 key.clear();
714 key << i;
715 if(!conf.Read(key, &outstring))
716 break;
717 page->m_playlist->AddToPlayList(outstring);
718 }
719
720 //
721 // Create a timer to update our status bar
722 //
723 m_timer = new wxMediaPlayerTimer(this);
724 m_timer->Start(500);
725 }
726
727 // ----------------------------------------------------------------------------
728 // wxMediaPlayerFrame Destructor
729 //
730 // 1) Deletes child objects implicitly
731 // 2) Delete our timer explicitly
732 // ----------------------------------------------------------------------------
733 wxMediaPlayerFrame::~wxMediaPlayerFrame()
734 {
735 // Shut down our timer
736 delete m_timer;
737
738 //
739 // Here we save our info to the registry or whatever
740 // mechanism the OS uses.
741 //
742 // This makes it so that when mediaplayer loads up again
743 // it restores the same files that were in the playlist
744 // this time, rather than the user manually re-adding them.
745 //
746 // We need to do conf->DeleteAll() here because by default
747 // the config still contains the same files as last time
748 // so we need to clear it before writing our new ones.
749 //
750 // TODO: Maybe you could add a menu option to the
751 // options menu to delete the configuration on exit -
752 // all you'd need to do is just remove everything after
753 // conf->DeleteAll() here
754 //
755 // As an exercise to the reader, try modifying this so
756 // that it saves the data for each notebook page
757 //
758 wxMediaPlayerListCtrl* playlist =
759 ((wxMediaPlayerNotebookPage*)m_notebook->GetPage(0))->m_playlist;
760
761 wxConfig conf;
762 conf.DeleteAll();
763
764 for(int i = 0; i < playlist->GetItemCount(); ++i)
765 {
766 wxString* pData = (wxString*) playlist->GetItemData(i);
767 wxString s;
768 s << i;
769 conf.Write(s, *(pData));
770 delete pData;
771 }
772 }
773
774 // ----------------------------------------------------------------------------
775 // wxMediaPlayerFrame::OnClose
776 // ----------------------------------------------------------------------------
777 void wxMediaPlayerFrame::OnClose(wxCloseEvent& event)
778 {
779 event.Skip(); //really close the frame
780 }
781
782 // ----------------------------------------------------------------------------
783 // wxMediaPlayerFrame::AddToPlayList
784 // ----------------------------------------------------------------------------
785 void wxMediaPlayerFrame::AddToPlayList(const wxString& szString)
786 {
787 wxMediaPlayerNotebookPage* currentpage =
788 ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage());
789
790 currentpage->m_playlist->AddToPlayList(szString);
791 }
792
793 // ----------------------------------------------------------------------------
794 // wxMediaPlayerFrame::OnQuit
795 //
796 // Called from file->quit.
797 // Closes this application.
798 // ----------------------------------------------------------------------------
799 void wxMediaPlayerFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
800 {
801 // true is to force the frame to close
802 Close(true);
803 }
804
805 // ----------------------------------------------------------------------------
806 // wxMediaPlayerFrame::OnAbout
807 //
808 // Called from help->about.
809 // Gets some info about this application.
810 // ----------------------------------------------------------------------------
811 void wxMediaPlayerFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
812 {
813 wxString msg;
814 msg.Printf( wxT("This is a test of wxMediaCtrl.\n\n")
815
816 wxT("Intructions:\n")
817
818 wxT("The top slider shows the current the current position, ")
819 wxT("which you can change by dragging and releasing it.\n")
820
821 wxT("The gauge (progress bar) shows the progress in ")
822 wxT("downloading data of the current file - it may always be ")
823 wxT("Empty due to lack of support from the current backend.\n")
824
825 wxT("The lower-left slider controls the volume and the lower-")
826 wxT("right slider controls the playback rate/speed of the ")
827 wxT("media\n\n")
828
829 wxT("Currently using: %s"), wxVERSION_STRING);
830
831 wxMessageBox(msg, wxT("About wxMediaCtrl test"),
832 wxOK | wxICON_INFORMATION, this);
833 }
834
835 // ----------------------------------------------------------------------------
836 // wxMediaPlayerFrame::OnLoop
837 //
838 // Called from file->loop.
839 // Changes the state of whether we want to loop or not.
840 // ----------------------------------------------------------------------------
841 void wxMediaPlayerFrame::OnLoop(wxCommandEvent& WXUNUSED(event))
842 {
843 wxMediaPlayerNotebookPage* currentpage =
844 ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage());
845
846 currentpage->m_bLoop = !currentpage->m_bLoop;
847 }
848
849 // ----------------------------------------------------------------------------
850 // wxMediaPlayerFrame::OnLoop
851 //
852 // Called from file->loop.
853 // Changes the state of whether we want to loop or not.
854 // ----------------------------------------------------------------------------
855 void wxMediaPlayerFrame::OnShowInterface(wxCommandEvent& event)
856 {
857 wxMediaPlayerNotebookPage* currentpage =
858 ((wxMediaPlayerNotebookPage*)m_notebook->GetCurrentPage());
859
860 if( !currentpage->m_mediactrl->ShowPlayerControls(event.IsChecked() ?
861 wxMEDIACTRLPLAYERCONTROLS_DEFAULT :
862 wxMEDIACTRLPLAYERCONTROLS_NONE) )
863 {
864 //error - uncheck and warn user
865 wxMenuItem* pSIItem = GetMenuBar()->FindItem(wxID_SHOWINTERFACE);
866 wxASSERT(pSIItem);
867 pSIItem->Check(!event.IsChecked());
868
869 if(event.IsChecked())
870 wxMessageBox(wxT("Could not show player controls"));
871 else
872 wxMessageBox(wxT("Could not hide player controls"));
873 }
874 }
875
876 // ----------------------------------------------------------------------------
877 // wxMediaPlayerFrame::OnOpenFileSamePage
878 //
879 // Called from file->openfile.
880 // Opens and plays a media file in the current notebook page
881 // ----------------------------------------------------------------------------
882 void wxMediaPlayerFrame::OnOpenFileSamePage(wxCommandEvent& WXUNUSED(event))
883 {
884 OpenFile(false);
885 }
886
887 // ----------------------------------------------------------------------------
888 // wxMediaPlayerFrame::OnOpenFileNewPage
889 //
890 // Called from file->openfileinnewpage.
891 // Opens and plays a media file in a new notebook page
892 // ----------------------------------------------------------------------------
893 void wxMediaPlayerFrame::OnOpenFileNewPage(wxCommandEvent& WXUNUSED(event))
894 {
895 OpenFile(true);
896 }
897
898 // ----------------------------------------------------------------------------
899 // wxMediaPlayerFrame::OpenFile
900 //
901 // Opens a file dialog asking the user for a filename, then
902 // calls DoOpenFile which will add the file to the playlist and play it
903 // ----------------------------------------------------------------------------
904 void wxMediaPlayerFrame::OpenFile(bool bNewPage)
905 {
906 wxFileDialog fd(this);
907
908 if(fd.ShowModal() == wxID_OK)
909 {
910 DoOpenFile(fd.GetPath(), bNewPage);
911 }
912 }
913
914 // ----------------------------------------------------------------------------
915 // wxMediaPlayerFrame::DoOpenFile
916 //
917 // Adds the file to our playlist, selects it in the playlist,
918 // and then calls DoPlayFile to play it
919 // ----------------------------------------------------------------------------
920 void wxMediaPlayerFrame::DoOpenFile(const wxString& path, bool bNewPage)
921 {
922 if(bNewPage)
923 {
924 m_notebook->AddPage(
925 new wxMediaPlayerNotebookPage(this, m_notebook),
926 path,
927 true);
928 }
929
930 wxMediaPlayerNotebookPage* currentpage =
931 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
932
933 if(currentpage->m_nLastFileId != -1)
934 currentpage->m_playlist->SetItemState(currentpage->m_nLastFileId,
935 0, wxLIST_STATE_SELECTED);
936
937 wxListItem newlistitem;
938 newlistitem.SetAlign(wxLIST_FORMAT_LEFT);
939
940 int nID;
941
942 newlistitem.SetId(nID = currentpage->m_playlist->GetItemCount());
943 newlistitem.SetMask(wxLIST_MASK_DATA | wxLIST_MASK_STATE);
944 newlistitem.SetState(wxLIST_STATE_SELECTED);
945 newlistitem.SetData(new wxString(path));
946
947 currentpage->m_playlist->InsertItem(newlistitem);
948 currentpage->m_playlist->SetItem(nID, 0, wxT("*"));
949 currentpage->m_playlist->SetItem(nID, 1, wxFileName(path).GetName());
950
951 if (nID % 2)
952 {
953 newlistitem.SetBackgroundColour(wxColour(192,192,192));
954 currentpage->m_playlist->SetItem(newlistitem);
955 }
956
957 DoPlayFile(path);
958 }
959
960 // ----------------------------------------------------------------------------
961 // wxMediaPlayerFrame::DoPlayFile
962 //
963 // Pauses the file if its the currently playing file,
964 // otherwise it plays the file
965 // ----------------------------------------------------------------------------
966 void wxMediaPlayerFrame::DoPlayFile(const wxString& path)
967 {
968 wxMediaPlayerNotebookPage* currentpage =
969 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
970
971 wxListItem listitem;
972 currentpage->m_playlist->GetSelectedItem(listitem);
973
974 if( ( listitem.GetData() &&
975 currentpage->m_nLastFileId == listitem.GetId() &&
976 currentpage->m_szFile.compare(path) == 0 ) ||
977 ( !listitem.GetData() &&
978 currentpage->m_nLastFileId != -1 &&
979 currentpage->m_szFile.compare(path) == 0)
980 )
981 {
982 if(currentpage->m_mediactrl->GetState() == wxMEDIASTATE_PLAYING)
983 {
984 if( !currentpage->m_mediactrl->Pause() )
985 wxMessageBox(wxT("Couldn't pause movie!"));
986 }
987 else
988 {
989 if( !currentpage->m_mediactrl->Play() )
990 wxMessageBox(wxT("Couldn't play movie!"));
991 }
992 }
993 else
994 {
995 int nNewId = listitem.GetData() ? listitem.GetId() :
996 currentpage->m_playlist->GetItemCount()-1;
997 m_notebook->SetPageText(m_notebook->GetSelection(),
998 wxFileName(path).GetName());
999
1000 if(currentpage->m_nLastFileId != -1)
1001 currentpage->m_playlist->SetItem(
1002 currentpage->m_nLastFileId, 0, wxT("*"));
1003
1004 wxURI uripath(path);
1005 if( uripath.IsReference() )
1006 {
1007 if( !currentpage->m_mediactrl->Load(path) )
1008 {
1009 wxMessageBox(wxT("Couldn't load file!"));
1010 currentpage->m_playlist->SetItem(nNewId, 0, wxT("E"));
1011 }
1012 else
1013 {
1014 currentpage->m_playlist->SetItem(nNewId, 0, wxT("O"));
1015 }
1016 }
1017 else
1018 {
1019 if( !currentpage->m_mediactrl->Load(uripath) )
1020 {
1021 wxMessageBox(wxT("Couldn't load URL!"));
1022 currentpage->m_playlist->SetItem(nNewId, 0, wxT("E"));
1023 }
1024 else
1025 {
1026 currentpage->m_playlist->SetItem(nNewId, 0, wxT("O"));
1027 }
1028 }
1029
1030 currentpage->m_nLastFileId = nNewId;
1031 currentpage->m_szFile = path;
1032 currentpage->m_playlist->SetItem(currentpage->m_nLastFileId,
1033 1, wxFileName(path).GetName());
1034 currentpage->m_playlist->SetItem(currentpage->m_nLastFileId,
1035 2, wxT(""));
1036 }
1037 }
1038
1039 // ----------------------------------------------------------------------------
1040 // wxMediaPlayerFrame::OnMediaLoaded
1041 //
1042 // Called when the media is ready to be played - and does
1043 // so, also gets the length of media and shows that in the list control
1044 // ----------------------------------------------------------------------------
1045 void wxMediaPlayerFrame::OnMediaLoaded(wxMediaEvent& WXUNUSED(evt))
1046 {
1047 wxMediaPlayerNotebookPage* currentpage =
1048 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1049
1050 if( !currentpage->m_mediactrl->Play() )
1051 {
1052 wxMessageBox(wxT("Couldn't play movie!"));
1053 currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT("E"));
1054 }
1055 else
1056 {
1057 currentpage->m_playlist->SetItem(currentpage->m_nLastFileId, 0, wxT(">"));
1058 }
1059
1060 }
1061
1062
1063 // ----------------------------------------------------------------------------
1064 // wxMediaPlayerFrame::OnSelectBackend
1065 //
1066 // Little debugging routine - enter the class name of a backend and it
1067 // will use that instead of letting wxMediaCtrl search the wxMediaBackend
1068 // RTTI class list.
1069 // ----------------------------------------------------------------------------
1070 void wxMediaPlayerFrame::OnSelectBackend(wxCommandEvent& WXUNUSED(evt))
1071 {
1072 wxString sBackend = wxGetTextFromUser(wxT("Enter backend to use"));
1073
1074 if(sBackend.empty() == false) //could have been cancelled by the user
1075 {
1076 int sel = m_notebook->GetSelection();
1077
1078 if (sel != wxNOT_FOUND)
1079 {
1080 m_notebook->DeletePage(sel);
1081 }
1082
1083 m_notebook->AddPage(new wxMediaPlayerNotebookPage(this, m_notebook,
1084 sBackend
1085 ), wxT(""), true);
1086
1087 DoOpenFile(
1088 ((wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage())->m_szFile,
1089 false);
1090 }
1091 }
1092
1093 // ----------------------------------------------------------------------------
1094 // wxMediaPlayerFrame::OnOpenURLSamePage
1095 //
1096 // Called from file->openurl.
1097 // Opens and plays a media file from a URL in the current notebook page
1098 // ----------------------------------------------------------------------------
1099 void wxMediaPlayerFrame::OnOpenURLSamePage(wxCommandEvent& WXUNUSED(event))
1100 {
1101 OpenURL(false);
1102 }
1103
1104 // ----------------------------------------------------------------------------
1105 // wxMediaPlayerFrame::OnOpenURLNewPage
1106 //
1107 // Called from file->openurlinnewpage.
1108 // Opens and plays a media file from a URL in a new notebook page
1109 // ----------------------------------------------------------------------------
1110 void wxMediaPlayerFrame::OnOpenURLNewPage(wxCommandEvent& WXUNUSED(event))
1111 {
1112 OpenURL(true);
1113 }
1114
1115 // ----------------------------------------------------------------------------
1116 // wxMediaPlayerFrame::OpenURL
1117 //
1118 // Just calls DoOpenFile with the url path - which calls DoPlayFile
1119 // which handles the real dirty work
1120 // ----------------------------------------------------------------------------
1121 void wxMediaPlayerFrame::OpenURL(bool bNewPage)
1122 {
1123 wxString sUrl = wxGetTextFromUser(
1124 wxT("Enter the URL that has the movie to play")
1125 );
1126
1127 if(sUrl.empty() == false) //could have been cancelled by user
1128 {
1129 DoOpenFile(sUrl, bNewPage);
1130 }
1131 }
1132
1133 // ----------------------------------------------------------------------------
1134 // wxMediaPlayerFrame::OnCloseCurrentPage
1135 //
1136 // Called when the user wants to close the current notebook page
1137 //
1138 // 1) Get the current page number (wxControl::GetSelection)
1139 // 2) If there is no current page, break out
1140 // 3) Delete the current page
1141 // ----------------------------------------------------------------------------
1142 void wxMediaPlayerFrame::OnCloseCurrentPage(wxCommandEvent& WXUNUSED(event))
1143 {
1144 if( m_notebook->GetPageCount() > 1 )
1145 {
1146 int sel = m_notebook->GetSelection();
1147
1148 if (sel != wxNOT_FOUND)
1149 {
1150 m_notebook->DeletePage(sel);
1151 }
1152 }
1153 else
1154 {
1155 wxMessageBox(wxT("Cannot close main page"));
1156 }
1157 }
1158
1159 // ----------------------------------------------------------------------------
1160 // wxMediaPlayerFrame::OnPlay
1161 //
1162 // Called from file->play.
1163 // Resumes the media if it is paused or stopped.
1164 // ----------------------------------------------------------------------------
1165 void wxMediaPlayerFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
1166 {
1167 wxMediaPlayerNotebookPage* currentpage =
1168 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1169
1170 wxListItem listitem;
1171 currentpage->m_playlist->GetSelectedItem(listitem);
1172 if ( !listitem.GetData() )
1173 {
1174 int nLast = -1;
1175 if ((nLast = currentpage->m_playlist->GetNextItem(nLast,
1176 wxLIST_NEXT_ALL,
1177 wxLIST_STATE_DONTCARE)) == -1)
1178 {
1179 //no items in list
1180 wxMessageBox(wxT("No items in playlist!"));
1181 }
1182 else
1183 {
1184 listitem.SetId(nLast);
1185 currentpage->m_playlist->GetItem(listitem);
1186 listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE);
1187 listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED);
1188 currentpage->m_playlist->SetItem(listitem);
1189 wxASSERT(listitem.GetData());
1190 DoPlayFile((*((wxString*) listitem.GetData())));
1191 }
1192 }
1193 else
1194 {
1195 wxASSERT(listitem.GetData());
1196 DoPlayFile((*((wxString*) listitem.GetData())));
1197 }
1198 }
1199
1200 // ----------------------------------------------------------------------------
1201 // wxMediaPlayerFrame::OnKeyDown
1202 //
1203 // Deletes all selected files from the playlist if the backspace key is pressed
1204 // ----------------------------------------------------------------------------
1205 void wxMediaPlayerFrame::OnKeyDown(wxKeyEvent& event)
1206 {
1207 if(event.GetKeyCode() == WXK_BACK/*DELETE*/)
1208 {
1209 wxMediaPlayerNotebookPage* currentpage =
1210 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1211 //delete all selected items
1212 while(true)
1213 {
1214 wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(
1215 -1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1216 if (nSelectedItem == -1)
1217 break;
1218
1219 wxListItem listitem;
1220 listitem.SetId(nSelectedItem);
1221 currentpage->m_playlist->GetItem(listitem);
1222 delete (wxString*) listitem.GetData();
1223
1224 currentpage->m_playlist->DeleteItem(nSelectedItem);
1225 }
1226 }
1227
1228 //Could be wxGetTextFromUser or something else important
1229 if(event.GetEventObject() != this)
1230 event.Skip();
1231 }
1232
1233 // ----------------------------------------------------------------------------
1234 // wxMediaPlayerFrame::OnStop
1235 //
1236 // Called from file->stop.
1237 // Where it stops depends on whether you can seek in the
1238 // media control or not - if you can it stops and seeks to the beginning,
1239 // otherwise it will appear to be at the end - but it will start over again
1240 // when Play() is called
1241 // ----------------------------------------------------------------------------
1242 void wxMediaPlayerFrame::OnStop(wxCommandEvent& WXUNUSED(evt))
1243 {
1244 wxMediaPlayerNotebookPage* currentpage =
1245 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1246
1247 if( !currentpage->m_mediactrl->Stop() )
1248 wxMessageBox(wxT("Couldn't stop movie!"));
1249 else
1250 currentpage->m_playlist->SetItem(
1251 currentpage->m_nLastFileId, 0, wxT("[]"));
1252 }
1253
1254
1255 // ----------------------------------------------------------------------------
1256 // wxMediaPlayerFrame::OnChangeSong
1257 //
1258 // Routine that plays the currently selected file in the playlist.
1259 // Called when the user actives the song from the playlist,
1260 // and from other various places in the sample
1261 // ----------------------------------------------------------------------------
1262 void wxMediaPlayerFrame::OnChangeSong(wxListEvent& WXUNUSED(evt))
1263 {
1264 wxMediaPlayerNotebookPage* currentpage =
1265 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1266
1267 wxListItem listitem;
1268 currentpage->m_playlist->GetSelectedItem(listitem);
1269 if(listitem.GetData())
1270 DoPlayFile((*((wxString*) listitem.GetData())));
1271 else
1272 wxMessageBox(wxT("No selected item!"));
1273 }
1274
1275 // ----------------------------------------------------------------------------
1276 // wxMediaPlayerFrame::OnPrev
1277 //
1278 // Tedious wxListCtrl stuff. Goes to prevous song in list, or if at the
1279 // beginning goes to the last in the list.
1280 // ----------------------------------------------------------------------------
1281 void wxMediaPlayerFrame::OnPrev(wxCommandEvent& WXUNUSED(event))
1282 {
1283 wxMediaPlayerNotebookPage* currentpage =
1284 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1285
1286 if (currentpage->m_playlist->GetItemCount() == 0)
1287 return;
1288
1289 wxInt32 nLastSelectedItem = -1;
1290 while(true)
1291 {
1292 wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem,
1293 wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1294 if (nSelectedItem == -1)
1295 break;
1296 nLastSelectedItem = nSelectedItem;
1297 currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED);
1298 }
1299
1300 if (nLastSelectedItem == -1)
1301 {
1302 //nothing selected, default to the file before the currently playing one
1303 if(currentpage->m_nLastFileId == 0)
1304 nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1;
1305 else
1306 nLastSelectedItem = currentpage->m_nLastFileId - 1;
1307 }
1308 else if (nLastSelectedItem == 0)
1309 nLastSelectedItem = currentpage->m_playlist->GetItemCount() - 1;
1310 else
1311 nLastSelectedItem -= 1;
1312
1313 if(nLastSelectedItem == currentpage->m_nLastFileId)
1314 return; //already playing... nothing to do
1315
1316 wxListItem listitem;
1317 listitem.SetId(nLastSelectedItem);
1318 listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA);
1319 currentpage->m_playlist->GetItem(listitem);
1320 listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE);
1321 listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED);
1322 currentpage->m_playlist->SetItem(listitem);
1323
1324 wxASSERT(listitem.GetData());
1325 DoPlayFile((*((wxString*) listitem.GetData())));
1326 }
1327
1328 // ----------------------------------------------------------------------------
1329 // wxMediaPlayerFrame::OnNext
1330 //
1331 // Tedious wxListCtrl stuff. Goes to next song in list, or if at the
1332 // end goes to the first in the list.
1333 // ----------------------------------------------------------------------------
1334 void wxMediaPlayerFrame::OnNext(wxCommandEvent& WXUNUSED(event))
1335 {
1336 wxMediaPlayerNotebookPage* currentpage =
1337 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1338
1339 if (currentpage->m_playlist->GetItemCount() == 0)
1340 return;
1341
1342 wxInt32 nLastSelectedItem = -1;
1343 while(true)
1344 {
1345 wxInt32 nSelectedItem = currentpage->m_playlist->GetNextItem(nLastSelectedItem,
1346 wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
1347 if (nSelectedItem == -1)
1348 break;
1349 nLastSelectedItem = nSelectedItem;
1350 currentpage->m_playlist->SetItemState(nSelectedItem, 0, wxLIST_STATE_SELECTED);
1351 }
1352
1353 if (nLastSelectedItem == -1)
1354 {
1355 if(currentpage->m_nLastFileId == currentpage->m_playlist->GetItemCount() - 1)
1356 nLastSelectedItem = 0;
1357 else
1358 nLastSelectedItem = currentpage->m_nLastFileId + 1;
1359 }
1360 else if (nLastSelectedItem == currentpage->m_playlist->GetItemCount() - 1)
1361 nLastSelectedItem = 0;
1362 else
1363 nLastSelectedItem += 1;
1364
1365 if(nLastSelectedItem == currentpage->m_nLastFileId)
1366 return; //already playing... nothing to do
1367
1368 wxListItem listitem;
1369 listitem.SetMask(wxLIST_MASK_TEXT | wxLIST_MASK_DATA);
1370 listitem.SetId(nLastSelectedItem);
1371 currentpage->m_playlist->GetItem(listitem);
1372 listitem.SetMask(listitem.GetMask() | wxLIST_MASK_STATE);
1373 listitem.SetState(listitem.GetState() | wxLIST_STATE_SELECTED);
1374 currentpage->m_playlist->SetItem(listitem);
1375
1376 wxASSERT(listitem.GetData());
1377 DoPlayFile((*((wxString*) listitem.GetData())));
1378 }
1379
1380
1381 // ----------------------------------------------------------------------------
1382 // wxMediaPlayerFrame::OnVolumeDown
1383 //
1384 // Lowers the volume of the media control by 5%
1385 // ----------------------------------------------------------------------------
1386 void wxMediaPlayerFrame::OnVolumeDown(wxCommandEvent& WXUNUSED(event))
1387 {
1388 wxMediaPlayerNotebookPage* currentpage =
1389 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1390
1391 double dVolume = currentpage->m_mediactrl->GetVolume();
1392 currentpage->m_mediactrl->SetVolume(dVolume < 0.05 ? 0.0 : dVolume - .05);
1393 }
1394
1395 // ----------------------------------------------------------------------------
1396 // wxMediaPlayerFrame::OnVolumeUp
1397 //
1398 // Increases the volume of the media control by 5%
1399 // ----------------------------------------------------------------------------
1400 void wxMediaPlayerFrame::OnVolumeUp(wxCommandEvent& WXUNUSED(event))
1401 {
1402 wxMediaPlayerNotebookPage* currentpage =
1403 (wxMediaPlayerNotebookPage*) m_notebook->GetCurrentPage();
1404
1405 double dVolume = currentpage->m_mediactrl->GetVolume();
1406 currentpage->m_mediactrl->SetVolume(dVolume > 0.95 ? 1.0 : dVolume + .05);
1407 }
1408
1409 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1410 //
1411 // wxMediaPlayerTimer
1412 //
1413 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1414
1415 // ----------------------------------------------------------------------------
1416 // wxMediaPlayerTimer::Notify
1417 //
1418 // 1) Updates media information on the status bar
1419 // 2) Sets the max/min length of the slider and guage
1420 //
1421 // Note that the reason we continually do this and don't cache it is because
1422 // some backends such as GStreamer are dynamic change values all the time
1423 // and often don't have things like duration or video size available
1424 // until the media is actually being played
1425 // ----------------------------------------------------------------------------
1426 void wxMediaPlayerTimer::Notify()
1427 {
1428 wxMediaPlayerNotebookPage* currentpage =
1429 (wxMediaPlayerNotebookPage*) m_frame->m_notebook->GetCurrentPage();
1430 wxMediaCtrl* currentMediaCtrl = currentpage->m_mediactrl;
1431
1432 if(currentpage)
1433 {
1434 // Number of minutes/seconds total
1435 wxLongLong llLength = currentpage->m_mediactrl->Length();
1436 int nMinutes = (int) (llLength / 60000).GetValue();
1437 int nSeconds = (int) ((llLength % 60000)/1000).GetValue();
1438
1439 // Duration string (i.e. MM:SS)
1440 wxString sDuration;
1441 sDuration.Printf(wxT("%2i:%02i"), nMinutes, nSeconds);
1442
1443
1444 // Number of minutes/seconds total
1445 wxLongLong llTell = currentpage->m_mediactrl->Tell();
1446 nMinutes = (int) (llTell / 60000).GetValue();
1447 nSeconds = (int) ((llTell % 60000)/1000).GetValue();
1448
1449 // Position string (i.e. MM:SS)
1450 wxString sPosition;
1451 sPosition.Printf(wxT("%2i:%02i"), nMinutes, nSeconds);
1452
1453
1454 // Set the third item in the listctrl entry to the duration string
1455 if(currentpage->m_nLastFileId >= 0)
1456 currentpage->m_playlist->SetItem(
1457 currentpage->m_nLastFileId, 2, sDuration);
1458
1459 // Setup the slider and gauge min/max values
1460 currentpage->m_slider->SetRange(0, (int)(llLength / 1000).GetValue());
1461 currentpage->m_gauge->SetRange(100);
1462
1463
1464 // if the slider is not being dragged then update it with the song position
1465 if(currentpage->IsBeingDragged() == false)
1466 currentpage->m_slider->SetValue((long)(llTell / 1000).GetValue());
1467
1468
1469 // Update the gauge with the download progress
1470 wxLongLong llDownloadProgress =
1471 currentpage->m_mediactrl->GetDownloadProgress();
1472 wxLongLong llDownloadTotal =
1473 currentpage->m_mediactrl->GetDownloadTotal();
1474
1475 if(llDownloadTotal.GetValue() != 0)
1476 {
1477 currentpage->m_gauge->SetValue(
1478 (int) ((llDownloadProgress * 100) / llDownloadTotal).GetValue()
1479 );
1480 }
1481
1482 // GetBestSize holds the original video size
1483 wxSize videoSize = currentMediaCtrl->GetBestSize();
1484
1485 // Now the big part - set the status bar text to
1486 // hold various metadata about the media
1487 #if wxUSE_STATUSBAR
1488 m_frame->SetStatusText(wxString::Format(
1489 wxT("Size(x,y):%i,%i ")
1490 wxT("Position:%s/%s Speed:%1.1fx ")
1491 wxT("State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
1492 videoSize.x,
1493 videoSize.y,
1494 sPosition.c_str(),
1495 sDuration.c_str(),
1496 currentMediaCtrl->GetPlaybackRate(),
1497 wxGetMediaStateText(currentpage->m_mediactrl->GetState()),
1498 currentpage->m_nLoops,
1499 (int)llDownloadProgress.GetValue(),
1500 (int)llDownloadTotal.GetValue(),
1501 (int)(currentpage->m_mediactrl->GetVolume() * 100)));
1502 #endif // wxUSE_STATUSBAR
1503 }
1504 }
1505
1506 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1507 //
1508 // wxMediaPlayerNotebookPage
1509 //
1510 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1511
1512 // ----------------------------------------------------------------------------
1513 // wxMediaPlayerNotebookPage Constructor
1514 //
1515 // Creates a media control and slider and adds it to this panel,
1516 // along with some sizers for positioning
1517 // ----------------------------------------------------------------------------
1518 wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentFrame,
1519 wxNotebook* theBook,
1520 const wxString& szBackend)
1521 : wxPanel(theBook, wxID_ANY),
1522 m_nLastFileId(-1),
1523 m_nLoops(0),
1524 m_bLoop(false),
1525 m_bIsBeingDragged(false),
1526 m_parentFrame(parentFrame)
1527 {
1528 //
1529 // Layout
1530 //
1531 // [wxMediaCtrl]
1532 // [playlist]
1533 // [5 control buttons]
1534 // [slider]
1535 // [gauge]
1536 //
1537
1538 //
1539 // Create and attach a 2-column grid sizer
1540 //
1541 wxFlexGridSizer* sizer = new wxFlexGridSizer(2);
1542 sizer->AddGrowableCol(0);
1543 this->SetSizer(sizer);
1544
1545 //
1546 // Create our media control
1547 //
1548 m_mediactrl = new wxMediaCtrl();
1549
1550 // Make sure creation was successful
1551 bool bOK = m_mediactrl->Create(this, wxID_MEDIACTRL, wxEmptyString,
1552 wxDefaultPosition, wxDefaultSize, 0,
1553 //you could specify a macrod backend here like
1554 // wxMEDIABACKEND_WMP10);
1555 // wxT("wxPDFMediaBackend"));
1556 szBackend);
1557 //you could change the cursor here like
1558 // m_mediactrl->SetCursor(wxCURSOR_BLANK);
1559 //note that this may not effect it if SetPlayerControls
1560 //is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
1561 wxASSERT_MSG(bOK, wxT("Could not create media control!"));
1562 wxUnusedVar(bOK);
1563
1564 sizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
1565
1566 //
1567 // Create the playlist/listctrl
1568 //
1569 m_playlist = new wxMediaPlayerListCtrl();
1570 m_playlist->Create(this, wxID_LISTCTRL, wxDefaultPosition,
1571 wxDefaultSize,
1572 wxLC_REPORT //wxLC_LIST
1573 | wxSUNKEN_BORDER);
1574
1575 // Set the background of our listctrl to white
1576 m_playlist->SetBackgroundColour(wxColour(255,255,255));
1577
1578 // The layout of the headers of the listctrl are like
1579 // | | File | Length
1580 //
1581 // Where Column one is a character representing the state the file is in:
1582 // * - not the current file
1583 // E - Error has occured
1584 // > - Currently Playing
1585 // [] - Stopped
1586 // || - Paused
1587 // (( - Volume Down 5%
1588 // )) - Volume Up 5%
1589 //
1590 // Column two is the name of the file
1591 //
1592 // Column three is the length in seconds of the file
1593 m_playlist->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER, 20);
1594 m_playlist->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT, /*wxLIST_AUTOSIZE_USEHEADER*/305);
1595 m_playlist->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER, 75);
1596
1597 #if wxUSE_DRAG_AND_DROP
1598 m_playlist->SetDropTarget(new wxPlayListDropTarget(*m_playlist));
1599 #endif
1600
1601 sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
1602
1603 //
1604 // Create the control buttons
1605 // TODO/FIXME/HACK: This part about sizers is really a nice hack
1606 // and probably isn't proper
1607 //
1608 wxBoxSizer* horsizer1 = new wxBoxSizer(wxHORIZONTAL);
1609 wxBoxSizer* vertsizer = new wxBoxSizer(wxHORIZONTAL);
1610
1611 m_prevButton = new wxButton();
1612 m_playButton = new wxButton();
1613 m_stopButton = new wxButton();
1614 m_nextButton = new wxButton();
1615 m_vdButton = new wxButton();
1616 m_vuButton = new wxButton();
1617
1618 m_prevButton->Create(this, wxID_BUTTONPREV, wxT("|<"));
1619 m_playButton->Create(this, wxID_BUTTONPLAY, wxT(">"));
1620 m_stopButton->Create(this, wxID_BUTTONSTOP, wxT("[]"));
1621 m_nextButton->Create(this, wxID_BUTTONNEXT, wxT(">|"));
1622 m_vdButton->Create(this, wxID_BUTTONVD, wxT("(("));
1623 m_vuButton->Create(this, wxID_BUTTONVU, wxT("))"));
1624 vertsizer->Add(m_prevButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1625 vertsizer->Add(m_playButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1626 vertsizer->Add(m_stopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1627 vertsizer->Add(m_nextButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1628 vertsizer->Add(m_vdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1629 vertsizer->Add(m_vuButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1630 horsizer1->Add(vertsizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1631 sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
1632
1633
1634 //
1635 // Create our slider
1636 //
1637 m_slider = new wxSlider(this, wxID_SLIDER, 0, //init
1638 0, //start
1639 0, //end
1640 wxDefaultPosition, wxDefaultSize,
1641 wxSL_HORIZONTAL );
1642 sizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
1643
1644 //
1645 // Create the gauge
1646 //
1647 m_gauge = new wxGauge();
1648 m_gauge->Create(this, wxID_GAUGE, 0, wxDefaultPosition, wxDefaultSize,
1649 wxGA_HORIZONTAL | wxGA_SMOOTH);
1650 sizer->Add(m_gauge, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
1651
1652
1653 //
1654 // Create the speed/volume sliders
1655 //
1656 wxBoxSizer* horsizer3 = new wxBoxSizer(wxHORIZONTAL);
1657
1658 m_volSlider = new wxSlider(this, wxID_VOLSLIDER, 100, // init
1659 0, // start
1660 100, // end
1661 wxDefaultPosition, wxSize(250,20),
1662 wxSL_HORIZONTAL );
1663 horsizer3->Add(m_volSlider, 1, wxALL, 5);
1664
1665 m_pbSlider = new wxSlider(this, wxID_PBSLIDER, 4, // init
1666 1, // start
1667 16, // end
1668 wxDefaultPosition, wxSize(250,20),
1669 wxSL_HORIZONTAL );
1670 horsizer3->Add(m_pbSlider, 1, wxALL, 5);
1671 sizer->Add(horsizer3, 1, wxCENTRE | wxALL, 5);
1672
1673 // Now that we have all our rows make some of them growable
1674 sizer->AddGrowableRow(0);
1675
1676 //
1677 // ListCtrl events
1678 //
1679 this->Connect( wxID_LISTCTRL, wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
1680 wxListEventHandler(wxMediaPlayerFrame::OnChangeSong),
1681 (wxObject*)0, parentFrame);
1682
1683 //
1684 // Slider events
1685 //
1686 this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBTRACK,
1687 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek));
1688 this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBRELEASE,
1689 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek));
1690 this->Connect(wxID_PBSLIDER, wxEVT_SCROLL_THUMBRELEASE,
1691 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnPBChange));
1692 this->Connect(wxID_VOLSLIDER, wxEVT_SCROLL_THUMBRELEASE,
1693 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnVolChange));
1694
1695 //
1696 // Media Control events
1697 //
1698 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PLAY,
1699 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPlay));
1700 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PAUSE,
1701 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPause));
1702 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_STOP,
1703 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaStop));
1704 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_FINISHED,
1705 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished));
1706 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_LOADED,
1707 wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded),
1708 (wxObject*)0, parentFrame);
1709
1710 //
1711 // Button events
1712 //
1713 this->Connect( wxID_BUTTONPREV, wxEVT_COMMAND_BUTTON_CLICKED,
1714 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev),
1715 (wxObject*)0, parentFrame);
1716 this->Connect( wxID_BUTTONPLAY, wxEVT_COMMAND_BUTTON_CLICKED,
1717 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay),
1718 (wxObject*)0, parentFrame);
1719 this->Connect( wxID_BUTTONSTOP, wxEVT_COMMAND_BUTTON_CLICKED,
1720 wxCommandEventHandler(wxMediaPlayerFrame::OnStop),
1721 (wxObject*)0, parentFrame);
1722 this->Connect( wxID_BUTTONNEXT, wxEVT_COMMAND_BUTTON_CLICKED,
1723 wxCommandEventHandler(wxMediaPlayerFrame::OnNext),
1724 (wxObject*)0, parentFrame);
1725 this->Connect( wxID_BUTTONVD, wxEVT_COMMAND_BUTTON_CLICKED,
1726 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown),
1727 (wxObject*)0, parentFrame);
1728 this->Connect( wxID_BUTTONVU, wxEVT_COMMAND_BUTTON_CLICKED,
1729 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp),
1730 (wxObject*)0, parentFrame);
1731 }
1732
1733 // ----------------------------------------------------------------------------
1734 // MyNotebook::OnBeginSeek
1735 //
1736 // Sets m_bIsBeingDragged to true to stop the timer from changing the position
1737 // of our slider
1738 // ----------------------------------------------------------------------------
1739 void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent& WXUNUSED(event))
1740 {
1741 m_bIsBeingDragged = true;
1742 }
1743
1744 // ----------------------------------------------------------------------------
1745 // MyNotebook::OnEndSeek
1746 //
1747 // Called from file->seek.
1748 // Called when the user moves the slider -
1749 // seeks to a position within the media
1750 // then sets m_bIsBeingDragged to false to ok the timer to change the position
1751 // ----------------------------------------------------------------------------
1752 void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent& WXUNUSED(event))
1753 {
1754 if( m_mediactrl->Seek(
1755 m_slider->GetValue() * 1000
1756 ) == wxInvalidOffset )
1757 wxMessageBox(wxT("Couldn't seek in movie!"));
1758
1759 m_bIsBeingDragged = false;
1760 }
1761
1762 // ----------------------------------------------------------------------------
1763 // wxMediaPlayerNotebookPage::IsBeingDragged
1764 //
1765 // Returns true if the user is dragging the slider
1766 // ----------------------------------------------------------------------------
1767 bool wxMediaPlayerNotebookPage::IsBeingDragged()
1768 {
1769 return m_bIsBeingDragged;
1770 }
1771
1772 // ----------------------------------------------------------------------------
1773 // wxMediaPlayerNotebookPage::OnVolChange
1774 //
1775 // Called when the user is done dragging the volume-changing slider
1776 // ----------------------------------------------------------------------------
1777 void wxMediaPlayerNotebookPage::OnVolChange(wxScrollEvent& WXUNUSED(event))
1778 {
1779 if( m_mediactrl->SetVolume(
1780 m_volSlider->GetValue() / 100.0
1781 ) == false )
1782 wxMessageBox(wxT("Couldn't set volume!"));
1783
1784 }
1785
1786 // ----------------------------------------------------------------------------
1787 // wxMediaPlayerNotebookPage::OnPBChange
1788 //
1789 // Called when the user is done dragging the speed-changing slider
1790 // ----------------------------------------------------------------------------
1791 void wxMediaPlayerNotebookPage::OnPBChange(wxScrollEvent& WXUNUSED(event))
1792 {
1793 if( m_mediactrl->SetPlaybackRate(
1794 m_pbSlider->GetValue() * .25
1795 ) == false )
1796 wxMessageBox(wxT("Couldn't set playbackrate!"));
1797
1798 }
1799
1800 // ----------------------------------------------------------------------------
1801 // wxMediaPlayerNotebookPage::OnMediaPlay
1802 //
1803 // Called when the media plays.
1804 // ----------------------------------------------------------------------------
1805 void wxMediaPlayerNotebookPage::OnMediaPlay(wxMediaEvent& WXUNUSED(event))
1806 {
1807 m_playlist->SetItem(m_nLastFileId, 0, wxT(">"));
1808 }
1809
1810 // ----------------------------------------------------------------------------
1811 // wxMediaPlayerNotebookPage::OnMediaPause
1812 //
1813 // Called when the media is paused.
1814 // ----------------------------------------------------------------------------
1815 void wxMediaPlayerNotebookPage::OnMediaPause(wxMediaEvent& WXUNUSED(event))
1816 {
1817 m_playlist->SetItem(m_nLastFileId, 0, wxT("||"));
1818 }
1819
1820 // ----------------------------------------------------------------------------
1821 // wxMediaPlayerNotebookPage::OnMediaStop
1822 //
1823 // Called when the media stops.
1824 // ----------------------------------------------------------------------------
1825 void wxMediaPlayerNotebookPage::OnMediaStop(wxMediaEvent& WXUNUSED(event))
1826 {
1827 m_playlist->SetItem(m_nLastFileId, 0, wxT("[]"));
1828 }
1829
1830 // ----------------------------------------------------------------------------
1831 // wxMediaPlayerNotebookPage::OnMediaFinished
1832 //
1833 // Called when the media finishes playing.
1834 // Here we loop it if the user wants to (has been selected from file menu)
1835 // ----------------------------------------------------------------------------
1836 void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent& WXUNUSED(event))
1837 {
1838 if(m_bLoop)
1839 {
1840 if ( !m_mediactrl->Play() )
1841 {
1842 wxMessageBox(wxT("Couldn't loop movie!"));
1843 m_playlist->SetItem(m_nLastFileId, 0, wxT("E"));
1844 }
1845 else
1846 ++m_nLoops;
1847 }
1848 else
1849 {
1850 m_playlist->SetItem(m_nLastFileId, 0, wxT("[]"));
1851 }
1852 }
1853
1854 //
1855 // End of MediaPlayer sample
1856 //