eaa8d75a7cf3fb64fe0602dcd1c7d1d4db704adb
[vuplus_xbmc] / xbmc / guilib / GUIProgressControl.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://xbmc.org
4  *
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)
8  *  any later version.
9  *
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.
14  *
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/>.
18  *
19  */
20
21 #include "GUIProgressControl.h"
22 #include "GUIInfoManager.h"
23 #include "GUIListItem.h"
24 #include "GUIWindowManager.h"
25 #include "FileItem.h"
26
27 CGUIProgressControl::CGUIProgressControl(int parentID, int controlID,
28                                          float posX, float posY, float width,
29                                          float height, const CTextureInfo& backGroundTexture,
30                                          const CTextureInfo& leftTexture,
31                                          const CTextureInfo& midTexture,
32                                          const CTextureInfo& rightTexture,
33                                          const CTextureInfo& overlayTexture,
34                                          bool reveal)
35     : CGUIControl(parentID, controlID, posX, posY, width, height)
36     , m_guiBackground(posX, posY, width, height, backGroundTexture)
37     , m_guiLeft(posX, posY, width, height, leftTexture)
38     , m_guiMid(posX, posY, width, height, midTexture)
39     , m_guiRight(posX, posY, width, height, rightTexture)
40     , m_guiOverlay(posX, posY, width, height, overlayTexture)
41 {
42   m_fPercent = 0;
43   m_iInfoCode = 0;
44   ControlType = GUICONTROL_PROGRESS;
45   m_bReveal = reveal;
46   m_bChanged = false;
47 }
48
49 CGUIProgressControl::~CGUIProgressControl(void)
50 {
51 }
52
53 void CGUIProgressControl::SetPosition(float posX, float posY)
54 {
55   // everything is positioned based on the background image position
56   CGUIControl::SetPosition(posX, posY);
57   m_guiBackground.SetPosition(posX, posY);
58 }
59
60 void CGUIProgressControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
61 {
62   bool changed = false;
63
64   if (!IsDisabled())
65     changed |= UpdateLayout();
66   changed |= m_guiBackground.Process(currentTime);
67   changed |= m_guiMid.Process(currentTime);
68   changed |= m_guiLeft.Process(currentTime);
69   changed |= m_guiRight.Process(currentTime);
70   changed |= m_guiOverlay.Process(currentTime);
71
72   if (changed)
73     MarkDirtyRegion();
74
75   CGUIControl::Process(currentTime, dirtyregions);
76 }
77
78 void CGUIProgressControl::Render()
79 {
80   if (!IsDisabled())
81   {
82     m_guiBackground.Render();
83
84     if (m_guiLeft.GetFileName().IsEmpty() && m_guiRight.GetFileName().IsEmpty())
85     {
86       if (m_bReveal && !m_guiMidClipRect.IsEmpty())
87       {
88         bool restore = g_graphicsContext.SetClipRegion(m_guiMidClipRect.x1, m_guiMidClipRect.y1, m_guiMidClipRect.Width(), m_guiMidClipRect.Height());
89         m_guiMid.Render();
90         if (restore)
91           g_graphicsContext.RestoreClipRegion();
92       }
93       else if (!m_bReveal && m_guiMid.GetWidth() > 0)
94         m_guiMid.Render();
95     }
96     else
97     {
98       m_guiLeft.Render();
99
100       if (m_bReveal && !m_guiMidClipRect.IsEmpty())
101       {
102         bool restore = g_graphicsContext.SetClipRegion(m_guiMidClipRect.x1, m_guiMidClipRect.y1, m_guiMidClipRect.Width(), m_guiMidClipRect.Height());
103         m_guiMid.Render();
104         if (restore)
105           g_graphicsContext.RestoreClipRegion();
106       }
107       else if (!m_bReveal && m_guiMid.GetWidth() > 0)
108         m_guiMid.Render();
109
110       m_guiRight.Render();
111     }
112
113     m_guiOverlay.Render();
114   }
115
116   CGUIControl::Render();
117 }
118
119
120 bool CGUIProgressControl::CanFocus() const
121 {
122   return false;
123 }
124
125
126 bool CGUIProgressControl::OnMessage(CGUIMessage& message)
127 {
128   return CGUIControl::OnMessage(message);
129 }
130
131 void CGUIProgressControl::SetPercentage(float fPercent)
132 {
133   fPercent = std::max(0.0f, std::min(fPercent, 100.0f));
134   if (m_fPercent != fPercent)
135     SetInvalid();
136   m_fPercent = fPercent;
137 }
138
139 float CGUIProgressControl::GetPercentage() const
140 {
141   return m_fPercent;
142 }
143 void CGUIProgressControl::FreeResources(bool immediately)
144 {
145   CGUIControl::FreeResources(immediately);
146   m_guiBackground.FreeResources(immediately);
147   m_guiMid.FreeResources(immediately);
148   m_guiRight.FreeResources(immediately);
149   m_guiLeft.FreeResources(immediately);
150   m_guiOverlay.FreeResources(immediately);
151 }
152
153 void CGUIProgressControl::DynamicResourceAlloc(bool bOnOff)
154 {
155   CGUIControl::DynamicResourceAlloc(bOnOff);
156   m_guiBackground.DynamicResourceAlloc(bOnOff);
157   m_guiMid.DynamicResourceAlloc(bOnOff);
158   m_guiRight.DynamicResourceAlloc(bOnOff);
159   m_guiLeft.DynamicResourceAlloc(bOnOff);
160   m_guiOverlay.DynamicResourceAlloc(bOnOff);
161 }
162
163 void CGUIProgressControl::AllocResources()
164 {
165   CGUIControl::AllocResources();
166   m_guiBackground.AllocResources();
167   m_guiMid.AllocResources();
168   m_guiRight.AllocResources();
169   m_guiLeft.AllocResources();
170   m_guiOverlay.AllocResources();
171
172   m_guiBackground.SetHeight(25);
173   m_guiRight.SetHeight(20);
174   m_guiLeft.SetHeight(20);
175   m_guiMid.SetHeight(20);
176   m_guiOverlay.SetHeight(20);
177 }
178
179 void CGUIProgressControl::SetInvalid()
180 {
181   CGUIControl::SetInvalid();
182   m_guiBackground.SetInvalid();
183   m_guiMid.SetInvalid();
184   m_guiRight.SetInvalid();
185   m_guiLeft.SetInvalid();
186   m_guiOverlay.SetInvalid();
187 }
188
189 void CGUIProgressControl::SetInfo(int iInfo)
190 {
191   m_iInfoCode = iInfo;
192 }
193
194 bool CGUIProgressControl::UpdateColors()
195 {
196   bool changed = CGUIControl::UpdateColors();
197   changed |= m_guiBackground.SetDiffuseColor(m_diffuseColor);
198   changed |= m_guiRight.SetDiffuseColor(m_diffuseColor);
199   changed |= m_guiLeft.SetDiffuseColor(m_diffuseColor);
200   changed |= m_guiMid.SetDiffuseColor(m_diffuseColor);
201   changed |= m_guiOverlay.SetDiffuseColor(m_diffuseColor);
202
203   return changed;
204 }
205
206 CStdString CGUIProgressControl::GetDescription() const
207 {
208   CStdString percent;
209   percent.Format("%2.f", m_fPercent);
210   return percent;
211 }
212
213 bool CGUIProgressControl::UpdateLayout(void)
214 {
215   bool bChanged(false);
216
217   if (m_width == 0)
218     m_width = m_guiBackground.GetTextureWidth();
219   if (m_height == 0)
220     m_height = m_guiBackground.GetTextureHeight();
221
222   bChanged |= m_guiBackground.SetHeight(m_height);
223   bChanged |= m_guiBackground.SetWidth(m_width);
224
225   float fScaleX, fScaleY;
226   fScaleY = m_guiBackground.GetTextureHeight() ? m_height / m_guiBackground.GetTextureHeight() : 1.0f;
227   fScaleX = m_guiBackground.GetTextureWidth() ? m_width / m_guiBackground.GetTextureWidth() : 1.0f;
228
229   float posX = m_guiBackground.GetXPosition();
230   float posY = m_guiBackground.GetYPosition();
231
232   if (m_guiLeft.GetFileName().IsEmpty() && m_guiRight.GetFileName().IsEmpty())
233   { // rendering without left and right image - fill the mid image completely
234     float width = m_fPercent * m_width * 0.01f;
235     float offset = fabs(fScaleY * 0.5f * (m_guiMid.GetTextureHeight() - m_guiBackground.GetTextureHeight()));
236     if (offset > 0)  //  Center texture to the background if necessary
237       bChanged |= m_guiMid.SetPosition(posX, posY + offset);
238     else
239       bChanged |= m_guiMid.SetPosition(posX, posY);
240     bChanged |= m_guiMid.SetHeight(fScaleY * m_guiMid.GetTextureHeight());
241     if (m_bReveal)
242     {
243       bChanged |= m_guiMid.SetWidth(m_width);
244       float x = posX, y = posY + offset, w = width, h = fScaleY * m_guiMid.GetTextureHeight();
245       CRect rect(x, y, x + w, y + h);
246       if (rect != m_guiMidClipRect)
247       {
248         m_guiMidClipRect = rect;
249         bChanged = true;
250       }
251     }
252     else
253     {
254       bChanged |= m_guiMid.SetWidth(width);
255       m_guiMidClipRect = CRect();
256     }
257   }
258   else
259   {
260     float fWidth = m_fPercent;
261     float fFullWidth = m_guiBackground.GetTextureWidth() - m_guiLeft.GetTextureWidth() - m_guiRight.GetTextureWidth();
262     fWidth /= 100.0f;
263     fWidth *= fFullWidth;
264
265     float offset = fabs(fScaleY * 0.5f * (m_guiLeft.GetTextureHeight() - m_guiBackground.GetTextureHeight()));
266     if (offset > 0)  //  Center texture to the background if necessary
267       bChanged |= m_guiLeft.SetPosition(posX, posY + offset);
268     else
269       bChanged |= m_guiLeft.SetPosition(posX, posY);
270     bChanged |= m_guiLeft.SetHeight(fScaleY * m_guiLeft.GetTextureHeight());
271     bChanged |= m_guiLeft.SetWidth(fScaleX * m_guiLeft.GetTextureWidth());
272
273     posX += fScaleX * m_guiLeft.GetTextureWidth();
274     offset = fabs(fScaleY * 0.5f * (m_guiMid.GetTextureHeight() - m_guiBackground.GetTextureHeight()));
275     if (offset > 0)  //  Center texture to the background if necessary
276       bChanged |= m_guiMid.SetPosition(posX, posY + offset);
277     else
278       bChanged |= m_guiMid.SetPosition(posX, posY);
279     bChanged |= m_guiMid.SetHeight(fScaleY * m_guiMid.GetTextureHeight());
280     if (m_bReveal)
281     {
282       bChanged |= m_guiMid.SetWidth(fScaleX * fFullWidth);
283       float x = posX, y = posY + offset, w =  fScaleX * fWidth, h = fScaleY * m_guiMid.GetTextureHeight();
284       CRect rect(x, y, x + w, y + h);
285       if (rect != m_guiMidClipRect)
286       {
287         m_guiMidClipRect = rect;
288         bChanged = true;
289       }
290     }
291     else
292     {
293       bChanged |= m_guiMid.SetWidth(fScaleX * fWidth);
294       m_guiMidClipRect = CRect();
295     }
296
297     posX += fWidth * fScaleX;
298
299     offset = fabs(fScaleY * 0.5f * (m_guiRight.GetTextureHeight() - m_guiBackground.GetTextureHeight()));
300     if (offset > 0)  //  Center texture to the background if necessary
301       bChanged |= m_guiRight.SetPosition(posX, posY + offset);
302     else
303       bChanged |= m_guiRight.SetPosition(posX, posY);
304     bChanged |= m_guiRight.SetHeight(fScaleY * m_guiRight.GetTextureHeight());
305     bChanged |= m_guiRight.SetWidth(fScaleX * m_guiRight.GetTextureWidth());
306   }
307   float offset = fabs(fScaleY * 0.5f * (m_guiOverlay.GetTextureHeight() - m_guiBackground.GetTextureHeight()));
308   if (offset > 0)  //  Center texture to the background if necessary
309     bChanged |= m_guiOverlay.SetPosition(m_guiBackground.GetXPosition(), m_guiBackground.GetYPosition() + offset);
310   else
311     bChanged |= m_guiOverlay.SetPosition(m_guiBackground.GetXPosition(), m_guiBackground.GetYPosition());
312   bChanged |= m_guiOverlay.SetHeight(fScaleY * m_guiOverlay.GetTextureHeight());
313   bChanged |= m_guiOverlay.SetWidth(fScaleX * m_guiOverlay.GetTextureWidth());
314
315   return bChanged;
316 }
317
318 void CGUIProgressControl::UpdateInfo(const CGUIListItem *item)
319 {
320   if (!IsDisabled())
321   {
322     if (m_iInfoCode)
323     {
324       int value;
325       if (g_infoManager.GetInt(value, m_iInfoCode, m_parentID, item))
326         m_fPercent = (float)value;
327
328       if (m_fPercent < 0.0f) m_fPercent = 0.0f;
329       if (m_fPercent > 100.0f) m_fPercent = 100.0f;
330     }
331   }
332 }