diff --git a/src/app/app.cpp b/src/app/app.cpp index 2a92892d94342..89ea85c9ef0e2 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -30,7 +30,7 @@ #include #endif -#include "appshell/view/internal/splashscreen.h" +#include "appshell/view/internal/splashscreen/splashscreen.h" #include "appshell/view/dockwindow/docksetup.h" #include "modularity/ioc.h" @@ -166,7 +166,13 @@ int App::run(int argc, char** argv) #ifdef MUE_BUILD_APPSHELL_MODULE SplashScreen* splashScreen = nullptr; if (runMode == framework::IApplication::RunMode::GuiApp) { - splashScreen = new SplashScreen(); + if (multiInstancesProvider()->isMainInstance()) { + splashScreen = new SplashScreen(SplashScreen::Default); + } else { + QString fileName = io::basename(startupScenario()->startupScorePath()).toQString(); + splashScreen = new SplashScreen(SplashScreen::ForNewInstance, fileName); + } + splashScreen->show(); } #endif diff --git a/src/app/app.h b/src/app/app.h index 623d02d673c6e..b8b6130355bf9 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -32,6 +32,7 @@ #include "diagnostics/idiagnosticdrawprovider.h" #include "autobot/iautobot.h" #include "audio/iregisteraudiopluginsscenario.h" +#include "multiinstances/imultiinstancesprovider.h" #include "ui/iuiconfiguration.h" #include "notation/inotationconfiguration.h" @@ -64,6 +65,7 @@ class App INJECT(app, iex::audioexport::IAudioExportConfiguration, audioExportConfiguration) INJECT(app, iex::videoexport::IVideoExportConfiguration, videoExportConfiguration) INJECT(app, iex::guitarpro::IGuitarProConfiguration, guitarProConfiguration) + INJECT(app, mi::IMultiInstancesProvider, multiInstancesProvider) public: App(); diff --git a/src/appshell/CMakeLists.txt b/src/appshell/CMakeLists.txt index 2e98a4d64054a..15d9b9bdfc370 100644 --- a/src/appshell/CMakeLists.txt +++ b/src/appshell/CMakeLists.txt @@ -98,8 +98,12 @@ set(MODULE_SRC ${CMAKE_CURRENT_LIST_DIR}/view/internal/iappmenumodelhook.h ${CMAKE_CURRENT_LIST_DIR}/view/internal/maintoolbarmodel.cpp ${CMAKE_CURRENT_LIST_DIR}/view/internal/maintoolbarmodel.h - ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen.cpp - ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen.h + ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen/splashscreen.cpp + ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen/splashscreen.h + ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen/loadingscreenview.cpp + ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen/loadingscreenview.h + ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen/newinstanceloadingscreenview.cpp + ${CMAKE_CURRENT_LIST_DIR}/view/internal/splashscreen/newinstanceloadingscreenview.h ${DOCKWINDOW_SRC} ) diff --git a/src/appshell/internal/istartupscenario.h b/src/appshell/internal/istartupscenario.h index 01c3e0d20fbae..c19027cb61388 100644 --- a/src/appshell/internal/istartupscenario.h +++ b/src/appshell/internal/istartupscenario.h @@ -35,6 +35,8 @@ class IStartupScenario : MODULE_EXPORT_INTERFACE virtual ~IStartupScenario() = default; virtual void setStartupType(const std::optional& type) = 0; + + virtual io::path_t startupScorePath() const = 0; virtual void setStartupScorePath(const std::optional& path) = 0; virtual void run() = 0; diff --git a/src/appshell/internal/startupscenario.cpp b/src/appshell/internal/startupscenario.cpp index 73e00ffff0ef1..1cb13b17a1b3f 100644 --- a/src/appshell/internal/startupscenario.cpp +++ b/src/appshell/internal/startupscenario.cpp @@ -60,6 +60,11 @@ void StartupScenario::setStartupType(const std::optional& type) m_startupTypeStr = type ? type.value() : ""; } +mu::io::path_t StartupScenario::startupScorePath() const +{ + return m_startupScorePath; +} + void StartupScenario::setStartupScorePath(const std::optional& path) { m_startupScorePath = path ? path.value() : ""; diff --git a/src/appshell/internal/startupscenario.h b/src/appshell/internal/startupscenario.h index 9908a72758c60..e5b947a24dd54 100644 --- a/src/appshell/internal/startupscenario.h +++ b/src/appshell/internal/startupscenario.h @@ -47,6 +47,8 @@ class StartupScenario : public IStartupScenario, public async::Asyncable public: void setStartupType(const std::optional& type) override; + + io::path_t startupScorePath() const override; void setStartupScorePath(const std::optional& path) override; void run() override; diff --git a/src/appshell/view/internal/splashscreen.cpp b/src/appshell/view/internal/splashscreen/loadingscreenview.cpp similarity index 71% rename from src/appshell/view/internal/splashscreen.cpp rename to src/appshell/view/internal/splashscreen/loadingscreenview.cpp index b10f220108815..8a4c528011201 100644 --- a/src/appshell/view/internal/splashscreen.cpp +++ b/src/appshell/view/internal/splashscreen/loadingscreenview.cpp @@ -20,7 +20,7 @@ * along with this program. If not, see . */ -#include "splashscreen.h" +#include "loadingscreenview.h" #include #include @@ -34,43 +34,28 @@ using namespace mu::appshell; static const QString imagePath(":/resources/LoadingScreen.svg"); -static constexpr QSize splashScreenSize(810, 405); +static constexpr QSize loadingScreenSize(810, 405); static const QColor messageColor("#99FFFFFF"); -static constexpr QRectF messageRect(splashScreenSize.width() / 2, 269, 0, 0); +static constexpr QRectF messageRect(loadingScreenSize.width() / 2, 269, 0, 0); static const QString website("www.musescore.org"); -static constexpr QRectF websiteRect(splashScreenSize.width() - 48, splashScreenSize.height() - 48, 0, 0); +static constexpr QRectF websiteRect(loadingScreenSize.width() - 48, loadingScreenSize.height() - 48, 0, 0); static const QColor versionNumberColor("#22A0F4"); static constexpr qreal versionNumberSpacing = 5.0; -#ifdef Q_OS_MAC -// Necessary to remove undesired background, so that we really get our rounded corners -static constexpr Qt::WindowFlags splashScreenWindowFlags = (Qt::SplashScreen | Qt::FramelessWindowHint) & ~Qt::Sheet | Qt::Window; -#else -static constexpr Qt::WindowFlags splashScreenWindowFlags = Qt::SplashScreen | Qt::FramelessWindowHint; -#endif - -SplashScreen::SplashScreen() - : QWidget(nullptr, splashScreenWindowFlags), +LoadingScreenView::LoadingScreenView(QWidget* parent) + : QWidget(parent), m_backgroundRenderer(new QSvgRenderer(imagePath, this)) { setAttribute(Qt::WA_TranslucentBackground); - setSize(splashScreenSize); + resize(loadingScreenSize); m_message = qtrc("appshell", "Loading…\u200e"); - - repaint(); -} - -void SplashScreen::repaint() -{ - QWidget::repaint(); - QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); } -bool SplashScreen::event(QEvent* event) +bool LoadingScreenView::event(QEvent* event) { if (event->type() == QEvent::Paint) { QPainter painter(this); @@ -81,7 +66,7 @@ bool SplashScreen::event(QEvent* event) return QWidget::event(event); } -void SplashScreen::draw(QPainter* painter) +void LoadingScreenView::draw(QPainter* painter) { painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); @@ -114,12 +99,3 @@ void SplashScreen::draw(QPainter* painter) Qt::AlignBottom | alignment | Qt::TextDontClip, qtrc("appshell", "Version %1").arg(QString::fromStdString(framework::MUVersion::fullVersion().toStdString()))); } - -void SplashScreen::setSize(const QSize& size) -{ - resize(size); - - if (screen()) { - move(screen()->geometry().center() - QPoint(size.width() / 2, size.height() / 2)); - } -} diff --git a/src/appshell/view/internal/splashscreen/loadingscreenview.h b/src/appshell/view/internal/splashscreen/loadingscreenview.h new file mode 100644 index 0000000000000..9128772dd6cf2 --- /dev/null +++ b/src/appshell/view/internal/splashscreen/loadingscreenview.h @@ -0,0 +1,54 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2022 MuseScore BVBA and others + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MU_APPSHELL_LOADINGSCREENVIEW_H +#define MU_APPSHELL_LOADINGSCREENVIEW_H + +#include + +#include "modularity/ioc.h" +#include "ui/iuiconfiguration.h" +#include "languages/ilanguagesservice.h" + +class QSvgRenderer; + +namespace mu::appshell { +class LoadingScreenView : public QWidget +{ + Q_OBJECT + + INJECT(appshell, ui::IUiConfiguration, uiConfiguration) + INJECT(appshell, languages::ILanguagesService, languagesService) + +public: + explicit LoadingScreenView(QWidget* parent = nullptr); + +private: + bool event(QEvent* event) override; + void draw(QPainter* painter); + + QString m_message; + QSvgRenderer* m_backgroundRenderer = nullptr; +}; +} + +#endif // MU_APPSHELL_LOADINGSCREENVIEW_H diff --git a/src/appshell/view/internal/splashscreen/newinstanceloadingscreenview.cpp b/src/appshell/view/internal/splashscreen/newinstanceloadingscreenview.cpp new file mode 100644 index 0000000000000..09665439140a2 --- /dev/null +++ b/src/appshell/view/internal/splashscreen/newinstanceloadingscreenview.cpp @@ -0,0 +1,81 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2022 MuseScore BVBA and others + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "newinstanceloadingscreenview.h" + +#include +#include +#include + +#include "translation.h" + +using namespace mu::appshell; + +NewInstanceLoadingScreenView::NewInstanceLoadingScreenView(const QString& openingFileName) + : QWidget(nullptr) +{ + setAttribute(Qt::WA_TranslucentBackground); + + if (openingFileName.isEmpty()) { + m_message = qtrc("appshell", "Loading new score…\u200e"); + m_dialogSize = QSize(288, 80); + } else { + m_message = qtrc("appshell", "Loading \"%1\"…\u200e").arg(openingFileName); + m_dialogSize = QSize(360, 80); + } + + resize(m_dialogSize); +} + +bool NewInstanceLoadingScreenView::event(QEvent* event) +{ + if (event->type() == QEvent::Paint) { + QPainter painter(this); + painter.setLayoutDirection(layoutDirection()); + draw(&painter); + } + + return QWidget::event(event); +} + +void NewInstanceLoadingScreenView::draw(QPainter* painter) +{ + painter->setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform); + + // Draw background + QString bgColorStr = uiConfiguration()->currentTheme().values.value(ui::BACKGROUND_PRIMARY_COLOR).toString(); + painter->fillRect(0, 0, width(), height(), QColor(bgColorStr)); + + // Draw message + QFont font(QString::fromStdString(uiConfiguration()->fontFamily())); + font.setPixelSize(uiConfiguration()->fontSize(ui::FontSizeType::BODY_LARGE)); + font.setBold(true); + + painter->setFont(font); + + QString messageColorStr = uiConfiguration()->currentTheme().values.value(ui::FONT_PRIMARY_COLOR).toString(); + QPen pen(messageColorStr); + painter->setPen(pen); + + const QRectF messageRect(m_dialogSize.width() / 2, m_dialogSize.height() / 2, 0, 0); + painter->drawText(messageRect, Qt::AlignCenter | Qt::TextDontClip, m_message); +} diff --git a/src/appshell/view/internal/splashscreen/newinstanceloadingscreenview.h b/src/appshell/view/internal/splashscreen/newinstanceloadingscreenview.h new file mode 100644 index 0000000000000..a7c5f670d3ca0 --- /dev/null +++ b/src/appshell/view/internal/splashscreen/newinstanceloadingscreenview.h @@ -0,0 +1,55 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2022 MuseScore BVBA and others + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MU_APPSHELL_NEWINSTANCELOADINSCREENVIEW_H +#define MU_APPSHELL_NEWINSTANCELOADINSCREENVIEW_H + +#include + +#include "modularity/ioc.h" +#include "ui/iuiconfiguration.h" +#include "languages/ilanguagesservice.h" + +class QSvgRenderer; + +namespace mu::appshell { +class NewInstanceLoadingScreenView : public QWidget +{ + Q_OBJECT + + INJECT(appshell, ui::IUiConfiguration, uiConfiguration) + INJECT(appshell, languages::ILanguagesService, languagesService) + +public: + explicit NewInstanceLoadingScreenView(const QString& openingFileName); + +private: + bool event(QEvent* event) override; + void draw(QPainter* painter); + + QString m_message; + + QSize m_dialogSize; +}; +} + +#endif // MU_APPSHELL_NEWINSTANCELOADINSCREENVIEW_H diff --git a/src/appshell/view/internal/splashscreen/splashscreen.cpp b/src/appshell/view/internal/splashscreen/splashscreen.cpp new file mode 100644 index 0000000000000..a41d35eb67bc7 --- /dev/null +++ b/src/appshell/view/internal/splashscreen/splashscreen.cpp @@ -0,0 +1,93 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-CLA-applies + * + * MuseScore + * Music Composition & Notation + * + * Copyright (C) 2022 MuseScore BVBA and others + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "splashscreen.h" + +#include +#include +#include + +#include "loadingscreenview.h" +#include "newinstanceloadingscreenview.h" + +using namespace mu::appshell; + +#ifdef Q_OS_MAC +// Necessary to remove undesired background, so that we really get our rounded corners +static constexpr Qt::WindowFlags splashScreenWindowFlags = (Qt::SplashScreen | Qt::FramelessWindowHint) & ~Qt::Sheet | Qt::Window; +#else +static constexpr Qt::WindowFlags splashScreenWindowFlags = Qt::SplashScreen | Qt::FramelessWindowHint; +#endif + +SplashScreen::SplashScreen(SplashScreen::SplashScreenType type, const QVariant& data) + : QWidget(nullptr, splashScreenWindowFlags) +{ + setAttribute(Qt::WA_TranslucentBackground); + + switch (type) { + case SplashScreen::Default: + m_view = new LoadingScreenView(); + break; + case SplashScreen::ForNewInstance: + m_view = new NewInstanceLoadingScreenView(data.toString()); + break; + } + + setSize(m_view->size()); + + repaint(); +} + +void SplashScreen::repaint() +{ + QWidget::repaint(); + QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents); +} + +bool SplashScreen::event(QEvent* event) +{ + if (event->type() == QEvent::Paint) { + QPainter painter(this); + painter.setLayoutDirection(layoutDirection()); + draw(&painter); + } + + return QWidget::event(event); +} + +void SplashScreen::draw(QPainter* painter) +{ + if (m_view) { + m_view->render(painter); + } +} + +void SplashScreen::setSize(const QSize& size) +{ + if (m_view) { + resize(m_view->size()); + + if (screen()) { + move(screen()->geometry().center() - QPoint(size.width() / 2, size.height() / 2)); + } + } +} diff --git a/src/appshell/view/internal/splashscreen.h b/src/appshell/view/internal/splashscreen/splashscreen.h similarity index 76% rename from src/appshell/view/internal/splashscreen.h rename to src/appshell/view/internal/splashscreen/splashscreen.h index 3af5b03b0dc7f..5cbe0921070b2 100644 --- a/src/appshell/view/internal/splashscreen.h +++ b/src/appshell/view/internal/splashscreen/splashscreen.h @@ -25,22 +25,18 @@ #include -#include "modularity/ioc.h" -#include "ui/iuiconfiguration.h" -#include "languages/ilanguagesservice.h" - class QSvgRenderer; namespace mu::appshell { class SplashScreen : public QWidget { - Q_OBJECT - - INJECT(appshell, ui::IUiConfiguration, uiConfiguration) - INJECT(appshell, languages::ILanguagesService, languagesService) - public: - SplashScreen(); + enum SplashScreenType { + Default, + ForNewInstance + }; + + explicit SplashScreen(SplashScreenType type, const QVariant& data = QVariant()); private: bool event(QEvent* event) override; @@ -48,8 +44,7 @@ class SplashScreen : public QWidget void draw(QPainter* painter); void setSize(const QSize& size); - QString m_message; - QSvgRenderer* m_backgroundRenderer = nullptr; + QWidget* m_view = nullptr; }; } diff --git a/src/multiinstances/multiinstancesmodule.cpp b/src/multiinstances/multiinstancesmodule.cpp index 0c1d3f87ae174..9494d093d1d5d 100644 --- a/src/multiinstances/multiinstancesmodule.cpp +++ b/src/multiinstances/multiinstancesmodule.cpp @@ -75,7 +75,7 @@ void MultiInstancesModule::registerResources() multiinstances_init_qrc(); } -void MultiInstancesModule::onInit(const framework::IApplication::RunMode& mode) +void MultiInstancesModule::onPreInit(const framework::IApplication::RunMode& mode) { if (mode != framework::IApplication::RunMode::GuiApp) { return; diff --git a/src/multiinstances/multiinstancesmodule.h b/src/multiinstances/multiinstancesmodule.h index 7524aa6507315..bbbfc0dd85113 100644 --- a/src/multiinstances/multiinstancesmodule.h +++ b/src/multiinstances/multiinstancesmodule.h @@ -34,7 +34,7 @@ class MultiInstancesModule : public modularity::IModuleSetup void resolveImports() override; void registerUiTypes() override; void registerResources() override; - void onInit(const framework::IApplication::RunMode& mode) override; + void onPreInit(const framework::IApplication::RunMode& mode) override; }; }