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