]> git.saurik.com Git - wxWidgets.git/blame - samples/mediaplayer/mediaplayer.cpp
Fix for listbox problem, when created on invisible
[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//
226ec5a7 15// This is a simple example of how to use all the funtionality of
ff4aedc5
RN
16// the wxMediaCtrl class in wxWidgets.
17//
18// To use this sample, simply select Open File from the file menu,
19// select the file you want to play - and MediaPlayer will play the file,
20// showing video if neccessary.
21//
22// You can select one of the menu options, or move the slider around
23// to manipulate what is playing.
24// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
eaf0d558
RN
25
26// ============================================================================
ff4aedc5 27// Definitions
eaf0d558
RN
28// ============================================================================
29
30// ----------------------------------------------------------------------------
ff4aedc5 31// Pre-compiled header stuff
eaf0d558
RN
32// ----------------------------------------------------------------------------
33
eaf0d558
RN
34#include "wx/wxprec.h"
35
36#ifdef __BORLANDC__
37 #pragma hdrstop
38#endif
39
eaf0d558
RN
40#ifndef WX_PRECOMP
41 #include "wx/wx.h"
42#endif
43
44// ----------------------------------------------------------------------------
ff4aedc5 45// Headers
eaf0d558
RN
46// ----------------------------------------------------------------------------
47
d0b9eaa2
RN
48#include "wx/mediactrl.h" //for wxMediaCtrl
49#include "wx/filedlg.h" //for opening files from OpenFile
50#include "wx/slider.h" //for a slider for seeking within media
51#include "wx/sizer.h" //for positioning controls/wxBoxSizer
52#include "wx/timer.h" //timer for updating status bar
53#include "wx/textdlg.h" //for getting user text from OpenURL
eaf0d558 54
ff4aedc5 55// ----------------------------------------------------------------------------
226ec5a7 56// Bail out if the user doesn't want one of the
ff4aedc5
RN
57// things we need
58// ----------------------------------------------------------------------------
eaf0d558 59
ff4aedc5
RN
60#if !wxUSE_GUI
61#error "This is a GUI sample"
eaf0d558
RN
62#endif
63
ff4aedc5
RN
64#if !wxUSE_MEDIACTRL || !wxUSE_MENUS || !wxUSE_SLIDER || !wxUSE_TIMER
65#error "menus, slider, mediactrl, and timers must all enabled for this sample!"
66#endif
67
68// ============================================================================
d0b9eaa2 69// Declarations
ff4aedc5
RN
70// ============================================================================
71
72// ----------------------------------------------------------------------------
73// Enumurations
74// ----------------------------------------------------------------------------
75
76// IDs for the controls and the menu commands
77enum
78{
79 // menu items
80 wxID_LOOP = 1,
81 wxID_OPENFILE,
82 wxID_PLAY,
83 wxID_PAUSE,
84// wxID_STOP, [built-in to wxWidgets]
85// wxID_ABOUT, [built-in to wxWidgets]
86// wxID_EXIT, [built-in to wxWidgets]
87
88 // id for our slider
89 wxID_SLIDER,
90
91 // id for our wxMediaCtrl
92 wxID_MEDIACTRL
93};
94
95// ----------------------------------------------------------------------------
96// MyApp
eaf0d558
RN
97// ----------------------------------------------------------------------------
98
eaf0d558
RN
99class MyApp : public wxApp
100{
101public:
eaf0d558
RN
102 virtual bool OnInit();
103};
104
ff4aedc5
RN
105// ----------------------------------------------------------------------------
106// MyFrame
107// ----------------------------------------------------------------------------
108
eaf0d558
RN
109class MyFrame : public wxFrame
110{
111public:
ff4aedc5 112 // Ctor/Dtor
eaf0d558
RN
113 MyFrame(const wxString& title);
114 ~MyFrame();
115
ff4aedc5 116 // Menu event handlers
eaf0d558
RN
117 void OnQuit(wxCommandEvent& event);
118 void OnAbout(wxCommandEvent& event);
119 void OnLoop(wxCommandEvent& event);
120
121 void OnOpenFile(wxCommandEvent& event);
122 void OnOpenURL(wxCommandEvent& event);
123
124 void OnPlay(wxCommandEvent& event);
125 void OnPause(wxCommandEvent& event);
126 void OnStop(wxCommandEvent& event);
127
ff4aedc5 128 // Slider event handlers
eaf0d558
RN
129 void OnSeek(wxCommandEvent& event);
130
ff4aedc5
RN
131 // Media event handlers
132 void OnMediaStop(wxMediaEvent& event);
eaf0d558
RN
133
134private:
ff4aedc5 135 // Rebuild base status string (see Implementation)
d0b9eaa2
RN
136 void ResetStatus();
137
ff4aedc5
RN
138 wxMediaCtrl* m_mediactrl; //Our media control
139 wxSlider* m_slider; //The slider below our media control
140 class MyTimer* m_timer; //Timer to write info to status bar
141 wxString m_basestatus; //Base status string (see ResetStatus())
142 int m_nLoops; //Counter, incremented each time media loops
143
144 // So that mytimer can access MyFrame's members
eaf0d558 145 friend class MyTimer;
ff4aedc5 146};
eaf0d558 147
ff4aedc5
RN
148// ----------------------------------------------------------------------------
149// MyTimer
150// ----------------------------------------------------------------------------
151
152class MyTimer : public wxTimer
153{
154public:
155 //Ctor
156 MyTimer(MyFrame* frame) {m_frame = frame;}
eaf0d558 157
ff4aedc5
RN
158 //Called each time the timer's timeout expires
159 void Notify();
160
161 MyFrame* m_frame; //The MyFrame
eaf0d558
RN
162};
163
ff4aedc5 164// ============================================================================
d0b9eaa2 165//
ff4aedc5 166// Implementation
d0b9eaa2 167//
ff4aedc5 168// ============================================================================
d0b9eaa2 169
ff4aedc5
RN
170// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
171//
172// [Functions]
d0b9eaa2 173//
ff4aedc5
RN
174// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
175
176// ----------------------------------------------------------------------------
177// wxGetMediaStateText
d0b9eaa2 178//
ff4aedc5
RN
179// Converts a wxMediaCtrl state into something useful that we can display
180// to the user
181// ----------------------------------------------------------------------------
eaf0d558
RN
182const wxChar* wxGetMediaStateText(int nState)
183{
184 switch(nState)
185 {
186 case wxMEDIASTATE_PLAYING:
187 return wxT("Playing");
188 case wxMEDIASTATE_STOPPED:
189 return wxT("Stopped");
190 ///case wxMEDIASTATE_PAUSED:
191 default:
192 return wxT("Paused");
193 }
194}
195
ff4aedc5
RN
196// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
197//
198// MyApp
199//
200// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
eaf0d558
RN
201
202// ----------------------------------------------------------------------------
ff4aedc5
RN
203// This sets up this wxApp as the global wxApp that gui calls in wxWidgets
204// use. For example, if you were to be in windows and use a file dialog,
205// wxWidgets would use wxTheApp->GetHInstance() which would get the instance
206// handle of the application. These routines in wx _DO NOT_ check to see if
207// the wxApp exists, and thus will crash the application if you try it.
208//
209// IMPLEMENT_APP does this, and also implements the platform-specific entry
226ec5a7 210// routine, such as main or WinMain(). Use IMPLEMENT_APP_NO_MAIN if you do
ff4aedc5 211// not desire this behavior.
eaf0d558 212// ----------------------------------------------------------------------------
eaf0d558
RN
213IMPLEMENT_APP(MyApp)
214
eaf0d558
RN
215
216// ----------------------------------------------------------------------------
ff4aedc5
RN
217// MyApp::OnInit
218//
219// Where execution starts - akin to a main or WinMain.
220// 1) Create the frame and show it to the user
221// 2) return true specifying that we want execution to continue past OnInit
eaf0d558 222// ----------------------------------------------------------------------------
eaf0d558
RN
223bool MyApp::OnInit()
224{
ff4aedc5 225 MyFrame *frame = new MyFrame(_T("MediaPlayer wxWidgets Sample"));
eaf0d558
RN
226 frame->Show(true);
227
eaf0d558
RN
228 return true;
229}
230
eaf0d558 231
ff4aedc5
RN
232// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
233//
234// MyFrame
d0b9eaa2 235//
ff4aedc5
RN
236// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
237
238// ----------------------------------------------------------------------------
239// MyFrame Constructor
d0b9eaa2 240//
ff4aedc5
RN
241// 1) Create our menus
242// 2) Create our controls and add them to some sizers
243// 3) Create our status bar
244// 4) Connect our events
245// 5) Start our timer
246// ----------------------------------------------------------------------------
9180b535 247
eaf0d558 248MyFrame::MyFrame(const wxString& title)
ff4aedc5 249 : wxFrame(NULL, wxID_ANY, title)
eaf0d558 250{
d0b9eaa2
RN
251 //
252 // Create Menus
253 //
eaf0d558
RN
254 wxMenu *menuFile = new wxMenu;
255
eaf0d558 256 wxMenu *helpMenu = new wxMenu;
226ec5a7
WS
257 helpMenu->Append(wxID_ABOUT,
258 _T("&About...\tF1"),
ff4aedc5 259 _T("Show about dialog"));
eaf0d558 260
ff4aedc5 261 menuFile->Append(wxID_OPENFILE, _T("&Open File"), _T("Open a File"));
eaf0d558 262 menuFile->AppendSeparator();
ff4aedc5
RN
263 menuFile->Append(wxID_PLAY, _T("&Play"), _T("Resume playback"));
264 menuFile->Append(wxID_PAUSE, _T("P&ause"), _T("Pause playback"));
265 menuFile->Append(wxID_STOP, _T("&Stop"), _T("Stop playback"));
eaf0d558 266 menuFile->AppendSeparator();
226ec5a7
WS
267 menuFile->AppendCheckItem(wxID_LOOP,
268 _T("&Loop"),
ff4aedc5 269 _T("Loop Selected Media"));
eaf0d558 270 menuFile->AppendSeparator();
226ec5a7
WS
271 menuFile->Append(wxID_EXIT,
272 _T("E&xit\tAlt-X"),
ff4aedc5 273 _T("Quit this program"));
eaf0d558 274
eaf0d558
RN
275 wxMenuBar *menuBar = new wxMenuBar();
276 menuBar->Append(menuFile, _T("&File"));
277 menuBar->Append(helpMenu, _T("&Help"));
278
eaf0d558 279 SetMenuBar(menuBar);
eaf0d558 280
d0b9eaa2
RN
281 //
282 // Create and attach the first/main sizer
283 //
ff4aedc5
RN
284 wxBoxSizer* vertsizer = new wxBoxSizer(wxVERTICAL);
285 this->SetSizer(vertsizer);
eaf0d558
RN
286 this->SetAutoLayout(true);
287
d0b9eaa2
RN
288 //
289 // Create our media control
290 //
ff4aedc5
RN
291 m_mediactrl = new wxMediaCtrl(this, wxID_MEDIACTRL);
292 vertsizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
d0b9eaa2
RN
293
294 //
295 // Create our slider
296 //
ff4aedc5 297 m_slider = new wxSlider(this, wxID_SLIDER, 0, //init
ceefc965
WS
298 0, //start
299 0, //end
300 wxDefaultPosition, wxDefaultSize,
eaf0d558 301 wxSL_HORIZONTAL );
ff4aedc5 302 vertsizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5);
eaf0d558 303
d0b9eaa2
RN
304
305 //
306 // Create the second sizer which will position things
ceefc965 307 // vertically -
d0b9eaa2
RN
308 //
309 // -------Menu----------
310 // [m_mediactrl]
311 //
312 // [m_slider]
313 //
eaf0d558 314 wxBoxSizer* horzsizer = new wxBoxSizer(wxHORIZONTAL);
ff4aedc5 315 vertsizer->Add(horzsizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5);
eaf0d558 316
d0b9eaa2
RN
317 //
318 // Create our status bar
319 //
eaf0d558
RN
320#if wxUSE_STATUSBAR
321 // create a status bar just for fun (by default with 1 pane only)
322 CreateStatusBar(1);
323 ResetStatus();
324 SetStatusText(m_basestatus);
325#endif // wxUSE_STATUSBAR
226ec5a7 326
ff4aedc5
RN
327 //
328 // Connect events.
226ec5a7 329 //
ff4aedc5
RN
330 // There are two ways in wxWidgets to use events -
331 // Message Maps and Connections.
332 //
333 // Message Maps are implemented by putting
334 // DECLARE_MESSAGE_MAP in your wxEvtHandler-derived
335 // class you want to use for events, such as MyFrame.
336 //
337 // Then after your class declaration you put
338 // BEGIN_EVENT_TABLE(MyFrame, wxFrame)
339 // EVT_XXX(XXX)...
340 // END_EVENT_TABLE()
341 //
342 // Where MyFrame is the class with the DECLARE_MESSAGE_MAP
226ec5a7 343 // in it. EVT_XXX(XXX) are each of your handlers, such
ff4aedc5
RN
344 // as EVT_MENU for menu events and the XXX inside
345 // is the parameters to the event macro - in the case
346 // of EVT_MENU the menu id and then the function to call.
347 //
348 // However, with wxEvtHandler::Connect you can avoid a
349 // global message map for your class and those annoying
350 // macros. You can also change the context in which
351 // the call the handler (more later).
352 //
353 // The downside is that due to the limitation that
354 // wxWidgets doesn't use templates in certain areas,
355 // You have to triple-cast the event function.
356 //
357 // There are five parameters to wxEvtHandler::Connect -
358 //
359 // The first is the id of the instance whose events
360 // you want to handle - i.e. a menu id for menus,
361 // a control id for controls (wxControl::GetId())
362 // and so on.
363 //
364 // The second is the event id. This is the same
365 // as the message maps (EVT_MENU) except prefixed
366 // with "wx" (wxEVT_MENU).
367 //
368 // The third is the function handler for the event -
369 // You need to cast it to the specific event handler
226ec5a7 370 // type, then to a wxEventFunction, then to a
ff4aedc5
RN
371 // wxObjectEventFunction - I.E.
372 // (wxObjectEventFunction)(wxEventFunction)
373 // (wxCommandEventFunction) &MyFrame::MyHandler
374 //
226ec5a7 375 // The fourth is an optional userdata param -
ff4aedc5
RN
376 // this is of historical relevance only and is
377 // there only for backwards compatability.
378 //
379 // The fifth is the context in which to call the
380 // handler - by default (this param is optional)
381 // this. For example in your event handler
226ec5a7 382 // if you were to call "this->MyFunc()"
ff4aedc5
RN
383 // it would literally do this->MyFunc. However,
384 // if you were to pass myHandler as the fifth
385 // parameter, for instance, you would _really_
386 // be calling myHandler->MyFunc, even though
387 // the compiler doesn't really know it.
388 //
d0b9eaa2
RN
389
390 //
ff4aedc5 391 // Menu events
d0b9eaa2 392 //
226ec5a7
WS
393 this->Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
394 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5 395 (wxCommandEventFunction) &MyFrame::OnQuit);
226ec5a7
WS
396
397 this->Connect(wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED,
398 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5
RN
399 (wxCommandEventFunction) &MyFrame::OnAbout);
400
226ec5a7
WS
401 this->Connect(wxID_LOOP, wxEVT_COMMAND_MENU_SELECTED,
402 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5
RN
403 (wxCommandEventFunction) &MyFrame::OnLoop);
404
226ec5a7
WS
405 this->Connect(wxID_OPENFILE, wxEVT_COMMAND_MENU_SELECTED,
406 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5 407 (wxCommandEventFunction) &MyFrame::OnOpenFile);
d0b9eaa2 408
226ec5a7
WS
409 this->Connect(wxID_PLAY, wxEVT_COMMAND_MENU_SELECTED,
410 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5
RN
411 (wxCommandEventFunction) &MyFrame::OnPlay);
412
226ec5a7
WS
413 this->Connect(wxID_PAUSE, wxEVT_COMMAND_MENU_SELECTED,
414 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5
RN
415 (wxCommandEventFunction) &MyFrame::OnPause);
416
226ec5a7
WS
417 this->Connect(wxID_STOP, wxEVT_COMMAND_MENU_SELECTED,
418 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5
RN
419 (wxCommandEventFunction) &MyFrame::OnStop);
420
421
422 //
423 // Slider events
424 //
226ec5a7
WS
425 this->Connect(wxID_SLIDER, wxEVT_COMMAND_SLIDER_UPDATED,
426 (wxObjectEventFunction) (wxEventFunction)
ff4aedc5
RN
427 (wxCommandEventFunction) &MyFrame::OnSeek);
428
429 //
430 // Media Control events
431 //
226ec5a7
WS
432 this->Connect(wxID_MEDIACTRL, wxEVT_MEDIA_STOP,
433 (wxObjectEventFunction) (wxEventFunction)
434 (wxMediaEventFunction) &MyFrame::OnMediaStop);
ff4aedc5
RN
435
436 //
437 // End of Events
438 //
439
440 //
441 // Set our loop counter to 0
442 //
443 m_nLoops = 0;
444
445 //
446 // Create a timer to update our status bar
447 //
d0b9eaa2
RN
448 m_timer = new MyTimer(this);
449 m_timer->Start(100);
eaf0d558
RN
450}
451
ff4aedc5
RN
452// ----------------------------------------------------------------------------
453// MyFrame Destructor
d0b9eaa2 454//
226ec5a7 455// 1) Deletes child objects implicitly
ff4aedc5
RN
456// 2) Delete our timer explicitly
457// ----------------------------------------------------------------------------
eaf0d558
RN
458MyFrame::~MyFrame()
459{
d0b9eaa2 460 delete m_timer;
eaf0d558
RN
461}
462
ff4aedc5
RN
463// ----------------------------------------------------------------------------
464// MyFrame::ResetStatus
465//
226ec5a7 466// Here we just make a simple status string with some useful info about
ff4aedc5
RN
467// the media that we won't change later - such as the length of the media.
468//
469// We then append some other info that changes in MyTimer::Notify, then
226ec5a7 470// set the status bar to this text.
d0b9eaa2 471//
ff4aedc5
RN
472// In real applications, you'd want to find a better way to do this,
473// such as static text controls (wxStaticText).
226ec5a7
WS
474//
475// We display info here in seconds (wxMediaCtrl uses milliseconds - that's why
ff4aedc5
RN
476// we divide by 1000).
477//
478// We also reset our loop counter here.
479// ----------------------------------------------------------------------------
480void MyFrame::ResetStatus()
481{
482 m_basestatus = wxString::Format(_T("Size(x,y):%i,%i ")
483 _T("Length(Seconds):%u Speed:%1.1fx"),
484 m_mediactrl->GetBestSize().x,
485 m_mediactrl->GetBestSize().y,
9180b535 486 (unsigned)((m_mediactrl->Length() / 1000)),
ff4aedc5
RN
487 m_mediactrl->GetPlaybackRate()
488 );
489
bbd030cd 490 m_slider->SetRange(0, (int)(m_mediactrl->Length() / 1000));
ff4aedc5
RN
491
492 m_nLoops = 0;
493}
494
495// ----------------------------------------------------------------------------
496// MyFrame::OnQuit
d0b9eaa2 497//
ff4aedc5
RN
498// Called from file->quit.
499// Closes this application.
500// ----------------------------------------------------------------------------
eaf0d558
RN
501void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
502{
503 // true is to force the frame to close
504 Close(true);
505}
506
ff4aedc5
RN
507// ----------------------------------------------------------------------------
508// MyFrame::OnAbout
226ec5a7 509//
ff4aedc5
RN
510// Called from help->about.
511// Gets some info about this application.
512// ----------------------------------------------------------------------------
eaf0d558
RN
513void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
514{
515 wxString msg;
516 msg.Printf( _T("This is a test of wxMediaCtrl.\n")
517 _T("Welcome to %s"), wxVERSION_STRING);
518
519 wxMessageBox(msg, _T("About wxMediaCtrl test"), wxOK | wxICON_INFORMATION, this);
520}
521
ff4aedc5
RN
522// ----------------------------------------------------------------------------
523// MyFrame::OnLoop
d0b9eaa2 524//
ff4aedc5
RN
525// Called from file->loop.
526// Changes the state of whether we want to loop or not.
527// ----------------------------------------------------------------------------
eaf0d558
RN
528void MyFrame::OnLoop(wxCommandEvent& WXUNUSED(event))
529{
ff4aedc5 530 m_mediactrl->Loop( !m_mediactrl->IsLooped() );
eaf0d558
RN
531}
532
ff4aedc5
RN
533// ----------------------------------------------------------------------------
534// MyFrame::OnOpenFile
d0b9eaa2 535//
ff4aedc5
RN
536// Called from file->openfile.
537// Opens and plays a media file
538// ----------------------------------------------------------------------------
eaf0d558
RN
539void MyFrame::OnOpenFile(wxCommandEvent& WXUNUSED(event))
540{
541 wxFileDialog fd(this);
542
543 if(fd.ShowModal() == wxID_OK)
544 {
d0b9eaa2 545 if( !m_mediactrl->Load(fd.GetPath()) )
eaf0d558
RN
546 wxMessageBox(wxT("Couldn't load file!"));
547
d0b9eaa2 548 if( !m_mediactrl->Play() )
ceefc965
WS
549 wxMessageBox(wxT("Couldn't play movie!"));
550
eaf0d558
RN
551 ResetStatus();
552 }
553}
554
ff4aedc5
RN
555// ----------------------------------------------------------------------------
556// MyFrame::OnPlay
226ec5a7 557//
ff4aedc5
RN
558// Called from file->play.
559// Resumes the media if it is paused or stopped.
560// ----------------------------------------------------------------------------
eaf0d558
RN
561void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
562{
d0b9eaa2 563 if( !m_mediactrl->Play() )
eaf0d558
RN
564 wxMessageBox(wxT("Couldn't play movie!"));
565}
566
ff4aedc5
RN
567// ----------------------------------------------------------------------------
568// MyFrame::OnPause
226ec5a7 569//
ff4aedc5
RN
570// Called from file->pause.
571// Pauses the media in-place.
572// ----------------------------------------------------------------------------
eaf0d558
RN
573void MyFrame::OnPause(wxCommandEvent& WXUNUSED(event))
574{
d0b9eaa2 575 if( !m_mediactrl->Pause() )
eaf0d558
RN
576 wxMessageBox(wxT("Couldn't pause movie!"));
577}
578
ff4aedc5
RN
579// ----------------------------------------------------------------------------
580// MyFrame::OnStop
226ec5a7 581//
ff4aedc5
RN
582// Called from file->stop.
583// Where it stops depends on whether you can seek in the
584// media control or not - if you can it stops and seeks to the beginning,
585// otherwise it will appear to be at the end - but it will start over again
586// when Play() is called
587// ----------------------------------------------------------------------------
eaf0d558
RN
588void MyFrame::OnStop(wxCommandEvent& WXUNUSED(event))
589{
d0b9eaa2 590 if( !m_mediactrl->Stop() )
eaf0d558
RN
591 wxMessageBox(wxT("Couldn't stop movie!"));
592}
593
ff4aedc5
RN
594// ----------------------------------------------------------------------------
595// MyFrame::OnSeek
226ec5a7 596//
ff4aedc5
RN
597// Called from file->seek.
598// Called when the user moves the slider -
599// seeks to a position within the media
600// ----------------------------------------------------------------------------
eaf0d558
RN
601void MyFrame::OnSeek(wxCommandEvent& WXUNUSED(event))
602{
9180b535 603 if( m_mediactrl->Seek( m_slider->GetValue() * 1000 ) == wxInvalidOffset )
eaf0d558
RN
604 wxMessageBox(wxT("Couldn't seek in movie!"));
605}
606
ff4aedc5
RN
607// ----------------------------------------------------------------------------
608// MyFrame::OnMediaStop
226ec5a7 609//
ff4aedc5
RN
610// Called when the media is about to stop playing.
611// Here we just increase our loop counter
612// ----------------------------------------------------------------------------
613void MyFrame::OnMediaStop(wxMediaEvent& WXUNUSED(event))
614{
615 ++m_nLoops;
616}
617
618// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
d0b9eaa2 619//
ff4aedc5 620// MyTimer
d0b9eaa2 621//
ff4aedc5
RN
622// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
623
624// ----------------------------------------------------------------------------
625// MyTimer::Notify
626//
627// 1) Update our slider with the position were are in in the media
628// 2) Update our status bar with the base text from MyFrame::ResetStatus,
226ec5a7 629// append some non-static (changing) info to it, then set the
ff4aedc5
RN
630// status bar text to that result
631// ----------------------------------------------------------------------------
632void MyTimer::Notify()
eaf0d558 633{
bbd030cd 634 long lPosition = (long)( m_frame->m_mediactrl->Tell() / 1000 );
ff4aedc5
RN
635 m_frame->m_slider->SetValue(lPosition);
636
637#if wxUSE_STATUSBAR
638 m_frame->SetStatusText(wxString::Format(
639 _T("%s Pos:%u State:%s Loops:%i"),
640 m_frame->m_basestatus.c_str(),
641 (unsigned int)lPosition,
642 wxGetMediaStateText(m_frame->m_mediactrl->GetState()),
643 m_frame->m_nLoops
644 )
645 );
646#endif
ceefc965 647}
ff4aedc5
RN
648
649//
650// End of MediaPlayer sample
651//