#include "splashscreen.h" #include #include #include #include #include #include #include #include #include #include SplashScreen::SplashScreen(QWidget *parent) : QSplashScreen() , mAnimationTimer(new QTimer(this)) { Q_UNUSED(parent); // 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); } // Connect animation timer connect(mAnimationTimer, &QTimer::timeout, this, &SplashScreen::onAnimationTick); } SplashScreen::~SplashScreen() { stopAnimation(); } 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::startAnimation() { mAnimationTimer->start(16); // ~60 FPS } void SplashScreen::stopAnimation() { mAnimationTimer->stop(); } void SplashScreen::finish(QWidget *mainWindow) { stopAnimation(); if (mainWindow) { mainWindow->show(); } close(); } void SplashScreen::onAnimationTick() { mAnimationPhase += 0.08f; if (mAnimationPhase > 2 * M_PI) { mAnimationPhase -= 2 * M_PI; } repaint(); } void SplashScreen::mousePressEvent(QMouseEvent *event) { Q_UNUSED(event); // Allow clicking to dismiss during loading if desired } void SplashScreen::keyPressEvent(QKeyEvent *event) { Q_UNUSED(event); // Allow key press to dismiss during loading if desired } void SplashScreen::drawContents(QPainter *painter) { painter->setRenderHint(QPainter::Antialiasing, true); painter->setRenderHint(QPainter::TextAntialiasing, true); drawBackground(painter); drawPowerupIcons(painter); drawTitle(painter); // Draw bouncing golf ball int ballX = 400; int ballY = 85 + static_cast(qSin(mAnimationPhase) * 15); drawGolfBall(painter, ballX, ballY, 25); drawProgressBar(painter); drawStatusText(painter); } void SplashScreen::drawBackground(QPainter *painter) { // Create clipping path for rounded corners QPainterPath clipPath; clipPath.addRoundedRect(0, 0, WIDTH, HEIGHT, 20, 20); painter->setClipPath(clipPath); // Draw gradient background (golf course green) QLinearGradient gradient(0, 0, 0, HEIGHT); gradient.setColorAt(0, mGreenLight); gradient.setColorAt(1, mGreenDark); painter->setBrush(gradient); painter->setPen(Qt::NoPen); painter->drawRect(0, 0, WIDTH, HEIGHT); // Draw subtle grass texture lines painter->setPen(QPen(mGreenDark.darker(110), 1)); for (int y = 20; y < HEIGHT - 60; y += 12) { int offset = static_cast(qSin(y * 0.1f + mAnimationPhase * 0.5f) * 3); painter->drawLine(10 + offset, y, WIDTH - 10 + offset, y); } // Draw decorative border painter->setClipping(false); painter->setPen(QPen(mGreenDark.darker(130), 3)); painter->setBrush(Qt::NoBrush); painter->drawRoundedRect(1, 1, WIDTH - 2, HEIGHT - 2, 20, 20); } void SplashScreen::drawGolfBall(QPainter *painter, int x, int y, int radius) { // Draw shadow painter->setBrush(QColor(0, 0, 0, 50)); painter->setPen(Qt::NoPen); painter->drawEllipse(x - radius + 5, y - radius + 8, radius * 2, radius * 2 - 5); // Draw golf ball with gradient QRadialGradient ballGradient(x - radius/3, y - radius/3, radius * 1.5); ballGradient.setColorAt(0, QColor(255, 255, 255)); ballGradient.setColorAt(0.7, QColor(240, 240, 240)); ballGradient.setColorAt(1, QColor(200, 200, 200)); painter->setBrush(ballGradient); painter->setPen(QPen(QColor(180, 180, 180), 1)); painter->drawEllipse(x - radius, y - radius, radius * 2, radius * 2); // Draw dimples painter->setPen(Qt::NoPen); painter->setBrush(QColor(180, 180, 180, 100)); int dimpleSize = 4; // Top row painter->drawEllipse(x - 8, y - 12, dimpleSize, dimpleSize); painter->drawEllipse(x + 4, y - 12, dimpleSize, dimpleSize); // Middle row painter->drawEllipse(x - 12, y - 4, dimpleSize, dimpleSize); painter->drawEllipse(x, y - 4, dimpleSize, dimpleSize); painter->drawEllipse(x + 8, y - 4, dimpleSize, dimpleSize); // Bottom row painter->drawEllipse(x - 8, y + 4, dimpleSize, dimpleSize); painter->drawEllipse(x + 4, y + 4, dimpleSize, dimpleSize); } void SplashScreen::drawPowerupIcons(QPainter *painter) { painter->setClipRect(0, 0, WIDTH, HEIGHT); // Draw scattered powerup icons around the edges // Lightning bolt - top left painter->setPen(Qt::NoPen); painter->setBrush(QColor("#FFEB3B")); // Yellow QPainterPath lightning; lightning.moveTo(60, 30); lightning.lineTo(75, 30); lightning.lineTo(65, 50); lightning.lineTo(80, 50); lightning.lineTo(55, 80); lightning.lineTo(65, 55); lightning.lineTo(50, 55); lightning.closeSubpath(); painter->drawPath(lightning); // Star - bottom left painter->setBrush(QColor("#FF9800")); // Orange QPainterPath star; int starX = 50, starY = 230; for (int i = 0; i < 5; i++) { double angle = i * 72 * M_PI / 180 - M_PI / 2; double innerAngle = angle + 36 * M_PI / 180; if (i == 0) { star.moveTo(starX + 15 * qCos(angle), starY + 15 * qSin(angle)); } else { star.lineTo(starX + 15 * qCos(angle), starY + 15 * qSin(angle)); } star.lineTo(starX + 7 * qCos(innerAngle), starY + 7 * qSin(innerAngle)); } star.closeSubpath(); painter->drawPath(star); // Speed lines - right side painter->setPen(QPen(QColor("#03A9F4"), 3, Qt::SolidLine, Qt::RoundCap)); // Blue painter->drawLine(420, 180, 460, 180); painter->drawLine(425, 190, 470, 190); painter->drawLine(420, 200, 460, 200); // Circle powerup - top right area QRadialGradient circleGrad(440, 35, 12); circleGrad.setColorAt(0, QColor("#E91E63")); // Pink circleGrad.setColorAt(1, QColor("#C2185B")); painter->setBrush(circleGrad); painter->setPen(Qt::NoPen); painter->drawEllipse(428, 23, 24, 24); // Small decorative dots painter->setBrush(QColor(255, 255, 255, 100)); painter->drawEllipse(90, 140, 6, 6); painter->drawEllipse(380, 250, 8, 8); painter->drawEllipse(120, 200, 5, 5); } void SplashScreen::drawTitle(QPainter *painter) { painter->setClipRect(0, 0, WIDTH, HEIGHT); // Draw drop shadow for title QFont titleFont("Segoe UI", 32, QFont::Bold); painter->setFont(titleFont); QString gwf = "GWF"; QString rest = " PowerUp Injector"; QFontMetrics fm(titleFont); int gwfWidth = fm.horizontalAdvance(gwf); int restWidth = fm.horizontalAdvance(rest); int totalWidth = gwfWidth + restWidth; int titleX = (WIDTH - totalWidth) / 2; int titleY = 100; // Draw shadow painter->setPen(QColor(0, 0, 0, 80)); painter->drawText(titleX + 2, titleY + 2, gwf); painter->drawText(titleX + gwfWidth + 2, titleY + 2, rest); // Draw "GWF" in gold/yellow accent painter->setPen(mGold); painter->drawText(titleX, titleY, gwf); // Draw rest in white painter->setPen(mWhite); painter->drawText(titleX + gwfWidth, titleY, rest); // Tagline QFont taglineFont("Segoe UI", 11); painter->setFont(taglineFont); painter->setPen(mLightGray); QString tagline = "Add powerups to your workshop maps!"; QFontMetrics taglineFm(taglineFont); int taglineWidth = taglineFm.horizontalAdvance(tagline); painter->drawText((WIDTH - taglineWidth) / 2, titleY + 28, tagline); // Version info QFont versionFont("Segoe UI", 9); painter->setFont(versionFont); painter->setPen(QColor(255, 255, 255, 150)); QString version = QString("Version %1").arg(QCoreApplication::applicationVersion()); QFontMetrics versionFm(versionFont); int versionWidth = versionFm.horizontalAdvance(version); painter->drawText((WIDTH - versionWidth) / 2, titleY + 48, version); // Copyright QString copyright = QString("%1 %2").arg(QCoreApplication::organizationName()) .arg(QDate::currentDate().year()); int copyrightWidth = versionFm.horizontalAdvance(copyright); painter->drawText((WIDTH - copyrightWidth) / 2, HEIGHT - 15, copyright); } void SplashScreen::drawProgressBar(QPainter *painter) { int progressX = 40; int progressY = HEIGHT - 60; int progressWidth = WIDTH - 80; int progressHeight = 12; // Progress bar background painter->setPen(Qt::NoPen); painter->setBrush(QColor(0, 0, 0, 80)); painter->drawRoundedRect(progressX, progressY, progressWidth, progressHeight, 6, 6); // Progress bar fill if (mProgressMax > 0 && mProgress > 0) { int fillWidth = (progressWidth * mProgress) / mProgressMax; if (fillWidth > 0) { // Gradient fill for progress QLinearGradient gradient(progressX, progressY, progressX + fillWidth, progressY); gradient.setColorAt(0, mGold); gradient.setColorAt(0.5, mGold.lighter(110)); gradient.setColorAt(1, mGold); painter->setBrush(gradient); painter->drawRoundedRect(progressX, progressY, fillWidth, progressHeight, 6, 6); // Add shine effect painter->setBrush(QColor(255, 255, 255, 60)); painter->drawRoundedRect(progressX, progressY, fillWidth, progressHeight / 2, 6, 6); } } } void SplashScreen::drawStatusText(QPainter *painter) { if (!mStatus.isEmpty()) { QFont statusFont("Segoe UI", 9); painter->setFont(statusFont); painter->setPen(mWhite); int progressX = 40; int progressY = HEIGHT - 60; int progressWidth = WIDTH - 80; QFontMetrics statusFm(statusFont); QString elidedStatus = statusFm.elidedText(mStatus, Qt::ElideMiddle, progressWidth); painter->drawText(progressX, progressY - 8, elidedStatus); } }