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