Qt: HiDPI (retina) support for splash screen
- remove splash screen images (reduce binary size) - dynamicly draw splash screen with available icon. - remove testnet icon - dynamicly colorize testnet icon
This commit is contained in:
parent
f3af0c898f
commit
54f2571a00
12 changed files with 122 additions and 36 deletions
|
@ -49,8 +49,7 @@ Jonas Schnelli
|
|||
src/qt/res/icons/tx_output.png, src/qt/res/icons/bitcoin.icns,
|
||||
src/qt/res/src/bitcoin.svg, src/qt/res/src/bitcoin.ico,
|
||||
src/qt/res/src/bitcoin.png, src/qt/res/src/bitcoin_testnet.png,
|
||||
docs/bitcoin_logo_doxygen.png, src/qt/res/images/splash.png,
|
||||
src/qt/res/images/splash_testnet.png, src/qt/res/src/tx*.svg,
|
||||
docs/bitcoin_logo_doxygen.png, src/qt/res/src/tx*.svg,
|
||||
src/qt/res/src/connect*.svg, src/qt/res/src/clock*.svg,
|
||||
src/qt/res/src/mine.svg, src/qt/res/src/qt.svg,
|
||||
src/qt/res/src/verify.svg,
|
||||
|
|
|
@ -216,8 +216,6 @@ RES_ICONS = \
|
|||
qt/res/icons/about_qt.png \
|
||||
qt/res/icons/bitcoin.ico \
|
||||
qt/res/icons/bitcoin.png \
|
||||
qt/res/icons/bitcoin_testnet.ico \
|
||||
qt/res/icons/bitcoin_testnet.png \
|
||||
qt/res/icons/clock1.png \
|
||||
qt/res/icons/clock2.png \
|
||||
qt/res/icons/clock3.png \
|
||||
|
@ -315,9 +313,7 @@ BITCOIN_QT_CPP += \
|
|||
endif
|
||||
|
||||
RES_IMAGES = \
|
||||
qt/res/images/about.png \
|
||||
qt/res/images/splash.png \
|
||||
qt/res/images/splash_testnet.png
|
||||
qt/res/images/about.png
|
||||
|
||||
RES_MOVIES = $(wildcard qt/res/movies/spinner-*.png)
|
||||
|
||||
|
@ -371,7 +367,7 @@ qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX
|
|||
#locale/foo.ts -> locale/foo.qm
|
||||
QT_QM=$(QT_TS:.ts=.qm)
|
||||
|
||||
.SECONDARY: $(QT_QM)
|
||||
SECONDARY: $(QT_QM)
|
||||
|
||||
qt/bitcoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wallet_a_SOURCES)
|
||||
@test -n $(XGETTEXT) || echo "xgettext is required for updating translations"
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
<file alias="editpaste">res/icons/editpaste.png</file>
|
||||
<file alias="editcopy">res/icons/editcopy.png</file>
|
||||
<file alias="add">res/icons/add.png</file>
|
||||
<file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file>
|
||||
<file alias="edit">res/icons/edit.png</file>
|
||||
<file alias="history">res/icons/history.png</file>
|
||||
<file alias="overview">res/icons/overview.png</file>
|
||||
|
@ -52,8 +51,6 @@
|
|||
</qresource>
|
||||
<qresource prefix="/images">
|
||||
<file alias="about">res/images/about.png</file>
|
||||
<file alias="splash">res/images/splash.png</file>
|
||||
<file alias="splash_testnet">res/images/splash_testnet.png</file>
|
||||
</qresource>
|
||||
<qresource prefix="/movies">
|
||||
<file alias="spinner-000">res/movies/spinner-000.png</file>
|
||||
|
|
|
@ -11,22 +11,22 @@
|
|||
static const struct {
|
||||
const char *networkId;
|
||||
const char *appName;
|
||||
const char *appIcon;
|
||||
const int iconColorHueShift;
|
||||
const int iconColorSaturationReduction;
|
||||
const char *titleAddText;
|
||||
const char *splashImage;
|
||||
} network_styles[] = {
|
||||
{"main", QAPP_APP_NAME_DEFAULT, ":/icons/bitcoin", "", ":/images/splash"},
|
||||
{"test", QAPP_APP_NAME_TESTNET, ":/icons/bitcoin_testnet", QT_TRANSLATE_NOOP("SplashScreen", "[testnet]"), ":/images/splash_testnet"},
|
||||
{"regtest", QAPP_APP_NAME_TESTNET, ":/icons/bitcoin_testnet", "[regtest]", ":/images/splash_testnet"}
|
||||
{"main", QAPP_APP_NAME_DEFAULT, 0, 0, ""},
|
||||
{"test", QAPP_APP_NAME_TESTNET, 70, 30, QT_TRANSLATE_NOOP("SplashScreen", "[testnet]")},
|
||||
{"regtest", QAPP_APP_NAME_TESTNET, 70, 30, "[regtest]"}
|
||||
};
|
||||
static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*network_styles);
|
||||
|
||||
// titleAddText needs to be const char* for tr()
|
||||
NetworkStyle::NetworkStyle(const QString &appName, const QString &appIcon, const char *titleAddText, const QString &splashImage):
|
||||
NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText):
|
||||
appName(appName),
|
||||
appIcon(appIcon),
|
||||
titleAddText(qApp->translate("SplashScreen", titleAddText)),
|
||||
splashImage(splashImage)
|
||||
iconColorHueShift(iconColorHueShift),
|
||||
iconColorSaturationReduction(iconColorSaturationReduction),
|
||||
titleAddText(qApp->translate("SplashScreen", titleAddText))
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,78 @@ const NetworkStyle *NetworkStyle::instantiate(const QString &networkId)
|
|||
{
|
||||
return new NetworkStyle(
|
||||
network_styles[x].appName,
|
||||
network_styles[x].appIcon,
|
||||
network_styles[x].titleAddText,
|
||||
network_styles[x].splashImage);
|
||||
network_styles[x].iconColorHueShift,
|
||||
network_styles[x].iconColorSaturationReduction,
|
||||
network_styles[x].titleAddText);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QIcon NetworkStyle::getAppIcon() const
|
||||
{
|
||||
return getAppIcon(QSize(256,256));
|
||||
}
|
||||
|
||||
QIcon NetworkStyle::getAppIcon(const QSize size) const
|
||||
{
|
||||
// load pixmap
|
||||
QPixmap pixmap(":/icons/bitcoin");
|
||||
|
||||
if(pixmap.size().width() != size.width() && pixmap.size().height() != size.height())
|
||||
{
|
||||
QPixmap scaledPixmap = pixmap.scaled(size, Qt::KeepAspectRatio);
|
||||
if(!scaledPixmap.isNull())
|
||||
{
|
||||
pixmap = scaledPixmap;
|
||||
}
|
||||
}
|
||||
|
||||
if(iconColorHueShift != 0 && iconColorSaturationReduction != 0)
|
||||
{
|
||||
// copy the pixmap because on linux the original pixmap will be affected
|
||||
pixmap = pixmap.copy();
|
||||
|
||||
// generate QImage from QPixmap
|
||||
QImage img = pixmap.toImage();
|
||||
|
||||
int h,s,l,a;
|
||||
|
||||
// traverse though lines
|
||||
for(int y=0;y<img.height();y++)
|
||||
{
|
||||
QRgb *scL = reinterpret_cast< QRgb *>( img.scanLine( y ) );
|
||||
|
||||
// loop through pixels
|
||||
for(int x=0;x<img.width();x++)
|
||||
{
|
||||
// preserve alpha because QColor::getHsl doesen'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
|
||||
h+=iconColorHueShift;
|
||||
|
||||
// change saturation value
|
||||
if(s>iconColorSaturationReduction)
|
||||
{
|
||||
s -= iconColorSaturationReduction;
|
||||
}
|
||||
col.setHsl(h,s,l,a);
|
||||
|
||||
// set the pixel
|
||||
scL[x] = col.rgba();
|
||||
}
|
||||
}
|
||||
|
||||
//convert back to QPixmap
|
||||
pixmap.convertFromImage(img);
|
||||
}
|
||||
|
||||
QIcon icon(pixmap);
|
||||
return icon;
|
||||
}
|
||||
|
|
|
@ -17,17 +17,17 @@ public:
|
|||
static const NetworkStyle *instantiate(const QString &networkId);
|
||||
|
||||
const QString &getAppName() const { return appName; }
|
||||
const QIcon &getAppIcon() const { return appIcon; }
|
||||
const QString &getTitleAddText() const { return titleAddText; }
|
||||
const QPixmap &getSplashImage() const { return splashImage; }
|
||||
|
||||
QIcon getAppIcon() const;
|
||||
QIcon getAppIcon(const QSize size) const;
|
||||
private:
|
||||
NetworkStyle(const QString &appName, const QString &appIcon, const char *titleAddText, const QString &splashImage);
|
||||
NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText);
|
||||
|
||||
QString appName;
|
||||
QIcon appIcon;
|
||||
int iconColorHueShift;
|
||||
int iconColorSaturationReduction;
|
||||
QString titleAddText;
|
||||
QPixmap splashImage;
|
||||
};
|
||||
|
||||
#endif // BITCOIN_QT_NETWORKSTYLE_H
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico"
|
||||
IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico"
|
||||
|
||||
#include <windows.h> // needed for VERSIONINFO
|
||||
#include "../../clientversion.h" // holds the needed client version information
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 342 KiB |
Binary file not shown.
Before Width: | Height: | Size: 45 KiB |
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
Binary file not shown.
Before Width: | Height: | Size: 42 KiB |
Binary file not shown.
Before Width: | Height: | Size: 33 KiB |
|
@ -19,6 +19,7 @@
|
|||
#include <QCloseEvent>
|
||||
#include <QDesktopWidget>
|
||||
#include <QPainter>
|
||||
#include <QRadialGradient>
|
||||
|
||||
SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle) :
|
||||
QWidget(0, f), curAlignment(0)
|
||||
|
@ -30,6 +31,10 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
int titleCopyrightVSpace = 40;
|
||||
|
||||
float fontFactor = 1.0;
|
||||
float devicePixelRatio = 1.0;
|
||||
#if QT_VERSION > 0x050100
|
||||
devicePixelRatio = ((QGuiApplication*)QCoreApplication::instance())->devicePixelRatio();
|
||||
#endif
|
||||
|
||||
// define text to place
|
||||
QString titleText = tr("Bitcoin Core");
|
||||
|
@ -39,12 +44,34 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
|
||||
QString font = "Arial";
|
||||
|
||||
// load the bitmap for writing some text over it
|
||||
pixmap = networkStyle->getSplashImage();
|
||||
// create a bitmap according to device pixelratio
|
||||
QSize splashSize(480*devicePixelRatio,320*devicePixelRatio);
|
||||
pixmap = QPixmap(splashSize);
|
||||
|
||||
#if QT_VERSION > 0x050100
|
||||
// change to HiDPI if it makes sense
|
||||
pixmap.setDevicePixelRatio(devicePixelRatio);
|
||||
#endif
|
||||
|
||||
QPainter pixPaint(&pixmap);
|
||||
pixPaint.setPen(QColor(100,100,100));
|
||||
|
||||
// draw a slighly radial gradient
|
||||
QRadialGradient gradient(QPoint(0,0), splashSize.width()/devicePixelRatio);
|
||||
gradient.setColorAt(0, Qt::white);
|
||||
gradient.setColorAt(1, QColor(247,247,247));
|
||||
QRect rGradient(QPoint(0,0), splashSize);
|
||||
pixPaint.fillRect(rGradient, gradient);
|
||||
|
||||
// draw the bitcoin icon, expected size of PNG: 1024x1024
|
||||
QRect rectIcon(QPoint(-150,-122), QSize(430,430));
|
||||
|
||||
const QSize requiredSize(1024,1024);
|
||||
QIcon appIcon = networkStyle->getAppIcon(requiredSize);
|
||||
QPixmap icon(appIcon.pixmap(requiredSize));
|
||||
|
||||
pixPaint.drawPixmap(rectIcon, icon);
|
||||
|
||||
// check font size and drawing with
|
||||
pixPaint.setFont(QFont(font, 33*fontFactor));
|
||||
QFontMetrics fm = pixPaint.fontMetrics();
|
||||
|
@ -57,7 +84,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
pixPaint.setFont(QFont(font, 33*fontFactor));
|
||||
fm = pixPaint.fontMetrics();
|
||||
titleTextWidth = fm.width(titleText);
|
||||
pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop,titleText);
|
||||
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop,titleText);
|
||||
|
||||
pixPaint.setFont(QFont(font, 15*fontFactor));
|
||||
|
||||
|
@ -68,11 +95,11 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
pixPaint.setFont(QFont(font, 10*fontFactor));
|
||||
titleVersionVSpace -= 5;
|
||||
}
|
||||
pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
|
||||
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight+2,paddingTop+titleVersionVSpace,versionText);
|
||||
|
||||
// draw copyright stuff
|
||||
pixPaint.setFont(QFont(font, 10*fontFactor));
|
||||
pixPaint.drawText(pixmap.width()-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText);
|
||||
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleTextWidth-paddingRight,paddingTop+titleCopyrightVSpace,copyrightText);
|
||||
|
||||
// draw additional text if special network
|
||||
if(!titleAddText.isEmpty()) {
|
||||
|
@ -81,7 +108,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
pixPaint.setFont(boldFont);
|
||||
fm = pixPaint.fontMetrics();
|
||||
int titleAddTextWidth = fm.width(titleAddText);
|
||||
pixPaint.drawText(pixmap.width()-titleAddTextWidth-10,15,titleAddText);
|
||||
pixPaint.drawText(pixmap.width()/devicePixelRatio-titleAddTextWidth-10,15,titleAddText);
|
||||
}
|
||||
|
||||
pixPaint.end();
|
||||
|
@ -90,7 +117,7 @@ SplashScreen::SplashScreen(Qt::WindowFlags f, const NetworkStyle *networkStyle)
|
|||
setWindowTitle(titleText + " " + titleAddText);
|
||||
|
||||
// Resize window and move to center of desktop, disallow resizing
|
||||
QRect r(QPoint(), pixmap.size());
|
||||
QRect r(QPoint(), QSize(pixmap.size().width()/devicePixelRatio,pixmap.size().height()/devicePixelRatio));
|
||||
resize(r.size());
|
||||
setFixedSize(r.size());
|
||||
move(QApplication::desktop()->screenGeometry().center() - r.center());
|
||||
|
|
Loading…
Reference in a new issue