diff --git a/include/Engine.h b/include/Engine.h index ad7abe399..659c1ee1a 100644 --- a/include/Engine.h +++ b/include/Engine.h @@ -27,6 +27,9 @@ #define ENGINE_H #include +#include +#include + #include "export.h" @@ -39,8 +42,9 @@ class Song; class Ladspa2LMMS; -class EXPORT Engine +class EXPORT Engine : public QObject { + Q_OBJECT public: static void init(); static void destroy(); @@ -94,6 +98,18 @@ public: return s_pluginFileHandling; } + static inline Engine * inst() + { + if( s_instanceOfMe == NULL ) + { + s_instanceOfMe = new Engine(); + } + return s_instanceOfMe; + } + +signals: + void initProgress(const QString &msg); + private: // small helper function which sets the pointer to NULL before actually deleting @@ -120,6 +136,9 @@ private: static QMap s_pluginFileHandling; + // even though most methods are static, an instance is needed for Qt slots/signals + static Engine * s_instanceOfMe; + static void initPluginFileHandling(); friend class GuiApplication; diff --git a/include/GuiApplication.h b/include/GuiApplication.h index c35994e81..40fb4578d 100644 --- a/include/GuiApplication.h +++ b/include/GuiApplication.h @@ -25,8 +25,12 @@ #ifndef GUIAPPLICATION_H #define GUIAPPLICATION_H +#include + #include "export.h" +class QLabel; + class AutomationEditorWindow; class BBEditor; class ControllerRackView; @@ -36,8 +40,9 @@ class PianoRollWindow; class ProjectNotes; class SongEditorWindow; -class EXPORT GuiApplication +class EXPORT GuiApplication : public QObject { + Q_OBJECT; public: explicit GuiApplication(); ~GuiApplication(); @@ -53,6 +58,9 @@ public: AutomationEditorWindow* automationEditor() { return m_automationEditor; } ControllerRackView* getControllerRackView() { return m_controllerRackView; } +public slots: + void displayInitProgress(const QString &msg); + private: static GuiApplication* s_instance; @@ -64,6 +72,7 @@ private: PianoRollWindow* m_pianoRoll; ProjectNotes* m_projectNotes; ControllerRackView* m_controllerRackView; + QLabel* m_loadingProgressLabel; }; #define gui GuiApplication::instance() diff --git a/include/MainWindow.h b/include/MainWindow.h index 5e1f294ae..f842cef00 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -190,6 +190,7 @@ private slots: signals: void periodicUpdate(); + void initProgress(const QString &msg); } ; diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 5730e977e..8e5d85139 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -52,11 +52,16 @@ QMap Engine::s_pluginFileHandling; void Engine::init() { + Engine *engine = inst(); + + emit engine->initProgress(tr("Generating wavetables")); // generate (load from file) bandlimited wavetables BandLimitedWave::generateWaves(); + emit engine->initProgress(tr("Locating plugins")); initPluginFileHandling(); + emit engine->initProgress(tr("Initializing data structures")); s_projectJournal = new ProjectJournal; s_mixer = new Mixer; s_song = new Song; @@ -67,11 +72,13 @@ void Engine::init() s_projectJournal->setJournalling( true ); + emit engine->initProgress(tr("Opening audio and midi devices")); s_mixer->initDevices(); PresetPreviewPlayHandle::init(); s_dummyTC = new DummyTrackContainer; + emit engine->initProgress(tr("Launching mixer threads")); s_mixer->startProcessing(); } @@ -142,3 +149,4 @@ void Engine::initPluginFileHandling() } +Engine * Engine::s_instanceOfMe = NULL; diff --git a/src/gui/GuiApplication.cpp b/src/gui/GuiApplication.cpp index 78cf609ef..64edcb364 100644 --- a/src/gui/GuiApplication.cpp +++ b/src/gui/GuiApplication.cpp @@ -49,6 +49,7 @@ GuiApplication* GuiApplication::instance() return s_instance; } + GuiApplication::GuiApplication() { // Init style and palette @@ -64,27 +65,60 @@ GuiApplication::GuiApplication() // Show splash screen QSplashScreen splashScreen( embed::getIconPixmap( "splash" ) ); splashScreen.show(); - splashScreen.showMessage( MainWindow::tr( "Version %1" ).arg( LMMS_VERSION ), - Qt::AlignRight | Qt::AlignBottom, Qt::white ); + + QHBoxLayout layout; + layout.setAlignment(Qt::AlignBottom); + splashScreen.setLayout(&layout); + + // Create a left-aligned label for loading progress + // & a right-aligned label for version info + QLabel loadingProgressLabel; + m_loadingProgressLabel = &loadingProgressLabel; + QLabel versionLabel(MainWindow::tr( "Version %1" ).arg( LMMS_VERSION )); + + loadingProgressLabel.setAlignment(Qt::AlignLeft); + versionLabel.setAlignment(Qt::AlignRight); + + layout.addWidget(&loadingProgressLabel); + layout.addWidget(&versionLabel); + + // may have long gaps between future frames, so force update now + splashScreen.update(); qApp->processEvents(); + connect(Engine::inst(), SIGNAL(initProgress(const QString&)), + this, SLOT(displayInitProgress(const QString&))); + // Init central engine which handles all components of LMMS Engine::init(); s_instance = this; - m_mainWindow = new MainWindow; + displayInitProgress(tr("Preparing UI")); + m_mainWindow = new MainWindow; + connect(m_mainWindow, SIGNAL(initProgress(const QString&)), + this, SLOT(displayInitProgress(const QString&))); + + displayInitProgress(tr("Preparing song editor")); m_songEditor = new SongEditorWindow(Engine::getSong()); + displayInitProgress(tr("Preparing mixer")); m_fxMixerView = new FxMixerView; + displayInitProgress(tr("Preparing controller rack")); m_controllerRackView = new ControllerRackView; + displayInitProgress(tr("Preparing project notes")); m_projectNotes = new ProjectNotes; + displayInitProgress(tr("Preparing beat/baseline editor")); m_bbEditor = new BBEditor(Engine::getBBTrackContainer()); + displayInitProgress(tr("Preparing piano roll")); m_pianoRoll = new PianoRollWindow(); + displayInitProgress(tr("Preparing automation editor")); m_automationEditor = new AutomationEditorWindow; m_mainWindow->finalize(); splashScreen.finish(m_mainWindow); + + m_loadingProgressLabel = nullptr; } GuiApplication::~GuiApplication() @@ -92,3 +126,14 @@ GuiApplication::~GuiApplication() InstrumentTrackView::cleanupWindowCache(); s_instance = nullptr; } + + +void GuiApplication::displayInitProgress(const QString &msg) +{ + Q_ASSERT(m_loadingProgressLabel != nullptr); + + m_loadingProgressLabel->setText(msg); + // must force a UI update and process events, as there may be long gaps between processEvents() calls during init + m_loadingProgressLabel->repaint(); + qApp->processEvents(); +} \ No newline at end of file diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 78df3798b..6dc28dffe 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -96,7 +96,9 @@ MainWindow::MainWindow() : ConfigManager* confMgr = ConfigManager::inst(); + emit initProgress(tr("Preparing plugin browser")); sideBar->appendTab( new PluginBrowser( splitter ) ); + emit initProgress(tr("Preparing file browsers")); sideBar->appendTab( new FileBrowser( confMgr->userProjectsDir() + "*" + confMgr->factoryProjectsDir(), @@ -150,6 +152,7 @@ MainWindow::MainWindow() : m_workspace = new QMdiArea( splitter ); // Load background + emit initProgress(tr("Loading background artwork")); QString bgArtwork = ConfigManager::inst()->backgroundArtwork(); QImage bgImage; if( !bgArtwork.isEmpty() )