2 * Copyright (C) 2005-2013 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, see
17 * <http://www.gnu.org/licenses/>.
21 #include "GUIDialog.h"
22 #include "GUIWindowManager.h"
23 #include "GUILabelControl.h"
24 #include "GUIAudioManager.h"
25 #include "threads/SingleLock.h"
26 #include "utils/TimeUtils.h"
27 #include "Application.h"
28 #include "ApplicationMessenger.h"
31 CGUIDialog::CGUIDialog(int id, const CStdString &xmlFile)
32 : CGUIWindow(id, xmlFile)
37 m_autoClosing = false;
41 m_bAutoClosed = false;
44 CGUIDialog::~CGUIDialog(void)
47 void CGUIDialog::OnWindowLoaded()
49 CGUIWindow::OnWindowLoaded();
51 // Clip labels to extents
52 if (m_children.size())
54 CGUIControl* pBase = m_children[0];
56 for (iControls p = m_children.begin() + 1; p != m_children.end(); ++p)
58 if ((*p)->GetControlType() == CGUIControl::GUICONTROL_LABEL)
60 CGUILabelControl* pLabel = (CGUILabelControl*)(*p);
62 if (!pLabel->GetWidth())
64 float spacing = (pLabel->GetXPosition() - pBase->GetXPosition()) * 2;
65 pLabel->SetWidth(pBase->GetWidth() - spacing);
72 bool CGUIDialog::OnAction(const CAction &action)
74 // keyboard or controller movement should prevent autoclosing
75 if (!action.IsMouse() && m_autoClosing)
76 SetAutoClose(m_showDuration);
78 return CGUIWindow::OnAction(action);
81 bool CGUIDialog::OnBack(int actionID)
87 bool CGUIDialog::OnMessage(CGUIMessage& message)
89 switch ( message.GetMessage() )
91 case GUI_MSG_WINDOW_DEINIT:
93 CGUIWindow *pWindow = g_windowManager.GetWindow(g_windowManager.GetActiveWindow());
95 g_windowManager.ShowOverlay(pWindow->GetOverlayState());
97 CGUIWindow::OnMessage(message);
100 case GUI_MSG_WINDOW_INIT:
102 CGUIWindow::OnMessage(message);
108 return CGUIWindow::OnMessage(message);
111 void CGUIDialog::OnDeinitWindow(int nextWindowID)
115 g_windowManager.RemoveDialog(GetID());
116 m_autoClosing = false;
118 CGUIWindow::OnDeinitWindow(nextWindowID);
121 void CGUIDialog::DoProcess(unsigned int currentTime, CDirtyRegionList &dirtyregions)
125 // if we were running but now we're not, mark us dirty
126 if (!m_active && m_wasRunning)
127 dirtyregions.push_back(m_renderRegion);
130 CGUIWindow::DoProcess(currentTime, dirtyregions);
132 m_wasRunning = m_active;
135 void CGUIDialog::UpdateVisibility()
137 if (m_visibleCondition)
139 if (m_visibleCondition->Get())
146 { // check if our timer is running
147 if (!m_showStartTime)
149 if (HasProcessed()) // start timer
150 m_showStartTime = CTimeUtils::GetFrameTime();
154 if (m_showStartTime + m_showDuration < CTimeUtils::GetFrameTime() && !m_closing)
156 m_bAutoClosed = true;
163 void CGUIDialog::DoModal_Internal(int iWindowID /*= WINDOW_INVALID */, const CStdString ¶m /* = "" */)
165 //Lock graphic context here as it is sometimes called from non rendering threads
166 //maybe we should have a critical section per window instead??
167 CSingleLock lock(g_graphicsContext);
169 if (!g_windowManager.Initialized())
170 return; // don't do anything
174 // set running before it's added to the window manager, else the auto-show code
175 // could show it as well if we are in a different thread from
176 // the main rendering thread (this should really be handled via
177 // a thread message though IMO)
179 g_windowManager.RouteToWindow(this);
181 // active this window...
182 CGUIMessage msg(GUI_MSG_WINDOW_INIT, 0, 0, WINDOW_INVALID, iWindowID);
183 msg.SetStringParam(param);
191 while (m_active && !g_application.m_bStop)
193 g_windowManager.ProcessRenderLoop();
197 void CGUIDialog::Show_Internal()
199 //Lock graphic context here as it is sometimes called from non rendering threads
200 //maybe we should have a critical section per window instead??
201 CSingleLock lock(g_graphicsContext);
203 if (m_active && !m_closing && !IsAnimating(ANIM_TYPE_WINDOW_CLOSE)) return;
205 if (!g_windowManager.Initialized())
206 return; // don't do anything
210 // set running before it's added to the window manager, else the auto-show code
211 // could show it as well if we are in a different thread from
212 // the main rendering thread (this should really be handled via
213 // a thread message though IMO)
216 g_windowManager.AddModeless(this);
218 // active this window...
219 CGUIMessage msg(GUI_MSG_WINDOW_INIT, 0, 0);
223 void CGUIDialog::DoModal(int iWindowID /*= WINDOW_INVALID */, const CStdString ¶m)
225 if (!g_application.IsCurrentThread())
227 // make sure graphics lock is not held
228 CSingleExit leaveIt(g_graphicsContext);
229 CApplicationMessenger::Get().DoModal(this, iWindowID, param);
232 DoModal_Internal(iWindowID, param);
235 void CGUIDialog::Show()
237 if (!g_application.IsCurrentThread())
239 // make sure graphics lock is not held
240 CSingleExit leaveIt(g_graphicsContext);
241 CApplicationMessenger::Get().Show(this);
247 void CGUIDialog::Render()
252 CGUIWindow::Render();
255 void CGUIDialog::SetDefaults()
257 CGUIWindow::SetDefaults();
261 void CGUIDialog::SetAutoClose(unsigned int timeoutMs)
263 m_autoClosing = true;
264 m_showDuration = timeoutMs;
268 void CGUIDialog::ResetAutoClose(void)
270 if (m_autoClosing && m_active)
271 m_showStartTime = CTimeUtils::GetFrameTime();