/xbmc/guilib/GUIListGroup.cpp

http://github.com/xbmc/xbmc · C++ · 224 lines · 193 code · 21 blank · 10 comment · 71 complexity · 3530f70cf831a2706534df985decc7f1 MD5 · raw file

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