2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "GUIListItemLayout.h"
12 #include "GUIControlFactory.h"
14 #include "GUIInfoManager.h"
15 #include "GUIListLabel.h"
16 #include "utils/XBMCTinyXML.h"
18 using namespace KODI::GUILIB
;
20 CGUIListItemLayout::CGUIListItemLayout()
21 : m_group(0, 0, 0, 0, 0, 0)
23 m_group
.SetPushUpdates(true);
26 CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout
& from
)
27 : CGUIListItemLayout(from
, nullptr)
31 CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout
& from
, CGUIControl
* control
)
32 : m_group(from
.m_group
),
33 m_width(from
.m_width
),
34 m_height(from
.m_height
),
35 m_focused(from
.m_focused
),
36 m_condition(from
.m_condition
),
37 m_isPlaying(from
.m_isPlaying
),
38 m_infoUpdateMillis(from
.m_infoUpdateMillis
)
40 m_group
.SetParentControl(control
);
41 m_infoUpdateTimeout
.Set(m_infoUpdateMillis
);
43 // m_group was just created, cloned controls with resources must be allocated
45 m_group
.AllocResources();
48 bool CGUIListItemLayout::IsAnimating(ANIMATION_TYPE animType
)
50 return m_group
.IsAnimating(animType
);
53 void CGUIListItemLayout::ResetAnimation(ANIMATION_TYPE animType
)
55 return m_group
.ResetAnimation(animType
);
58 float CGUIListItemLayout::Size(ORIENTATION orientation
) const
60 return (orientation
== HORIZONTAL
) ? m_width
: m_height
;
63 void CGUIListItemLayout::Process(CGUIListItem
*item
, int parentID
, unsigned int currentTime
, CDirtyRegionList
&dirtyregions
)
66 { // need to update our item
67 m_invalidated
= false;
68 // could use a dynamic cast here if RTTI was enabled. As it's not,
69 // let's use a static cast with a virtual base function
70 CFileItem
*fileItem
= item
->IsFileItem() ? static_cast<CFileItem
*>(item
) : new CFileItem(*item
);
71 m_isPlaying
.Update(INFO::DEFAULT_CONTEXT
, item
);
73 m_group
.UpdateInfo(fileItem
);
74 // delete our temporary fileitem
75 if (!item
->IsFileItem())
78 m_infoUpdateTimeout
.Set(m_infoUpdateMillis
);
80 else if (m_infoUpdateTimeout
.IsTimePast())
82 m_isPlaying
.Update(INFO::DEFAULT_CONTEXT
, item
);
83 m_group
.UpdateInfo(item
);
85 m_infoUpdateTimeout
.Set(m_infoUpdateMillis
);
88 // update visibility, and render
89 m_group
.SetState(item
->IsSelected() || m_isPlaying
, m_focused
);
90 m_group
.UpdateVisibility(item
);
91 m_group
.DoProcess(currentTime
, dirtyregions
);
94 void CGUIListItemLayout::Render(CGUIListItem
*item
, int parentID
)
99 void CGUIListItemLayout::SetFocusedItem(unsigned int focus
)
101 m_group
.SetFocusedItem(focus
);
104 unsigned int CGUIListItemLayout::GetFocusedItem() const
106 return m_group
.GetFocusedItem();
109 void CGUIListItemLayout::SetWidth(float width
)
111 if (m_width
!= width
)
113 m_group
.EnlargeWidth(width
- m_width
);
119 void CGUIListItemLayout::SetHeight(float height
)
121 if (m_height
!= height
)
123 m_group
.EnlargeHeight(height
- m_height
);
129 void CGUIListItemLayout::SelectItemFromPoint(const CPoint
&point
)
131 m_group
.SelectItemFromPoint(point
);
134 bool CGUIListItemLayout::MoveLeft()
136 return m_group
.MoveLeft();
139 bool CGUIListItemLayout::MoveRight()
141 return m_group
.MoveRight();
144 bool CGUIListItemLayout::CheckCondition()
146 return !m_condition
|| m_condition
->Get(INFO::DEFAULT_CONTEXT
);
149 void CGUIListItemLayout::LoadControl(TiXmlElement
*child
, CGUIControlGroup
*group
)
153 CRect
rect(group
->GetXPosition(), group
->GetYPosition(), group
->GetXPosition() + group
->GetWidth(), group
->GetYPosition() + group
->GetHeight());
155 CGUIControlFactory factory
;
156 CGUIControl
*control
= factory
.Create(0, rect
, child
, true); // true indicating we're inside a list for the
157 // different label control + defaults.
160 group
->AddControl(control
);
161 if (control
->IsGroup())
163 TiXmlElement
*grandChild
= child
->FirstChildElement("control");
166 LoadControl(grandChild
, static_cast<CGUIControlGroup
*>(control
));
167 grandChild
= grandChild
->NextSiblingElement("control");
173 void CGUIListItemLayout::LoadLayout(TiXmlElement
*layout
, int context
, bool focused
, float maxWidth
, float maxHeight
)
176 layout
->QueryFloatAttribute("width", &m_width
);
177 layout
->QueryFloatAttribute("height", &m_height
);
178 const char *condition
= layout
->Attribute("condition");
180 m_condition
= CServiceBroker::GetGUI()->GetInfoManager().Register(condition
, context
);
181 unsigned int infoupdatemillis
= 0;
182 layout
->QueryUnsignedAttribute("infoupdate", &infoupdatemillis
);
183 if (infoupdatemillis
> 0)
184 m_infoUpdateMillis
= std::chrono::milliseconds(infoupdatemillis
);
186 m_infoUpdateTimeout
.Set(m_infoUpdateMillis
);
187 m_isPlaying
.Parse("listitem.isplaying", context
);
188 // ensure width and height are valid
192 m_height
= maxHeight
;
193 m_width
= std::max(1.0f
, m_width
);
194 m_height
= std::max(1.0f
, m_height
);
195 m_group
.SetWidth(m_width
);
196 m_group
.SetHeight(m_height
);
198 TiXmlElement
*child
= layout
->FirstChildElement("control");
201 LoadControl(child
, &m_group
);
202 child
= child
->NextSiblingElement("control");
206 //#ifdef GUILIB_PYTHON_COMPATIBILITY
207 void CGUIListItemLayout::CreateListControlLayouts(float width
, float height
, bool focused
, const CLabelInfo
&labelInfo
, const CLabelInfo
&labelInfo2
, const CTextureInfo
&texture
, const CTextureInfo
&textureFocus
, float texHeight
, float iconWidth
, float iconHeight
, const std::string
&nofocusCondition
, const std::string
&focusCondition
)
212 m_isPlaying
.Parse("listitem.isplaying", 0);
213 CGUIImage
*tex
= new CGUIImage(0, 0, 0, 0, width
, texHeight
, texture
);
214 tex
->SetVisibleCondition(nofocusCondition
);
215 m_group
.AddControl(tex
);
218 CGUIImage
*tex
= new CGUIImage(0, 0, 0, 0, width
, texHeight
, textureFocus
);
219 tex
->SetVisibleCondition(focusCondition
);
220 m_group
.AddControl(tex
);
222 CGUIImage
*image
= new CGUIImage(0, 0, 8, 0, iconWidth
, texHeight
, CTextureInfo(""));
223 image
->SetInfo(GUIINFO::CGUIInfoLabel("$INFO[ListItem.Icon]", "", m_group
.GetParentID()));
224 image
->SetAspectRatio(CAspectRatio::AR_KEEP
);
225 m_group
.AddControl(image
);
226 float x
= iconWidth
+ labelInfo
.offsetX
+ 10;
227 CGUIListLabel
*label
= new CGUIListLabel(0, 0, x
, labelInfo
.offsetY
, width
- x
- 18, height
, labelInfo
, GUIINFO::CGUIInfoLabel("$INFO[ListItem.Label]", "", m_group
.GetParentID()), CGUIControl::FOCUS
);
228 m_group
.AddControl(label
);
229 x
= labelInfo2
.offsetX
? labelInfo2
.offsetX
: m_width
- 16;
230 label
= new CGUIListLabel(0, 0, x
, labelInfo2
.offsetY
, x
- iconWidth
- 20, height
, labelInfo2
, GUIINFO::CGUIInfoLabel("$INFO[ListItem.Label2]", "", m_group
.GetParentID()), CGUIControl::FOCUS
);
231 m_group
.AddControl(label
);
235 void CGUIListItemLayout::FreeResources(bool immediately
)
237 m_group
.FreeResources(immediately
);
240 void CGUIListItemLayout::AssignDepth()
242 m_group
.AssignDepth();
246 void CGUIListItemLayout::DumpTextureUse()
248 m_group
.DumpTextureUse();