]> git.saurik.com Git - wxWidgets.git/blob - contrib/samples/mmedia/mmboard.cpp
don't eat all events if m_maxLength is 0: this means no limit according to the docs...
[wxWidgets.git] / contrib / samples / mmedia / mmboard.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: mmboard.cpp
3 // Purpose: Multimedia Library sample
4 // Author: Guilhem Lavaux (created from minimal by J. Smart)
5 // Modified by:
6 // Created: 13/02/2000
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers
29 #ifndef WX_PRECOMP
30 #include "wx/wx.h"
31 #endif
32
33 // ----------------------------------------------------------------------------
34 // ressources
35 // ----------------------------------------------------------------------------
36 // the application icon
37 #if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__)
38 #include "mondrian.xpm"
39 #endif
40
41 // include multimedia classes
42 #include "wx/mmedia/sndbase.h"
43 #ifdef __WIN32__
44 #include "wx/mmedia/sndwin.h"
45 #endif
46 #ifdef __UNIX__
47 #include "wx/mmedia/sndoss.h"
48 #include "wx/mmedia/sndesd.h"
49 #endif
50
51 #include "wx/statline.h"
52 #include "wx/stattext.h"
53
54 // include personnal classes
55 #include "mmboard.h"
56 #include "mmbman.h"
57
58 #include "play.xpm"
59 #include "stop.xpm"
60 #include "eject.xpm"
61 #include "pause.xpm"
62
63 // ----------------------------------------------------------------------------
64 // private classes
65 // ----------------------------------------------------------------------------
66
67 // Main Multimedia Board frame
68 class MMBoardFrame : public wxFrame
69 {
70 public:
71 // ctor(s)
72 MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
73 // dtor
74 ~MMBoardFrame();
75
76 // event handlers
77 void OnQuit(wxCommandEvent& event);
78 void OnAbout(wxCommandEvent& event);
79 void OnOpen(wxCommandEvent& event);
80 void OnPlay(wxCommandEvent& event);
81 void OnStop(wxCommandEvent& event);
82 void OnPause(wxCommandEvent& event);
83 void OnEject(wxCommandEvent& event);
84 void OnRefreshInfo(wxEvent& event);
85 void OnSetPosition(wxCommandEvent& event);
86
87 void OpenVideoWindow();
88 void CloseVideoWindow();
89
90 private:
91 // any class wishing to process wxWidgets events must use this macro
92 DECLARE_EVENT_TABLE()
93
94 private:
95 void UpdateMMedInfo();
96 void UpdateInfoText();
97
98 MMBoardFile *m_opened_file;
99
100 wxSlider *m_positionSlider;
101 wxBitmapButton *m_playButton, *m_pauseButton, *m_stopButton, *m_ejectButton;
102 wxStaticText *m_fileType, *m_infoText;
103 wxWindow *m_video_window;
104
105 wxPanel *m_panel;
106 wxSizer *m_sizer;
107
108 wxTimer *m_refreshTimer;
109 };
110
111 // ----------------------------------------------------------------------------
112 // constants
113 // ----------------------------------------------------------------------------
114
115 // IDs for the controls and the menu commands
116 enum
117 {
118 // menu items
119 MMBoard_Quit = 1,
120 MMBoard_Open,
121 MMBoard_About,
122 MMBoard_PositionSlider,
123 MMBoard_PlayButton,
124 MMBoard_PauseButton,
125 MMBoard_ResumeButton,
126 MMBoard_StopButton,
127 MMBoard_EjectButton,
128 MMBoard_RefreshInfo
129 };
130
131 // ----------------------------------------------------------------------------
132 // event tables and other macros for wxWidgets
133 // ----------------------------------------------------------------------------
134
135 BEGIN_EVENT_TABLE(MMBoardFrame, wxFrame)
136 EVT_MENU(MMBoard_Quit, MMBoardFrame::OnQuit)
137 EVT_MENU(MMBoard_About, MMBoardFrame::OnAbout)
138 EVT_MENU(MMBoard_Open, MMBoardFrame::OnOpen)
139 EVT_BUTTON(MMBoard_PlayButton, MMBoardFrame::OnPlay)
140 EVT_BUTTON(MMBoard_StopButton, MMBoardFrame::OnStop)
141 EVT_BUTTON(MMBoard_PauseButton, MMBoardFrame::OnPause)
142 EVT_BUTTON(MMBoard_EjectButton, MMBoardFrame::OnEject)
143 EVT_SLIDER(MMBoard_PositionSlider, MMBoardFrame::OnSetPosition)
144 EVT_CUSTOM(wxEVT_TIMER, MMBoard_RefreshInfo, MMBoardFrame::OnRefreshInfo)
145 END_EVENT_TABLE()
146
147 // ---------------------------------------------------------------------------
148 // Main board application launcher
149 // ---------------------------------------------------------------------------
150
151 IMPLEMENT_APP(MMBoardApp)
152
153 // ============================================================================
154 // implementation
155 // ============================================================================
156
157 // ----------------------------------------------------------------------------
158 // the application class
159 // ----------------------------------------------------------------------------
160
161 bool MMBoardApp::OnInit()
162 {
163 // create the main application window
164 MMBoardFrame *frame = new MMBoardFrame(_T("Multimedia Board"),
165 wxPoint(50, 50), wxSize(450, 340));
166
167 // and show it (the frames, unlike simple controls, are not shown when
168 // created initially)
169 frame->Show();
170
171 m_caps = TestMultimediaCaps();
172
173 if (!m_caps) {
174 wxMessageBox(_T("Your system has no multimedia capabilities. We are exiting now."), _T("Major error !"), wxOK | wxICON_ERROR, NULL);
175 return false;
176 }
177
178 wxString msg;
179 msg.Printf(_T("Detected : %s%s%s"), (m_caps & MM_SOUND_OSS) ? _T("OSS ") : _T(""),
180 (m_caps & MM_SOUND_ESD) ? _T("ESD ") : _T(""),
181 (m_caps & MM_SOUND_WIN) ? _T("WIN") : _T(""));
182
183 wxMessageBox(msg, _T("Good !"), wxOK | wxICON_INFORMATION, NULL);
184
185 // success: wxApp::OnRun() will be called which will enter the main message
186 // loop and the application will run. If we returned false here, the
187 // application would exit immediately.
188 return true;
189 }
190
191 wxUint8 MMBoardApp::TestMultimediaCaps()
192 {
193 wxSoundStream *dev;
194 wxUint8 caps;
195
196 caps = 0;
197
198 #ifdef __WIN32__
199 // We test the Windows sound support.
200
201 dev = new wxSoundStreamWin();
202 if (dev->GetError() == wxSOUND_NOERROR)
203 caps |= MM_SOUND_WIN;
204 delete dev;
205
206 #elif defined __UNIX__
207 // We now test the ESD support
208
209 dev = new wxSoundStreamESD();
210 if (dev->GetError() == wxSOUND_NOERROR)
211 caps |= MM_SOUND_ESD;
212 delete dev;
213
214 // We test the OSS (Open Sound System) support.
215 // WARNING: There is a conflict between ESD and ALSA. We may be interrested
216 // in disabling the auto detection of OSS is ESD has been detected.
217 #if 1
218 if (!(caps & MM_SOUND_ESD)) {
219 #endif
220
221 dev = new wxSoundStreamOSS();
222 if (dev->GetError() == wxSOUND_NOERROR)
223 caps |= MM_SOUND_OSS;
224 delete dev;
225 #if 1
226 }
227 #endif
228
229 #endif
230
231 return caps;
232 }
233
234 // ----------------------------------------------------------------------------
235 // main frame
236 // ----------------------------------------------------------------------------
237
238 // frame constructor
239 MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
240 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
241 {
242 #ifdef __WXMAC__
243 // we need this in order to allow the about menu relocation, since ABOUT is
244 // not the default id of the about menu
245 wxApp::s_macAboutMenuItemId = MMBoard_About;
246 #endif
247
248 // set the frame icon
249 SetIcon(wxICON(mondrian));
250
251 // create a menu bar
252 wxMenu *menuFile = new wxMenu(wxEmptyString, wxMENU_TEAROFF);
253
254 // the "About" item should be in the help menu
255 wxMenu *helpMenu = new wxMenu;
256 helpMenu->Append(MMBoard_About, wxT("&About...\tCtrl-A"), wxT("Show about dialog"));
257
258 menuFile->Append(MMBoard_Open, wxT("&Open\tAlt-O"), wxT("Open file"));
259 menuFile->AppendSeparator();
260 menuFile->Append(MMBoard_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
261
262 // now append the freshly created menu to the menu bar...
263 wxMenuBar *menuBar = new wxMenuBar();
264 menuBar->Append(menuFile, wxT("&File"));
265 menuBar->Append(helpMenu, wxT("&Help"));
266
267 // ... and attach this menu bar to the frame
268 SetMenuBar(menuBar);
269
270 #if wxUSE_STATUSBAR
271 // create a status bar just for fun (by default with 1 pane only)
272 CreateStatusBar(3);
273 SetStatusText(wxT("Welcome to wxWidgets!"));
274 #endif // wxUSE_STATUSBAR
275
276 // Misc variables
277 m_opened_file = NULL;
278
279 m_panel = new wxPanel(this, wxID_ANY);
280
281 // Initialize main slider
282 m_positionSlider = new wxSlider( m_panel, MMBoard_PositionSlider, 0, 0, 60,
283 wxDefaultPosition, wxSize(300, wxDefaultCoord),
284 wxSL_HORIZONTAL | wxSL_AUTOTICKS);
285 m_positionSlider->SetPageSize(60); // 60 secs
286 m_positionSlider->Disable();
287
288 // Initialize info panel
289 wxPanel *infoPanel = new wxPanel( m_panel, wxID_ANY);
290 infoPanel->SetBackgroundColour(*wxBLACK);
291 infoPanel->SetForegroundColour(*wxWHITE);
292
293 wxBoxSizer *infoSizer = new wxBoxSizer(wxVERTICAL);
294
295 m_fileType = new wxStaticText(infoPanel, wxID_ANY, wxEmptyString);
296 #if wxUSE_STATLINE
297 wxStaticLine *line = new wxStaticLine(infoPanel, wxID_ANY);
298 #endif // wxUSE_STATLINE
299 m_infoText = new wxStaticText(infoPanel, wxID_ANY, wxEmptyString);
300
301 UpdateInfoText();
302
303 infoSizer->Add(m_fileType, 0, wxGROW | wxALL, 1);
304 #if wxUSE_STATLINE
305 infoSizer->Add(line, 0, wxGROW | wxCENTRE, 20);
306 #endif // wxUSE_STATLINE
307 infoSizer->Add(m_infoText, 0, wxGROW | wxALL, 1);
308
309 infoPanel->SetSizer(infoSizer);
310
311 // Bitmap button panel
312 wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
313
314 wxBitmap play_bmp(play_back_xpm);
315 wxBitmap stop_bmp(stop_back_xpm);
316 wxBitmap eject_bmp(eject_xpm);
317 wxBitmap pause_bmp(pause_xpm);
318
319 m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, play_bmp);
320 m_playButton->Disable();
321 m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, pause_bmp);
322 m_pauseButton->Disable();
323 m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, stop_bmp);
324 m_stopButton->Disable();
325 m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, eject_bmp);
326 m_ejectButton->Disable();
327
328 buttonSizer->Add(m_playButton, 0, wxALL, 2);
329 buttonSizer->Add(m_pauseButton, 0, wxALL, 2);
330 buttonSizer->Add(m_stopButton, 0, wxALL, 2);
331 buttonSizer->Add(m_ejectButton, 0, wxALL, 2);
332
333 // Top sizer
334 m_sizer = new wxBoxSizer(wxVERTICAL);
335 #if wxUSE_STATLINE
336 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
337 #endif // wxUSE_STATLINE
338 m_sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
339 #if wxUSE_STATLINE
340 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
341 #endif // wxUSE_STATLINE
342 m_sizer->Add(buttonSizer, 0, wxALL, 0);
343 #if wxUSE_STATLINE
344 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
345 #endif // wxUSE_STATLINE
346 m_sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
347
348 m_panel->SetSizer(m_sizer);
349 m_sizer->Fit(this);
350 m_sizer->SetSizeHints(this);
351
352 // Timer
353 m_refreshTimer = new wxTimer(this, MMBoard_RefreshInfo);
354
355 // Video window
356 m_video_window = NULL;
357
358 // Multimedia file
359 m_opened_file = NULL;
360 }
361
362 MMBoardFrame::~MMBoardFrame()
363 {
364 if (m_opened_file)
365 delete m_opened_file;
366
367 delete m_refreshTimer;
368 }
369
370 void MMBoardFrame::OpenVideoWindow()
371 {
372 if (m_video_window)
373 return;
374
375 m_video_window = new wxWindow(m_panel, wxID_ANY, wxDefaultPosition, wxSize(200, 200));
376 m_video_window->SetBackgroundColour(*wxBLACK);
377 m_sizer->Prepend(m_video_window, 2, wxGROW | wxSHRINK | wxCENTRE, 1);
378
379 m_sizer->Fit(this);
380 }
381
382 void MMBoardFrame::CloseVideoWindow()
383 {
384 if (!m_video_window)
385 return;
386
387 m_sizer->Detach( m_video_window );
388 delete m_video_window;
389 m_video_window = NULL;
390
391 m_sizer->Fit(this);
392 }
393
394 // event handlers
395
396 void MMBoardFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
397 {
398 // true is to force the frame to close
399 Close(true);
400 }
401
402 void MMBoardFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
403 {
404 wxString msg;
405 msg.Printf( wxT("wxWidgets Multimedia board v1.0a, wxMMedia v2.0a:\n")
406 wxT("an example of the capabilities of the wxWidgets multimedia classes.\n")
407 wxT("Copyright 1999, 2000, Guilhem Lavaux.\n"));
408
409 wxMessageBox(msg, _T("About MMBoard"), wxOK | wxICON_INFORMATION, this);
410 }
411
412 void MMBoardFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
413 {
414 wxString selected_file;
415
416 if (m_opened_file) {
417 if (!m_opened_file->IsStopped()) {
418 wxCommandEvent event2;
419 OnStop(event2);
420 }
421 delete m_opened_file;
422 }
423
424 // select a file to be opened
425 #if wxUSE_FILEDLG
426 selected_file = wxLoadFileSelector(_T("multimedia"), _T("*"), NULL, this);
427 #endif // wxUSE_FILEDLG
428 if (selected_file.empty())
429 return;
430
431 m_opened_file = MMBoardManager::Open(selected_file);
432
433 // Change the range values of the slider.
434 MMBoardTime length;
435
436 length = m_opened_file->GetLength();
437 m_positionSlider->SetRange(0, length.hours * 3600 + length.minutes * 60 + length.seconds);
438
439 // Update misc info
440 UpdateMMedInfo();
441
442 #if wxUSE_STATUSBAR
443 SetStatusText(selected_file, 2);
444 #endif // wxUSE_STATUSBAR
445
446 // Update info text
447 UpdateInfoText();
448
449 // Enable a few buttons
450 m_playButton->Enable();
451 m_ejectButton->Enable();
452 m_positionSlider->Enable();
453
454 if (m_opened_file->NeedWindow()) {
455 OpenVideoWindow();
456 m_opened_file->SetWindow(m_video_window);
457 } else
458 CloseVideoWindow();
459 }
460
461 void MMBoardFrame::UpdateInfoText()
462 {
463 wxString infotext1, infotext2;
464
465 if (m_opened_file) {
466 infotext1 = wxT("File type:\n\t");
467 infotext1 += m_opened_file->GetStringType() + wxT("\n");
468
469 infotext2 = wxT("File informations:\n\n");
470 infotext2 += m_opened_file->GetStringInformation();
471 } else {
472 infotext1 = wxT("File type: \n\tNo file opened");
473 infotext2 = wxT("File informations:\nNo information\n\n\n\n\n");
474 }
475
476 m_fileType->SetLabel(infotext1);
477 m_infoText->SetLabel(infotext2);
478 }
479
480 void MMBoardFrame::UpdateMMedInfo()
481 {
482 MMBoardTime current, length;
483
484 if (m_opened_file) {
485 current = m_opened_file->GetPosition();
486 length = m_opened_file->GetLength();
487 } else {
488 current.hours = current.minutes = current.seconds = 0;
489 length = current;
490 }
491
492 #if wxUSE_STATUSBAR
493 // We refresh the status bar
494 wxString temp_string;
495 temp_string.Printf(wxT("%02d:%02d / %02d:%02d"), current.hours * 60 + current.minutes,
496 current.seconds, length.hours * 60 + length.minutes, length.seconds);
497 SetStatusText(temp_string, 1);
498 #else
499 wxUnusedVar(length);
500 #endif // wxUSE_STATUSBAR
501
502 // We set the slider position
503 m_positionSlider->SetValue(current.hours * 3600 + current.minutes * 60 + current.seconds);
504 }
505
506 // ----------------------------------------------------------------------------
507 // Playing management, refreshers, ...
508
509 void MMBoardFrame::OnRefreshInfo(wxEvent& WXUNUSED(event))
510 {
511 UpdateMMedInfo();
512
513 if (m_opened_file->IsStopped())
514 {
515 m_refreshTimer->Stop();
516 m_playButton->Enable();
517 m_stopButton->Disable();
518 m_pauseButton->Disable();
519 }
520 }
521
522 void MMBoardFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
523 {
524 m_stopButton->Enable();
525 m_pauseButton->Enable();
526 m_playButton->Disable();
527
528 if (m_opened_file->IsPaused())
529 {
530 m_opened_file->Resume();
531 return;
532 }
533
534 m_refreshTimer->Start(1000, false);
535
536 m_opened_file->Play();
537
538 m_stopButton->Enable();
539 m_pauseButton->Enable();
540 m_playButton->Disable();
541 }
542
543 void MMBoardFrame::OnStop(wxCommandEvent& WXUNUSED(event))
544 {
545 m_opened_file->Stop();
546 m_refreshTimer->Stop();
547
548 m_stopButton->Disable();
549 m_playButton->Enable();
550
551 UpdateMMedInfo();
552 }
553
554 void MMBoardFrame::OnPause(wxCommandEvent& WXUNUSED(event))
555 {
556 m_opened_file->Pause();
557
558 m_playButton->Enable();
559 m_pauseButton->Disable();
560 }
561
562 void MMBoardFrame::OnEject(wxCommandEvent& WXUNUSED(event))
563 {
564 m_opened_file->Stop();
565
566 delete m_opened_file;
567 m_opened_file = NULL;
568
569 m_playButton->Disable();
570 m_pauseButton->Disable();
571 m_stopButton->Disable();
572 m_ejectButton->Disable();
573 m_positionSlider->Disable();
574
575 UpdateInfoText();
576 UpdateMMedInfo();
577 }
578
579 void MMBoardFrame::OnSetPosition(wxCommandEvent& WXUNUSED(event))
580 {
581 wxUint32 itime;
582 MMBoardTime btime;
583
584 itime = m_positionSlider->GetValue();
585 btime.seconds = itime % 60;
586 btime.minutes = (itime / 60) % 60;
587 btime.hours = itime / 3600;
588 m_opened_file->SetPosition(btime);
589
590 UpdateMMedInfo();
591 }