MythTV master
mythscreenstack.cpp
Go to the documentation of this file.
3
4#include "mythscreenstack.h"
5#include "mythmainwindow.h"
6#include "mythscreentype.h"
7#include "mythpainter.h"
8
9#include <chrono>
10
11#include <QCoreApplication>
12#include <QString>
13#include <QTimer>
14
15const int kFadeVal = 20;
16
18 bool mainstack)
19 : QObject(parent)
20{
21 setObjectName(name);
22
23 if (parent)
24 parent->AddScreenStack(this, mainstack);
25
27}
28
30{
31 CheckDeletes(true);
32
33 while (!m_children.isEmpty())
34 {
35 MythScreenType *child = m_children.back();
36 MythScreenStack::PopScreen(child, false, true); // Don't fade, do delete
37 }
38}
39
41{
42 m_doTransitions = GetMythDB()->GetBoolSetting("SmoothTransitions", true) &&
45}
46
48{
49 return m_children.count();
50}
51
52void MythScreenStack::AddScreen(MythScreenType *screen, bool allowFade)
53{
54 if (!screen)
55 return;
56
57 m_doInit = false;
58
60 if (old && screen->IsFullscreen())
61 old->aboutToHide();
62
63 m_children.push_back(screen);
64
65 if (allowFade && m_doTransitions)
66 {
67 m_newTop = screen;
69 }
70 else
71 {
72 if (parent())
73 reinterpret_cast<MythMainWindow *>(parent())->update();
75 if (!screen->IsInitialized())
76 m_doInit = true;
77 }
78
79 screen->aboutToShow();
80
81 m_topScreen = screen;
82
84}
85
86void MythScreenStack::PopScreen(MythScreenType *screen, bool allowFade,
87 bool deleteScreen)
88{
89 if (!screen)
90 {
91 screen = m_topScreen;
92 }
93 if (!screen || screen->IsDeleting())
94 return;
95
96 bool poppedFullscreen = screen->IsFullscreen();
97
98 screen->aboutToHide();
99
100 if (m_children.isEmpty())
101 return;
102
103 MythMainWindow *mainwindow = GetMythMainWindow();
104
105 screen->setParent(nullptr);
106 if ((screen == m_topScreen) && allowFade && m_doTransitions
107 && !mainwindow->IsExitingToMain())
108 {
109 screen->SetFullscreen(false);
110 if (deleteScreen)
111 {
112 screen->SetDeleting(true);
113 m_toDelete.push_back(screen);
114 }
115 screen->AdjustAlpha(1, -kFadeVal);
116 }
117 else
118 {
119 for (int i = 0; i < m_children.size(); ++i)
120 {
121 if (m_children.at(i) == screen)
122 m_children.remove(i);
123 }
124 if (deleteScreen)
125 screen->deleteLater();
126
127 screen = nullptr;
128
129 mainwindow->update();
130 if (mainwindow->IsExitingToMain())
131 {
132 QCoreApplication::postEvent(
133 mainwindow, new QEvent(MythEvent::kExitToMainMenuEventType));
134 }
135 }
136
137 m_topScreen = nullptr;
138
140
141 // If we're fading it, we still want to draw it.
142 if (screen && !m_drawOrder.contains(screen))
143 m_drawOrder.push_back(screen);
144
145 if (!m_children.isEmpty())
146 {
147 for (auto *draw : std::as_const(m_drawOrder))
148 {
149 if (draw != screen && !draw->IsDeleting())
150 {
151 m_topScreen = draw;
152 draw->SetAlpha(255);
153 if (poppedFullscreen)
154 draw->aboutToShow();
155 }
156 }
157 }
158
159 if (m_topScreen)
160 {
162
163 if (!allowFade || !m_doTransitions)
165 }
166 else
167 {
168 // Screen still needs to be redrawn if we have popped the last screen
169 // off the popup stack, or similar
170 if (mainwindow->GetMainStack())
171 {
172 MythScreenType *mainscreen = mainwindow->GetMainStack()->GetTopScreen();
173 if (mainscreen)
174 mainscreen->SetRedraw();
175 }
176
177 if (!allowFade || !m_doTransitions)
178 emit topScreenChanged(nullptr);
179 }
180}
181
183{
184 if (m_topScreen)
185 return m_topScreen;
186 if (!m_drawOrder.isEmpty())
187 return m_drawOrder.back();
188 return nullptr;
189}
190
191void MythScreenStack::GetDrawOrder(QVector<MythScreenType *> &screens)
192{
195 CheckDeletes();
196
197 screens = m_drawOrder;
198}
199
200void MythScreenStack::GetScreenList(QVector<MythScreenType *> &screens)
201{
204 CheckDeletes();
205
206 screens = m_children;
207}
208
210{
211 // make sure Init() is called outside the paintEvent
214 {
215 m_initTimerStarted = true;
216 QTimer::singleShot(100ms, this, &MythScreenStack::doInit);
217 }
218}
219
221{
222 if (m_doInit && m_topScreen)
223 {
224 m_doInit = false;
225
226 if (!m_topScreen->IsLoaded())
228
231 }
232 m_initTimerStarted = false;
233}
234
236{
237 m_drawOrder.clear();
238
239 if (m_children.isEmpty())
240 return;
241
242 for (auto *screen : std::as_const(m_children))
243 {
244 if (screen->IsFullscreen())
245 m_drawOrder.clear();
246
247 m_drawOrder.push_back(screen);
248 }
249
250 if (m_drawOrder.isEmpty())
251 {
252 MythScreenType *screen = GetTopScreen();
253 if (screen)
254 m_drawOrder.push_back(screen);
255 }
256}
257
259{
260 m_inNewTransition = true;
261 m_newTop->SetAlpha(0);
263
264 if (m_newTop->IsFullscreen())
265 {
266 for (auto *draw : std::as_const(m_drawOrder))
267 {
268 if (!draw->IsDeleting())
269 draw->AdjustAlpha(1, -kFadeVal);
270 }
271
272 m_drawOrder.push_back(m_newTop);
273 }
274 else
275 {
277 }
278}
279
281{
282 if (!m_newTop)
283 {
284 m_inNewTransition = false;
285 return;
286 }
287
288 if (m_newTop->GetAlpha() >= 255)
289 {
290 m_inNewTransition = false;
291 if (!m_newTop->IsInitialized())
292 m_doInit = true;
293 m_newTop = nullptr;
294
296 }
297}
298
300{
301 if (m_toDelete.isEmpty())
302 return;
303
304 bool changed = false;
305
306 QVector<MythScreenType *>::Iterator it = m_toDelete.begin();
307 while (it != m_toDelete.end() && !m_toDelete.isEmpty())
308 {
309 bool deleteit = false;
310
311 if (force || (*it)->GetAlpha() <= 0)
312 {
313 deleteit = true;
314 }
315
316 if (!deleteit)
317 {
318 bool found = false;
319
320 for (const auto *test : std::as_const(m_drawOrder))
321 {
322 if (*it == test)
323 {
324 found = true;
325 break;
326 }
327 }
328
329 if (!found)
330 deleteit = true;
331 }
332
333 if (deleteit)
334 {
335 // NOLINTNEXTLINE(readability-qualified-auto) for Qt6
336 for (auto test = m_children.begin();
337 test != m_children.end();
338 ++test)
339 {
340 if (*test == *it)
341 {
342 m_children.erase(test);
343 break;
344 }
345 }
346
347 if (*it == m_newTop)
348 m_newTop = nullptr;
349 delete (*it);
350 it = m_toDelete.erase(it);
351 changed = true;
352 continue;
353 }
354
355 ++it;
356 }
357
358 if (changed)
359 {
362 }
363}
364
365QString MythScreenStack::GetLocation(bool fullPath) const
366{
367 if (fullPath)
368 {
369 QString path;
370 for (auto *child : std::as_const(m_children))
371 {
372 if (!child->IsDeleting())
373 {
374 if (path.isEmpty())
375 path = child->objectName();
376 else
377 path += '/' + child->objectName();
378 }
379 }
380 return path;
381 }
382
383 if (m_topScreen)
384 return m_topScreen->objectName();
385
386 return {};
387}
388
390{
391 return GetMythPainter();
392}
static const Type kExitToMainMenuEventType
Definition: mythevent.h:82
MythScreenStack * GetMainStack()
bool IsExitingToMain() const
void AddScreenStack(MythScreenStack *Stack, bool Main=false)
virtual bool SupportsAlpha(void)=0
virtual bool SupportsAnimation(void)=0
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
void GetScreenList(QVector< MythScreenType * > &screens)
MythScreenType * m_newTop
void GetDrawOrder(QVector< MythScreenType * > &screens)
virtual void RecalculateDrawOrder(void)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void EnableEffects(void)
void ScheduleInitIfNeeded(void)
QVector< MythScreenType * > m_drawOrder
QVector< MythScreenType * > m_children
int TotalScreens() const
MythScreenType * m_topScreen
void topScreenChanged(MythScreenType *screen)
virtual MythScreenType * GetTopScreen(void) const
void CheckDeletes(bool force=false)
static MythPainter * GetPainter(void)
QString GetLocation(bool fullPath) const
~MythScreenStack() override
MythScreenStack(MythMainWindow *parent, const QString &name, bool main=false)
QVector< MythScreenType * > m_toDelete
Screen in which all other widgets are contained and rendered.
bool IsLoading(void) const
void SetFullscreen(bool full)
void SetDeleting(bool deleting)
bool IsLoaded(void) const
virtual void aboutToShow(void)
virtual void aboutToHide(void)
bool IsDeleting(void) const
bool IsInitialized(void) const
Has Init() been called on this screen?
void LoadInForeground(void)
bool IsFullscreen(void) const
void AdjustAlpha(int mode, int alphachange, int minalpha=0, int maxalpha=255)
Definition: mythuitype.cpp:928
void SetRedraw(void)
Definition: mythuitype.cpp:313
void SetAlpha(int newalpha)
Definition: mythuitype.cpp:942
int GetAlpha(void) const
Definition: mythuitype.cpp:951
MythDB * GetMythDB(void)
Definition: mythdb.cpp:51
MythPainter * GetMythPainter(void)
MythMainWindow * GetMythMainWindow(void)
const int kFadeVal