339 lines
10 KiB
C++
339 lines
10 KiB
C++
#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);
|
|
}
|
|
}
|