Fix keymap.
[vuplus_xbmc] / xbmc / guilib / GUIListGroup.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 "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   g_graphicsContext.SetOrigin(m_posX, m_posY);
67
68   CRect rect;
69   for (iControls it = m_children.begin(); it != m_children.end(); ++it)
70   {
71     CGUIControl *control = *it;
72     control->UpdateVisibility(m_item);
73     unsigned int oldDirty = dirtyregions.size();
74     control->DoProcess(currentTime, dirtyregions);
75     if (control->IsVisible() || (oldDirty != dirtyregions.size())) // visible or dirty (was visible?)
76       rect.Union(control->GetRenderRegion());
77   }
78
79   g_graphicsContext.RestoreOrigin();
80   CGUIControl::Process(currentTime, dirtyregions);
81   m_renderRegion = rect;
82   m_item = NULL;
83 }
84
85 void CGUIListGroup::ResetAnimation(ANIMATION_TYPE type)
86 {
87   CGUIControl::ResetAnimation(type);
88   for (iControls it = m_children.begin(); it != m_children.end(); ++it)
89     (*it)->ResetAnimation(type);
90 }
91
92 void CGUIListGroup::UpdateVisibility(const CGUIListItem *item)
93 {
94   CGUIControlGroup::UpdateVisibility(item);
95   m_item = item;
96 }
97
98 void CGUIListGroup::UpdateInfo(const CGUIListItem *item)
99 {
100   for (iControls it = m_children.begin(); it != m_children.end(); it++)
101   {
102     (*it)->UpdateInfo(item);
103     (*it)->UpdateVisibility(item);
104   }
105   // now we have to check our overlapping label pairs
106   for (unsigned int i = 0; i < m_children.size(); i++)
107   {
108     if (m_children[i]->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL && m_children[i]->IsVisible())
109     {
110       for (unsigned int j = i + 1; j < m_children.size(); j++)
111       {
112         if (m_children[j]->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL && m_children[j]->IsVisible())
113           CGUIListLabel::CheckAndCorrectOverlap(*(CGUIListLabel *)m_children[i], *(CGUIListLabel *)m_children[j]);
114       }
115     }
116   }
117 }
118
119 void CGUIListGroup::EnlargeWidth(float difference)
120 {
121   // Alters the width of the controls that have an ID of 1 to 14
122   for (iControls it = m_children.begin(); it != m_children.end(); it++)
123   {
124     CGUIControl *child = *it;
125     if (child->GetID() >= 1 && child->GetID() <= 14)
126     {
127       if (child->GetID() == 1)
128       {
129         child->SetWidth(child->GetWidth() + difference);
130         child->SetVisible(child->GetWidth() > 10);
131       }
132       else
133       {
134         child->SetWidth(child->GetWidth() + difference);
135       }
136     }
137   }
138   SetInvalid();
139 }
140
141 void CGUIListGroup::EnlargeHeight(float difference)
142 {
143   // Alters the height of the controls that have an ID of 1 to 14
144   for (iControls it = m_children.begin(); it != m_children.end(); it++)
145   {
146     CGUIControl *child = *it;
147     if (child->GetID() >= 1 && child->GetID() <= 14)
148     {
149       if (child->GetID() == 1)
150       {
151         child->SetHeight(child->GetHeight() + difference);
152         child->SetVisible(child->GetHeight() > 10);
153       }
154       else
155       {
156         child->SetHeight(child->GetHeight() + difference);
157       }
158     }
159   }
160   SetInvalid();
161 }
162
163 void CGUIListGroup::SetInvalid()
164 {
165   if (!m_bInvalidated)
166   { // this can be triggered by an item change, so all children need invalidating rather than just the group
167     for (iControls it = m_children.begin(); it != m_children.end(); ++it)
168       (*it)->SetInvalid();
169     CGUIControlGroup::SetInvalid();
170   }
171 }
172
173 void CGUIListGroup::SetFocusedItem(unsigned int focus)
174 {
175   for (iControls it = m_children.begin(); it != m_children.end(); it++)
176   {
177     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT)
178       ((CGUIMultiSelectTextControl *)(*it))->SetFocusedItem(focus);
179     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP)
180       ((CGUIListGroup *)(*it))->SetFocusedItem(focus);
181     else
182       (*it)->SetFocus(focus > 0);
183   }
184   SetFocus(focus > 0);
185 }
186
187 unsigned int CGUIListGroup::GetFocusedItem() const
188 {
189   for (ciControls it = m_children.begin(); it != m_children.end(); it++)
190   {
191     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT && ((CGUIMultiSelectTextControl *)(*it))->GetFocusedItem())
192       return ((CGUIMultiSelectTextControl *)(*it))->GetFocusedItem();
193     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP && ((CGUIListGroup *)(*it))->GetFocusedItem())
194       return ((CGUIListGroup *)(*it))->GetFocusedItem();
195   }
196   return 0;
197 }
198
199 bool CGUIListGroup::MoveLeft()
200 {
201   for (iControls it = m_children.begin(); it != m_children.end(); it++)
202   {
203     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT && ((CGUIMultiSelectTextControl *)(*it))->MoveLeft())
204       return true;
205     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP && ((CGUIListGroup *)(*it))->MoveLeft())
206       return true;
207   }
208   return false;
209 }
210
211 bool CGUIListGroup::MoveRight()
212 {
213   for (iControls it = m_children.begin(); it != m_children.end(); it++)
214   {
215     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT && ((CGUIMultiSelectTextControl *)(*it))->MoveLeft())
216       return true;
217     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP && ((CGUIListGroup *)(*it))->MoveLeft())
218       return true;
219   }
220   return false;
221 }
222
223 void CGUIListGroup::SetState(bool selected, bool focused)
224 {
225   for (iControls it = m_children.begin(); it != m_children.end(); it++)
226   {
227     if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTLABEL)
228     {
229       CGUIListLabel *label = (CGUIListLabel *)(*it);
230       label->SetSelected(selected);
231       label->SetScrolling(focused);
232     }
233     else if ((*it)->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP)
234       ((CGUIListGroup *)(*it))->SetState(selected, focused);
235   }
236 }
237
238 void CGUIListGroup::SelectItemFromPoint(const CPoint &point)
239 {
240   CPoint controlCoords(point);
241   m_transform.InverseTransformPosition(controlCoords.x, controlCoords.y);
242   for (iControls it = m_children.begin(); it != m_children.end(); ++it)
243   {
244     CGUIControl *child = *it;
245     if (child->GetControlType() == CGUIControl::GUICONTROL_MULTISELECT)
246       ((CGUIMultiSelectTextControl *)child)->SelectItemFromPoint(point);
247     else if (child->GetControlType() == CGUIControl::GUICONTROL_LISTGROUP)
248       ((CGUIListGroup *)child)->SelectItemFromPoint(point);
249   }
250 }