root/trunk/gui/src/HydrogenApp.cpp @ 570

Revision 570, 11.3 KB (checked in by wolke, 5 years ago)

merge the audio-file-browser branch

Line 
1/*
2 * Hydrogen
3 * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4 *
5 * http://www.hydrogen-music.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY, without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 *
21 */
22
23#include "version.h"
24
25#include "HydrogenApp.h"
26#include "Skin.h"
27#include "PreferencesDialog.h"
28#include "MainForm.h"
29#include "PlayerControl.h"
30#include "AudioEngineInfoForm.h"
31#include "HelpBrowser.h"
32#include "LadspaFXProperties.h"
33#include "InstrumentRack.h"
34
35#include "PatternEditor/PatternEditorPanel.h"
36#include "InstrumentEditor/InstrumentEditorPanel.h"
37#include "SongEditor/SongEditor.h"
38#include "SongEditor/SongEditorPanel.h"
39#include "PlaylistEditor/PlaylistDialog.h"
40//#include "AudioFileBrowser/AudioFileBrowser.h"
41
42#include "Mixer/Mixer.h"
43#include "Mixer/MixerLine.h"
44
45#include <hydrogen/hydrogen.h>
46#include <hydrogen/event_queue.h>
47#include <hydrogen/fx/LadspaFX.h>
48#include <hydrogen/Preferences.h>
49#include <hydrogen/Song.h>
50
51#include <QtGui>
52
53using namespace H2Core;
54
55HydrogenApp* HydrogenApp::m_pInstance = NULL;
56
57HydrogenApp::HydrogenApp( MainForm *pMainForm, Song *pFirstSong )
58 : Object( "HydrogenApp" )
59 , m_pMainForm( pMainForm )
60 , m_pMixer( NULL )
61 , m_pPatternEditorPanel( NULL )
62 , m_pAudioEngineInfoForm( NULL )
63 , m_pSongEditorPanel( NULL )
64 , m_pHelpBrowser( NULL )
65 , m_pFirstTimeInfo( NULL )
66 , m_pPlayerControl( NULL )
67 , m_pPlaylistDialog( NULL )
68// , m_pAudioFileBrowser( NULL )
69
70{
71        m_pInstance = this;
72
73        m_pEventQueueTimer = new QTimer(this);
74        connect( m_pEventQueueTimer, SIGNAL( timeout() ), this, SLOT( onEventQueueTimer() ) );
75        m_pEventQueueTimer->start(50);  // update at 20 fps
76
77
78        // Create the audio engine :)
79        Hydrogen::get_instance();
80        Hydrogen::get_instance()->setSong( pFirstSong );
81        Preferences::getInstance()->setLastSongFilename( pFirstSong->get_filename() );
82
83        // set initial title
84        QString qsSongName( pFirstSong->__name );
85        m_pMainForm->setWindowTitle( ( "Hydrogen " + QString( get_version().c_str()) + QString( " - " ) + qsSongName ) );
86
87        Preferences *pPref = Preferences::getInstance();
88
89        setupSinglePanedInterface();
90
91        // restore audio engine form properties
92        m_pAudioEngineInfoForm = new AudioEngineInfoForm( 0 );
93        WindowProperties audioEngineInfoProp = pPref->getAudioEngineInfoProperties();
94        m_pAudioEngineInfoForm->move( audioEngineInfoProp.x, audioEngineInfoProp.y );
95        if ( audioEngineInfoProp.visible ) {
96                m_pAudioEngineInfoForm->show();
97        }
98        else {
99                m_pAudioEngineInfoForm->hide();
100        }
101       
102         m_pPlaylistDialog = new PlaylistDialog( 0 );
103//       m_pAudioFileBrowser = new AudioFileBrowser( 0 );
104       
105        showInfoSplash();       // First time information
106}
107
108
109
110HydrogenApp::~HydrogenApp()
111{
112        INFOLOG( "[~HydrogenApp]" );
113        m_pEventQueueTimer->stop();
114
115        delete m_pHelpBrowser;
116        delete m_pAudioEngineInfoForm;
117        delete m_pMixer;
118        delete m_pPlaylistDialog;
119//      delete m_pAudioFileBrowser;
120
121        Hydrogen *engine = Hydrogen::get_instance();
122        if (engine) {
123                H2Core::Song * song = engine->getSong();
124                // Hydrogen calls removeSong on from its destructor, so here we just delete the objects:
125                delete engine;
126                delete song;
127        }
128
129        #ifdef LADSPA_SUPPORT
130        for (uint nFX = 0; nFX < MAX_FX; nFX++) {
131                delete m_pLadspaFXProperties[nFX];
132        }
133        #endif
134}
135
136
137
138/// Return an HydrogenApp m_pInstance
139HydrogenApp* HydrogenApp::getInstance() {
140        if (m_pInstance == NULL) {
141                std::cerr << "Error! HydrogenApp::getInstance (m_pInstance = NULL)" << std::endl;
142        }
143        return m_pInstance;
144}
145
146
147
148
149void HydrogenApp::setupSinglePanedInterface()
150{
151        Preferences *pPref = Preferences::getInstance();
152
153        // MAINFORM
154        WindowProperties mainFormProp = pPref->getMainFormProperties();
155        m_pMainForm->resize( mainFormProp.width, mainFormProp.height );
156        m_pMainForm->move( mainFormProp.x, mainFormProp.y );
157
158        QSplitter *pSplitter = new QSplitter( NULL );
159        pSplitter->setOrientation( Qt::Vertical );
160        pSplitter->setOpaqueResize( true );
161
162        // SONG EDITOR
163        m_pSongEditorPanel = new SongEditorPanel( pSplitter );
164        WindowProperties songEditorProp = pPref->getSongEditorProperties();
165        m_pSongEditorPanel->resize( songEditorProp.width, songEditorProp.height );
166
167        // this HBox will contain the InstrumentRack and the Pattern editor
168        QWidget *pSouthPanel = new QWidget( pSplitter );
169        QHBoxLayout *pEditorHBox = new QHBoxLayout();
170        pEditorHBox->setSpacing( 5 );
171        pEditorHBox->setMargin( 0 );
172        pSouthPanel->setLayout( pEditorHBox );
173
174        // INSTRUMENT RACK
175        m_pInstrumentRack = new InstrumentRack( NULL );
176
177        // PATTERN EDITOR
178        m_pPatternEditorPanel = new PatternEditorPanel( NULL );
179        WindowProperties patternEditorProp = pPref->getPatternEditorProperties();
180        m_pPatternEditorPanel->resize( patternEditorProp.width, patternEditorProp.height );
181
182        pEditorHBox->addWidget( m_pPatternEditorPanel );
183        pEditorHBox->addWidget( m_pInstrumentRack );
184
185        // PLayer control
186        m_pPlayerControl = new PlayerControl( NULL );
187
188
189        QWidget *mainArea = new QWidget( m_pMainForm ); // this is the main widget
190        m_pMainForm->setCentralWidget( mainArea );
191
192        // LAYOUT!!
193        QVBoxLayout *pMainVBox = new QVBoxLayout();
194        pMainVBox->setSpacing( 5 );
195        pMainVBox->setMargin( 0 );
196        pMainVBox->addWidget( m_pPlayerControl );
197        pMainVBox->addWidget( pSplitter );
198
199        mainArea->setLayout( pMainVBox );
200
201
202
203
204        // MIXER
205        m_pMixer = new Mixer(0);
206        WindowProperties mixerProp = pPref->getMixerProperties();
207        m_pMixer->resize( mixerProp.width, mixerProp.height );
208        m_pMixer->move( mixerProp.x, mixerProp.y );
209        m_pMixer->updateMixer();
210        if ( mixerProp.visible ) {
211                m_pMixer->show();
212        }
213        else {
214                m_pMixer->hide();
215        }
216
217
218        // HELP BROWSER
219        QString sDocPath = QString( DataPath::get_data_path() ) + "/doc";
220        QString sDocURI = sDocPath + "/manual.html";
221        m_pHelpBrowser = new SimpleHTMLBrowser( NULL, sDocPath, sDocURI, SimpleHTMLBrowser::MANUAL );
222
223#ifdef LADSPA_SUPPORT
224        // LADSPA FX
225        for (uint nFX = 0; nFX < MAX_FX; nFX++) {
226                m_pLadspaFXProperties[nFX] = new LadspaFXProperties( NULL, nFX );
227                m_pLadspaFXProperties[nFX]->hide();
228                WindowProperties prop = pPref->getLadspaProperties(nFX);
229                m_pLadspaFXProperties[nFX]->move( prop.x, prop.y );
230                if ( prop.visible ) {
231                        m_pLadspaFXProperties[nFX]->show();
232                }
233                else {
234                        m_pLadspaFXProperties[nFX]->hide();
235                }
236        }
237#endif
238
239//      m_pMainForm->showMaximized();
240}
241
242
243void HydrogenApp::closeFXProperties()
244{
245#ifdef LADSPA_SUPPORT
246        for (uint nFX = 0; nFX < MAX_FX; nFX++) {
247                m_pLadspaFXProperties[nFX]->close();
248        }
249#endif
250}
251
252void HydrogenApp::setSong(Song* song)
253{
254
255
256        Song* oldSong = (Hydrogen::get_instance())->getSong();
257        if (oldSong != NULL) {
258                (Hydrogen::get_instance())->removeSong();
259                delete oldSong;
260                oldSong = NULL;
261        }
262
263        Hydrogen::get_instance()->setSong( song );
264        Preferences::getInstance()->setLastSongFilename( song->get_filename() );
265
266        m_pSongEditorPanel->updateAll();
267        m_pPatternEditorPanel->updateSLnameLabel();
268
269        QString songName( song->__name );
270        m_pMainForm->setWindowTitle( ( "Hydrogen " + QString(get_version().c_str()) + QString( " - " ) + songName ) );
271
272        m_pMainForm->updateRecentUsedSongList();
273}
274
275
276
277void HydrogenApp::showMixer(bool show)
278{
279        m_pMixer->setVisible( show );
280}
281
282
283
284void HydrogenApp::showPreferencesDialog()
285{
286        PreferencesDialog preferencesDialog(m_pMainForm);
287        preferencesDialog.exec();
288}
289
290
291
292
293void HydrogenApp::setStatusBarMessage( const QString& msg, int msec )
294{
295        getPlayerControl()->showMessage( msg, msec );
296}
297
298
299void HydrogenApp::setScrollStatusBarMessage( const QString& msg, int msec, bool test )
300{
301        getPlayerControl()->showScrollMessage( msg, msec , test);
302}
303
304
305
306void HydrogenApp::showAudioEngineInfoForm()
307{
308        m_pAudioEngineInfoForm->hide();
309        m_pAudioEngineInfoForm->show();
310}
311
312void HydrogenApp::showPlaylistDialog()
313{
314        m_pPlaylistDialog->hide();
315        m_pPlaylistDialog->show();
316}
317
318//void HydrogenApp::showAudioFileBrowser()
319//{
320//      m_pAudioFileBrowser->hide();
321//      m_pAudioFileBrowser->show();
322//}
323
324void HydrogenApp::showInfoSplash()
325{
326        QString sDocPath( DataPath::get_data_path().append( "/doc/infoSplash" ) );
327
328        QDir dir(sDocPath);
329        if ( !dir.exists() ) {
330                ERRORLOG( QString("[showInfoSplash] Directory ").append( sDocPath ).append( " not found." ) );
331                return;
332        }
333
334        QString sFilename = "";
335        int nNewsID = 0;
336        QFileInfoList list = dir.entryInfoList();
337
338        for ( int i =0; i < list.size(); ++i ) {
339                QString sFile = list.at( i ).fileName();
340
341                if ( sFile == "." || sFile == ".." ) {
342                        continue;
343                }
344
345                int nPos = sFile.lastIndexOf( "-" );
346                QString sNewsID = sFile.mid( nPos + 1, sFile.length() - nPos - 1 );
347                int nID = sNewsID.toInt();
348                if ( nID > nNewsID ) {
349                        sFilename = sFile;
350                }
351//              INFOLOG( "news: " + sFilename + " id: " + sNewsID );
352        }
353        INFOLOG( "[showInfoSplash] Selected news: " + sFilename );
354
355        QString sLastRead = Preferences::getInstance()->getLastNews();
356        if ( sLastRead != sFilename && sFilename != "" ) {
357                QString sDocURI = sDocPath;
358                sDocURI.append( "/" ).append( sFilename );
359                SimpleHTMLBrowser *m_pFirstTimeInfo = new SimpleHTMLBrowser( m_pMainForm, sDocPath, sDocURI, SimpleHTMLBrowser::WELCOME );
360                if ( m_pFirstTimeInfo->exec() == QDialog::Accepted ) {
361                        Preferences::getInstance()->setLastNews( sFilename );
362                }
363        }
364}
365
366void HydrogenApp::onDrumkitLoad( QString name ){
367        setStatusBarMessage( trUtf8( "Drumkit loaded: [%1]" ).arg( name ), 2000 );
368        m_pPatternEditorPanel->updateSLnameLabel( );
369}
370
371void HydrogenApp::onEventQueueTimer()
372{
373        // use the timer to do schedule instrument slaughter;
374        EventQueue *pQueue = EventQueue::get_instance();
375
376        Event event;
377        while ( ( event = pQueue->pop_event() ).type != EVENT_NONE ) {
378                for (int i = 0; i < (int)m_eventListeners.size(); i++ ) {
379                        EventListener *pListener = m_eventListeners[ i ];
380
381                        switch ( event.type ) {
382                                case EVENT_STATE:
383                                        pListener->stateChangedEvent( event.value );
384                                        break;
385
386                                case EVENT_PATTERN_CHANGED:
387                                        pListener->patternChangedEvent();
388                                        break;
389
390                                case EVENT_PATTERN_MODIFIED:
391                                        pListener->patternModifiedEvent();
392                                        break;
393
394                                case EVENT_SELECTED_PATTERN_CHANGED:
395                                        pListener->selectedPatternChangedEvent();
396                                        break;
397
398                                case EVENT_SELECTED_INSTRUMENT_CHANGED:
399                                        pListener->selectedInstrumentChangedEvent();
400                                        break;
401
402                                case EVENT_MIDI_ACTIVITY:
403                                        pListener->midiActivityEvent();
404                                        break;
405
406                                case EVENT_NOTEON:
407                                        pListener->noteOnEvent( event.value );
408                                        break;
409
410                                case EVENT_ERROR:
411                                        pListener->errorEvent( event.value );
412                                        break;
413
414                                case EVENT_XRUN:
415                                        pListener->XRunEvent();
416                                        break;
417
418                                case EVENT_METRONOME:
419                                        pListener->metronomeEvent( event.value );
420                                        break;
421
422                                case EVENT_PROGRESS:
423                                        pListener->progressEvent( event.value );
424                                        break;
425
426                                default:
427                                        ERRORLOG( "[onEventQueueTimer] Unhandled event: " + to_string( event.type ) );
428                        }
429
430                }
431        }
432}
433
434
435void HydrogenApp::addEventListener( EventListener* pListener )
436{
437        if (pListener) {
438                m_eventListeners.push_back( pListener );
439        }
440}
441
442
443void HydrogenApp::removeEventListener( EventListener* pListener )
444{
445        for ( uint i = 0; i < m_eventListeners.size(); i++ ) {
446                if ( pListener == m_eventListeners[ i ] ) {
447                        m_eventListeners.erase( m_eventListeners.begin() + i );
448                }
449        }
450}
451
Note: See TracBrowser for help on using the browser.