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