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 
15 const int kFadeVal = 20;
16 
17 MythScreenStack::MythScreenStack(MythMainWindow *parent, const QString &name,
18  bool mainstack)
19  : QObject(parent)
20 {
21  setObjectName(name);
22 
23  if (parent)
24  parent->AddScreenStack(this, mainstack);
25 
26  EnableEffects();
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 
52 void 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 
86 void 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 
191 void MythScreenStack::GetDrawOrder(QVector<MythScreenType *> &screens)
192 {
193  if (m_inNewTransition)
195  CheckDeletes();
196 
197  screens = m_drawOrder;
198 }
199 
200 void MythScreenStack::GetScreenList(QVector<MythScreenType *> &screens)
201 {
202  if (m_inNewTransition)
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 
229  if (!m_topScreen->IsInitialized())
230  m_topScreen->doInit();
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
276 }
277 
279 {
280  if (!m_newTop)
281  {
282  m_inNewTransition = false;
283  return;
284  }
285 
286  if (m_newTop->GetAlpha() >= 255)
287  {
288  m_inNewTransition = false;
289  if (!m_newTop->IsInitialized())
290  m_doInit = true;
291  m_newTop = nullptr;
292 
294  }
295 }
296 
298 {
299  if (m_toDelete.isEmpty())
300  return;
301 
302  bool changed = false;
303 
304  QVector<MythScreenType *>::Iterator it = m_toDelete.begin();
305  while (it != m_toDelete.end() && !m_toDelete.isEmpty())
306  {
307  bool deleteit = false;
308 
309  if (force || (*it)->GetAlpha() <= 0)
310  {
311  deleteit = true;
312  }
313 
314  if (!deleteit)
315  {
316  bool found = false;
317 
318  for (const auto *test : std::as_const(m_drawOrder))
319  {
320  if (*it == test)
321  {
322  found = true;
323  break;
324  }
325  }
326 
327  if (!found)
328  deleteit = true;
329  }
330 
331  if (deleteit)
332  {
333  // NOLINTNEXTLINE(readability-qualified-auto) for Qt6
334  for (auto test = m_children.begin();
335  test != m_children.end();
336  ++test)
337  {
338  if (*test == *it)
339  {
340  m_children.erase(test);
341  break;
342  }
343  }
344 
345  if (*it == m_newTop)
346  m_newTop = nullptr;
347  delete (*it);
348  it = m_toDelete.erase(it);
349  changed = true;
350  continue;
351  }
352 
353  ++it;
354  }
355 
356  if (changed)
357  {
360  }
361 }
362 
363 QString MythScreenStack::GetLocation(bool fullPath) const
364 {
365  if (fullPath)
366  {
367  QString path;
368  for (auto *child : std::as_const(m_children))
369  {
370  if (!child->IsDeleting())
371  {
372  if (path.isEmpty())
373  path = child->objectName();
374  else
375  path += '/' + child->objectName();
376  }
377  }
378  return path;
379  }
380 
381  if (m_topScreen)
382  return m_topScreen->objectName();
383 
384  return {};
385 }
386 
388 {
389  return GetMythPainter();
390 }
MythScreenType::IsLoading
bool IsLoading(void) const
Definition: mythscreentype.h:83
MythScreenStack::m_doTransitions
bool m_doTransitions
Definition: mythscreenstack.h:61
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
mythevent.h
MythPainter::SupportsAlpha
virtual bool SupportsAlpha(void)=0
MythPainter::SupportsAnimation
virtual bool SupportsAnimation(void)=0
MythScreenStack::ScheduleInitIfNeeded
void ScheduleInitIfNeeded(void)
Definition: mythscreenstack.cpp:209
mythscreenstack.h
MythScreenStack::m_inNewTransition
bool m_inNewTransition
Definition: mythscreenstack.h:64
kFadeVal
const int kFadeVal
Definition: mythscreenstack.cpp:15
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
GetMythDB
MythDB * GetMythDB(void)
Definition: mythdb.cpp:50
MythScreenStack::EnableEffects
void EnableEffects(void)
Definition: mythscreenstack.cpp:40
force
bool force
Definition: mythcommflag.cpp:70
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:191
MythMainWindow::AddScreenStack
void AddScreenStack(MythScreenStack *Stack, bool Main=false)
Definition: mythmainwindow.cpp:297
MythScreenStack::GetScreenList
void GetScreenList(QVector< MythScreenType * > &screens)
Definition: mythscreenstack.cpp:200
MythScreenStack::CheckDeletes
void CheckDeletes(bool force=false)
Definition: mythscreenstack.cpp:297
MythScreenType::IsLoaded
bool IsLoaded(void) const
Definition: mythscreentype.h:84
MythScreenStack::DoNewFadeTransition
void DoNewFadeTransition()
Definition: mythscreenstack.cpp:258
MythUIType::SetAlpha
void SetAlpha(int newalpha)
Definition: mythuitype.cpp:947
MythScreenStack::doInit
void doInit(void)
Definition: mythscreenstack.cpp:220
MythScreenStack::topScreenChanged
void topScreenChanged(MythScreenType *screen)
MythUIType::AdjustAlpha
void AdjustAlpha(int mode, int alphachange, int minalpha=0, int maxalpha=255)
Definition: mythuitype.cpp:929
mythpainter.h
MythScreenStack::GetPainter
static MythPainter * GetPainter(void)
Definition: mythscreenstack.cpp:387
MythScreenStack::TotalScreens
int TotalScreens() const
Definition: mythscreenstack.cpp:47
MythScreenType::LoadInForeground
void LoadInForeground(void)
Definition: mythscreentype.cpp:301
MythScreenStack::~MythScreenStack
~MythScreenStack() override
Definition: mythscreenstack.cpp:29
MythScreenType::doInit
void doInit(void)
Definition: mythscreentype.cpp:365
MythScreenStack::m_initTimerStarted
bool m_initTimerStarted
Definition: mythscreenstack.h:63
mythcorecontext.h
MythScreenStack::m_toDelete
QVector< MythScreenType * > m_toDelete
Definition: mythscreenstack.h:67
MythPainter
Definition: mythpainter.h:34
MythScreenType::IsDeleting
bool IsDeleting(void) const
Definition: mythscreentype.cpp:256
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:86
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:1040
MythScreenStack::MythScreenStack
MythScreenStack(MythMainWindow *parent, const QString &name, bool main=false)
Definition: mythscreenstack.cpp:17
MythUIType::GetAlpha
int GetAlpha(void) const
Definition: mythuitype.cpp:956
MythScreenStack::GetLocation
QString GetLocation(bool fullPath) const
Definition: mythscreenstack.cpp:363
MythEvent::kExitToMainMenuEventType
static const Type kExitToMainMenuEventType
Definition: mythevent.h:82
MythScreenStack::m_doInit
bool m_doInit
Definition: mythscreenstack.h:62
MythScreenStack::CheckNewFadeTransition
void CheckNewFadeTransition()
Definition: mythscreenstack.cpp:278
MythScreenType::aboutToHide
virtual void aboutToHide(void)
Definition: mythscreentype.cpp:222
MythScreenType::SetDeleting
void SetDeleting(bool deleting)
Definition: mythscreentype.cpp:261
MythScreenStack::RecalculateDrawOrder
virtual void RecalculateDrawOrder(void)
Definition: mythscreenstack.cpp:235
GetMythPainter
MythPainter * GetMythPainter(void)
Definition: mythmainwindow.cpp:119
MythScreenType::aboutToShow
virtual void aboutToShow(void)
Definition: mythscreentype.cpp:238
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
MythUIType::SetRedraw
void SetRedraw(void)
Definition: mythuitype.cpp:310
MythScreenType::IsInitialized
bool IsInitialized(void) const
Has Init() been called on this screen?
Definition: mythscreentype.cpp:360
MythScreenType::IsFullscreen
bool IsFullscreen(void) const
Definition: mythscreentype.cpp:103
MythScreenStack::m_newTop
MythScreenType * m_newTop
Definition: mythscreenstack.h:65
MythMainWindow
Definition: mythmainwindow.h:28
mythscreentype.h
MythScreenType::SetFullscreen
void SetFullscreen(bool full)
Definition: mythscreentype.cpp:108
MythScreenStack::GetTopScreen
virtual MythScreenType * GetTopScreen(void) const
Definition: mythscreenstack.cpp:182