[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / guilib / GUIListGroup.cpp
1 /*
2  *      Copyright (C) 2005-2013 Team XBMC
3  *      http://www.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 "GUIListGroup.h"
22 #include "GUIListLabel.h"
23 #include "GUIMultiSelectText.h"
24 #include "GUIBorderedImage.h"
25 #include "GUIControlProfiler.h"
26 #include "utils/log.h"
27
28 CGUIListGroup::CGUIListGroup(int parentID, int controlID, float posX, float posY, float width, float height)
29 : CGUIControlGroup(parentID, controlID, posX, posY, width, height)
30 {
31   m_item = NULL;
32   ControlType = GUICONTROL_LISTGROUP;
33 }
34
35 CGUIListGroup::CGUIListGroup(const CGUIListGroup &right)
36 : CGUIControlGroup(right)
37 {
38   m_item = NULL;
39   ControlType = GUICONTROL_LISTGROUP;
40 }
41
42 CGUIListGroup::~CGUIListGroup(void)
43 {
44   FreeResources();
45 }
46
47 void CGUIListGroup::AddControl(CGUIControl *control, int position /*= -1*/)
48 {
49   if (control)
50   {
51     if (!(control->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL ||
52           control->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP ||
53           control->GetControlType() == CGUIControl::GUICONTROL_IMAGE ||
54           control->GetControlType() == CGUIControl::GUICONTROL_BORDEREDIMAGE ||
55           control->GetControlType() == CGUIControl::GUICONTROL_MULTI_IMAGE ||
56           control->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT ||
57           control->GetControlType() == CGUIControl::GUICONTROL_TEXTBOX ||
58           control->GetControlType() == CGUIControl::GUICONTROL_PROGRESS))
59       CLog::Log(LOGWARNING, "Trying to add unsupported control type %d", control->GetControlType());
60   }
61   CGUIControlGroup::AddControl(control, position);
62 }
63
64 void CGUIListGroup::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
65 {
66   CPoint pos(GetPosition());
67   g_graphicsContext.SetOrigin(m_posX, m_posY);
68
69   CRect rect;
70   for (iControls it = m_children.begin(); it != m_children.end(); ++it)
71   {
72     CGUIControl *control = *it;
73     control->UpdateVisibility(m_item);
74     unsigned int oldDirty = dirtyregions.size();
75     control->DoProcess(currentTime, dirtyregions);
76     if (control->IsVisible() || (oldDirty != dirtyregions.size())) // visible or dirty (was visible?)
77       rect.Union(control->GetRenderRegion());
78   }
79
80   g_graphicsContext.RestoreOrigin();
81   CGUIControl::Process(currentTime, dirtyregions);
82   m_renderRegion = rect;
83   m_item = NULL;
84 }
85
86 void CGUIListGroup::ResetAnimation(ANIMATION_TYPE type)
87 {
88   CGUIControl::ResetAnimation(type);
89   for (iControls it = m_children.begin(); it != m_children.end(); ++it)
90     (*it)->ResetAnimation(type);
91 }
92
93 void CGUIListGroup::UpdateVisibility(const CGUIListItem *item)
94 {
95   CGUIControlGroup::UpdateVisibility(item);
96   m_item = item;
97 }
98
99 void CGUIListGroup::UpdateInfo(const CGUIListItem *item)
100 {
101   for (iControls it = m_children.begin(); it != m_children.end(); it++)
102   {
103     (*it)->UpdateInfo(item);
104     (*it)->UpdateVisibility(item);
105   }
106   // now we have to check our overlapping label pairs
107   for (unsigned int i = 0; i < m_children.size(); i++)
108   {
109     if (m_children[i]->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL && m_children[i]->IsVisible())
110     {
111       for (unsigned int j = i + 1; j < m_children.size(); j++)
112       {
113         if (m_children[j]->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL && m_children[j]->IsVisible())
114           CGUIListLabel::CheckAndCorrectOverlap(*(CGUIListLabel *)m_children[i], *(CGUIListLabel *)m_children[j]);
115       }
116     }
117   }
118 }
119
120 void CGUIListGroup::EnlargeWidth(float difference)
121 {
122   // Alters the width of the controls that have an ID of 1
123   for (iControls it = m_children.begin(); it != m_children.end(); it++)
124   {
125     CGUIControl *child = *it;
126     if (child->GetID() >= 1 && child->GetID() <= 14)
127     {
128       if (child->GetID() == 1) // label
129       {
130         child->SetWidth(child->GetWidth() + difference - 10);
131         child->SetVisible(child->GetWidth() > 10); ///
132       }
133       else
134       {
135         child->SetWidth(child->GetWidth() + difference);
136       }
137     }
138   }
139   SetInvalid();
140 }
141
142 void CGUIListGroup::EnlargeHeight(float difference)
143 {
144   // Alters the width of the controls that have an ID of 1
145   for (iControls it = m_children.begin(); it != m_children.end(); it++)
146   {
147     CGUIControl *child = *it;
148     if (child->GetID() >= 1 && child->GetID() <= 14)
149     {
150       if (child->GetID() == 1) // label
151       {
152         child->SetHeight(child->GetHeight() + difference);
153         child->SetVisible(child->GetHeight() > 10); ///
154       }
155       else
156       {
157         child->SetHeight(child->GetHeight() + difference);
158       }
159     }
160   }
161   SetInvalid();
162 }
163
164 void CGUIListGroup::SetInvalid()
165 {
166   if (!m_bInvalidated)
167   { // this can be triggered by an item change, so all children need invalidating rather than just the group
168     for (iControls it = m_children.begin(); it != m_children.end(); ++it)
169       (*it)->SetInvalid();
170     CGUIControlGroup::SetInvalid();
171   }
172 }
173
174 void CGUIListGroup::SetFocusedItem(unsigned int focus)
175 {
176   for (iControls it = m_children.begin(); it != m_children.end(); it++)
177   {
178     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT)
179       ((CGUIMultiSelectTextControl *)(*it))->SetFocusedItem(focus);
180     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP)
181       ((CGUIListGroup *)(*it))->SetFocusedItem(focus);
182     else
183       (*it)->SetFocus(focus > 0);
184   }
185   SetFocus(focus > 0);
186 }
187
188 unsigned int CGUIListGroup::GetFocusedItem() const
189 {
190   for (ciControls it = m_children.begin(); it != m_children.end(); it++)
191   {
192     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT && ((CGUIMultiSelectTextControl *)(*it))->GetFocusedItem())
193       return ((CGUIMultiSelectTextControl *)(*it))->GetFocusedItem();
194     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP && ((CGUIListGroup *)(*it))->GetFocusedItem())
195       return ((CGUIListGroup *)(*it))->GetFocusedItem();
196   }
197   return 0;
198 }
199
200 bool CGUIListGroup::MoveLeft()
201 {
202   for (iControls it = m_children.begin(); it != m_children.end(); it++)
203   {
204     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT && ((CGUIMultiSelectTextControl *)(*it))->MoveLeft())
205       return true;
206     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP && ((CGUIListGroup *)(*it))->MoveLeft())
207       return true;
208   }
209   return false;
210 }
211
212 bool CGUIListGroup::MoveRight()
213 {
214   for (iControls it = m_children.begin(); it != m_children.end(); it++)
215   {
216     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT && ((CGUIMultiSelectTextControl *)(*it))->MoveLeft())
217       return true;
218     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP && ((CGUIListGroup *)(*it))->MoveLeft())
219       return true;
220   }
221   return false;
222 }
223
224 void CGUIListGroup::SetState(bool selected, bool focused)
225 {
226   for (iControls it = m_children.begin(); it != m_children.end(); it++)
227   {
228     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL)
229     {
230       CGUIListLabel *label = (CGUIListLabel *)(*it);
231       label->SetSelected(selected);
232       label->SetScrolling(focused);
233     }
234   }
235 }
236
237 void CGUIListGroup::SelectItemFromPoint(const CPoint &point)
238 {
239   CPoint controlCoords(point);
240   m_transform.InverseTransformPosition(controlCoords.x, controlCoords.y);
241   for (iControls it = m_children.begin(); it != m_children.end(); ++it)
242   {
243     CGUIControl *child = *it;
244     if (child->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT)
245       ((CGUIMultiSelectTextControl *)child)->SelectItemFromPoint(point);
246     else if (child->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP)
247       ((CGUIListGroup *)child)->SelectItemFromPoint(point);
248   }
249 }