]> git.saurik.com Git - wxWidgets.git/blame - contrib/samples/mmedia/mmboard.cpp
define ChangeSelection() (fixes wxMotif build)
[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// ----------------------------------------------------------------------------
36// the application icon
618f2efa 37#if defined(__WXGTK__) || defined(__WXX11__) || defined(__WXMOTIF__) || defined(__WXMAC__)
e8482f24
GL
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
68class MMBoardFrame : public wxFrame
69{
70public:
71 // ctor(s)
72 MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size);
73 // dtor
74 ~MMBoardFrame();
dabbc6a5 75
e8482f24
GL
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);
dabbc6a5 86
e8482f24
GL
87 void OpenVideoWindow();
88 void CloseVideoWindow();
dabbc6a5 89
e8482f24 90private:
be5a51fb 91 // any class wishing to process wxWidgets events must use this macro
e8482f24
GL
92 DECLARE_EVENT_TABLE()
93
94private:
dabbc6a5 95 void UpdateMMedInfo();
e8482f24 96 void UpdateInfoText();
dabbc6a5 97
e8482f24 98 MMBoardFile *m_opened_file;
dabbc6a5 99
e8482f24
GL
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;
dabbc6a5 104
e8482f24
GL
105 wxPanel *m_panel;
106 wxSizer *m_sizer;
dabbc6a5 107
e8482f24
GL
108 wxTimer *m_refreshTimer;
109};
110
111// ----------------------------------------------------------------------------
112// constants
113// ----------------------------------------------------------------------------
114
115// IDs for the controls and the menu commands
116enum
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// ----------------------------------------------------------------------------
be5a51fb 132// event tables and other macros for wxWidgets
e8482f24
GL
133// ----------------------------------------------------------------------------
134
135BEGIN_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)
dabbc6a5 142 EVT_BUTTON(MMBoard_EjectButton, MMBoardFrame::OnEject)
e8482f24
GL
143 EVT_SLIDER(MMBoard_PositionSlider, MMBoardFrame::OnSetPosition)
144 EVT_CUSTOM(wxEVT_TIMER, MMBoard_RefreshInfo, MMBoardFrame::OnRefreshInfo)
145END_EVENT_TABLE()
146
147// ---------------------------------------------------------------------------
148// Main board application launcher
149// ---------------------------------------------------------------------------
150
151IMPLEMENT_APP(MMBoardApp)
152
153// ============================================================================
154// implementation
155// ============================================================================
156
157// ----------------------------------------------------------------------------
158// the application class
159// ----------------------------------------------------------------------------
160
161bool MMBoardApp::OnInit()
162{
163 // create the main application window
2bbf230a 164 MMBoardFrame *frame = new MMBoardFrame(_T("Multimedia Board"),
e8482f24
GL
165 wxPoint(50, 50), wxSize(450, 340));
166
167 // and show it (the frames, unlike simple controls, are not shown when
168 // created initially)
dabbc6a5 169 frame->Show();
e8482f24
GL
170
171 m_caps = TestMultimediaCaps();
172
173 if (!m_caps) {
2bbf230a 174 wxMessageBox(_T("Your system has no multimedia capabilities. We are exiting now."), _T("Major error !"), wxOK | wxICON_ERROR, NULL);
dabbc6a5 175 return false;
e8482f24
GL
176 }
177
178 wxString msg;
2bbf230a 179 msg.Printf(_T("Detected : %s%s%s"), (m_caps & MM_SOUND_OSS) ? _T("OSS ") : _T(""),
dabbc6a5
DS
180 (m_caps & MM_SOUND_ESD) ? _T("ESD ") : _T(""),
181 (m_caps & MM_SOUND_WIN) ? _T("WIN") : _T(""));
e8482f24 182
2bbf230a 183 wxMessageBox(msg, _T("Good !"), wxOK | wxICON_INFORMATION, NULL);
e8482f24
GL
184
185 // success: wxApp::OnRun() will be called which will enter the main message
dabbc6a5 186 // loop and the application will run. If we returned false here, the
e8482f24 187 // application would exit immediately.
dabbc6a5 188 return true;
e8482f24
GL
189}
190
191wxUint8 MMBoardApp::TestMultimediaCaps()
192{
193 wxSoundStream *dev;
194 wxUint8 caps;
dabbc6a5 195
e8482f24 196 caps = 0;
dabbc6a5 197
69067986
MW
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__
e8482f24 207 // We now test the ESD support
dabbc6a5 208
e8482f24 209 dev = new wxSoundStreamESD();
dabbc6a5 210 if (dev->GetError() == wxSOUND_NOERROR)
e8482f24
GL
211 caps |= MM_SOUND_ESD;
212 delete dev;
dabbc6a5 213
e8482f24 214 // We test the OSS (Open Sound System) support.
c42b1de6
GL
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
e8482f24
GL
221 dev = new wxSoundStreamOSS();
222 if (dev->GetError() == wxSOUND_NOERROR)
223 caps |= MM_SOUND_OSS;
224 delete dev;
c42b1de6
GL
225#if 1
226 }
227#endif
228
e8482f24 229#endif
dabbc6a5 230
e8482f24
GL
231 return caps;
232}
233
234// ----------------------------------------------------------------------------
235// main frame
236// ----------------------------------------------------------------------------
237
238// frame constructor
239MMBoardFrame::MMBoardFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
dabbc6a5 240 : wxFrame((wxFrame *)NULL, wxID_ANY, title, pos, size)
e8482f24
GL
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
dabbc6a5 252 wxMenu *menuFile = new wxMenu(wxEmptyString, wxMENU_TEAROFF);
e8482f24
GL
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);
be5a51fb 273 SetStatusText(wxT("Welcome to wxWidgets!"));
e8482f24
GL
274#endif // wxUSE_STATUSBAR
275
276 // Misc variables
277 m_opened_file = NULL;
278
dabbc6a5 279 m_panel = new wxPanel(this, wxID_ANY);
e8482f24
GL
280
281 // Initialize main slider
282 m_positionSlider = new wxSlider( m_panel, MMBoard_PositionSlider, 0, 0, 60,
422d0ff0 283 wxDefaultPosition, wxSize(300, wxDefaultCoord),
dabbc6a5 284 wxSL_HORIZONTAL | wxSL_AUTOTICKS);
e8482f24 285 m_positionSlider->SetPageSize(60); // 60 secs
dabbc6a5
DS
286 m_positionSlider->Disable();
287
e8482f24 288 // Initialize info panel
dabbc6a5 289 wxPanel *infoPanel = new wxPanel( m_panel, wxID_ANY);
e8482f24
GL
290 infoPanel->SetBackgroundColour(*wxBLACK);
291 infoPanel->SetForegroundColour(*wxWHITE);
292
293 wxBoxSizer *infoSizer = new wxBoxSizer(wxVERTICAL);
294
dabbc6a5 295 m_fileType = new wxStaticText(infoPanel, wxID_ANY, wxEmptyString);
e38c6b5f 296#if wxUSE_STATLINE
dabbc6a5 297 wxStaticLine *line = new wxStaticLine(infoPanel, wxID_ANY);
e38c6b5f 298#endif // wxUSE_STATLINE
dabbc6a5 299 m_infoText = new wxStaticText(infoPanel, wxID_ANY, wxEmptyString);
e8482f24
GL
300
301 UpdateInfoText();
302
303 infoSizer->Add(m_fileType, 0, wxGROW | wxALL, 1);
e38c6b5f 304#if wxUSE_STATLINE
e8482f24 305 infoSizer->Add(line, 0, wxGROW | wxCENTRE, 20);
e38c6b5f 306#endif // wxUSE_STATLINE
e8482f24 307 infoSizer->Add(m_infoText, 0, wxGROW | wxALL, 1);
dabbc6a5 308
e8482f24 309 infoPanel->SetSizer(infoSizer);
e8482f24
GL
310
311 // Bitmap button panel
312 wxBoxSizer *buttonSizer = new wxBoxSizer(wxHORIZONTAL);
dabbc6a5 313
a977709b
JS
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);
e8482f24 318
a977709b 319 m_playButton = new wxBitmapButton(m_panel, MMBoard_PlayButton, play_bmp);
dabbc6a5 320 m_playButton->Disable();
a977709b 321 m_pauseButton = new wxBitmapButton(m_panel, MMBoard_PauseButton, pause_bmp);
dabbc6a5 322 m_pauseButton->Disable();
a977709b 323 m_stopButton = new wxBitmapButton(m_panel, MMBoard_StopButton, stop_bmp);
dabbc6a5 324 m_stopButton->Disable();
a977709b 325 m_ejectButton = new wxBitmapButton(m_panel, MMBoard_EjectButton, eject_bmp);
dabbc6a5
DS
326 m_ejectButton->Disable();
327
e8482f24 328 buttonSizer->Add(m_playButton, 0, wxALL, 2);
dabbc6a5 329 buttonSizer->Add(m_pauseButton, 0, wxALL, 2);
e8482f24
GL
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);
e38c6b5f 335#if wxUSE_STATLINE
dabbc6a5 336 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
e38c6b5f 337#endif // wxUSE_STATLINE
e8482f24 338 m_sizer->Add(m_positionSlider, 0, wxCENTRE | wxGROW | wxALL, 2);
e38c6b5f 339#if wxUSE_STATLINE
dabbc6a5 340 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
e38c6b5f 341#endif // wxUSE_STATLINE
e8482f24 342 m_sizer->Add(buttonSizer, 0, wxALL, 0);
e38c6b5f 343#if wxUSE_STATLINE
dabbc6a5 344 m_sizer->Add(new wxStaticLine(m_panel, wxID_ANY), 0, wxGROW | wxCENTRE, 0);
e38c6b5f 345#endif // wxUSE_STATLINE
e8482f24 346 m_sizer->Add(infoPanel, 1, wxCENTRE | wxGROW, 0);
dabbc6a5 347
e8482f24 348 m_panel->SetSizer(m_sizer);
e8482f24
GL
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
362MMBoardFrame::~MMBoardFrame()
363{
364 if (m_opened_file)
365 delete m_opened_file;
dabbc6a5 366
e8482f24
GL
367 delete m_refreshTimer;
368}
369
370void MMBoardFrame::OpenVideoWindow()
371{
372 if (m_video_window)
373 return;
374
dabbc6a5 375 m_video_window = new wxWindow(m_panel, wxID_ANY, wxDefaultPosition, wxSize(200, 200));
e8482f24
GL
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
382void MMBoardFrame::CloseVideoWindow()
383{
384 if (!m_video_window)
385 return;
12a3f227
RL
386
387 m_sizer->Detach( m_video_window );
e8482f24
GL
388 delete m_video_window;
389 m_video_window = NULL;
12a3f227 390
e8482f24
GL
391 m_sizer->Fit(this);
392}
393
394// event handlers
395
396void MMBoardFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
397{
dabbc6a5
DS
398 // true is to force the frame to close
399 Close(true);
e8482f24
GL
400}
401
402void MMBoardFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
403{
404 wxString msg;
be5a51fb
JS
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")
dabbc6a5
DS
407 wxT("Copyright 1999, 2000, Guilhem Lavaux.\n"));
408
2bbf230a 409 wxMessageBox(msg, _T("About MMBoard"), wxOK | wxICON_INFORMATION, this);
e8482f24
GL
410}
411
412void MMBoardFrame::OnOpen(wxCommandEvent& WXUNUSED(event))
413{
414 wxString selected_file;
dabbc6a5 415
e8482f24
GL
416 if (m_opened_file) {
417 if (!m_opened_file->IsStopped()) {
418 wxCommandEvent event2;
419 OnStop(event2);
420 }
421 delete m_opened_file;
422 }
dabbc6a5 423
e8482f24 424 // select a file to be opened
c54e5eb0 425#if wxUSE_FILEDLG
2bbf230a 426 selected_file = wxLoadFileSelector(_T("multimedia"), _T("*"), NULL, this);
c54e5eb0
WS
427#endif // wxUSE_FILEDLG
428 if (selected_file.empty())
e8482f24 429 return;
dabbc6a5 430
e8482f24 431 m_opened_file = MMBoardManager::Open(selected_file);
dabbc6a5 432
e8482f24
GL
433 // Change the range values of the slider.
434 MMBoardTime length;
dabbc6a5 435
e8482f24
GL
436 length = m_opened_file->GetLength();
437 m_positionSlider->SetRange(0, length.hours * 3600 + length.minutes * 60 + length.seconds);
dabbc6a5 438
e8482f24
GL
439 // Update misc info
440 UpdateMMedInfo();
dabbc6a5 441
d96cdd4a 442#if wxUSE_STATUSBAR
e8482f24 443 SetStatusText(selected_file, 2);
d96cdd4a 444#endif // wxUSE_STATUSBAR
dabbc6a5 445
e8482f24
GL
446 // Update info text
447 UpdateInfoText();
dabbc6a5 448
e8482f24 449 // Enable a few buttons
dabbc6a5
DS
450 m_playButton->Enable();
451 m_ejectButton->Enable();
452 m_positionSlider->Enable();
453
e8482f24
GL
454 if (m_opened_file->NeedWindow()) {
455 OpenVideoWindow();
456 m_opened_file->SetWindow(m_video_window);
457 } else
458 CloseVideoWindow();
459}
460
461void MMBoardFrame::UpdateInfoText()
462{
463 wxString infotext1, infotext2;
dabbc6a5 464
e8482f24
GL
465 if (m_opened_file) {
466 infotext1 = wxT("File type:\n\t");
467 infotext1 += m_opened_file->GetStringType() + wxT("\n");
dabbc6a5 468
e8482f24
GL
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 }
dabbc6a5 475
e8482f24
GL
476 m_fileType->SetLabel(infotext1);
477 m_infoText->SetLabel(infotext2);
478}
479
480void MMBoardFrame::UpdateMMedInfo()
481{
e8482f24 482 MMBoardTime current, length;
dabbc6a5 483
e8482f24
GL
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
d96cdd4a 492#if wxUSE_STATUSBAR
e8482f24 493 // We refresh the status bar
d96cdd4a 494 wxString temp_string;
e8482f24
GL
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);
d96cdd4a
WS
498#else
499 wxUnusedVar(length);
500#endif // wxUSE_STATUSBAR
dabbc6a5 501
e8482f24
GL
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
509void MMBoardFrame::OnRefreshInfo(wxEvent& WXUNUSED(event))
510{
511 UpdateMMedInfo();
dabbc6a5
DS
512
513 if (m_opened_file->IsStopped())
514 {
e8482f24 515 m_refreshTimer->Stop();
dabbc6a5
DS
516 m_playButton->Enable();
517 m_stopButton->Disable();
518 m_pauseButton->Disable();
e8482f24
GL
519 }
520}
521
522void MMBoardFrame::OnPlay(wxCommandEvent& WXUNUSED(event))
523{
dabbc6a5
DS
524 m_stopButton->Enable();
525 m_pauseButton->Enable();
526 m_playButton->Disable();
527
528 if (m_opened_file->IsPaused())
529 {
e8482f24
GL
530 m_opened_file->Resume();
531 return;
532 }
dabbc6a5
DS
533
534 m_refreshTimer->Start(1000, false);
535
e8482f24 536 m_opened_file->Play();
dabbc6a5
DS
537
538 m_stopButton->Enable();
539 m_pauseButton->Enable();
540 m_playButton->Disable();
e8482f24
GL
541}
542
543void MMBoardFrame::OnStop(wxCommandEvent& WXUNUSED(event))
544{
545 m_opened_file->Stop();
546 m_refreshTimer->Stop();
547
dabbc6a5
DS
548 m_stopButton->Disable();
549 m_playButton->Enable();
550
e8482f24
GL
551 UpdateMMedInfo();
552}
553
554void MMBoardFrame::OnPause(wxCommandEvent& WXUNUSED(event))
555{
556 m_opened_file->Pause();
dabbc6a5
DS
557
558 m_playButton->Enable();
559 m_pauseButton->Disable();
e8482f24
GL
560}
561
562void MMBoardFrame::OnEject(wxCommandEvent& WXUNUSED(event))
563{
564 m_opened_file->Stop();
565
566 delete m_opened_file;
567 m_opened_file = NULL;
dabbc6a5
DS
568
569 m_playButton->Disable();
570 m_pauseButton->Disable();
571 m_stopButton->Disable();
572 m_ejectButton->Disable();
573 m_positionSlider->Disable();
e8482f24
GL
574
575 UpdateInfoText();
576 UpdateMMedInfo();
577}
578
579void MMBoardFrame::OnSetPosition(wxCommandEvent& WXUNUSED(event))
580{
581 wxUint32 itime;
582 MMBoardTime btime;
dabbc6a5 583
e8482f24
GL
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}