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