]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia2/board/mmboard.cpp
* Some more missing files. MMBoard tested (wave files) on MSVC 5
[wxWidgets.git] / utils / wxMMedia2 / board / 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 #ifdef __GNUG__
20 #pragma implementation "mmboard.cpp"
21 #endif
22
23 // For compilers that support precompilation, includes "wx/wx.h".
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 // for all others, include the necessary headers (this file is usually all you
31 // need because it includes almost all "standard" wxWindows headers
32 #ifndef WX_PRECOMP
33 #include "wx/wx.h"
34 #endif
35
36 // ----------------------------------------------------------------------------
37 // ressources
38 // ----------------------------------------------------------------------------
39 // the application icon
40 #if defined(__WXGTK__) || defined(__WXMOTIF__)
41 #include "mondrian.xpm"
42 #endif
43
44 // include multimedia classes
45 #include "sndbase.h"
46 #ifdef __WIN32__
47 #include "sndwin.h"
48 #endif
49 #ifdef __UNIX__
50 #include "sndoss.h"
51 #include "sndesd.h"
52 #endif
53
54 #include "wx/statline.h"
55 #include "wx/stattext.h"
56
57 // include personnal classes
58 #include "mmboard.h"
59 #include "mmbman.h"
60
61 #include "play.xpm"
62 #include "stop.xpm"
63 #include "eject.xpm"
64 #include "pause.xpm"
65
66 // ----------------------------------------------------------------------------
67 // private classes
68 // ----------------------------------------------------------------------------
69
70 // Main Multimedia Board frame
71 class MMBoardFrame : public wxFrame
72 {
73 public:
74 // ctor(s)
75 MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
76 // dtor
77 ~MMBoardFrame();
78
79 // event handlers
80 void OnQuit(wxCommandEvent& event);
81 void OnAbout(wxCommandEvent& event);
82 void OnOpen(wxCommandEvent& event);
83 void OnPlay(wxCommandEvent& event);
84 void OnStop(wxCommandEvent& event);
85 void OnPause(wxCommandEvent& event);
86 void OnRefreshInfo(wxEvent& event);
87
88 void OpenVideoWindow();
89 void CloseVideoWindow();
90
91 private:
92 // any class wishing to process wxWindows events must use this macro
93 DECLARE_EVENT_TABLE()
94
95 private:
96 void UpdateMMedInfo();
97 void UpdateInfoText();
98
99 MMBoardFile *m_opened_file;
100
101 wxSlider *m_positionSlider;
102 wxBitmapButton *m_playButton, *m_pauseButton, *m_stopButton, *m_ejectButton;
103 wxStaticText *m_fileType, *m_infoText;
104 wxWindow *m_video_window;
105
106 wxPanel *m_panel;
107 wxSizer *m_sizer;
108
109 wxTimer *m_refreshTimer;
110
111 };
112
113 // ----------------------------------------------------------------------------
114 // constants
115 // ----------------------------------------------------------------------------
116
117 // IDs for the controls and the menu commands
118 enum
119 {
120 // menu items
121 MMBoard_Quit = 1,
122 MMBoard_Open,
123 MMBoard_About,
124 MMBoard_PositionSlider,
125 MMBoard_PlayButton,
126 MMBoard_PauseButton,
127 MMBoard_ResumeButton,
128 MMBoard_StopButton,
129 MMBoard_EjectButton,
130 MMBoard_RefreshInfo
131 };
132
133 // ----------------------------------------------------------------------------
134 // event tables and other macros for wxWindows
135 // ----------------------------------------------------------------------------
136
137 BEGIN_EVENT_TABLE(MMBoardFrame, wxFrame)
138 EVT_MENU(MMBoard_Quit, MMBoardFrame::OnQuit)
139 EVT_MENU(MMBoard_About, MMBoardFrame::OnAbout)
140 EVT_MENU(MMBoard_Open, MMBoardFrame::OnOpen)
141 EVT_BUTTON(MMBoard_PlayButton, MMBoardFrame::OnPlay)
142 EVT_BUTTON(MMBoard_StopButton, MMBoardFrame::OnStop)
143 EVT_BUTTON(MMBoard_PauseButton, MMBoardFrame::OnPause)
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("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(TRUE);
170
171 m_caps = TestMultimediaCaps();
172
173 if (!m_caps) {
174 wxMessageBox("Your system has no multimedia capabilities. We are exiting now.", "Major error !", wxOK | wxICON_ERROR, NULL);
175 return FALSE;
176 }
177
178 wxString msg;
179 msg.Printf("Detected : %s%s%s", (m_caps & MM_SOUND_OSS) ? "OSS " : "",
180 (m_caps & MM_SOUND_ESD) ? "ESD " : "",
181 (m_caps & MM_SOUND_WIN) ? "WIN" : "");
182
183 wxMessageBox(msg, "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 __UNIX__
199 // We test the OSS (Open Sound System) support.
200
201 dev = new wxSoundStreamOSS();
202 if (dev->GetError() == wxSOUND_NOERR)
203 caps |= MM_SOUND_OSS;
204 delete dev;
205
206 // We now test the ESD support
207
208 dev = new wxSoundStreamESD();
209 if (dev->GetError() == wxSOUND_NOERR)
210 caps |= MM_SOUND_ESD;
211 delete dev;
212 #endif
213
214 #ifdef __WIN32__
215 // We test the Windows sound support.
216
217 dev = new wxSoundStreamWin();
218 if (dev->GetError() == wxSOUND_NOERR)
219 caps |= MM_SOUND_WIN;
220 delete dev;
221 #endif
222
223 return caps;
224 }
225
226 // ----------------------------------------------------------------------------
227 // main frame
228 // ----------------------------------------------------------------------------
229
230 // frame constructor
231 MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
232 : wxFrame((wxFrame *)NULL, -1, title, pos, size)
233 {
234 #ifdef __WXMAC__
235 // we need this in order to allow the about menu relocation, since ABOUT is
236 // not the default id of the about menu
237 wxApp::s_macAboutMenuItemId = MMBoard_About;
238 #endif
239
240 // set the frame icon
241 SetIcon(wxICON(mondrian));
242
243 // create a menu bar
244 wxMenu *menuFile = new wxMenu(_T(""), wxMENU_TEAROFF);
245
246 // the "About" item should be in the help menu
247 wxMenu *helpMenu = new wxMenu;
248 helpMenu->Append(MMBoard_About, _T("&About...\tCtrl-A"), _T("Show about dialog"));
249
250 menuFile->Append(MMBoard_Open, _T("&Open\tAlt-O"), _T("Open file"));
251 menuFile->AppendSeparator();
252 menuFile->Append(MMBoard_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
253
254 // now append the freshly created menu to the menu bar...
255 wxMenuBar *menuBar = new wxMenuBar();
256 menuBar->Append(menuFile, _T("&File"));
257 menuBar->Append(helpMenu, _T("&Help"));
258
259 // ... and attach this menu bar to the frame
260 SetMenuBar(menuBar);
261
262 #if wxUSE_STATUSBAR
263 // create a status bar just for fun (by default with 1 pane only)
264 CreateStatusBar(3);
265 SetStatusText(_T("Welcome to wxWindows!"));
266 #endif // wxUSE_STATUSBAR
267
268 // Misc variables
269 m_opened_file = NULL;
270
271 m_panel = new wxPanel(this, -1);
272
273 // Initialize main slider
274 m_positionSlider = new wxSlider( m_panel, MMBoard_PositionSlider, 0, 0, 60,
275 wxDefaultPosition, wxSize(300, -1),
276 wxSL_HORIZONTAL | wxSL_AUTOTICKS);
277 m_positionSlider->SetPageSize(60); // 60 secs
278
279 // Initialize info panel
280 wxPanel *infoPanel = new wxPanel( m_panel, -1);
281 infoPanel->SetBackgroundColour(*wxBLACK);
282 infoPanel->SetForegroundColour(*wxWHITE);
283
284 wxBoxSizer *infoSizer = new wxBoxSizer(wxVERTICAL);
285
286 m_fileType = new wxStaticText(infoPanel, -1, _T(""));
287 wxStaticLine *line = new wxStaticLine(infoPanel, -1);
288 m_infoText = new wxStaticText(infoPanel, -1, "");
289
290 UpdateInfoText();
291
292 infoSizer->Add(m_fileType, 0, wxGROW | wxALL, 1);
293 infoSizer->Add(line, 0, wxGROW | wxCENTRE, 20);
294 infoSizer->Add(m_infoText, 0, wxGROW | wxALL, 1);
295
296 infoPanel->SetSizer(infoSizer);
297 infoPanel->SetAutoLayout(TRUE);
298
299 // Bitmap button panel
300 wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
301
302 wxBitmap *play_bmp = new wxBitmap(play_back_xpm);
303 wxBitmap *stop_bmp = new wxBitmap(stop_back_xpm);
304 wxBitmap *eject_bmp = new wxBitmap(eject_xpm);
305 wxBitmap *pause_bmp = new wxBitmap(pause_xpm);
306
307 m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, *play_bmp);
308 m_playButton->Enable(FALSE);
309 m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, *pause_bmp);
310 m_pauseButton->Enable(FALSE);
311 m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, *stop_bmp);
312 m_stopButton->Enable(FALSE);
313 m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, *eject_bmp);
314 m_ejectButton->Enable(FALSE);
315
316 buttonSizer->Add(m_playButton, 0, wxALL, 2);
317 buttonSizer->Add(m_pauseButton, 0, wxALL, 2);
318 buttonSizer->Add(m_stopButton, 0, wxALL, 2);
319 buttonSizer->Add(m_ejectButton, 0, wxALL, 2);
320
321 // Top sizer
322 m_sizer = new wxBoxSizer(wxVERTICAL);
323 m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
324 m_sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
325 m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
326 m_sizer->Add(buttonSizer, 0, wxALL, 0);
327 m_sizer->Add(new wxStaticLine(m_panel, -1), 0, wxGROW | wxCENTRE, 0);
328 m_sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
329
330 m_panel->SetSizer(m_sizer);
331 m_panel->SetAutoLayout(TRUE);
332 m_sizer->Fit(this);
333 m_sizer->SetSizeHints(this);
334
335 // Timer
336 m_refreshTimer = new wxTimer(this, MMBoard_RefreshInfo);
337
338 // Video window
339 m_video_window = NULL;
340
341 // Multimedia file
342 m_opened_file = NULL;
343 }
344
345 MMBoardFrame::~MMBoardFrame()
346 {
347 if (m_opened_file)
348 delete m_opened_file;
349
350 delete m_refreshTimer;
351 }
352
353 void MMBoardFrame::OpenVideoWindow()
354 {
355 if (m_video_window)
356 return;
357
358 m_video_window = new wxWindow(m_panel, -1, wxDefaultPosition, wxSize(400, 400));
359 m_video_window->SetBackgroundColour(*wxBLACK);
360 m_sizer->Prepend(m_video_window, 0, wxGROW | wxSHRINK | wxCENTRE, 0);
361
362 m_sizer->Fit(this);
363 }
364
365 void MMBoardFrame::CloseVideoWindow()
366 {
367 if (!m_video_window)
368 return;
369
370 m_sizer->Remove(m_video_window);
371 delete m_video_window;
372 m_video_window = NULL;
373
374 m_sizer->Fit(this);
375 }
376
377 // event handlers
378
379 void MMBoardFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
380 {
381 // TRUE is to force the frame to close
382 Close(TRUE);
383 }
384
385 void MMBoardFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
386 {
387 wxString msg;
388 msg.Printf( _T("wxWindows Multimedia board v1.0a, wxMMedia v2.0a:\n")
389 _T("an example of the capabilities of the wxWindows multimedia classes.\n")
390 _T("Copyright 1999, 2000, Guilhem Lavaux.\n"));
391
392 wxMessageBox(msg, "About MMBoard", wxOK | wxICON_INFORMATION, this);
393 }
394
395 void MMBoardFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
396 {
397 wxString selected_file;
398
399 if (m_opened_file) {
400 if (!m_opened_file->IsStopped()) {
401 wxCommandEvent event2;
402 OnStop(event2);
403 }
404 delete m_opened_file;
405 }
406
407 // select a file to be opened
408 selected_file = wxLoadFileSelector("multimedia", "*", NULL, this);
409 if (selected_file.IsNull())
410 return;
411
412 m_opened_file = MMBoardManager::Open(selected_file);
413
414 // Change the range values of the slider.
415 MMBoardTime length;
416
417 length = m_opened_file->GetLength();
418 m_positionSlider->SetRange(0, length.hours * 3600 + length.minutes * 60 + length.seconds);
419
420 // Update misc info
421 UpdateMMedInfo();
422
423 SetStatusText(selected_file, 2);
424
425 // Update info text
426 UpdateInfoText();
427
428 // Enable a few buttons
429 m_playButton->Enable(TRUE);
430 m_ejectButton->Enable(TRUE);
431
432 if (m_opened_file->NeedWindow()) {
433 OpenVideoWindow();
434 m_opened_file->SetWindow(m_video_window);
435 } else
436 CloseVideoWindow();
437 }
438
439 void MMBoardFrame::UpdateInfoText()
440 {
441 wxString infotext1, infotext2;
442
443 if (m_opened_file) {
444 infotext1 = _T("File type:\n\t");
445 infotext1 += m_opened_file->GetStringType() + _T("\n");
446
447 infotext2 = _T("File informations:\n\n");
448 infotext2 += m_opened_file->GetStringInformation();
449 } else {
450 infotext1 = _T("File type: \n\tNo file opened");
451 infotext2 = _T("File informations:\nNo information\n\n\n\n\n");
452 }
453
454 m_fileType->SetLabel(infotext1);
455 m_infoText->SetLabel(infotext2);
456 }
457
458 void MMBoardFrame::UpdateMMedInfo()
459 {
460 wxString temp_string;
461 MMBoardTime current, length;
462
463 if (m_opened_file) {
464 current = m_opened_file->GetPosition();
465 length = m_opened_file->GetLength();
466 }
467
468 // We refresh the status bar
469 temp_string.Printf("%02d:%02d / %02d:%02d", current.hours * 60 + current.minutes,
470 current.seconds, length.hours * 60 + length.minutes, length.seconds);
471 SetStatusText(temp_string, 1);
472
473 // We set the slider position
474 m_positionSlider->SetValue(current.hours * 3600 + current.minutes * 60 + current.seconds);
475 }
476
477 // ----------------------------------------------------------------------------
478 // Playing management, refreshers, ...
479
480 void MMBoardFrame::OnRefreshInfo(wxEvent& WXUNUSED(event))
481 {
482 UpdateMMedInfo();
483
484 if (m_opened_file->IsStopped()) {
485 m_refreshTimer->Stop();
486 m_playButton->Enable(TRUE);
487 m_stopButton->Enable(FALSE);
488 m_pauseButton->Enable(FALSE);
489 }
490 }
491
492 void MMBoardFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
493 {
494 m_stopButton->Enable(TRUE);
495 m_pauseButton->Enable(TRUE);
496 m_playButton->Enable(FALSE);
497
498 if (m_opened_file->IsPaused()) {
499 m_opened_file->Resume();
500 return;
501 }
502
503 m_refreshTimer->Start(1000, FALSE);
504
505 m_opened_file->Play();
506
507 m_stopButton->Enable(TRUE);
508 m_pauseButton->Enable(TRUE);
509 m_playButton->Enable(FALSE);
510 }
511
512 void MMBoardFrame::OnStop(wxCommandEvent& WXUNUSED(event))
513 {
514 m_opened_file->Stop();
515 m_refreshTimer->Stop();
516
517 m_stopButton->Enable(FALSE);
518 m_playButton->Enable(TRUE);
519
520 UpdateMMedInfo();
521 }
522
523 void MMBoardFrame::OnPause(wxCommandEvent& WXUNUSED(event))
524 {
525 m_opened_file->Pause();
526
527 m_playButton->Enable(TRUE);
528 m_pauseButton->Enable(FALSE);
529 }