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