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