2 * Copyright (C) 2005-2008 Team XBMC
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, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 #include "GUIWindowManager.h"
23 #include "GUIAudioManager.h"
24 #include "GUIDialog.h"
25 #include "Application.h"
26 #include "GUIPassword.h"
27 #include "utils/GUIInfoManager.h"
28 #include "utils/SingleLock.h"
30 #include "GUISettings.h"
32 #include "addons/Skin.h"
36 CGUIWindowManager g_windowManager;
38 CGUIWindowManager::CGUIWindowManager(void)
41 m_bShowOverlay = true;
45 CGUIWindowManager::~CGUIWindowManager(void)
49 void CGUIWindowManager::Initialize()
51 LoadNotOnDemandWindows();
54 bool CGUIWindowManager::SendMessage(int message, int senderID, int destID, int param1, int param2)
56 CGUIMessage msg(message, senderID, destID, param1, param2);
57 return SendMessage(msg);
60 bool CGUIWindowManager::SendMessage(CGUIMessage& message)
63 // CLog::Log(LOGDEBUG,"SendMessage: mess=%d send=%d control=%d param1=%d", message.GetMessage(), message.GetSenderId(), message.GetControlId(), message.GetParam1());
64 // Send the message to all none window targets
65 for (int i = 0; i < (int) m_vecMsgTargets.size(); i++)
67 IMsgTargetCallback* pMsgTarget = m_vecMsgTargets[i];
71 if (pMsgTarget->OnMessage( message )) handled = true;
75 // A GUI_MSG_NOTIFY_ALL is send to any active modal dialog
76 // and all windows whether they are active or not
77 if (message.GetMessage()==GUI_MSG_NOTIFY_ALL)
79 CSingleLock lock(g_graphicsContext);
80 for (rDialog it = m_activeDialogs.rbegin(); it != m_activeDialogs.rend(); ++it)
82 CGUIWindow *dialog = *it;
83 dialog->OnMessage(message);
86 for (WindowMap::iterator it = m_mapWindows.begin(); it != m_mapWindows.end(); it++)
88 CGUIWindow *pWindow = (*it).second;
89 pWindow->OnMessage(message);
94 // Normal messages are sent to:
95 // 1. All active modeless dialogs
96 // 2. The topmost dialog that accepts the message
97 // 3. The underlying window (only if it is the sender or receiver if a modal dialog is active)
99 bool hasModalDialog(false);
100 bool modalAcceptedMessage(false);
101 // don't use an iterator for this loop, as some messages mean that m_activeDialogs is altered,
102 // which will invalidate any iterator
103 CSingleLock lock(g_graphicsContext);
104 unsigned int topWindow = m_activeDialogs.size();
107 CGUIWindow* dialog = m_activeDialogs[--topWindow];
109 if (!modalAcceptedMessage && dialog->IsModalDialog())
111 hasModalDialog = true;
112 if (!modalAcceptedMessage && dialog->OnMessage( message ))
114 modalAcceptedMessage = handled = true;
117 else if (!dialog->IsModalDialog())
119 if (dialog->OnMessage( message ))
123 if (topWindow > m_activeDialogs.size())
124 topWindow = m_activeDialogs.size();
128 // now send to the underlying window
129 CGUIWindow* window = GetWindow(GetActiveWindow());
134 // only send the message to the underlying window if it's the recipient
135 // or sender (or we have no sender)
136 if (message.GetSenderId() == window->GetID() ||
137 message.GetControlId() == window->GetID() ||
138 message.GetSenderId() == 0 )
140 if (window->OnMessage(message)) handled = true;
145 if (window->OnMessage(message)) handled = true;
151 bool CGUIWindowManager::SendMessage(CGUIMessage& message, int window)
153 CGUIWindow* pWindow = GetWindow(window);
155 return pWindow->OnMessage(message);
160 void CGUIWindowManager::AddUniqueInstance(CGUIWindow *window)
162 CSingleLock lock(g_graphicsContext);
163 // increment our instance (upper word of windowID)
164 // until we get a window we don't have
166 while (GetWindow(window->GetID()))
167 window->SetID(window->GetID() + (++instance << 16));
171 void CGUIWindowManager::Add(CGUIWindow* pWindow)
175 CLog::Log(LOGERROR, "Attempted to add a NULL window pointer to the window manager.");
178 // push back all the windows if there are more than one covered by this class
179 CSingleLock lock(g_graphicsContext);
180 for (int i = 0; i < pWindow->GetIDRange(); i++)
182 WindowMap::iterator it = m_mapWindows.find(pWindow->GetID() + i);
183 if (it != m_mapWindows.end())
185 CLog::Log(LOGERROR, "Error, trying to add a second window with id %u "
186 "to the window manager",
190 m_mapWindows.insert(pair<int, CGUIWindow *>(pWindow->GetID() + i, pWindow));
194 void CGUIWindowManager::AddCustomWindow(CGUIWindow* pWindow)
196 CSingleLock lock(g_graphicsContext);
198 m_vecCustomWindows.push_back(pWindow);
201 void CGUIWindowManager::AddModeless(CGUIWindow* dialog)
203 CSingleLock lock(g_graphicsContext);
204 // only add the window if it's not already added
205 for (iDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
206 if (*it == dialog) return;
207 m_activeDialogs.push_back(dialog);
210 void CGUIWindowManager::Remove(int id)
212 CSingleLock lock(g_graphicsContext);
213 WindowMap::iterator it = m_mapWindows.find(id);
214 if (it != m_mapWindows.end())
216 for(vector<CGUIWindow*>::iterator it2 = m_activeDialogs.begin(); it2 != m_activeDialogs.end();)
218 if(*it2 == it->second)
219 it2 = m_activeDialogs.erase(it2);
224 m_mapWindows.erase(it);
228 CLog::Log(LOGWARNING, "Attempted to remove window %u "
229 "from the window manager when it didn't exist",
234 // removes and deletes the window. Should only be called
235 // from the class that created the window using new.
236 void CGUIWindowManager::Delete(int id)
238 CSingleLock lock(g_graphicsContext);
239 CGUIWindow *pWindow = GetWindow(id);
243 m_deleteWindows.push_back(pWindow);
247 void CGUIWindowManager::PreviousWindow()
249 // deactivate any window
250 CSingleLock lock(g_graphicsContext);
251 CLog::Log(LOGDEBUG,"CGUIWindowManager::PreviousWindow: Deactivate");
252 int currentWindow = GetActiveWindow();
253 CGUIWindow *pCurrentWindow = GetWindow(currentWindow);
255 return; // no windows or window history yet
257 // check to see whether our current window has a <previouswindow> tag
258 if (pCurrentWindow->GetPreviousWindow() != WINDOW_INVALID)
260 // TODO: we may need to test here for the
261 // whether our history should be changed
263 // don't reactivate the previouswindow if it is ourselves.
264 if (currentWindow != pCurrentWindow->GetPreviousWindow())
265 ActivateWindow(pCurrentWindow->GetPreviousWindow());
268 // get the previous window in our stack
269 if (m_windowHistory.size() < 2)
270 { // no previous window history yet - check if we should just activate home
271 if (GetActiveWindow() != WINDOW_INVALID && GetActiveWindow() != WINDOW_HOME)
273 ClearWindowHistory();
274 ActivateWindow(WINDOW_HOME);
278 m_windowHistory.pop();
279 int previousWindow = GetActiveWindow();
280 m_windowHistory.push(currentWindow);
282 CGUIWindow *pNewWindow = GetWindow(previousWindow);
285 CLog::Log(LOGERROR, "Unable to activate the previous window");
286 ClearWindowHistory();
287 ActivateWindow(WINDOW_HOME);
291 // ok to go to the previous window now
293 // tell our info manager which window we are going to
294 g_infoManager.SetNextWindow(previousWindow);
296 // set our overlay state (enables out animations on window change)
297 HideOverlay(pNewWindow->GetOverlayState());
299 // deinitialize our window
300 g_audioManager.PlayWindowSound(pCurrentWindow->GetID(), SOUND_DEINIT);
301 CGUIMessage msg(GUI_MSG_WINDOW_DEINIT, 0, 0);
302 pCurrentWindow->OnMessage(msg);
304 g_infoManager.SetNextWindow(WINDOW_INVALID);
305 g_infoManager.SetPreviousWindow(currentWindow);
307 // remove the current window off our window stack
308 m_windowHistory.pop();
310 // ok, initialize the new window
311 CLog::Log(LOGDEBUG,"CGUIWindowManager::PreviousWindow: Activate new");
312 g_audioManager.PlayWindowSound(pNewWindow->GetID(), SOUND_INIT);
313 CGUIMessage msg2(GUI_MSG_WINDOW_INIT, 0, 0, WINDOW_INVALID, GetActiveWindow());
314 pNewWindow->OnMessage(msg2);
316 g_infoManager.SetPreviousWindow(WINDOW_INVALID);
320 void CGUIWindowManager::ChangeActiveWindow(int newWindow, const CStdString& strPath)
322 vector<CStdString> params;
323 if (!strPath.IsEmpty())
324 params.push_back(strPath);
325 ActivateWindow(newWindow, params, true);
328 void CGUIWindowManager::ActivateWindow(int iWindowID, const CStdString& strPath)
330 vector<CStdString> params;
331 if (!strPath.IsEmpty())
332 params.push_back(strPath);
333 ActivateWindow(iWindowID, params, false);
336 void CGUIWindowManager::ActivateWindow(int iWindowID, const vector<CStdString>& params, bool swappingWindows)
338 if (!g_application.IsCurrentThread())
340 // make sure graphics lock is not held
341 int nCount = ExitCriticalSection(g_graphicsContext);
342 g_application.getApplicationMessenger().ActivateWindow(iWindowID, params, swappingWindows);
343 RestoreCriticalSection(g_graphicsContext, nCount);
346 ActivateWindow_Internal(iWindowID, params, swappingWindows);
349 void CGUIWindowManager::ActivateWindow_Internal(int iWindowID, const vector<CStdString>& params, bool swappingWindows)
351 bool passParams = true;
352 // translate virtual windows
353 // virtual music window which returns the last open music window (aka the music start window)
354 if (iWindowID == WINDOW_MUSIC)
356 iWindowID = g_settings.m_iMyMusicStartWindow;
357 // ensure the music virtual window only returns music files and music library windows
358 if (iWindowID != WINDOW_MUSIC_NAV)
359 iWindowID = WINDOW_MUSIC_FILES;
360 // destination path cannot be used with virtual window
363 // virtual video window which returns the last open video window (aka the video start window)
364 if (iWindowID == WINDOW_VIDEOS)
366 iWindowID = g_settings.m_iVideoStartWindow;
367 // ensure the virtual video window only returns video windows
368 if (iWindowID != WINDOW_VIDEO_NAV)
369 iWindowID = WINDOW_VIDEO_FILES;
370 // destination path cannot be used with virtual window
373 if (iWindowID == WINDOW_SCRIPTS)
374 { // backward compatibility for pre-Dharma
375 iWindowID = WINDOW_PROGRAMS;
377 if (iWindowID == WINDOW_START)
378 { // virtual start window
379 iWindowID = g_SkinInfo->GetStartWindow();
383 CLog::Log(LOGDEBUG, "Activating window ID: %i", iWindowID);
385 if (!g_passwordManager.CheckMenuLock(iWindowID))
387 CLog::Log(LOGERROR, "MasterCode is Wrong: Window with id %d will not be loaded! Enter a correct MasterCode!", iWindowID);
388 if (GetActiveWindow() == WINDOW_INVALID && iWindowID != WINDOW_HOME)
389 ActivateWindow(WINDOW_HOME);
393 // first check existence of the window we wish to activate.
394 CGUIWindow *pNewWindow = GetWindow(iWindowID);
396 { // nothing to see here - move along
397 CLog::Log(LOGERROR, "Unable to locate window with id %d. Check skin files", iWindowID - WINDOW_HOME);
400 else if (pNewWindow->IsDialog())
401 { // if we have a dialog, we do a DoModal() rather than activate the window
402 if (!pNewWindow->IsDialogRunning())
403 ((CGUIDialog *)pNewWindow)->DoModal(iWindowID, (passParams && params.size()) ? params[0] : "");
407 g_infoManager.SetNextWindow(iWindowID);
409 // set our overlay state
410 HideOverlay(pNewWindow->GetOverlayState());
412 // deactivate any window
413 int currentWindow = GetActiveWindow();
414 CGUIWindow *pWindow = GetWindow(currentWindow);
417 // Play the window specific deinit sound
418 g_audioManager.PlayWindowSound(pWindow->GetID(), SOUND_DEINIT);
419 CGUIMessage msg(GUI_MSG_WINDOW_DEINIT, 0, 0, iWindowID);
420 pWindow->OnMessage(msg);
422 g_infoManager.SetNextWindow(WINDOW_INVALID);
424 // Add window to the history list (we must do this before we activate it,
425 // as all messages done in WINDOW_INIT will want to be sent to the new
426 // topmost window). If we are swapping windows, we pop the old window
427 // off the history stack
428 if (swappingWindows && m_windowHistory.size())
429 m_windowHistory.pop();
430 AddToWindowHistory(iWindowID);
432 g_infoManager.SetPreviousWindow(currentWindow);
433 g_audioManager.PlayWindowSound(pNewWindow->GetID(), SOUND_INIT);
434 // Send the init message
435 CGUIMessage msg(GUI_MSG_WINDOW_INIT, 0, 0, currentWindow, iWindowID);
437 msg.SetStringParams(params);
438 pNewWindow->OnMessage(msg);
439 // g_infoManager.SetPreviousWindow(WINDOW_INVALID);
442 void CGUIWindowManager::CloseDialogs(bool forceClose)
444 CSingleLock lock(g_graphicsContext);
445 while (m_activeDialogs.size() > 0)
447 CGUIWindow* win = m_activeDialogs[0];
448 win->Close(forceClose);
452 bool CGUIWindowManager::OnAction(const CAction &action)
454 CSingleLock lock(g_graphicsContext);
455 unsigned int topMost = m_activeDialogs.size();
458 CGUIWindow *dialog = m_activeDialogs[--topMost];
460 if (dialog->IsModalDialog())
461 { // we have the topmost modal dialog
462 if (!dialog->IsAnimating(ANIM_TYPE_WINDOW_CLOSE))
464 bool fallThrough = (dialog->GetID() == WINDOW_DIALOG_FULLSCREEN_INFO);
465 if (dialog->OnAction(action))
467 // dialog didn't want the action - we'd normally return false
468 // but for some dialogs we want to drop the actions through
473 return true; // do nothing with the action until the anim is finished
475 // music or video overlay are handled as a special case, as they're modeless, but we allow
476 // clicking on them with the mouse.
477 if (action.IsMouse() && (dialog->GetID() == WINDOW_VIDEO_OVERLAY ||
478 dialog->GetID() == WINDOW_MUSIC_OVERLAY))
480 if (dialog->OnAction(action))
484 if (topMost > m_activeDialogs.size())
485 topMost = m_activeDialogs.size();
488 CGUIWindow* window = GetWindow(GetActiveWindow());
490 return window->OnAction(action);
494 bool RenderOrderSortFunction(CGUIWindow *first, CGUIWindow *second)
496 return first->GetRenderOrder() < second->GetRenderOrder();
499 void CGUIWindowManager::Render()
501 assert(g_application.IsCurrentThread());
502 CSingleLock lock(g_graphicsContext);
503 CGUIWindow* pWindow = GetWindow(GetActiveWindow());
506 pWindow->ClearBackground();
510 // we render the dialogs based on their render order.
511 vector<CGUIWindow *> renderList = m_activeDialogs;
512 stable_sort(renderList.begin(), renderList.end(), RenderOrderSortFunction);
514 for (iDialog it = renderList.begin(); it != renderList.end(); ++it)
516 if ((*it)->IsDialogRunning())
521 void CGUIWindowManager::FrameMove()
523 assert(g_application.IsCurrentThread());
524 CSingleLock lock(g_graphicsContext);
528 // delete any windows queued for deletion
529 for(iDialog it = m_deleteWindows.begin(); it != m_deleteWindows.end(); it++)
531 // Free any window resources
532 (*it)->FreeResources(true);
535 m_deleteWindows.clear();
538 CGUIWindow* pWindow = GetWindow(GetActiveWindow());
540 pWindow->FrameMove();
541 // update any dialogs - we take a copy of the vector as some dialogs may close themselves
543 vector<CGUIWindow *> dialogs = m_activeDialogs;
544 for (iDialog it = dialogs.begin(); it != dialogs.end(); ++it)
548 CGUIWindow* CGUIWindowManager::GetWindow(int id) const
550 if (id == WINDOW_INVALID)
555 CSingleLock lock(g_graphicsContext);
556 WindowMap::const_iterator it = m_mapWindows.find(id);
557 if (it != m_mapWindows.end())
562 // Shows and hides modeless dialogs as necessary.
563 void CGUIWindowManager::UpdateModelessVisibility()
565 CSingleLock lock(g_graphicsContext);
566 for (WindowMap::iterator it = m_mapWindows.begin(); it != m_mapWindows.end(); it++)
568 CGUIWindow *pWindow = (*it).second;
569 if (pWindow && pWindow->IsDialog() && pWindow->GetVisibleCondition())
571 if (g_infoManager.GetBool(pWindow->GetVisibleCondition(), GetActiveWindow()))
572 ((CGUIDialog *)pWindow)->Show();
574 ((CGUIDialog *)pWindow)->Close();
579 void CGUIWindowManager::Process(bool renderOnly /*= false*/)
581 if (g_application.IsCurrentThread() && m_pCallback)
586 m_pCallback->Process();
587 m_pCallback->FrameMove();
589 m_pCallback->Render();
594 void CGUIWindowManager::SetCallback(IWindowManagerCallback& callback)
596 m_pCallback = &callback;
599 void CGUIWindowManager::DeInitialize()
601 CSingleLock lock(g_graphicsContext);
602 for (WindowMap::iterator it = m_mapWindows.begin(); it != m_mapWindows.end(); it++)
604 CGUIWindow* pWindow = (*it).second;
605 if (IsWindowActive(it->first))
607 pWindow->DisableAnimations();
608 CGUIMessage msg(GUI_MSG_WINDOW_DEINIT, 0, 0);
609 pWindow->OnMessage(msg);
611 pWindow->ResetControlStates();
612 pWindow->FreeResources(true);
614 UnloadNotOnDemandWindows();
616 m_vecMsgTargets.erase( m_vecMsgTargets.begin(), m_vecMsgTargets.end() );
618 // destroy our custom windows...
619 for (int i = 0; i < (int)m_vecCustomWindows.size(); i++)
621 CGUIWindow *pWindow = m_vecCustomWindows[i];
622 Remove(pWindow->GetID());
626 // clear our vectors of windows
627 m_vecCustomWindows.clear();
628 m_activeDialogs.clear();
631 /// \brief Route to a window
632 /// \param pWindow Window to route to
633 void CGUIWindowManager::RouteToWindow(CGUIWindow* dialog)
635 CSingleLock lock(g_graphicsContext);
636 // Just to be sure: Unroute this window,
637 // #we may have routed to it before
638 RemoveDialog(dialog->GetID());
640 m_activeDialogs.push_back(dialog);
643 /// \brief Unroute window
644 /// \param id ID of the window routed
645 void CGUIWindowManager::RemoveDialog(int id)
647 CSingleLock lock(g_graphicsContext);
648 for (iDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
650 if ((*it)->GetID() == id)
652 m_activeDialogs.erase(it);
658 bool CGUIWindowManager::HasModalDialog() const
660 CSingleLock lock(g_graphicsContext);
661 for (ciDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
663 CGUIWindow *window = *it;
664 if (window->IsModalDialog())
665 { // have a modal window
666 if (!window->IsAnimating(ANIM_TYPE_WINDOW_CLOSE))
673 bool CGUIWindowManager::HasDialogOnScreen() const
675 return (m_activeDialogs.size() > 0);
678 /// \brief Get the ID of the top most routed window
679 /// \return id ID of the window or WINDOW_INVALID if no routed window available
680 int CGUIWindowManager::GetTopMostModalDialogID() const
682 CSingleLock lock(g_graphicsContext);
683 for (crDialog it = m_activeDialogs.rbegin(); it != m_activeDialogs.rend(); ++it)
685 CGUIWindow *dialog = *it;
686 if (dialog->IsModalDialog())
687 { // have a modal window
688 return dialog->GetID();
691 return WINDOW_INVALID;
694 void CGUIWindowManager::SendThreadMessage(CGUIMessage& message)
696 CSingleLock lock(m_critSection);
698 CGUIMessage* msg = new CGUIMessage(message);
699 m_vecThreadMessages.push_back( pair<CGUIMessage*,int>(msg,0) );
702 void CGUIWindowManager::SendThreadMessage(CGUIMessage& message, int window)
704 CSingleLock lock(m_critSection);
706 CGUIMessage* msg = new CGUIMessage(message);
707 m_vecThreadMessages.push_back( pair<CGUIMessage*,int>(msg,window) );
710 void CGUIWindowManager::DispatchThreadMessages()
712 CSingleLock lock(m_critSection);
713 vector< pair<CGUIMessage*,int> > messages(m_vecThreadMessages);
714 m_vecThreadMessages.erase(m_vecThreadMessages.begin(), m_vecThreadMessages.end());
717 while ( messages.size() > 0 )
719 vector< pair<CGUIMessage*,int> >::iterator it = messages.begin();
720 CGUIMessage* pMsg = it->first;
721 int window = it->second;
722 // first remove the message from the queue,
723 // else the message could be processed more then once
724 it = messages.erase(it);
727 SendMessage( *pMsg, window );
729 SendMessage( *pMsg );
734 void CGUIWindowManager::AddMsgTarget( IMsgTargetCallback* pMsgTarget )
736 m_vecMsgTargets.push_back( pMsgTarget );
739 int CGUIWindowManager::GetActiveWindow() const
741 if (!m_windowHistory.empty())
742 return m_windowHistory.top();
743 return WINDOW_INVALID;
746 // same as GetActiveWindow() except it first grabs dialogs
747 int CGUIWindowManager::GetFocusedWindow() const
749 int dialog = GetTopMostModalDialogID();
750 if (dialog != WINDOW_INVALID)
753 return GetActiveWindow();
756 bool CGUIWindowManager::IsWindowActive(int id, bool ignoreClosing /* = true */) const
758 // mask out multiple instances of the same window
759 id &= WINDOW_ID_MASK;
760 if ((GetActiveWindow() & WINDOW_ID_MASK) == id) return true;
761 // run through the dialogs
762 CSingleLock lock(g_graphicsContext);
763 for (ciDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
765 CGUIWindow *window = *it;
766 if ((window->GetID() & WINDOW_ID_MASK) == id && (!ignoreClosing || !window->IsAnimating(ANIM_TYPE_WINDOW_CLOSE)))
769 return false; // window isn't active
772 bool CGUIWindowManager::IsWindowActive(const CStdString &xmlFile, bool ignoreClosing /* = true */) const
774 CSingleLock lock(g_graphicsContext);
775 CGUIWindow *window = GetWindow(GetActiveWindow());
776 if (window && CUtil::GetFileName(window->GetProperty("xmlfile")).Equals(xmlFile)) return true;
777 // run through the dialogs
778 for (ciDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
780 CGUIWindow *window = *it;
781 if (CUtil::GetFileName(window->GetProperty("xmlfile")).Equals(xmlFile) && (!ignoreClosing || !window->IsAnimating(ANIM_TYPE_WINDOW_CLOSE)))
784 return false; // window isn't active
787 bool CGUIWindowManager::IsWindowVisible(int id) const
789 return IsWindowActive(id, false);
792 bool CGUIWindowManager::IsWindowVisible(const CStdString &xmlFile) const
794 return IsWindowActive(xmlFile, false);
797 void CGUIWindowManager::LoadNotOnDemandWindows()
799 CSingleLock lock(g_graphicsContext);
800 for (WindowMap::iterator it = m_mapWindows.begin(); it != m_mapWindows.end(); it++)
802 CGUIWindow *pWindow = (*it).second;
803 if (!pWindow ->GetLoadOnDemand())
805 pWindow->FreeResources(true);
806 pWindow->Initialize();
811 void CGUIWindowManager::UnloadNotOnDemandWindows()
813 CSingleLock lock(g_graphicsContext);
814 for (WindowMap::iterator it = m_mapWindows.begin(); it != m_mapWindows.end(); it++)
816 CGUIWindow *pWindow = (*it).second;
817 if (!pWindow->GetLoadOnDemand())
819 pWindow->FreeResources(true);
824 bool CGUIWindowManager::IsOverlayAllowed() const
826 if (GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO ||
827 GetActiveWindow() == WINDOW_SCREENSAVER)
829 return m_bShowOverlay;
832 void CGUIWindowManager::ShowOverlay(CGUIWindow::OVERLAY_STATE state)
834 if (state != CGUIWindow::OVERLAY_STATE_PARENT_WINDOW)
835 m_bShowOverlay = state == CGUIWindow::OVERLAY_STATE_SHOWN;
838 void CGUIWindowManager::HideOverlay(CGUIWindow::OVERLAY_STATE state)
840 if (state == CGUIWindow::OVERLAY_STATE_HIDDEN)
841 m_bShowOverlay = false;
844 void CGUIWindowManager::AddToWindowHistory(int newWindowID)
846 // Check the window stack to see if this window is in our history,
847 // and if so, pop all the other windows off the stack so that we
848 // always have a predictable "Back" behaviour for each window
849 stack<int> historySave = m_windowHistory;
850 while (historySave.size())
852 if (historySave.top() == newWindowID)
856 if (!historySave.empty())
857 { // found window in history
858 m_windowHistory = historySave;
861 { // didn't find window in history - add it to the stack
862 m_windowHistory.push(newWindowID);
866 void CGUIWindowManager::GetActiveModelessWindows(vector<int> &ids)
868 // run through our modeless windows, and construct a vector of them
869 // useful for saving and restoring the modeless windows on skin change etc.
870 CSingleLock lock(g_graphicsContext);
871 for (iDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
873 if (!(*it)->IsModalDialog())
874 ids.push_back((*it)->GetID());
878 CGUIWindow *CGUIWindowManager::GetTopMostDialog() const
880 CSingleLock lock(g_graphicsContext);
881 // find the window with the lowest render order
882 vector<CGUIWindow *> renderList = m_activeDialogs;
883 stable_sort(renderList.begin(), renderList.end(), RenderOrderSortFunction);
885 if (!renderList.size())
888 // return the last window in the list
889 return *renderList.rbegin();
892 bool CGUIWindowManager::IsWindowTopMost(int id) const
894 CGUIWindow *topMost = GetTopMostDialog();
895 if (topMost && (topMost->GetID() & WINDOW_ID_MASK) == id)
900 bool CGUIWindowManager::IsWindowTopMost(const CStdString &xmlFile) const
902 CGUIWindow *topMost = GetTopMostDialog();
903 if (topMost && CUtil::GetFileName(topMost->GetProperty("xmlfile")).Equals(xmlFile))
908 void CGUIWindowManager::ClearWindowHistory()
910 while (m_windowHistory.size())
911 m_windowHistory.pop();
915 void CGUIWindowManager::DumpTextureUse()
917 CGUIWindow* pWindow = GetWindow(GetActiveWindow());
919 pWindow->DumpTextureUse();
921 CSingleLock lock(g_graphicsContext);
922 for (iDialog it = m_activeDialogs.begin(); it != m_activeDialogs.end(); ++it)
924 if ((*it)->IsDialogRunning())
925 (*it)->DumpTextureUse();