OSDN Git Service

6e04ab07222f01bebf1039afd647b59d0ec18476
[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 //UIC includes
26 #include "UIC_SplashScreen.h"
27
28 //Internal
29 #include "Global.h"
30
31 //MUtils
32 #include <MUtils/Global.h>
33 #include <MUtils/GUI.h>
34 #include <MUtils/Taskbar7.h>
35
36 //Qt
37 #include <QThread>
38 #include <QMovie>
39 #include <QKeyEvent>
40 #include <QTimer>
41
42 #define FADE_DELAY 16
43 #define OPACITY_DELTA 0.04
44
45 //Setup taskbar indicator
46 #define SET_TASKBAR_STATE(WIDGET,FLAG) do \
47 { \
48         if((WIDGET)->m_taskBarFlag != (FLAG)) \
49         { \
50                 if((WIDGET)->m_taskbar->setTaskbarState((FLAG) ? MUtils::Taskbar7::TASKBAR_STATE_INTERMEDIATE : MUtils::Taskbar7::TASKBAR_STATE_NONE)) \
51                 { \
52                         (WIDGET)->m_taskBarFlag = (FLAG); \
53                 } \
54         } \
55 } \
56 while(0)
57
58 ////////////////////////////////////////////////////////////
59 // Constructor
60 ////////////////////////////////////////////////////////////
61
62 SplashScreen::SplashScreen(QWidget *parent)
63 :
64         QFrame(parent, Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint),
65         ui(new Ui::SplashScreen),
66         m_opacitySteps(qRound(1.0 / OPACITY_DELTA)),
67         m_taskbar(new MUtils::Taskbar7(this))
68 {
69         //Init the dialog, from the .ui file
70         ui->setupUi(this);
71
72         //Make size fixed
73         setFixedSize(this->size());
74         
75         //Create event loop
76         m_loop.reset(new QEventLoop(this));
77
78         //Create timer
79         m_timer.reset(new QTimer(this));
80         m_timer->setInterval(FADE_DELAY);
81         m_timer->setSingleShot(false);
82
83         //Connect timer to slot
84         connect(m_timer.data(), SIGNAL(timeout()), this, SLOT(updateHandler()));
85
86         //Enable "sheet of glass" effect on splash screen
87         if(!MUtils::GUI::sheet_of_glass(this))
88         {
89                 setStyleSheet("background-image: url(:/images/Background.jpg)");
90         }
91
92         //Start animation
93         m_working.reset(new QMovie(":/images/Loading4.gif"));
94         m_working->setCacheMode(QMovie::CacheAll);
95         ui->labelLoading->setMovie(m_working.data());
96         m_working->start();
97
98         //Init status
99         m_canClose = false;
100         m_status = STATUS_FADE_IN;
101         m_fadeValue = 0;
102         m_taskBarFlag = false;
103 }
104
105 ////////////////////////////////////////////////////////////
106 // Destructor
107 ////////////////////////////////////////////////////////////
108
109 SplashScreen::~SplashScreen(void)
110 {
111         if(m_working)
112         {
113                 m_working->stop();
114         }
115
116         delete ui;
117 }
118
119 ////////////////////////////////////////////////////////////
120 // PUBLIC FUNCTIONS
121 ////////////////////////////////////////////////////////////
122
123 void SplashScreen::showSplash(QThread *thread)
124 {
125         QScopedPointer<SplashScreen> splashScreen(new SplashScreen());
126
127         //Show splash
128         splashScreen->setWindowOpacity(OPACITY_DELTA);
129         splashScreen->show();
130
131         //Set wait cursor
132         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
133
134         //Wait for window to show
135         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
136         splashScreen->repaint(); MUtils::GUI::bring_to_front(splashScreen.data());
137         QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
138
139         //Connect thread signals
140         connect(thread, SIGNAL(terminated()), splashScreen.data(), SLOT(threadComplete()), Qt::QueuedConnection);
141         connect(thread, SIGNAL(finished()),   splashScreen.data(), SLOT(threadComplete()), Qt::QueuedConnection);
142
143         //Init taskbar
144         SET_TASKBAR_STATE(splashScreen, true);
145
146         //Start the thread
147         splashScreen->m_timer->start(FADE_DELAY);
148         QTimer::singleShot(8*60*1000, splashScreen->m_loop.data(), SLOT(quit()));
149         QTimer::singleShot(333, thread, SLOT(start()));
150
151         //Start event handling!
152         const int ret = splashScreen->m_loop->exec(QEventLoop::ExcludeUserInputEvents);
153
154         //Check for timeout
155         if(ret != 42)
156         {
157                 thread->terminate();
158                 qFatal("Deadlock in initialization thread encountered!");
159         }
160
161         //Restore taskbar
162         SET_TASKBAR_STATE(splashScreen, false);
163
164         //Restore cursor
165         QApplication::restoreOverrideCursor();
166
167         //Hide splash
168         splashScreen->m_canClose = true;
169         splashScreen->close();
170 }
171
172 ////////////////////////////////////////////////////////////
173 // SLOTS
174 ////////////////////////////////////////////////////////////
175
176 void SplashScreen::updateHandler(void)
177 {
178         if(m_status == STATUS_FADE_IN)
179         {
180                 if(m_fadeValue < m_opacitySteps)
181                 {
182                         setWindowOpacity(OPACITY_DELTA * static_cast<double>(++m_fadeValue));
183                         SET_TASKBAR_STATE(this, true);
184                 }
185                 else
186                 {
187                         setWindowOpacity(1.0);
188                         MUtils::GUI::bring_to_front(this);
189                         m_timer->stop();
190                         m_status = STATUS_WAIT;
191                 }
192         }
193         else if(m_status == STATUS_FADE_OUT)
194         {
195                 if(m_fadeValue > 0)
196                 {
197                         setWindowOpacity(OPACITY_DELTA * static_cast<double>(--m_fadeValue));
198                         SET_TASKBAR_STATE(this, true);
199                 }
200                 else
201                 {
202                         setWindowOpacity(0.0);
203                         m_timer->stop();
204                         m_status = STATUS_DONE;
205                         m_loop->exit(42);
206                 }
207         }
208 }
209
210 void SplashScreen::threadComplete(void)
211 {
212         m_status = STATUS_FADE_OUT;
213         if(!m_timer->isActive())
214         {
215                 m_timer->start(FADE_DELAY);
216         }
217         MUtils::GUI::bring_to_front(this);
218 }
219
220 ////////////////////////////////////////////////////////////
221 // EVENTS
222 ////////////////////////////////////////////////////////////
223
224 void SplashScreen::keyPressEvent(QKeyEvent *event)
225 {
226         event->ignore();
227 }
228
229 void SplashScreen::keyReleaseEvent(QKeyEvent *event)
230 {
231         event->ignore();
232 }
233
234 void SplashScreen::closeEvent(QCloseEvent *event)
235 {
236         if(!m_canClose) event->ignore();
237 }