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