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