GWF_PowerUpInjector/splashscreen.cpp

339 lines
10 KiB
C++
Raw Normal View History

#include "splashscreen.h"
#include <QPainter>
#include <QPainterPath>
#include <QPixmap>
#include <QApplication>
#include <QScreen>
#include <QCoreApplication>
#include <QDate>
#include <QtMath>
#include <QLinearGradient>
#include <QRadialGradient>
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<int>(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<int>(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);
}
}