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);
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) {
int h,s,l,a;
@ -39,24 +53,9 @@ void NetworkStyle::rotateColors(QImage& img, const int iconColorHueShift, const
// loop through pixels
for(int x=0;x<img.width();x++)
{
// preserve alpha because QColor::getHsl doesn't return the alpha value
a = qAlpha(scL[x]);
QColor col(scL[x]);
// 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
QColor col;
col.setRgba(scL[x]);
rotateColor(col, iconColorHueShift, iconColorSaturationReduction);
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()
NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *_titleAddText):
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
QApplication::setApplicationName(appName);
@ -73,25 +73,21 @@ NetworkStyle::NetworkStyle(const QString &_appName, const int iconColorHueShift,
GUIUtil::migrateQtSettings();
// load pixmap
QPixmap appIconPixmap(":/icons/bitcoin");
QPixmap splashImagePixmap(":/images/splash");
if(iconColorHueShift != 0 && iconColorSaturationReduction != 0)
{
// generate QImage from QPixmap
QImage appIconImg = appIconPixmap.toImage();
QImage splashImageImg = splashImagePixmap.toImage();
rotateColors(appIconImg, iconColorHueShift, iconColorSaturationReduction);
rotateColors(splashImageImg, iconColorHueShift, iconColorSaturationReduction);
//convert back to QPixmap
appIconPixmap.convertFromImage(appIconImg);
splashImagePixmap.convertFromImage(splashImageImg);
// tweak badge color
rotateColor(badgeColor, iconColorHueShift, iconColorSaturationReduction);
}
appIcon = QIcon(appIconPixmap);
trayAndWindowIcon = QIcon(appIconPixmap.scaled(QSize(256,256)));
splashImage = splashImagePixmap;
splashImage = QPixmap(":/images/splash");
}
const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)

View File

@ -22,6 +22,7 @@ public:
const QPixmap &getSplashImage() const { return splashImage; }
const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; }
const QString &getTitleAddText() const { return titleAddText; }
const QColor &getBadgeColor() const { return badgeColor; }
private:
NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText);
@ -31,7 +32,9 @@ private:
QPixmap splashImage;
QIcon trayAndWindowIcon;
QString titleAddText;
QColor badgeColor;
void rotateColor(QColor& col, 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/networkstyle.h>
#include <chainparams.h>
#include <clientversion.h>
#include <init.h>
#include <util.h>
@ -37,70 +38,94 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
// no window decorations
setWindowFlags(Qt::FramelessWindowHint);
// Geometries of splashscreen
int width = 380;
int height = 460;
int logoWidth = 270;
int logoHeight = 270;
// set reference point, paddings
int paddingLeft = 14;
int paddingTop = 470;
int titleVersionVSpace = 17;
int titleCopyrightVSpace = 22;
int paddingTop = 10;
int titleVersionVSpace = 25;
float fontFactor = 1.0;
float scale = qApp->devicePixelRatio();
// define text to place
QString titleText = tr(PACKAGE_NAME);
QString versionText = QString(tr("Version %1")).arg(QString::fromStdString(FormatFullVersion()));
QString copyrightText = QString::fromUtf8(CopyrightHolders("\xc2\xA9", 2014, COPYRIGHT_YEAR).c_str());
QString versionText = QString::fromStdString(FormatFullVersion()).remove(0, 1);
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
pixmap = networkStyle->getSplashImage();
QPixmap pixmapLogo = 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);
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
font.setPointSize(28 * fontFactor);
pixPaint.setFont(font);
fontBold.setPointSize(50 * fontFactor);
pixPaint.setFont(fontBold);
QFontMetrics fm = pixPaint.fontMetrics();
int titleTextWidth = fm.width(titleText);
if (titleTextWidth > 160) {
if (titleTextWidth > width * 0.8) {
fontFactor = 0.75;
}
font.setPointSize(28 * fontFactor);
pixPaint.setFont(font);
fontBold.setPointSize(50 * fontFactor);
pixPaint.setFont(fontBold);
fm = pixPaint.fontMetrics();
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);
pixPaint.setFont(font);
pixPaint.drawText(paddingLeft,paddingTop+titleVersionVSpace,versionText);
// draw copyright stuff
{
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);
}
fontNormal.setPointSize(16 * fontFactor);
pixPaint.setFont(fontNormal);
fm = pixPaint.fontMetrics();
int versionTextWidth = fm.width(versionText);
pixPaint.drawText((width / 2) - (versionTextWidth / 2), titleTextHeight + paddingTop + titleVersionVSpace, versionText);
// draw additional text if special network
if(!titleAddText.isEmpty()) {
QFont boldFont = GUIUtil::getFontBold();
boldFont.setPointSize(10 * fontFactor);
fontBold.setPointSize(10 * fontFactor);
pixPaint.setFont(fontBold);
fm = pixPaint.fontMetrics();
int titleAddTextWidth = fm.width(titleAddText);
pixPaint.drawText(pixmap.width()-titleAddTextWidth-10,pixmap.height()-25,titleAddText);
int titleAddTextWidth = fm.width(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();
// Resize window and move to center of desktop, disallow resizing
QRect r(QPoint(), pixmap.size());
QRect r(QPoint(), QSize(width, height));
resize(r.size());
setFixedSize(r.size());
move(QApplication::desktop()->screenGeometry().center() - r.center());
@ -141,8 +166,8 @@ static void InitMessage(SplashScreen *splash, const std::string &message)
QMetaObject::invokeMethod(splash, "showMessage",
Qt::QueuedConnection,
Q_ARG(QString, QString::fromStdString(message)),
Q_ARG(int, Qt::AlignBottom|Qt::AlignHCenter),
Q_ARG(QColor, QColor(55,55,55)));
Q_ARG(int, Qt::AlignBottom | Qt::AlignHCenter),
Q_ARG(QColor, GUIUtil::getThemedQColor(GUIUtil::ThemedColor::DEFAULT)));
}
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)
{
QPainter painter(this);
painter.setFont(GUIUtil::getFontNormal());
QFont messageFont = GUIUtil::getFontNormal();
messageFont.setPointSize(14);
painter.setFont(messageFont);
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.drawText(r, curAlignment, curMessage);
}