fixed #16810: Progress dialog instead of splash screen for new instance

This commit is contained in:
Eism 2023-05-08 14:21:47 +03:00 committed by Elnur Ismailzada
parent 12bc39b721
commit 46c5d0dfd1
17 changed files with 331 additions and 51 deletions

View file

@ -30,7 +30,7 @@
#include <QThreadPool>
#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::filename(startupScenario()->startupScorePath(), true /* includingExtension */).toQString();
splashScreen = new SplashScreen(SplashScreen::ForNewInstance, fileName);
}
splashScreen->show();
}
#endif

View file

@ -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"
@ -54,6 +55,7 @@ class App
INJECT(diagnostics::IDiagnosticDrawProvider, diagnosticDrawProvider)
INJECT(autobot::IAutobot, autobot)
INJECT(audio::IRegisterAudioPluginsScenario, registerAudioPluginsScenario)
INJECT(mi::IMultiInstancesProvider, multiInstancesProvider)
INJECT(ui::IUiConfiguration, uiConfiguration)
INJECT(appshell::IAppShellConfiguration, appshellConfiguration)
INJECT(appshell::IStartupScenario, startupScenario)

View file

@ -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}
)

View file

@ -35,6 +35,8 @@ public:
virtual ~IStartupScenario() = default;
virtual void setStartupType(const std::optional<std::string>& type) = 0;
virtual io::path_t startupScorePath() const = 0;
virtual void setStartupScorePath(const std::optional<io::path_t>& path) = 0;
virtual void run() = 0;

View file

@ -60,6 +60,11 @@ void StartupScenario::setStartupType(const std::optional<std::string>& type)
m_startupTypeStr = type ? type.value() : "";
}
mu::io::path_t StartupScenario::startupScorePath() const
{
return m_startupScorePath;
}
void StartupScenario::setStartupScorePath(const std::optional<io::path_t>& path)
{
m_startupScorePath = path ? path.value() : "";

View file

@ -47,6 +47,8 @@ class StartupScenario : public IStartupScenario, public async::Asyncable
public:
void setStartupType(const std::optional<std::string>& type) override;
io::path_t startupScorePath() const override;
void setStartupScorePath(const std::optional<io::path_t>& path) override;
void run() override;

View file

@ -20,7 +20,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "splashscreen.h"
#include "loadingscreenview.h"
#include <QApplication>
#include <QPainter>
@ -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));
}
}

View file

@ -20,8 +20,8 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MU_APPSHELL_SPLASHSCREEN_H
#define MU_APPSHELL_SPLASHSCREEN_H
#ifndef MU_APPSHELL_LOADINGSCREENVIEW_H
#define MU_APPSHELL_LOADINGSCREENVIEW_H
#include <QWidget>
@ -32,7 +32,7 @@
class QSvgRenderer;
namespace mu::appshell {
class SplashScreen : public QWidget
class LoadingScreenView : public QWidget
{
Q_OBJECT
@ -40,17 +40,15 @@ class SplashScreen : public QWidget
INJECT(languages::ILanguagesService, languagesService)
public:
SplashScreen();
explicit LoadingScreenView(QWidget* parent = nullptr);
private:
bool event(QEvent* event) override;
void repaint();
void draw(QPainter* painter);
void setSize(const QSize& size);
QString m_message;
QSvgRenderer* m_backgroundRenderer = nullptr;
};
}
#endif // MU_APPSHELL_SPLASHSCREEN_H
#endif // MU_APPSHELL_LOADINGSCREENVIEW_H

View file

@ -0,0 +1,85 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "newinstanceloadingscreenview.h"
#include <QApplication>
#include <QPainter>
#include <QScreen>
#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);
QFontMetrics fontMetrics(font);
QRectF messageRect(0, 0, m_dialogSize.width(), m_dialogSize.height());
messageRect -= QMargins(8, 8, 8, 8);
QString elidedText = fontMetrics.elidedText(m_message, Qt::ElideMiddle, messageRect.width());
painter->drawText(messageRect, Qt::AlignCenter | Qt::TextDontClip, elidedText);
}

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
#ifndef MU_APPSHELL_NEWINSTANCELOADINSCREENVIEW_H
#define MU_APPSHELL_NEWINSTANCELOADINSCREENVIEW_H
#include <QWidget>
#include "modularity/ioc.h"
#include "ui/iuiconfiguration.h"
#include "languages/ilanguagesservice.h"
class QSvgRenderer;
namespace mu::appshell {
class NewInstanceLoadingScreenView : public QWidget
{
Q_OBJECT
INJECT(ui::IUiConfiguration, uiConfiguration)
INJECT(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

View file

@ -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 <https://www.gnu.org/licenses/>.
*/
#include "splashscreen.h"
#include <QApplication>
#include <QPainter>
#include <QScreen>
#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));
}
}
}

View file

@ -0,0 +1,51 @@
/*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef MU_APPSHELL_SPLASHSCREEN_H
#define MU_APPSHELL_SPLASHSCREEN_H
#include <QWidget>
class QSvgRenderer;
namespace mu::appshell {
class SplashScreen : public QWidget
{
public:
enum SplashScreenType {
Default,
ForNewInstance
};
explicit SplashScreen(SplashScreenType type, const QVariant& data = QVariant());
private:
bool event(QEvent* event) override;
void repaint();
void draw(QPainter* painter);
void setSize(const QSize& size);
QWidget* m_view = nullptr;
};
}
#endif // MU_APPSHELL_SPLASHSCREEN_H

View file

@ -163,7 +163,7 @@ static const QMap<ThemeStyleKey, QVariant> HIGH_CONTRAST_WHITE_THEME_VALUES {
{ ITEM_OPACITY_DISABLED, 0.3 }
};
void UiConfiguration::initSettings()
void UiConfiguration::init()
{
settings()->setDefaultValue(UI_CURRENT_THEME_CODE_KEY, Val(LIGHT_THEME_CODE));
settings()->setDefaultValue(UI_FOLLOW_SYSTEM_THEME_KEY, Val(false));
@ -212,6 +212,8 @@ void UiConfiguration::initSettings()
m_uiArrangement.stateChanged(WINDOW_GEOMETRY_KEY).onNotify(this, [this]() {
m_windowGeometryChanged.notify();
});
initThemes();
}
void UiConfiguration::load()

View file

@ -40,8 +40,7 @@ class UiConfiguration : public IUiConfiguration, public async::Asyncable
INJECT(IPlatformTheme, platformTheme)
public:
void initSettings();
void initThemes();
void init();
void load();
void deinit();
@ -112,6 +111,7 @@ public:
int flickableMaxVelocity() const override;
private:
void initThemes();
void notifyAboutCurrentThemeChanged();
void updateCurrentTheme();
void updateThemes();

View file

@ -166,7 +166,7 @@ void UiModule::onPreInit(const framework::IApplication::RunMode& mode)
return;
}
m_configuration->initSettings();
m_configuration->init();
}
void UiModule::onInit(const framework::IApplication::RunMode& mode)
@ -177,7 +177,6 @@ void UiModule::onInit(const framework::IApplication::RunMode& mode)
QFontDatabase::addApplicationFont(":/fonts/mscore/MusescoreIcon.ttf"); // icons
m_configuration->initThemes();
m_keyNavigationController->init();
}

View file

@ -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;

View file

@ -37,7 +37,7 @@ public:
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;
private: