]> git.saurik.com Git - wxWidgets.git/blob - samples/mediaplayer/mediaplayer.cpp
Speed up adding pages during freezing
[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 // Number of minutes/seconds total
1433 wxLongLong llLength = currentpage->m_mediactrl->Length();
1434 int nMinutes = (int) (llLength / 60000).GetValue();
1435 int nSeconds = (int) ((llLength % 60000)/1000).GetValue();
1436
1437 // Duration string (i.e. MM:SS)
1438 wxString sDuration;
1439 sDuration.Printf(wxT("%2i:%02i"), nMinutes, nSeconds);
1440
1441
1442 // Number of minutes/seconds total
1443 wxLongLong llTell = currentpage->m_mediactrl->Tell();
1444 nMinutes = (int) (llTell / 60000).GetValue();
1445 nSeconds = (int) ((llTell % 60000)/1000).GetValue();
1446
1447 // Position string (i.e. MM:SS)
1448 wxString sPosition;
1449 sPosition.Printf(wxT("%2i:%02i"), nMinutes, nSeconds);
1450
1451
1452 // Set the third item in the listctrl entry to the duration string
1453 if(currentpage->m_nLastFileId >= 0)
1454 currentpage->m_playlist->SetItem(
1455 currentpage->m_nLastFileId, 2, sDuration);
1456
1457 // Setup the slider and gauge min/max values
1458 currentpage->m_slider->SetRange(0, (int)(llLength / 1000).GetValue());
1459 currentpage->m_gauge->SetRange(100);
1460
1461
1462 // if the slider is not being dragged then update it with the song position
1463 if(currentpage->IsBeingDragged() == false)
1464 currentpage->m_slider->SetValue((long)(llTell / 1000).GetValue());
1465
1466
1467 // Update the gauge with the download progress
1468 wxLongLong llDownloadProgress =
1469 currentpage->m_mediactrl->GetDownloadProgress();
1470 wxLongLong llDownloadTotal =
1471 currentpage->m_mediactrl->GetDownloadTotal();
1472
1473 if(llDownloadTotal.GetValue() != 0)
1474 {
1475 currentpage->m_gauge->SetValue(
1476 (int) ((llDownloadProgress * 100) / llDownloadTotal).GetValue()
1477 );
1478 }
1479
1480 // GetBestSize holds the original video size
1481 wxSize videoSize = currentMediaCtrl->GetBestSize();
1482
1483 // Now the big part - set the status bar text to
1484 // hold various metadata about the media
1485 #if wxUSE_STATUSBAR
1486 m_frame->SetStatusText(wxString::Format(
1487 wxT("Size(x,y):%i,%i ")
1488 wxT("Position:%s/%s Speed:%1.1fx ")
1489 wxT("State:%s Loops:%i D/T:[%i]/[%i] V:%i%%"),
1490 videoSize.x,
1491 videoSize.y,
1492 sPosition.c_str(),
1493 sDuration.c_str(),
1494 currentMediaCtrl->GetPlaybackRate(),
1495 wxGetMediaStateText(currentpage->m_mediactrl->GetState()),
1496 currentpage->m_nLoops,
1497 (int)llDownloadProgress.GetValue(),
1498 (int)llDownloadTotal.GetValue(),
1499 (int)(currentpage->m_mediactrl->GetVolume() * 100)));
1500 #endif // wxUSE_STATUSBAR
1501 }
1502
1503 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1504 //
1505 // wxMediaPlayerNotebookPage
1506 //
1507 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1508
1509 // ----------------------------------------------------------------------------
1510 // wxMediaPlayerNotebookPage Constructor
1511 //
1512 // Creates a media control and slider and adds it to this panel,
1513 // along with some sizers for positioning
1514 // ----------------------------------------------------------------------------
1515 wxMediaPlayerNotebookPage::wxMediaPlayerNotebookPage(wxMediaPlayerFrame* parentFrame,
1516 wxNotebook* theBook,
1517 const wxString& szBackend)
1518 : wxPanel(theBook, wxID_ANY),
1519 m_nLastFileId(-1),
1520 m_nLoops(0),
1521 m_bLoop(false),
1522 m_bIsBeingDragged(false),
1523 m_parentFrame(parentFrame)
1524 {
1525 //
1526 // Layout
1527 //
1528 // [wxMediaCtrl]
1529 // [playlist]
1530 // [5 control buttons]
1531 // [slider]
1532 // [gauge]
1533 //
1534
1535 //
1536 // Create and attach a 2-column grid sizer
1537 //
1538 wxFlexGridSizer* sizer = new wxFlexGridSizer(2);
1539 sizer->AddGrowableCol(0);
1540 this->SetSizer(sizer);
1541
1542 //
1543 // Create our media control
1544 //
1545 m_mediactrl = new wxMediaCtrl();
1546
1547 // Make sure creation was successful
1548 bool bOK = m_mediactrl->Create(this, wxID_MEDIACTRL, wxEmptyString,
1549 wxDefaultPosition, wxDefaultSize, 0,
1550 //you could specify a macrod backend here like
1551 // wxMEDIABACKEND_WMP10);
1552 // wxT("wxPDFMediaBackend"));
1553 szBackend);
1554 //you could change the cursor here like
1555 // m_mediactrl->SetCursor(wxCURSOR_BLANK);
1556 //note that this may not effect it if SetPlayerControls
1557 //is set to something else than wxMEDIACTRLPLAYERCONTROLS_NONE
1558 wxASSERT_MSG(bOK, wxT("Could not create media control!"));
1559 wxUnusedVar(bOK);
1560
1561 sizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
1562
1563 //
1564 // Create the playlist/listctrl
1565 //
1566 m_playlist = new wxMediaPlayerListCtrl();
1567 m_playlist->Create(this, wxID_LISTCTRL, wxDefaultPosition,
1568 wxDefaultSize,
1569 wxLC_REPORT //wxLC_LIST
1570 | wxSUNKEN_BORDER);
1571
1572 // Set the background of our listctrl to white
1573 m_playlist->SetBackgroundColour(wxColour(255,255,255));
1574
1575 // The layout of the headers of the listctrl are like
1576 // | | File | Length
1577 //
1578 // Where Column one is a character representing the state the file is in:
1579 // * - not the current file
1580 // E - Error has occured
1581 // > - Currently Playing
1582 // [] - Stopped
1583 // || - Paused
1584 // (( - Volume Down 5%
1585 // )) - Volume Up 5%
1586 //
1587 // Column two is the name of the file
1588 //
1589 // Column three is the length in seconds of the file
1590 m_playlist->InsertColumn(0,_(""), wxLIST_FORMAT_CENTER, 20);
1591 m_playlist->InsertColumn(1,_("File"), wxLIST_FORMAT_LEFT, /*wxLIST_AUTOSIZE_USEHEADER*/305);
1592 m_playlist->InsertColumn(2,_("Length"), wxLIST_FORMAT_CENTER, 75);
1593
1594 #if wxUSE_DRAG_AND_DROP
1595 m_playlist->SetDropTarget(new wxPlayListDropTarget(*m_playlist));
1596 #endif
1597
1598 sizer->Add(m_playlist, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND, 5);
1599
1600 //
1601 // Create the control buttons
1602 // TODO/FIXME/HACK: This part about sizers is really a nice hack
1603 // and probably isn't proper
1604 //
1605 wxBoxSizer* horsizer1 = new wxBoxSizer(wxHORIZONTAL);
1606 wxBoxSizer* vertsizer = new wxBoxSizer(wxHORIZONTAL);
1607
1608 m_prevButton = new wxButton();
1609 m_playButton = new wxButton();
1610 m_stopButton = new wxButton();
1611 m_nextButton = new wxButton();
1612 m_vdButton = new wxButton();
1613 m_vuButton = new wxButton();
1614
1615 m_prevButton->Create(this, wxID_BUTTONPREV, wxT("|<"));
1616 m_playButton->Create(this, wxID_BUTTONPLAY, wxT(">"));
1617 m_stopButton->Create(this, wxID_BUTTONSTOP, wxT("[]"));
1618 m_nextButton->Create(this, wxID_BUTTONNEXT, wxT(">|"));
1619 m_vdButton->Create(this, wxID_BUTTONVD, wxT("(("));
1620 m_vuButton->Create(this, wxID_BUTTONVU, wxT("))"));
1621 vertsizer->Add(m_prevButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1622 vertsizer->Add(m_playButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1623 vertsizer->Add(m_stopButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1624 vertsizer->Add(m_nextButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1625 vertsizer->Add(m_vdButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1626 vertsizer->Add(m_vuButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1627 horsizer1->Add(vertsizer, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5);
1628 sizer->Add(horsizer1, 0, wxALIGN_CENTER_VERTICAL|wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
1629
1630
1631 //
1632 // Create our slider
1633 //
1634 m_slider = new wxSlider(this, wxID_SLIDER, 0, //init
1635 0, //start
1636 0, //end
1637 wxDefaultPosition, wxDefaultSize,
1638 wxSL_HORIZONTAL );
1639 sizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
1640
1641 //
1642 // Create the gauge
1643 //
1644 m_gauge = new wxGauge();
1645 m_gauge->Create(this, wxID_GAUGE, 0, wxDefaultPosition, wxDefaultSize,
1646 wxGA_HORIZONTAL | wxGA_SMOOTH);
1647 sizer->Add(m_gauge, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
1648
1649
1650 //
1651 // Create the speed/volume sliders
1652 //
1653 wxBoxSizer* horsizer3 = new wxBoxSizer(wxHORIZONTAL);
1654
1655 m_volSlider = new wxSlider(this, wxID_VOLSLIDER, 100, // init
1656 0, // start
1657 100, // end
1658 wxDefaultPosition, wxSize(250,20),
1659 wxSL_HORIZONTAL );
1660 horsizer3->Add(m_volSlider, 1, wxALL, 5);
1661
1662 m_pbSlider = new wxSlider(this, wxID_PBSLIDER, 4, // init
1663 1, // start
1664 16, // end
1665 wxDefaultPosition, wxSize(250,20),
1666 wxSL_HORIZONTAL );
1667 horsizer3->Add(m_pbSlider, 1, wxALL, 5);
1668 sizer->Add(horsizer3, 1, wxCENTRE | wxALL, 5);
1669
1670 // Now that we have all our rows make some of them growable
1671 sizer->AddGrowableRow(0);
1672
1673 //
1674 // ListCtrl events
1675 //
1676 this->Connect( wxID_LISTCTRL, wxEVT_COMMAND_LIST_ITEM_ACTIVATED,
1677 wxListEventHandler(wxMediaPlayerFrame::OnChangeSong),
1678 (wxObject*)0, parentFrame);
1679
1680 //
1681 // Slider events
1682 //
1683 this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBTRACK,
1684 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnBeginSeek));
1685 this->Connect(wxID_SLIDER, wxEVT_SCROLL_THUMBRELEASE,
1686 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnEndSeek));
1687 this->Connect(wxID_PBSLIDER, wxEVT_SCROLL_THUMBRELEASE,
1688 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnPBChange));
1689 this->Connect(wxID_VOLSLIDER, wxEVT_SCROLL_THUMBRELEASE,
1690 wxScrollEventHandler(wxMediaPlayerNotebookPage::OnVolChange));
1691
1692 //
1693 // Media Control events
1694 //
1695 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PLAY,
1696 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPlay));
1697 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_PAUSE,
1698 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaPause));
1699 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_STOP,
1700 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaStop));
1701 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_FINISHED,
1702 wxMediaEventHandler(wxMediaPlayerNotebookPage::OnMediaFinished));
1703 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_LOADED,
1704 wxMediaEventHandler(wxMediaPlayerFrame::OnMediaLoaded),
1705 (wxObject*)0, parentFrame);
1706
1707 //
1708 // Button events
1709 //
1710 this->Connect( wxID_BUTTONPREV, wxEVT_COMMAND_BUTTON_CLICKED,
1711 wxCommandEventHandler(wxMediaPlayerFrame::OnPrev),
1712 (wxObject*)0, parentFrame);
1713 this->Connect( wxID_BUTTONPLAY, wxEVT_COMMAND_BUTTON_CLICKED,
1714 wxCommandEventHandler(wxMediaPlayerFrame::OnPlay),
1715 (wxObject*)0, parentFrame);
1716 this->Connect( wxID_BUTTONSTOP, wxEVT_COMMAND_BUTTON_CLICKED,
1717 wxCommandEventHandler(wxMediaPlayerFrame::OnStop),
1718 (wxObject*)0, parentFrame);
1719 this->Connect( wxID_BUTTONNEXT, wxEVT_COMMAND_BUTTON_CLICKED,
1720 wxCommandEventHandler(wxMediaPlayerFrame::OnNext),
1721 (wxObject*)0, parentFrame);
1722 this->Connect( wxID_BUTTONVD, wxEVT_COMMAND_BUTTON_CLICKED,
1723 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeDown),
1724 (wxObject*)0, parentFrame);
1725 this->Connect( wxID_BUTTONVU, wxEVT_COMMAND_BUTTON_CLICKED,
1726 wxCommandEventHandler(wxMediaPlayerFrame::OnVolumeUp),
1727 (wxObject*)0, parentFrame);
1728 }
1729
1730 // ----------------------------------------------------------------------------
1731 // MyNotebook::OnBeginSeek
1732 //
1733 // Sets m_bIsBeingDragged to true to stop the timer from changing the position
1734 // of our slider
1735 // ----------------------------------------------------------------------------
1736 void wxMediaPlayerNotebookPage::OnBeginSeek(wxScrollEvent& WXUNUSED(event))
1737 {
1738 m_bIsBeingDragged = true;
1739 }
1740
1741 // ----------------------------------------------------------------------------
1742 // MyNotebook::OnEndSeek
1743 //
1744 // Called from file->seek.
1745 // Called when the user moves the slider -
1746 // seeks to a position within the media
1747 // then sets m_bIsBeingDragged to false to ok the timer to change the position
1748 // ----------------------------------------------------------------------------
1749 void wxMediaPlayerNotebookPage::OnEndSeek(wxScrollEvent& WXUNUSED(event))
1750 {
1751 if( m_mediactrl->Seek(
1752 m_slider->GetValue() * 1000
1753 ) == wxInvalidOffset )
1754 wxMessageBox(wxT("Couldn't seek in movie!"));
1755
1756 m_bIsBeingDragged = false;
1757 }
1758
1759 // ----------------------------------------------------------------------------
1760 // wxMediaPlayerNotebookPage::IsBeingDragged
1761 //
1762 // Returns true if the user is dragging the slider
1763 // ----------------------------------------------------------------------------
1764 bool wxMediaPlayerNotebookPage::IsBeingDragged()
1765 {
1766 return m_bIsBeingDragged;
1767 }
1768
1769 // ----------------------------------------------------------------------------
1770 // wxMediaPlayerNotebookPage::OnVolChange
1771 //
1772 // Called when the user is done dragging the volume-changing slider
1773 // ----------------------------------------------------------------------------
1774 void wxMediaPlayerNotebookPage::OnVolChange(wxScrollEvent& WXUNUSED(event))
1775 {
1776 if( m_mediactrl->SetVolume(
1777 m_volSlider->GetValue() / 100.0
1778 ) == false )
1779 wxMessageBox(wxT("Couldn't set volume!"));
1780
1781 }
1782
1783 // ----------------------------------------------------------------------------
1784 // wxMediaPlayerNotebookPage::OnPBChange
1785 //
1786 // Called when the user is done dragging the speed-changing slider
1787 // ----------------------------------------------------------------------------
1788 void wxMediaPlayerNotebookPage::OnPBChange(wxScrollEvent& WXUNUSED(event))
1789 {
1790 if( m_mediactrl->SetPlaybackRate(
1791 m_pbSlider->GetValue() * .25
1792 ) == false )
1793 wxMessageBox(wxT("Couldn't set playbackrate!"));
1794
1795 }
1796
1797 // ----------------------------------------------------------------------------
1798 // wxMediaPlayerNotebookPage::OnMediaPlay
1799 //
1800 // Called when the media plays.
1801 // ----------------------------------------------------------------------------
1802 void wxMediaPlayerNotebookPage::OnMediaPlay(wxMediaEvent& WXUNUSED(event))
1803 {
1804 m_playlist->SetItem(m_nLastFileId, 0, wxT(">"));
1805 }
1806
1807 // ----------------------------------------------------------------------------
1808 // wxMediaPlayerNotebookPage::OnMediaPause
1809 //
1810 // Called when the media is paused.
1811 // ----------------------------------------------------------------------------
1812 void wxMediaPlayerNotebookPage::OnMediaPause(wxMediaEvent& WXUNUSED(event))
1813 {
1814 m_playlist->SetItem(m_nLastFileId, 0, wxT("||"));
1815 }
1816
1817 // ----------------------------------------------------------------------------
1818 // wxMediaPlayerNotebookPage::OnMediaStop
1819 //
1820 // Called when the media stops.
1821 // ----------------------------------------------------------------------------
1822 void wxMediaPlayerNotebookPage::OnMediaStop(wxMediaEvent& WXUNUSED(event))
1823 {
1824 m_playlist->SetItem(m_nLastFileId, 0, wxT("[]"));
1825 }
1826
1827 // ----------------------------------------------------------------------------
1828 // wxMediaPlayerNotebookPage::OnMediaFinished
1829 //
1830 // Called when the media finishes playing.
1831 // Here we loop it if the user wants to (has been selected from file menu)
1832 // ----------------------------------------------------------------------------
1833 void wxMediaPlayerNotebookPage::OnMediaFinished(wxMediaEvent& WXUNUSED(event))
1834 {
1835 if(m_bLoop)
1836 {
1837 if ( !m_mediactrl->Play() )
1838 {
1839 wxMessageBox(wxT("Couldn't loop movie!"));
1840 m_playlist->SetItem(m_nLastFileId, 0, wxT("E"));
1841 }
1842 else
1843 ++m_nLoops;
1844 }
1845 else
1846 {
1847 m_playlist->SetItem(m_nLastFileId, 0, wxT("[]"));
1848 }
1849 }
1850
1851 //
1852 // End of MediaPlayer sample
1853 //