OSDN Git Service

Moved JobObject as well as the remaining GUI functions into the MUtilities library.
[lamexp/LameXP.git] / src / Dialog_SplashScreen.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // LameXP - Audio Encoder Front-End
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version, but always including the *additional*
9 // restrictions defined in the "License.txt" file.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License along
17 // with this program; if not, write to the Free Software Foundation, Inc.,
18 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 //
20 // http://www.gnu.org/licenses/gpl-2.0.txt
21 ///////////////////////////////////////////////////////////////////////////////
22
23 #include "Dialog_SplashScreen.h"
24
25 //Internal
26 #include "Global.h"
27 #include "WinSevenTaskbar.h"
28
29 //MUtils
30 #include <MUtils/Global.h>
31 #include <MUtils/GUI.h>
32
33 //Qt
34 #include <QThread>
35 #include <QMovie>
36 #include <QKeyEvent>
37 #include <QTimer>
38
39 #define FADE_DELAY 16
40 #define OPACITY_DELTA 0.04
41
42 //Setup taskbar indicator
43 #define SET_TASKBAR_STATE(WIDGET,VAR,FLAG) do \
44 { \
45         if(FLAG) \
46         { \
47                 if(!(VAR)) (VAR) = WinSevenTaskbar::setTaskbarState((WIDGET), WinSevenTaskbar::WinSevenTaskbarIndeterminateState); \
48         } \
49         else \
50         { \
51                 if((VAR)) (VAR) = (!WinSevenTaskbar::setTaskbarState((WIDGET), WinSevenTaskbar::WinSevenTaskbarNoState)); \
52         } \
53 } \
54 while(0)
55
56 ////////////////////////////////////////////////////////////
57 // Constructor
58 ////////////////////////////////////////////////////////////
59
60 SplashScreen::SplashScreen(QWidget *parent)
61 :
62         m_opacitySteps(qRound(1.0 / OPACITY_DELTA)),
63         QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint)
64 {
65         //Init the dialog, from the .ui file
66         setupUi(this);
67
68         //Make size fixed
69         setFixedSize(this->size());
70         
71         //Create event loop
72         m_loop = new QEventLoop(this);
73
74         //Create timer
75         m_timer = new QTimer(this);
76         m_timer->setInterval(FADE_DELAY);
77         m_timer->setSingleShot(false);
78
79         //Connect timer to slot
80         connect(m_timer, SIGNAL(timeout()), this, SLOT(updateHandler()));
81
82         //Enable "sheet of glass" effect on splash screen
83         if(!MUtils::GUI::sheet_of_glass(this))
84         {
85                 setStyleSheet("background-image: url(:/images/Background.jpg)");
86         }
87
88         //Start animation
89         m_working = new QMovie(":/images/Loading4.gif");
90         m_working->setCacheMode(QMovie::CacheAll);
91         labelLoading->setMovie(m_working);
92         m_working->start();
93
94         //Init status
95         m_canClose = false;
96         m_status = STATUS_FADE_IN;
97         m_fadeValue = 0;
98         m_taskBarInit = false;
99 }
100
101 ////////////////////////////////////////////////////////////
102 // Destructor
103 ////////////////////////////////////////////////////////////
104
105 SplashScreen::~SplashScreen(void)
106 {
107         if(m_working)
108         {
109                 m_working->stop();
110         }
111
112         MUTILS_DELETE(m_working);
113         MUTILS_DELETE(m_loop);
114         MUTILS_DELETE(m_timer);
115 }
116
117 ////////////////////////////////////////////////////////////
118 // PUBLIC FUNCTIONS
119 ////////////////////////////////////////////////////////////
120
121 void SplashScreen::showSplash(QThread *thread)
122 {
123         SplashScreen *splashScreen = new SplashScreen();
124
125         //Show splash
126         splashScreen->setWindowOpacity(OPACITY_DELTA);
127         splashScreen->show();
128
129         //Set wait cursor
130         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
131
132         //Wait for window to show
133         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
134         splashScreen->repaint(); MUtils::GUI::bring_to_front(splashScreen);
135         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
136
137         //Connect thread signals
138         connect(thread, SIGNAL(terminated()), splashScreen, SLOT(threadComplete()), Qt::QueuedConnection);
139         connect(thread, SIGNAL(finished()),   splashScreen, SLOT(threadComplete()), Qt::QueuedConnection);
140
141         //Init taskbar
142         SET_TASKBAR_STATE(splashScreen, splashScreen->m_taskBarInit, true);
143
144         //Start the thread
145         splashScreen->m_timer->start(FADE_DELAY);
146         QTimer::singleShot(8*60*1000, splashScreen->m_loop, SLOT(quit()));
147         QTimer::singleShot(333, thread, SLOT(start()));
148
149         //Start event handling!
150         const int ret = splashScreen->m_loop->exec(QEventLoop::ExcludeUserInputEvents);
151
152         //Check for timeout
153         if(ret != 42)
154         {
155                 thread->terminate();
156                 qFatal("Deadlock in initialization thread encountered!");
157         }
158
159         //Restore taskbar
160         SET_TASKBAR_STATE(splashScreen, splashScreen->m_taskBarInit, false);
161
162         //Restore cursor
163         QApplication::restoreOverrideCursor();
164
165         //Hide splash
166         splashScreen->m_canClose = true;
167         splashScreen->close();
168
169         //Free
170         MUTILS_DELETE(splashScreen);
171 }
172
173 ////////////////////////////////////////////////////////////
174 // SLOTS
175 ////////////////////////////////////////////////////////////
176
177 void SplashScreen::updateHandler(void)
178 {
179         if(m_status == STATUS_FADE_IN)
180         {
181                 if(m_fadeValue < m_opacitySteps)
182                 {
183                         setWindowOpacity(OPACITY_DELTA * static_cast<double>(++m_fadeValue));
184                         SET_TASKBAR_STATE(this, m_taskBarInit, true);
185                 }
186                 else
187                 {
188                         setWindowOpacity(1.0);
189                         MUtils::GUI::bring_to_front(this);
190                         m_timer->stop();
191                         m_status = STATUS_WAIT;
192                 }
193         }
194         else if(m_status == STATUS_FADE_OUT)
195         {
196                 if(m_fadeValue > 0)
197                 {
198                         setWindowOpacity(OPACITY_DELTA * static_cast<double>(--m_fadeValue));
199                         SET_TASKBAR_STATE(this, m_taskBarInit, true);
200                 }
201                 else
202                 {
203                         setWindowOpacity(0.0);
204                         m_timer->stop();
205                         m_status = STATUS_DONE;
206                         m_loop->exit(42);
207                 }
208         }
209 }
210
211 void SplashScreen::threadComplete(void)
212 {
213         m_status = STATUS_FADE_OUT;
214         if(!m_timer->isActive())
215         {
216                 m_timer->start(FADE_DELAY);
217         }
218         MUtils::GUI::bring_to_front(this);
219 }
220
221 ////////////////////////////////////////////////////////////
222 // EVENTS
223 ////////////////////////////////////////////////////////////
224
225 void SplashScreen::keyPressEvent(QKeyEvent *event)
226 {
227         event->ignore();
228 }
229
230 void SplashScreen::keyReleaseEvent(QKeyEvent *event)
231 {
232         event->ignore();
233 }
234
235 void SplashScreen::closeEvent(QCloseEvent *event)
236 {
237         if(!m_canClose) event->ignore();
238 }
239
240 bool SplashScreen::winEvent(MSG *message, long *result)
241 {
242         return WinSevenTaskbar::handleWinEvent(message, result);
243 }