qt: Splashscreen redesign (#3613)

* qt: Splashscreen redesign

- Make it theme related dark or light
- Fixes bluriness issues
- Fixes issues with overlapping init messages at the bottom of the
splashscreen
- Give it a cleaner look -> Removed copyrights and prefix `Version v` of the version string

* Do not rotate colors of the splash image

* Adjust logo color based on the current theme for all networks

* Draw network-specific text as a "badge" with a network-specific color

* Introduce `NetworkStyle::rotateColor()` helper

* Introduce badge color in NetworkStyle and use it in SplashScreen's ctor

Replaces the getTrayAndWindowIcon hack

* refactor loops

Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
This commit is contained in:
dustinface 2020-07-28 22:49:17 +02:00 committed by GitHub
parent a37ad95ae8
commit 3408f4a9d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 90 additions and 64 deletions

View File

@ -28,6 +28,20 @@ static const struct {
}; };
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles); static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
void NetworkStyle::rotateColor(QColor& col, const int iconColorHueShift, const int iconColorSaturationReduction)
{
int h, s, l, a;
col.getHsl(&h, &s, &l, &a);
// rotate color on RGB color circle
h += iconColorHueShift;
// change saturation value
s -= iconColorSaturationReduction;
s = std::max(s, 0);
col.setHsl(h,s,l,a);
}
void NetworkStyle::rotateColors(QImage& img, const int iconColorHueShift, const int iconColorSaturationReduction) { void NetworkStyle::rotateColors(QImage& img, const int iconColorHueShift, const int iconColorSaturationReduction) {
int h,s,l,a; int h,s,l,a;
@ -39,24 +53,9 @@ void NetworkStyle::rotateColors(QImage& img, const int iconColorHueShift, const
// loop through pixels // loop through pixels
for(int x=0;x<img.width();x++) for(int x=0;x<img.width();x++)
{ {
// preserve alpha because QColor::getHsl doesn't return the alpha value QColor col;
a = qAlpha(scL[x]); col.setRgba(scL[x]);
QColor col(scL[x]); rotateColor(col, iconColorHueShift, iconColorSaturationReduction);
// get hue value
col.getHsl(&h,&s,&l);
// rotate color on RGB color circle
// 70° should end up with the typical "testnet" green (in bitcoin)
h+=iconColorHueShift;
// change saturation value
s -= iconColorSaturationReduction;
s = std::max(s, 0);
col.setHsl(h,s,l,a);
// set the pixel
scL[x] = col.rgba(); scL[x] = col.rgba();
} }
} }
@ -65,7 +64,8 @@ void NetworkStyle::rotateColors(QImage& img, const int iconColorHueShift, const
// titleAddText needs to be const char* for tr() // titleAddText needs to be const char* for tr()
NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *_titleAddText): NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *_titleAddText):
appName(_appName), appName(_appName),
titleAddText(qApp->translate("SplashScreen", _titleAddText)) titleAddText(qApp->translate("SplashScreen", _titleAddText)),
badgeColor(QColor(0, 141, 228)) // default badge color is the original Dash's blue, regardless of the current theme
{ {
// Allow for separate UI settings for testnets // Allow for separate UI settings for testnets
QApplication::setApplicationName(appName); QApplication::setApplicationName(appName);
@ -73,25 +73,21 @@ NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift,
GUIUtil::migrateQtSettings(); GUIUtil::migrateQtSettings();
// load pixmap // load pixmap
QPixmap appIconPixmap(":/icons/bitcoin"); QPixmap appIconPixmap(":/icons/bitcoin");
QPixmap splashImagePixmap(":/images/splash");
if(iconColorHueShift != 0 && iconColorSaturationReduction != 0) if(iconColorHueShift != 0 && iconColorSaturationReduction != 0)
{ {
// generate QImage from QPixmap // generate QImage from QPixmap
QImage appIconImg = appIconPixmap.toImage(); QImage appIconImg = appIconPixmap.toImage();
QImage splashImageImg = splashImagePixmap.toImage();
rotateColors(appIconImg, iconColorHueShift, iconColorSaturationReduction); rotateColors(appIconImg, iconColorHueShift, iconColorSaturationReduction);
rotateColors(splashImageImg, iconColorHueShift, iconColorSaturationReduction);
//convert back to QPixmap //convert back to QPixmap
appIconPixmap.convertFromImage(appIconImg); appIconPixmap.convertFromImage(appIconImg);
splashImagePixmap.convertFromImage(splashImageImg); // tweak badge color
rotateColor(badgeColor, iconColorHueShift, iconColorSaturationReduction);
} }
appIcon = QIcon(appIconPixmap); appIcon = QIcon(appIconPixmap);
trayAndWindowIcon = QIcon(appIconPixmap.scaled(QSize(256,256))); trayAndWindowIcon = QIcon(appIconPixmap.scaled(QSize(256,256)));
splashImage = splashImagePixmap; splashImage = QPixmap(":/images/splash");
} }
const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)

View File

@ -22,6 +22,7 @@ public:
const QPixmap &getSplashImage() const { return splashImage; } const QPixmap &getSplashImage() const { return splashImage; }
const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; } const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; }
const QString &getTitleAddText() const { return titleAddText; } const QString &getTitleAddText() const { return titleAddText; }
const QColor &getBadgeColor() const { return badgeColor; }
private: private:
NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText); NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText);
@ -31,7 +32,9 @@ private:
QPixmap splashImage; QPixmap splashImage;
QIcon trayAndWindowIcon; QIcon trayAndWindowIcon;
QString titleAddText; QString titleAddText;
QColor badgeColor;
void rotateColor(QColor& col, const int iconColorHueShift, const int iconColorSaturationReduction);
void rotateColors(QImage& img, const int iconColorHueShift, const int iconColorSaturationReduction); void rotateColors(QImage& img, const int iconColorHueShift, const int iconColorSaturationReduction);
}; };

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -12,6 +12,7 @@
#include <qt/guiutil.h> #include <qt/guiutil.h>
#include <qt/networkstyle.h> #include <qt/networkstyle.h>
#include <chainparams.h>
#include <clientversion.h> #include <clientversion.h>
#include <init.h> #include <init.h>
#include <util.h> #include <util.h>
@ -37,70 +38,94 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
// no window decorations // no window decorations
setWindowFlags(Qt::FramelessWindowHint); setWindowFlags(Qt::FramelessWindowHint);
// Geometries of splashscreen
int width = 380;
int height = 460;
int logoWidth = 270;
int logoHeight = 270;
// set reference point, paddings // set reference point, paddings
int paddingLeft = 14; int paddingTop = 10;
int paddingTop = 470; int titleVersionVSpace = 25;
int titleVersionVSpace = 17;
int titleCopyrightVSpace = 22;
float fontFactor = 1.0; float fontFactor = 1.0;
float scale = qApp->devicePixelRatio();
// define text to place // define text to place
QString titleText = tr(PACKAGE_NAME); QString titleText = tr(PACKAGE_NAME);
QString versionText = QString(tr("Version %1")).arg(QString::fromStdString(FormatFullVersion())); QString versionText = QString::fromStdString(FormatFullVersion()).remove(0, 1);
QString copyrightText = QString::fromUtf8(CopyrightHolders("\xc2\xA9", 2014, COPYRIGHT_YEAR).c_str());
QString titleAddText = networkStyle->getTitleAddText(); QString titleAddText = networkStyle->getTitleAddText();
QFont font = GUIUtil::getFontNormal(); QFont fontNormal = GUIUtil::getFontNormal();
QFont fontBold = GUIUtil::getFontBold();
// load the bitmap for writing some text over it QPixmap pixmapLogo = networkStyle->getSplashImage();
pixmap = networkStyle->getSplashImage(); pixmapLogo.setDevicePixelRatio(scale);
// Adjust logo color based on the current theme
QImage imgLogo = pixmapLogo.toImage().convertToFormat(QImage::Format_ARGB32);
QColor logoColor = GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BLUE);
for (int x = 0; x < imgLogo.width(); ++x) {
for (int y = 0; y < imgLogo.height(); ++y) {
const QRgb rgb = imgLogo.pixel(x, y);
imgLogo.setPixel(x, y, qRgba(logoColor.red(), logoColor.green(), logoColor.blue(), qAlpha(rgb)));
}
}
pixmapLogo.convertFromImage(imgLogo);
pixmap = QPixmap(width * scale, height * scale);
pixmap.setDevicePixelRatio(scale);
pixmap.fill(GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BORDER_WIDGET));
QPainter pixPaint(&pixmap); QPainter pixPaint(&pixmap);
pixPaint.setPen(QColor(100,100,100));
QRect rect = QRect(1, 1, width - 2, height - 2);
pixPaint.fillRect(rect, GUIUtil::getThemedQColor(GUIUtil::ThemedColor::BACKGROUND_WIDGET));
pixPaint.drawPixmap((width / 2) - (logoWidth / 2), (height / 2) - (logoHeight / 2) + 20, pixmapLogo.scaled(logoWidth * scale, logoHeight * scale, Qt::KeepAspectRatio, Qt::SmoothTransformation));
pixPaint.setPen(GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT));
// check font size and drawing with // check font size and drawing with
font.setPointSize(28 * fontFactor); fontBold.setPointSize(50 * fontFactor);
pixPaint.setFont(font); pixPaint.setFont(fontBold);
QFontMetrics fm = pixPaint.fontMetrics(); QFontMetrics fm = pixPaint.fontMetrics();
int titleTextWidth = fm.width(titleText); int titleTextWidth = fm.width(titleText);
if (titleTextWidth > 160) { if (titleTextWidth > width * 0.8) {
fontFactor = 0.75; fontFactor = 0.75;
} }
font.setPointSize(28 * fontFactor); fontBold.setPointSize(50 * fontFactor);
pixPaint.setFont(font); pixPaint.setFont(fontBold);
fm = pixPaint.fontMetrics(); fm = pixPaint.fontMetrics();
titleTextWidth = fm.width(titleText); titleTextWidth = fm.width(titleText);
pixPaint.drawText(paddingLeft,paddingTop,titleText); int titleTextHeight = fm.height();
pixPaint.drawText((width / 2) - (titleTextWidth / 2), titleTextHeight + paddingTop, titleText);
font.setPointSize(15 * fontFactor); fontNormal.setPointSize(16 * fontFactor);
pixPaint.setFont(font); pixPaint.setFont(fontNormal);
pixPaint.drawText(paddingLeft,paddingTop+titleVersionVSpace,versionText); fm = pixPaint.fontMetrics();
int versionTextWidth = fm.width(versionText);
// draw copyright stuff pixPaint.drawText((width / 2) - (versionTextWidth / 2), titleTextHeight + paddingTop + titleVersionVSpace, versionText);
{
font.setPointSize(10 * fontFactor);
pixPaint.setFont(font);
const int x = paddingLeft;
const int y = paddingTop+titleCopyrightVSpace;
QRect copyrightRect(x, y, pixmap.width() - x, pixmap.height() - y);
pixPaint.drawText(copyrightRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, copyrightText);
}
// draw additional text if special network // draw additional text if special network
if(!titleAddText.isEmpty()) { if(!titleAddText.isEmpty()) {
QFont boldFont = GUIUtil::getFontBold(); fontBold.setPointSize(10 * fontFactor);
boldFont.setPointSize(10 * fontFactor); pixPaint.setFont(fontBold);
fm = pixPaint.fontMetrics(); fm = pixPaint.fontMetrics();
int titleAddTextWidth = fm.width(titleAddText); int titleAddTextWidth = fm.width(titleAddText);
pixPaint.drawText(pixmap.width()-titleAddTextWidth-10,pixmap.height()-25,titleAddText); // Draw the badge backround with the network-specific color
QRect badgeRect = QRect(width - titleAddTextWidth - 20, 5, width, fm.height() + 10);
QColor badgeColor = networkStyle->getBadgeColor();
pixPaint.fillRect(badgeRect, badgeColor);
// Draw the text itself using white color, regardless of the current theme
pixPaint.setPen(QColor(255, 255, 255));
pixPaint.drawText(width - titleAddTextWidth - 10, paddingTop + 10, titleAddText);
} }
pixPaint.end(); pixPaint.end();
// Resize window and move to center of desktop, disallow resizing // Resize window and move to center of desktop, disallow resizing
QRect r(QPoint(), pixmap.size()); QRect r(QPoint(), QSize(width, height));
resize(r.size()); resize(r.size());
setFixedSize(r.size()); setFixedSize(r.size());
move(QApplication::desktop()->screenGeometry().center() - r.center()); move(QApplication::desktop()->screenGeometry().center() - r.center());
@ -142,7 +167,7 @@ static void InitMessage(SplashScreen *splash, const std::string &message)
Qt::QueuedConnection, Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(message)), Q_ARG(QString, QString::fromStdString(message)),
Q_ARG(int, Qt::AlignBottom | Qt::AlignHCenter), Q_ARG(int, Qt::AlignBottom | Qt::AlignHCenter),
Q_ARG(QColor, QColor(55,55,55))); Q_ARG(QColor, GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT)));
} }
static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress, bool resume_possible) static void ShowProgress(SplashScreen *splash, const std::string &title, int nProgress, bool resume_possible)
@ -195,9 +220,11 @@ void SplashScreen::showMessage(const QString &message, int alignment, const QCol
void SplashScreen::paintEvent(QPaintEvent *event) void SplashScreen::paintEvent(QPaintEvent *event)
{ {
QPainter painter(this); QPainter painter(this);
painter.setFont(GUIUtil::getFontNormal()); QFont messageFont = GUIUtil::getFontNormal();
messageFont.setPointSize(14);
painter.setFont(messageFont);
painter.drawPixmap(0, 0, pixmap); painter.drawPixmap(0, 0, pixmap);
QRect r = rect().adjusted(5, 5, -5, -5); QRect r = rect().adjusted(5, 5, -5, -15);
painter.setPen(curColor); painter.setPen(curColor);
painter.drawText(r, curAlignment, curMessage); painter.drawText(r, curAlignment, curMessage);
} }