XPlor/app/splashscreen.cpp

220 lines
6.6 KiB
C++
Raw Permalink Normal View History

#include "splashscreen.h"
#include "settings.h"
#include <QPainter>
#include <QPainterPath>
#include <QApplication>
#include <QScreen>
#include <QCoreApplication>
#include <QDate>
SplashScreen::SplashScreen(QWidget *parent)
: QSplashScreen()
{
Q_UNUSED(parent);
// Load theme colors
loadThemeColors();
// Create transparent pixmap
QPixmap pixmap(WIDTH, HEIGHT);
pixmap.fill(Qt::transparent);
setPixmap(pixmap);
setWindowFlags(Qt::SplashScreen | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
setAttribute(Qt::WA_TranslucentBackground);
// Center on screen
if (QScreen *screen = QApplication::primaryScreen()) {
QRect screenGeometry = screen->geometry();
int x = (screenGeometry.width() - WIDTH) / 2;
int y = (screenGeometry.height() - HEIGHT) / 2;
move(x, y);
}
}
void SplashScreen::loadThemeColors()
{
Theme theme = Settings::instance().theme();
mPrimaryColor = QColor(theme.accentColor);
mBgColor = QColor(theme.backgroundColor);
mPanelColor = QColor(theme.panelColor);
mTextColor = QColor(theme.textColor);
mTextColorMuted = QColor(theme.textColorMuted);
mBorderColor = QColor(theme.borderColor);
}
void SplashScreen::setStatus(const QString &message)
{
mStatus = message;
repaint();
QApplication::processEvents();
}
void SplashScreen::setProgress(int value, int max)
{
mProgress = value;
mProgressMax = max;
repaint();
QApplication::processEvents();
}
void SplashScreen::setWaitForInteraction(bool wait)
{
mWaitForInteraction = wait;
}
void SplashScreen::finish(QWidget *mainWindow)
{
// Always show the main window
if (mainWindow) {
mainWindow->show();
}
if (mWaitForInteraction && !mInteractionReceived) {
// Keep splash visible on top until user interacts
mPendingMainWindow = mainWindow;
raise();
activateWindow();
mStatus = "Click or press any key to continue...";
repaint();
return;
}
// Normal behavior - close splash
close();
}
void SplashScreen::mousePressEvent(QMouseEvent *event)
{
Q_UNUSED(event);
mInteractionReceived = true;
if (mWaitForInteraction && mPendingMainWindow) {
close(); // Just close the splash
}
}
void SplashScreen::keyPressEvent(QKeyEvent *event)
{
Q_UNUSED(event);
mInteractionReceived = true;
if (mWaitForInteraction && mPendingMainWindow) {
close(); // Just close the splash
}
}
void SplashScreen::drawContents(QPainter *painter)
{
painter->setRenderHint(QPainter::Antialiasing, true);
painter->setRenderHint(QPainter::TextAntialiasing, true);
// Create clipping path for rounded corners
QPainterPath clipPath;
clipPath.addRoundedRect(0, 0, WIDTH, HEIGHT, 12, 12);
painter->setClipPath(clipPath);
// Draw background
painter->setPen(Qt::NoPen);
painter->setBrush(mBgColor);
painter->drawRect(0, 0, WIDTH, HEIGHT);
// Draw accent stripe at top (clipped to rounded corners)
painter->setBrush(mPrimaryColor);
painter->drawRect(0, 0, WIDTH, 8);
// Draw logo/title area
QFont titleFont("Segoe UI", 36, QFont::Bold);
painter->setFont(titleFont);
painter->setPen(mTextColor);
// App name with primary color accent
QString appName = "XPlor";
QFontMetrics titleMetrics(titleFont);
int titleWidth = titleMetrics.horizontalAdvance(appName);
int titleX = (WIDTH - titleWidth) / 2;
int titleY = 80;
// Draw "X" in primary color
painter->setPen(mPrimaryColor);
painter->drawText(titleX, titleY, "X");
// Draw "Plor" in text color
painter->setPen(mTextColor);
int xWidth = titleMetrics.horizontalAdvance("X");
painter->drawText(titleX + xWidth, titleY, "Plor");
// Tagline
QFont taglineFont("Segoe UI", 11);
painter->setFont(taglineFont);
painter->setPen(mTextColorMuted);
QString tagline = "Binary File Format Explorer";
QFontMetrics taglineMetrics(taglineFont);
int taglineWidth = taglineMetrics.horizontalAdvance(tagline);
painter->drawText((WIDTH - taglineWidth) / 2, titleY + 25, tagline);
// Version info
QFont versionFont("Segoe UI", 10);
painter->setFont(versionFont);
painter->setPen(mTextColorMuted);
QString version = QString("Version %1").arg(QCoreApplication::applicationVersion());
QFontMetrics versionMetrics(versionFont);
int versionWidth = versionMetrics.horizontalAdvance(version);
painter->drawText((WIDTH - versionWidth) / 2, titleY + 50, version);
// Company/copyright - use QCoreApplication values
QFont copyrightFont("Segoe UI", 9);
painter->setFont(copyrightFont);
painter->setPen(mTextColorMuted);
QString orgName = QCoreApplication::organizationName();
QFontMetrics copyrightMetrics(copyrightFont);
int copyrightWidth = copyrightMetrics.horizontalAdvance(orgName);
painter->drawText((WIDTH - copyrightWidth) / 2, HEIGHT - 45, orgName);
QString year = QString::number(QDate::currentDate().year());
int yearWidth = copyrightMetrics.horizontalAdvance(year);
painter->drawText((WIDTH - yearWidth) / 2, HEIGHT - 30, year);
// Progress bar background
int progressX = 40;
int progressY = HEIGHT - 80;
int progressWidth = WIDTH - 80;
int progressHeight = 6;
painter->setPen(Qt::NoPen);
painter->setBrush(mPanelColor);
painter->drawRoundedRect(progressX, progressY, progressWidth, progressHeight, 3, 3);
// Progress bar fill
if (mProgressMax > 0 && mProgress > 0) {
int fillWidth = (progressWidth * mProgress) / mProgressMax;
if (fillWidth > 0) {
// Gradient from primary to lighter
QLinearGradient gradient(progressX, 0, progressX + fillWidth, 0);
gradient.setColorAt(0, mPrimaryColor);
gradient.setColorAt(1, mPrimaryColor.lighter(120));
painter->setBrush(gradient);
painter->drawRoundedRect(progressX, progressY, fillWidth, progressHeight, 3, 3);
}
}
// Status text
if (!mStatus.isEmpty()) {
QFont statusFont("Segoe UI", 9);
painter->setFont(statusFont);
painter->setPen(mTextColorMuted);
QFontMetrics statusMetrics(statusFont);
QString elidedStatus = statusMetrics.elidedText(mStatus, Qt::ElideMiddle, progressWidth);
painter->drawText(progressX, progressY - 8, elidedStatus);
}
// Draw subtle border (disable clipping first)
painter->setClipping(false);
painter->setPen(QPen(mBorderColor, 1));
painter->setBrush(Qt::NoBrush);
painter->drawRoundedRect(0, 0, WIDTH - 1, HEIGHT - 1, 12, 12);
}