///////////////////////////////////////////////////////////////////////////////
// LameXP - Audio Encoder Front-End
-// Copyright (C) 2004-2011 LoRd_MuldeR <MuldeR2@GMX.de>
+// Copyright (C) 2004-2012 LoRd_MuldeR <MuldeR2@GMX.de>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
#include <QThread>
#include <QMovie>
#include <QKeyEvent>
+#include <QTimer>
#include "WinSevenTaskbar.h"
-#define EPS (1.0E-5)
-#define FADE_DELAY 4
+#define FADE_DELAY 16
+#define OPACITY_DELTA 0.02
+
+/* It can happen that the QThread has just terminated and already emitted the 'terminated' signal, but did NOT change the 'isRunning' flag to FALSE yet. */
+/* For this reason the macro will first check the 'isRunning' flag. If (and only if) the flag still returns TRUE, then we will wait() for at most 50 ms. */
+/* If, after 50 ms, the wait() function returns with FALSE, then the thread probably is still running and we return TRUE. Otherwise we can return FALSE. */
+#define THREAD_RUNNING(THRD) (((THRD)->isRunning()) ? (!((THRD)->wait(50))) : false)
+
////////////////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////////////////
SplashScreen::SplashScreen(QWidget *parent)
- : QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
+:
+ QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
{
//Init the dialog, from the .ui file
setupUi(this);
void SplashScreen::showSplash(QThread *thread)
{
- double opacity = 0.0;
+ double opacity = OPACITY_DELTA;
+ const int opacitySteps = qRound(1.0 / OPACITY_DELTA);
SplashScreen *splashScreen = new SplashScreen();
//Show splash
splashScreen->m_canClose = false;
splashScreen->setWindowOpacity(opacity);
+ splashScreen->setFixedSize(splashScreen->size());
splashScreen->show();
//Wait for window to show
- QApplication::processEvents();
- Sleep(100);
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
+ splashScreen->repaint();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//Setup the event loop
QEventLoop *loop = new QEventLoop(splashScreen);
connect(thread, SIGNAL(terminated()), loop, SLOT(quit()), Qt::QueuedConnection);
connect(thread, SIGNAL(finished()), loop, SLOT(quit()), Qt::QueuedConnection);
+ //Create timer
+ QTimer *timer = new QTimer();
+ connect(timer, SIGNAL(timeout()), loop, SLOT(quit()));
+
//Start thread
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
thread->start();
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
//Init taskbar
WinSevenTaskbar::setTaskbarState(splashScreen, WinSevenTaskbar::WinSevenTaskbarIndeterminateState);
//Fade in
- for(int i = 0; i <= 100; i++)
+ for(int i = 1; i <= opacitySteps; i++)
{
- opacity = 0.01 * static_cast<double>(i);
+ opacity = OPACITY_DELTA * static_cast<double>(i);
splashScreen->setWindowOpacity(opacity);
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY);
Sleep(FADE_DELAY);
}
- //Loop while thread is running
- loop->exec();
-
+ //Start the timer
+ timer->start(30720);
+
+ //Loop while thread is still running
+ if(bool bIsRunning = THREAD_RUNNING(thread))
+ {
+ while(bIsRunning)
+ {
+ loop->exec();
+ if(bIsRunning = THREAD_RUNNING(thread))
+ {
+ qWarning("Potential deadlock in initialization thread!");
+ }
+ }
+ }
+
+ //Stop the timer
+ timer->stop();
+
//Fade out
- for(int i = 100; i >= 0; i--)
+ for(int i = opacitySteps; i >= 0; i--)
{
- opacity = 0.01 * static_cast<double>(i);
+ opacity = OPACITY_DELTA * static_cast<double>(i);
splashScreen->setWindowOpacity(opacity);
- QApplication::processEvents();
+ QApplication::processEvents(QEventLoop::ExcludeUserInputEvents, FADE_DELAY);
Sleep(FADE_DELAY);
}
//Free
LAMEXP_DELETE(loop);
+ LAMEXP_DELETE(timer);
LAMEXP_DELETE(splashScreen);
}
void SplashScreen::closeEvent(QCloseEvent *event)
{
- if(!m_canClose && !lamexp_session_ending()) event->ignore();
+ if(!m_canClose) event->ignore();
}
bool SplashScreen::winEvent(MSG *message, long *result)