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