1 // Copyright (c) 2011-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #if defined(HAVE_CONFIG_H)
6 #include "config/bitcoin-config.h"
9 #include "splashscreen.h"
11 #include "networkstyle.h"
13 #include "clientversion.h"
16 #include "ui_interface.h"
20 #include "wallet/wallet.h"
23 #include <QApplication>
24 #include <QCloseEvent>
25 #include <QDesktopWidget>
27 #include <QRadialGradient>
29 SplashScreen::SplashScreen(Qt::WindowFlags f
, const NetworkStyle
*networkStyle
) :
30 QWidget(0, f
), curAlignment(0)
32 // set reference point, paddings
33 int paddingRight
= 50;
35 int titleVersionVSpace
= 17;
36 int titleCopyrightVSpace
= 40;
38 float fontFactor
= 1.0;
39 float devicePixelRatio
= 1.0;
40 #if QT_VERSION > 0x050100
41 devicePixelRatio
= ((QGuiApplication
*)QCoreApplication::instance())->devicePixelRatio();
44 // define text to place
45 QString titleText
= tr(PACKAGE_NAME
);
46 QString versionText
= QString("Version %1").arg(QString::fromStdString(FormatFullVersion()));
47 QString copyrightText
= QString::fromUtf8(CopyrightHolders(strprintf("\xc2\xA9 %u-%u ", 2009, COPYRIGHT_YEAR
)).c_str());
48 QString titleAddText
= networkStyle
->getTitleAddText();
50 QString font
= QApplication::font().toString();
52 // create a bitmap according to device pixelratio
53 QSize
splashSize(480*devicePixelRatio
,320*devicePixelRatio
);
54 pixmap
= QPixmap(splashSize
);
56 #if QT_VERSION > 0x050100
57 // change to HiDPI if it makes sense
58 pixmap
.setDevicePixelRatio(devicePixelRatio
);
61 QPainter
pixPaint(&pixmap
);
62 pixPaint
.setPen(QColor(100,100,100));
64 // draw a slightly radial gradient
65 QRadialGradient
gradient(QPoint(0,0), splashSize
.width()/devicePixelRatio
);
66 gradient
.setColorAt(0, Qt::white
);
67 gradient
.setColorAt(1, QColor(247,247,247));
68 QRect
rGradient(QPoint(0,0), splashSize
);
69 pixPaint
.fillRect(rGradient
, gradient
);
71 // draw the bitcoin icon, expected size of PNG: 1024x1024
72 QRect
rectIcon(QPoint(-150,-122), QSize(430,430));
74 const QSize
requiredSize(1024,1024);
75 QPixmap
icon(networkStyle
->getAppIcon().pixmap(requiredSize
));
77 pixPaint
.drawPixmap(rectIcon
, icon
);
79 // check font size and drawing with
80 pixPaint
.setFont(QFont(font
, 33*fontFactor
));
81 QFontMetrics fm
= pixPaint
.fontMetrics();
82 int titleTextWidth
= fm
.width(titleText
);
83 if (titleTextWidth
> 176) {
84 fontFactor
= fontFactor
* 176 / titleTextWidth
;
87 pixPaint
.setFont(QFont(font
, 33*fontFactor
));
88 fm
= pixPaint
.fontMetrics();
89 titleTextWidth
= fm
.width(titleText
);
90 pixPaint
.drawText(pixmap
.width()/devicePixelRatio
-titleTextWidth
-paddingRight
,paddingTop
,titleText
);
92 pixPaint
.setFont(QFont(font
, 15*fontFactor
));
94 // if the version string is to long, reduce size
95 fm
= pixPaint
.fontMetrics();
96 int versionTextWidth
= fm
.width(versionText
);
97 if(versionTextWidth
> titleTextWidth
+paddingRight
-10) {
98 pixPaint
.setFont(QFont(font
, 10*fontFactor
));
99 titleVersionVSpace
-= 5;
101 pixPaint
.drawText(pixmap
.width()/devicePixelRatio
-titleTextWidth
-paddingRight
+2,paddingTop
+titleVersionVSpace
,versionText
);
103 // draw copyright stuff
105 pixPaint
.setFont(QFont(font
, 10*fontFactor
));
106 const int x
= pixmap
.width()/devicePixelRatio
-titleTextWidth
-paddingRight
;
107 const int y
= paddingTop
+titleCopyrightVSpace
;
108 QRect
copyrightRect(x
, y
, pixmap
.width() - x
- paddingRight
, pixmap
.height() - y
);
109 pixPaint
.drawText(copyrightRect
, Qt::AlignLeft
| Qt::AlignTop
| Qt::TextWordWrap
, copyrightText
);
112 // draw additional text if special network
113 if(!titleAddText
.isEmpty()) {
114 QFont boldFont
= QFont(font
, 10*fontFactor
);
115 boldFont
.setWeight(QFont::Bold
);
116 pixPaint
.setFont(boldFont
);
117 fm
= pixPaint
.fontMetrics();
118 int titleAddTextWidth
= fm
.width(titleAddText
);
119 pixPaint
.drawText(pixmap
.width()/devicePixelRatio
-titleAddTextWidth
-10,15,titleAddText
);
125 setWindowTitle(titleText
+ " " + titleAddText
);
127 // Resize window and move to center of desktop, disallow resizing
128 QRect
r(QPoint(), QSize(pixmap
.size().width()/devicePixelRatio
,pixmap
.size().height()/devicePixelRatio
));
130 setFixedSize(r
.size());
131 move(QApplication::desktop()->screenGeometry().center() - r
.center());
133 subscribeToCoreSignals();
134 installEventFilter(this);
137 SplashScreen::~SplashScreen()
139 unsubscribeFromCoreSignals();
142 bool SplashScreen::eventFilter(QObject
* obj
, QEvent
* ev
) {
143 if (ev
->type() == QEvent::KeyPress
) {
144 QKeyEvent
*keyEvent
= static_cast<QKeyEvent
*>(ev
);
145 if(keyEvent
->text()[0] == 'q') {
149 return QObject::eventFilter(obj
, ev
);
152 void SplashScreen::slotFinish(QWidget
*mainWin
)
156 /* If the window is minimized, hide() will be ignored. */
157 /* Make sure we de-minimize the splashscreen window before hiding */
161 deleteLater(); // No more need for this
164 static void InitMessage(SplashScreen
*splash
, const std::string
&message
)
166 QMetaObject::invokeMethod(splash
, "showMessage",
167 Qt::QueuedConnection
,
168 Q_ARG(QString
, QString::fromStdString(message
)),
169 Q_ARG(int, Qt::AlignBottom
|Qt::AlignHCenter
),
170 Q_ARG(QColor
, QColor(55,55,55)));
173 static void ShowProgress(SplashScreen
*splash
, const std::string
&title
, int nProgress
, bool resume_possible
)
175 InitMessage(splash
, title
+ std::string("\n") +
176 (resume_possible
? _("(press q to shutdown and continue later)")
177 : _("press q to shutdown")) +
178 strprintf("\n%d", nProgress
) + "%");
182 void SplashScreen::ConnectWallet(CWallet
* wallet
)
184 wallet
->ShowProgress
.connect(boost::bind(ShowProgress
, this, _1
, _2
, false));
185 connectedWallets
.push_back(wallet
);
189 void SplashScreen::subscribeToCoreSignals()
191 // Connect signals to client
192 uiInterface
.InitMessage
.connect(boost::bind(InitMessage
, this, _1
));
193 uiInterface
.ShowProgress
.connect(boost::bind(ShowProgress
, this, _1
, _2
, _3
));
195 uiInterface
.LoadWallet
.connect(boost::bind(&SplashScreen::ConnectWallet
, this, _1
));
199 void SplashScreen::unsubscribeFromCoreSignals()
201 // Disconnect signals from client
202 uiInterface
.InitMessage
.disconnect(boost::bind(InitMessage
, this, _1
));
203 uiInterface
.ShowProgress
.disconnect(boost::bind(ShowProgress
, this, _1
, _2
, _3
));
205 for (CWallet
* const & pwallet
: connectedWallets
) {
206 pwallet
->ShowProgress
.disconnect(boost::bind(ShowProgress
, this, _1
, _2
, false));
211 void SplashScreen::showMessage(const QString
&message
, int alignment
, const QColor
&color
)
213 curMessage
= message
;
214 curAlignment
= alignment
;
219 void SplashScreen::paintEvent(QPaintEvent
*event
)
221 QPainter
painter(this);
222 painter
.drawPixmap(0, 0, pixmap
);
223 QRect r
= rect().adjusted(5, 5, -5, -5);
224 painter
.setPen(curColor
);
225 painter
.drawText(r
, curAlignment
, curMessage
);
228 void SplashScreen::closeEvent(QCloseEvent
*event
)
230 StartShutdown(); // allows an "emergency" shutdown during startup