3#include <QElapsedTimer>
4#include <QGuiApplication>
12constexpr int SPLASH_BORDER_PX = 16;
14QString themedSplashResource(
const string& imageName) {
15 if (imageName !=
"gemcArchitecture") {
19 const QPalette palette = QGuiApplication::palette();
20 const bool use_dark = palette.color(QPalette::Window).lightness() <
21 palette.color(QPalette::WindowText).lightness();
22 return use_dark ? QStringLiteral(
":/gemcArchitecture_dark")
23 : QStringLiteral(
":/gemcArchitecture_light");
26QPixmap scaledPixmap(QPixmap pixmap,
double scale) {
27 if (pixmap.isNull() || !std::isfinite(scale) || scale <= 0.0 || scale == 1.0) {
31 const QSize scaled_size(
32 std::max(1,
static_cast<int>(std::round(pixmap.width() * scale))),
33 std::max(1,
static_cast<int>(std::round(pixmap.height() * scale)))
35 if (scaled_size.isValid() && !scaled_size.isEmpty()) {
36 pixmap = pixmap.scaled(scaled_size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
41QPixmap borderedPixmap(
const QPixmap& pixmap) {
42 if (pixmap.isNull()) {
46 const QPalette palette = QGuiApplication::palette();
47 const QSize bordered_size(
48 pixmap.width() + 2 * SPLASH_BORDER_PX,
49 pixmap.height() + 2 * SPLASH_BORDER_PX
51 QPixmap bordered(bordered_size);
52 bordered.fill(palette.color(QPalette::Window));
54 QPainter painter(&bordered);
55 painter.drawPixmap(SPLASH_BORDER_PX, SPLASH_BORDER_PX, pixmap);
56 painter.setPen(palette.color(QPalette::Mid));
57 painter.drawRect(bordered.rect().adjusted(0, 0, -1, -1));
66 const std::shared_ptr<GOptions>& gopts,
69 if (!gopts || !gopts->getSwitch(
"gui"))
71 return std::unique_ptr<GSplash>(
new GSplash(gopts, img, splashTime));
78GSplash::GSplash(
const std::shared_ptr<GOptions>& gopts,
const string& imageName,
double splashTime)
82 splash_time = option_splash_time >= 0.0 ? option_splash_time : splashTime;
88 pixmap.load(filename);
93 " must point to an image file.");
98 const auto themed_resource = themedSplashResource(imageName);
99 if (!themed_resource.isEmpty() && pixmap.load(themed_resource)) {
102 else if (!pixmap.load(QString::fromStdString(imageName))) {
103 pixmap.load(QString(
":/%1").arg(QString::fromStdString(imageName)));
111 if (!pixmap.isNull()) {
112 pixmap = scaledPixmap(pixmap, splash_scale);
113 pixmap = borderedPixmap(pixmap);
114 splash = std::make_unique<QSplashScreen>(pixmap);
116 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
124 const int splash_time_ms =
static_cast<int>(std::max(0.0, splash_time) * 1000.0);
125 if (splash_time_ms > 0) {
128 while (timer.elapsed() < splash_time_ms) {
129 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
134 splash->finish(callingWindow);
142 QPointer<QSplashScreen> sp = splash.get();
143 QTimer::singleShot(delay_ms, sp, [sp, qmsg = QString::fromStdString(msg)] {
145 sp->showMessage(qmsg, Qt::AlignLeft, Qt::black);
146 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
154 splash->showMessage(QString::fromStdString(msg), Qt::AlignLeft, Qt::black);
155 QCoreApplication::processEvents(QEventLoop::AllEvents, 50);
std::shared_ptr< GLogger > log
void error(int exit_code, Args &&... args) const
Splash screen utility for GUI runs.
void finish(QWidget *callingWindow) const
Finishes the splash screen and returns focus to the calling window.
static std::unique_ptr< GSplash > create(const std::shared_ptr< GOptions > &gopts, const std::string &imageName="gemcArchitecture", double splashTime=-1.0)
Factory method for creating a GSplash instance.
void message(const std::string &msg)
Displays a message on the splash screen immediately.
void messageAfter(int delay, const std::string &msg)
Displays a message on the splash screen after a delay.
constexpr const char * GSPLASH_SCALE_OPTION
#define GSPLASHENVIRONMENT
#define NOSPLASHIMAGESELECTED
constexpr const char * GSPLASH_LOGGER
Default logger name used by this module.
constexpr const char * GSPLASH_TIME_OPTION
#define ERR_NOSPLASHENVFOUND