From 54f2571a00632e9813b9fabb447c7cc80f74ad29 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 6 Nov 2014 16:28:29 +0100 Subject: 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 --- src/Makefile.qt.include | 8 +-- src/qt/bitcoin.qrc | 3 -- src/qt/networkstyle.cpp | 92 ++++++++++++++++++++++++++++++----- src/qt/networkstyle.h | 10 ++-- src/qt/res/bitcoin-qt-res.rc | 1 - src/qt/res/icons/bitcoin.png | Bin 32547 -> 350390 bytes src/qt/res/icons/bitcoin_testnet.ico | Bin 45855 -> 0 bytes src/qt/res/icons/bitcoin_testnet.png | Bin 28227 -> 0 bytes src/qt/res/images/splash.png | Bin 43398 -> 0 bytes src/qt/res/images/splash_testnet.png | Bin 34142 -> 0 bytes src/qt/splashscreen.cpp | 41 +++++++++++++--- 11 files changed, 121 insertions(+), 34 deletions(-) delete mode 100755 src/qt/res/icons/bitcoin_testnet.ico delete mode 100644 src/qt/res/icons/bitcoin_testnet.png delete mode 100644 src/qt/res/images/splash.png delete mode 100644 src/qt/res/images/splash_testnet.png (limited to 'src') diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 4c455483a0..25d76c146b 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -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" diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index cd71b4b3fc..b54f2e2ed6 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -25,7 +25,6 @@ res/icons/editpaste.png res/icons/editcopy.png res/icons/add.png - res/icons/bitcoin_testnet.png res/icons/edit.png res/icons/history.png res/icons/overview.png @@ -52,8 +51,6 @@ res/images/about.png - res/images/splash.png - res/images/splash_testnet.png res/movies/spinner-000.png diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 62c44703f4..b8112799df 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -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.scanLine( y ) ); + + // loop through pixels + for(int x=0;xiconColorSaturationReduction) + { + 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; +} diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index e49b86c950..2bfb3c1d55 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -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 diff --git a/src/qt/res/bitcoin-qt-res.rc b/src/qt/res/bitcoin-qt-res.rc index 809235be5f..a72dfc02f6 100644 --- a/src/qt/res/bitcoin-qt-res.rc +++ b/src/qt/res/bitcoin-qt-res.rc @@ -1,5 +1,4 @@ IDI_ICON1 ICON DISCARDABLE "icons/bitcoin.ico" -IDI_ICON2 ICON DISCARDABLE "icons/bitcoin_testnet.ico" #include // needed for VERSIONINFO #include "../../clientversion.h" // holds the needed client version information diff --git a/src/qt/res/icons/bitcoin.png b/src/qt/res/icons/bitcoin.png index ce5fbb0c2c..705a20260a 100644 Binary files a/src/qt/res/icons/bitcoin.png and b/src/qt/res/icons/bitcoin.png differ diff --git a/src/qt/res/icons/bitcoin_testnet.ico b/src/qt/res/icons/bitcoin_testnet.ico deleted file mode 100755 index d67d9d5ce5..0000000000 Binary files a/src/qt/res/icons/bitcoin_testnet.ico and /dev/null differ diff --git a/src/qt/res/icons/bitcoin_testnet.png b/src/qt/res/icons/bitcoin_testnet.png deleted file mode 100644 index 1202021f53..0000000000 Binary files a/src/qt/res/icons/bitcoin_testnet.png and /dev/null differ diff --git a/src/qt/res/images/splash.png b/src/qt/res/images/splash.png deleted file mode 100644 index 3f2b2fb2bf..0000000000 Binary files a/src/qt/res/images/splash.png and /dev/null differ diff --git a/src/qt/res/images/splash_testnet.png b/src/qt/res/images/splash_testnet.png deleted file mode 100644 index 786dc9c3bb..0000000000 Binary files a/src/qt/res/images/splash_testnet.png and /dev/null differ diff --git a/src/qt/splashscreen.cpp b/src/qt/splashscreen.cpp index b4b81440ca..bfc69636bb 100644 --- a/src/qt/splashscreen.cpp +++ b/src/qt/splashscreen.cpp @@ -19,6 +19,7 @@ #include #include #include +#include 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()); -- cgit v1.2.3 From 8e76ca0429db552cbf6f51dadd5467a1bc899027 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Fri, 14 Nov 2014 12:58:30 +0100 Subject: Qt: Go back to using QIcon functionality for scaling --- src/qt/networkstyle.cpp | 58 +++++++++++++++---------------------------------- src/qt/networkstyle.h | 6 ++--- src/qt/splashscreen.cpp | 3 +-- 3 files changed, 20 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index b8112799df..3762b84842 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -24,52 +24,13 @@ static const unsigned network_styles_count = sizeof(network_styles)/sizeof(*netw // titleAddText needs to be const char* for tr() NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, const int iconColorSaturationReduction, const char *titleAddText): appName(appName), - iconColorHueShift(iconColorHueShift), - iconColorSaturationReduction(iconColorSaturationReduction), titleAddText(qApp->translate("SplashScreen", titleAddText)) -{ -} - -const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) -{ - for (unsigned x=0; xgetAppIcon(requiredSize); - QPixmap icon(appIcon.pixmap(requiredSize)); + QPixmap icon(networkStyle->getAppIcon().pixmap(requiredSize)); pixPaint.drawPixmap(rectIcon, icon); -- cgit v1.2.3 From ac23394ea8118fe50131513bcd68c822a7ac4095 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 14 Nov 2014 17:16:31 +0100 Subject: resize tray icon because a 1024x1024 icon won't show in ubuntu (bug) --- src/qt/bitcoingui.cpp | 6 +++--- src/qt/networkstyle.cpp | 3 ++- src/qt/networkstyle.h | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index f63ebac6ea..3f5d0a191b 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -115,8 +115,8 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) : } windowTitle += " " + networkStyle->getTitleAddText(); #ifndef Q_OS_MAC - QApplication::setWindowIcon(networkStyle->getAppIcon()); - setWindowIcon(networkStyle->getAppIcon()); + QApplication::setWindowIcon(networkStyle->getTrayAndWindowIcon()); + setWindowIcon(networkStyle->getTrayAndWindowIcon()); #else MacDockIconHandler::instance()->setIcon(networkStyle->getAppIcon()); #endif @@ -491,7 +491,7 @@ void BitcoinGUI::createTrayIcon(const NetworkStyle *networkStyle) trayIcon = new QSystemTrayIcon(this); QString toolTip = tr("Bitcoin Core client") + " " + networkStyle->getTitleAddText(); trayIcon->setToolTip(toolTip); - trayIcon->setIcon(networkStyle->getAppIcon()); + trayIcon->setIcon(networkStyle->getTrayAndWindowIcon()); trayIcon->show(); #endif diff --git a/src/qt/networkstyle.cpp b/src/qt/networkstyle.cpp index 3762b84842..ff05174fb4 100644 --- a/src/qt/networkstyle.cpp +++ b/src/qt/networkstyle.cpp @@ -71,7 +71,8 @@ NetworkStyle::NetworkStyle(const QString &appName, const int iconColorHueShift, pixmap.convertFromImage(img); } - appIcon = QIcon(pixmap); + appIcon = QIcon(pixmap); + trayAndWindowIcon = QIcon(pixmap.scaled(QSize(256,256))); } const NetworkStyle *NetworkStyle::instantiate(const QString &networkId) diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index 3e3332cd8b..953004c127 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -18,6 +18,7 @@ public: const QString &getAppName() const { return appName; } const QIcon &getAppIcon() const { return appIcon; } + const QIcon &getTrayAndWindowIcon() const { return trayAndWindowIcon; } const QString &getTitleAddText() const { return titleAddText; } private: @@ -25,6 +26,7 @@ private: QString appName; QIcon appIcon; + QIcon trayAndWindowIcon; QString titleAddText; }; -- cgit v1.2.3