]>
Commit | Line | Data |
---|---|---|
eaf0d558 | 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 | |
10 | ///////////////////////////////////////////////////////////////////////////// | |
11 | ||
12 | // ============================================================================ | |
13 | // declarations | |
14 | // ============================================================================ | |
15 | ||
16 | // ---------------------------------------------------------------------------- | |
17 | // headers | |
18 | // ---------------------------------------------------------------------------- | |
19 | ||
eaf0d558 RN |
20 | #include "wx/wxprec.h" |
21 | ||
22 | #ifdef __BORLANDC__ | |
23 | #pragma hdrstop | |
24 | #endif | |
25 | ||
eaf0d558 RN |
26 | #ifndef WX_PRECOMP |
27 | #include "wx/wx.h" | |
28 | #endif | |
29 | ||
30 | // ---------------------------------------------------------------------------- | |
31 | // resources | |
32 | // ---------------------------------------------------------------------------- | |
33 | ||
d0b9eaa2 RN |
34 | #include "wx/mediactrl.h" //for wxMediaCtrl |
35 | #include "wx/filedlg.h" //for opening files from OpenFile | |
36 | #include "wx/slider.h" //for a slider for seeking within media | |
37 | #include "wx/sizer.h" //for positioning controls/wxBoxSizer | |
38 | #include "wx/timer.h" //timer for updating status bar | |
39 | #include "wx/textdlg.h" //for getting user text from OpenURL | |
eaf0d558 RN |
40 | |
41 | ||
42 | #if !wxUSE_MEDIACTRL | |
43 | #error "wxUSE_MEDIACTRL must be enabled to use this sample!" | |
44 | #endif | |
45 | ||
46 | // ---------------------------------------------------------------------------- | |
d0b9eaa2 | 47 | // Declarations |
eaf0d558 RN |
48 | // ---------------------------------------------------------------------------- |
49 | ||
eaf0d558 RN |
50 | class MyApp : public wxApp |
51 | { | |
52 | public: | |
eaf0d558 RN |
53 | virtual bool OnInit(); |
54 | }; | |
55 | ||
eaf0d558 RN |
56 | class MyFrame : public wxFrame |
57 | { | |
58 | public: | |
59 | // ctor(s) | |
60 | MyFrame(const wxString& title); | |
61 | ~MyFrame(); | |
62 | ||
63 | // event handlers (these functions should _not_ be virtual) | |
64 | void OnQuit(wxCommandEvent& event); | |
65 | void OnAbout(wxCommandEvent& event); | |
66 | void OnLoop(wxCommandEvent& event); | |
67 | ||
68 | void OnOpenFile(wxCommandEvent& event); | |
69 | void OnOpenURL(wxCommandEvent& event); | |
70 | ||
71 | void OnPlay(wxCommandEvent& event); | |
72 | void OnPause(wxCommandEvent& event); | |
73 | void OnStop(wxCommandEvent& event); | |
74 | ||
75 | void OnSeek(wxCommandEvent& event); | |
76 | ||
77 | void OnMediaFinished(wxMediaEvent& event); | |
78 | ||
79 | private: | |
d0b9eaa2 RN |
80 | void ResetStatus(); |
81 | ||
82 | wxMediaCtrl* m_mediactrl; | |
eaf0d558 RN |
83 | wxSlider* m_slider; |
84 | wxBoxSizer* m_sizer; | |
85 | class MyTimer* m_timer; | |
86 | friend class MyTimer; | |
87 | wxString m_basestatus; | |
88 | ||
89 | bool m_bLoop; | |
90 | ||
91 | // any class wishing to process wxWidgets events must use this macro | |
92 | DECLARE_EVENT_TABLE() | |
93 | }; | |
94 | ||
d0b9eaa2 RN |
95 | // |
96 | //ResetStatus | |
97 | //----------- | |
98 | //Here we just make a simple status string | |
99 | //with some useful info about the media | |
100 | //We display info here in seconds (wxMediaCtrl | |
101 | //uses milliseconds - that's why we divide by 1000) | |
102 | // | |
103 | void MyFrame::ResetStatus() | |
104 | { | |
105 | m_basestatus = wxString::Format(_T("Size(x,y):%i,%i Length(Seconds):%u Speed:%1.1fx"), | |
106 | m_mediactrl->GetBestSize().x, | |
107 | m_mediactrl->GetBestSize().y, | |
108 | m_mediactrl->GetDuration() / 1000, | |
109 | m_mediactrl->GetPlaybackRate() | |
110 | ); | |
111 | ||
112 | m_slider->SetRange(0, m_mediactrl->GetDuration() / 1000); | |
113 | } | |
114 | ||
115 | // | |
116 | //wxGetMediaStateText | |
117 | //------------------- | |
118 | //Converts a wxMediaCtrl state into something | |
119 | //useful that we can display | |
120 | // | |
eaf0d558 RN |
121 | const wxChar* wxGetMediaStateText(int nState) |
122 | { | |
123 | switch(nState) | |
124 | { | |
125 | case wxMEDIASTATE_PLAYING: | |
126 | return wxT("Playing"); | |
127 | case wxMEDIASTATE_STOPPED: | |
128 | return wxT("Stopped"); | |
129 | ///case wxMEDIASTATE_PAUSED: | |
130 | default: | |
131 | return wxT("Paused"); | |
132 | } | |
133 | } | |
134 | ||
135 | class MyTimer : public wxTimer | |
136 | { | |
137 | public: | |
138 | MyTimer(MyFrame* frame) {m_frame = frame;} | |
139 | ||
d0b9eaa2 RN |
140 | // |
141 | //Notify | |
142 | //----------- | |
143 | //Updates the main frame's status bar with the current | |
144 | //position within the media and state the media is in | |
145 | // | |
eaf0d558 RN |
146 | void Notify() |
147 | { | |
d0b9eaa2 | 148 | long lPosition = m_frame->m_mediactrl->GetPosition() / 1000; |
eaf0d558 RN |
149 | m_frame->m_slider->SetValue(lPosition); |
150 | ||
151 | ||
152 | m_frame->SetStatusText(wxString::Format(_T("%s Pos:%u State:%s"), | |
153 | m_frame->m_basestatus.c_str(), | |
154 | lPosition, | |
d0b9eaa2 | 155 | wxGetMediaStateText(m_frame->m_mediactrl->GetState()) |
eaf0d558 RN |
156 | ) |
157 | ); | |
158 | ||
159 | } | |
160 | ||
161 | MyFrame* m_frame; | |
162 | }; | |
163 | ||
164 | ||
165 | // ---------------------------------------------------------------------------- | |
166 | // constants | |
167 | // ---------------------------------------------------------------------------- | |
168 | ||
169 | // IDs for the controls and the menu commands | |
170 | enum | |
171 | { | |
172 | // menu items | |
173 | Minimal_Quit = wxID_EXIT, | |
eaf0d558 RN |
174 | Minimal_Loop, |
175 | Minimal_OpenFile, | |
eaf0d558 RN |
176 | Minimal_Play, |
177 | Minimal_Pause, | |
d0b9eaa2 RN |
178 | Minimal_Stop, |
179 | Minimal_About = wxID_ABOUT, | |
180 | ||
181 | // id for our slider | |
182 | Minimal_Slider = 1, | |
183 | ||
184 | // id for our wxMediaCtrl | |
185 | Minimal_Media | |
eaf0d558 RN |
186 | }; |
187 | ||
188 | // ---------------------------------------------------------------------------- | |
189 | // event tables and other macros for wxWidgets | |
190 | // ---------------------------------------------------------------------------- | |
191 | ||
eaf0d558 | 192 | BEGIN_EVENT_TABLE(MyFrame, wxFrame) |
d0b9eaa2 | 193 | //Menu events |
eaf0d558 RN |
194 | EVT_MENU(Minimal_Quit, MyFrame::OnQuit) |
195 | EVT_MENU(Minimal_About, MyFrame::OnAbout) | |
196 | EVT_MENU(Minimal_Loop, MyFrame::OnLoop) | |
197 | EVT_MENU(Minimal_OpenFile, MyFrame::OnOpenFile) | |
eaf0d558 RN |
198 | EVT_MENU(Minimal_Play, MyFrame::OnPlay) |
199 | EVT_MENU(Minimal_Pause, MyFrame::OnPause) | |
200 | EVT_MENU(Minimal_Stop, MyFrame::OnStop) | |
d0b9eaa2 RN |
201 | |
202 | //Slider events | |
eaf0d558 | 203 | EVT_SLIDER(Minimal_Slider, MyFrame::OnSeek) |
d0b9eaa2 RN |
204 | |
205 | //wxMediaCtrl events | |
eaf0d558 RN |
206 | EVT_MEDIA_FINISHED(Minimal_Media, MyFrame::OnMediaFinished) |
207 | END_EVENT_TABLE() | |
208 | ||
d0b9eaa2 | 209 | //main/WinMain() |
eaf0d558 RN |
210 | IMPLEMENT_APP(MyApp) |
211 | ||
212 | // ============================================================================ | |
213 | // implementation | |
214 | // ============================================================================ | |
215 | ||
216 | // ---------------------------------------------------------------------------- | |
d0b9eaa2 | 217 | // MyApp |
eaf0d558 RN |
218 | // ---------------------------------------------------------------------------- |
219 | ||
220 | // 'Main program' equivalent: the program execution "starts" here | |
221 | bool MyApp::OnInit() | |
222 | { | |
eaf0d558 | 223 | MyFrame *frame = new MyFrame(_T("Minimal wxWidgets App")); |
eaf0d558 RN |
224 | frame->Show(true); |
225 | ||
eaf0d558 RN |
226 | return true; |
227 | } | |
228 | ||
229 | // ---------------------------------------------------------------------------- | |
230 | // main frame | |
231 | // ---------------------------------------------------------------------------- | |
232 | ||
d0b9eaa2 RN |
233 | // |
234 | //MyFrame | |
235 | //------- | |
236 | //Creates our menus and controls | |
237 | // | |
eaf0d558 RN |
238 | MyFrame::MyFrame(const wxString& title) |
239 | : wxFrame(NULL, wxID_ANY, title), m_timer(NULL) | |
240 | { | |
d0b9eaa2 RN |
241 | // |
242 | // Create Menus | |
243 | // | |
eaf0d558 | 244 | #if wxUSE_MENUS |
eaf0d558 RN |
245 | wxMenu *menuFile = new wxMenu; |
246 | ||
eaf0d558 RN |
247 | wxMenu *helpMenu = new wxMenu; |
248 | helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog")); | |
249 | ||
250 | menuFile->Append(Minimal_OpenFile, _T("&Open File"), _T("Open a File")); | |
eaf0d558 RN |
251 | menuFile->AppendSeparator(); |
252 | menuFile->Append(Minimal_Play, _T("&Play"), _T("Resume playback")); | |
253 | menuFile->Append(Minimal_Pause, _T("P&ause"), _T("Pause playback")); | |
254 | menuFile->Append(Minimal_Stop, _T("&Stop"), _T("Stop playback")); | |
255 | menuFile->AppendSeparator(); | |
256 | menuFile->AppendCheckItem(Minimal_Loop, _T("&Loop"), _T("Loop Selected Media")); | |
257 | menuFile->AppendSeparator(); | |
258 | menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); | |
259 | ||
eaf0d558 RN |
260 | wxMenuBar *menuBar = new wxMenuBar(); |
261 | menuBar->Append(menuFile, _T("&File")); | |
262 | menuBar->Append(helpMenu, _T("&Help")); | |
263 | ||
eaf0d558 RN |
264 | SetMenuBar(menuBar); |
265 | #endif // wxUSE_MENUS | |
266 | ||
d0b9eaa2 RN |
267 | // |
268 | // Create and attach the first/main sizer | |
269 | // | |
270 | ||
eaf0d558 RN |
271 | m_sizer = new wxBoxSizer(wxVERTICAL); |
272 | this->SetSizer(m_sizer); | |
273 | this->SetAutoLayout(true); | |
274 | ||
d0b9eaa2 RN |
275 | // |
276 | // Create our media control | |
277 | // | |
278 | ||
279 | m_mediactrl = new wxMediaCtrl(this, Minimal_Media, wxT("")); | |
280 | m_sizer->Add(m_mediactrl, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); | |
281 | ||
282 | // | |
283 | // Create our slider | |
284 | // | |
eaf0d558 RN |
285 | |
286 | m_slider = new wxSlider(this, Minimal_Slider, 0, //init | |
287 | 0, //start | |
288 | 0, //end | |
289 | wxDefaultPosition, wxDefaultSize, | |
290 | wxSL_HORIZONTAL ); | |
291 | m_sizer->Add(m_slider, 0, wxALIGN_CENTER_HORIZONTAL|wxALL|wxEXPAND , 5); | |
292 | ||
d0b9eaa2 RN |
293 | |
294 | // | |
295 | // Create the second sizer which will position things | |
296 | // vertically - | |
297 | // | |
298 | // -------Menu---------- | |
299 | // [m_mediactrl] | |
300 | // | |
301 | // [m_slider] | |
302 | // | |
303 | ||
eaf0d558 RN |
304 | wxBoxSizer* horzsizer = new wxBoxSizer(wxHORIZONTAL); |
305 | m_sizer->Add(horzsizer, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); | |
306 | ||
d0b9eaa2 RN |
307 | // |
308 | // We arn't looping initially | |
309 | // | |
eaf0d558 | 310 | |
d0b9eaa2 | 311 | m_bLoop = false; |
eaf0d558 | 312 | |
d0b9eaa2 RN |
313 | // |
314 | // Create our status bar | |
315 | // | |
eaf0d558 RN |
316 | #if wxUSE_STATUSBAR |
317 | // create a status bar just for fun (by default with 1 pane only) | |
318 | CreateStatusBar(1); | |
319 | ResetStatus(); | |
320 | SetStatusText(m_basestatus); | |
321 | #endif // wxUSE_STATUSBAR | |
d0b9eaa2 RN |
322 | |
323 | // | |
324 | // Create a timer to update our status bar | |
325 | // | |
326 | ||
327 | m_timer = new MyTimer(this); | |
328 | m_timer->Start(100); | |
eaf0d558 RN |
329 | } |
330 | ||
d0b9eaa2 RN |
331 | // |
332 | //~MyFrame | |
e4b12a53 | 333 | //-------- |
d0b9eaa2 RN |
334 | //Deletes child objects implicitly and our timer explicitly |
335 | // | |
eaf0d558 RN |
336 | MyFrame::~MyFrame() |
337 | { | |
d0b9eaa2 | 338 | delete m_timer; |
eaf0d558 RN |
339 | } |
340 | ||
d0b9eaa2 RN |
341 | // |
342 | //OnQuit | |
e4b12a53 | 343 | //------ |
d0b9eaa2 RN |
344 | //Called from file->quit. |
345 | //Closes this application. | |
346 | // | |
eaf0d558 RN |
347 | void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) |
348 | { | |
349 | // true is to force the frame to close | |
350 | Close(true); | |
351 | } | |
352 | ||
d0b9eaa2 RN |
353 | // |
354 | //OnAbout | |
355 | //------- | |
356 | //Called from help->about. | |
357 | //Gets some info about this application. | |
358 | // | |
eaf0d558 RN |
359 | void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) |
360 | { | |
361 | wxString msg; | |
362 | msg.Printf( _T("This is a test of wxMediaCtrl.\n") | |
363 | _T("Welcome to %s"), wxVERSION_STRING); | |
364 | ||
365 | wxMessageBox(msg, _T("About wxMediaCtrl test"), wxOK | wxICON_INFORMATION, this); | |
366 | } | |
367 | ||
d0b9eaa2 RN |
368 | // |
369 | //OnLoop | |
e4b12a53 | 370 | //------ |
d0b9eaa2 RN |
371 | //Called from file->loop. |
372 | //Changes the state of whether we want to loop or not. | |
373 | // | |
eaf0d558 RN |
374 | void MyFrame::OnLoop(wxCommandEvent& WXUNUSED(event)) |
375 | { | |
376 | m_bLoop = !m_bLoop; | |
377 | } | |
378 | ||
d0b9eaa2 RN |
379 | // |
380 | //OnOpenFile | |
e4b12a53 | 381 | //---------- |
d0b9eaa2 RN |
382 | //Called from file->openfile. |
383 | //Opens and plays a media file | |
384 | // | |
eaf0d558 RN |
385 | void MyFrame::OnOpenFile(wxCommandEvent& WXUNUSED(event)) |
386 | { | |
387 | wxFileDialog fd(this); | |
388 | ||
389 | if(fd.ShowModal() == wxID_OK) | |
390 | { | |
d0b9eaa2 | 391 | if( !m_mediactrl->Load(fd.GetPath()) ) |
eaf0d558 RN |
392 | wxMessageBox(wxT("Couldn't load file!")); |
393 | ||
d0b9eaa2 | 394 | if( !m_mediactrl->Play() ) |
eaf0d558 RN |
395 | wxMessageBox(wxT("Couldn't play movie!")); |
396 | ||
397 | ResetStatus(); | |
398 | } | |
399 | } | |
400 | ||
d0b9eaa2 RN |
401 | // |
402 | //OnPlay | |
e4b12a53 | 403 | //------ |
d0b9eaa2 RN |
404 | //Called from file->play. |
405 | //Resumes the media if it is paused or stopped. | |
406 | // | |
eaf0d558 RN |
407 | void MyFrame::OnPlay(wxCommandEvent& WXUNUSED(event)) |
408 | { | |
d0b9eaa2 | 409 | if( !m_mediactrl->Play() ) |
eaf0d558 RN |
410 | wxMessageBox(wxT("Couldn't play movie!")); |
411 | } | |
412 | ||
d0b9eaa2 RN |
413 | // |
414 | //OnPause | |
415 | //------- | |
416 | //Called from file->pause. | |
417 | //Pauses the media in-place. | |
418 | // | |
eaf0d558 RN |
419 | void MyFrame::OnPause(wxCommandEvent& WXUNUSED(event)) |
420 | { | |
d0b9eaa2 | 421 | if( !m_mediactrl->Pause() ) |
eaf0d558 RN |
422 | wxMessageBox(wxT("Couldn't pause movie!")); |
423 | } | |
424 | ||
d0b9eaa2 RN |
425 | // |
426 | //OnStop | |
e4b12a53 | 427 | //------ |
d0b9eaa2 | 428 | //Called from file->stop. |
e4b12a53 RN |
429 | //Where it stops depends on whether you can seek in the |
430 | //media control or not - if you can it stops and seeks to the beginning, | |
431 | //otherwise it will appear to be at the end - but it will start over again | |
432 | //when play() is called | |
d0b9eaa2 | 433 | // |
eaf0d558 RN |
434 | void MyFrame::OnStop(wxCommandEvent& WXUNUSED(event)) |
435 | { | |
d0b9eaa2 | 436 | if( !m_mediactrl->Stop() ) |
eaf0d558 RN |
437 | wxMessageBox(wxT("Couldn't stop movie!")); |
438 | } | |
439 | ||
d0b9eaa2 RN |
440 | // |
441 | //OnSeek | |
e4b12a53 | 442 | //------ |
d0b9eaa2 RN |
443 | //Called from file->seek. |
444 | //Called when the user moves the slider - | |
445 | //seeks to a position within the media | |
446 | // | |
eaf0d558 RN |
447 | void MyFrame::OnSeek(wxCommandEvent& WXUNUSED(event)) |
448 | { | |
d0b9eaa2 | 449 | if( !m_mediactrl->SetPosition( m_slider->GetValue() * 1000 ) ) |
eaf0d558 RN |
450 | wxMessageBox(wxT("Couldn't seek in movie!")); |
451 | } | |
452 | ||
d0b9eaa2 RN |
453 | // |
454 | //OnMediaFinished | |
e4b12a53 | 455 | //--------------- |
d0b9eaa2 RN |
456 | //Called when the media stops playing. |
457 | //Here we loop it if the user wants to (has been selected from file menu) | |
458 | // | |
eaf0d558 RN |
459 | void MyFrame::OnMediaFinished(wxMediaEvent& WXUNUSED(event)) |
460 | { | |
461 | if(m_bLoop) | |
462 | { | |
e4b12a53 RN |
463 | if ( !m_mediactrl->Play() ) |
464 | wxMessageBox(wxT("Couldn't loop movie!")); | |
eaf0d558 RN |
465 | } |
466 | } |