Fix keymap.
[vuplus_xbmc] / xbmc / guilib / GUIListItemLayout.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 "system.h"
22 #include "GUIListItemLayout.h"
23 #include "FileItem.h"
24 #include "GUIControlFactory.h"
25 #include "GUIInfoManager.h"
26 #include "GUIListLabel.h"
27 #include "GUIImage.h"
28 #include "utils/XBMCTinyXML.h"
29
30 using namespace std;
31
32 CGUIListItemLayout::CGUIListItemLayout()
33 : m_group(0, 0, 0, 0, 0, 0)
34 {
35   m_width = 0;
36   m_height = 0;
37   m_focused = false;
38   m_invalidated = true;
39   m_group.SetPushUpdates(true);
40 }
41
42 CGUIListItemLayout::CGUIListItemLayout(const CGUIListItemLayout &from)
43 : m_group(from.m_group), m_isPlaying(from.m_isPlaying)
44 {
45   m_width = from.m_width;
46   m_height = from.m_height;
47   m_focused = from.m_focused;
48   m_condition = from.m_condition;
49   m_invalidated = true;
50 }
51
52 CGUIListItemLayout::~CGUIListItemLayout()
53 {
54 }
55
56 bool CGUIListItemLayout::IsAnimating(ANIMATION_TYPE animType)
57 {
58   return m_group.IsAnimating(animType);
59 }
60
61 void CGUIListItemLayout::ResetAnimation(ANIMATION_TYPE animType)
62 {
63   return m_group.ResetAnimation(animType);
64 }
65
66 float CGUIListItemLayout::Size(ORIENTATION orientation) const
67 {
68   return (orientation == HORIZONTAL) ? m_width : m_height;
69 }
70
71 void CGUIListItemLayout::Process(CGUIListItem *item, int parentID, unsigned int currentTime, CDirtyRegionList &dirtyregions)
72 {
73   if (m_invalidated)
74   { // need to update our item
75     m_invalidated = false;
76     // could use a dynamic cast here if RTTI was enabled.  As it's not,
77     // let's use a static cast with a virtual base function
78     CFileItem *fileItem = item->IsFileItem() ? (CFileItem *)item : new CFileItem(*item);
79     m_isPlaying.Update(item);
80     m_group.SetInvalid();
81     m_group.UpdateInfo(fileItem);
82     // delete our temporary fileitem
83     if (!item->IsFileItem())
84       delete fileItem;
85   }
86
87   // update visibility, and render
88   m_group.SetState(item->IsSelected() || m_isPlaying, m_focused);
89   m_group.UpdateVisibility(item);
90   m_group.DoProcess(currentTime, dirtyregions);
91 }
92
93 void CGUIListItemLayout::Render(CGUIListItem *item, int parentID)
94 {
95   m_group.DoRender();
96 }
97
98 void CGUIListItemLayout::SetFocusedItem(unsigned int focus)
99 {
100   m_group.SetFocusedItem(focus);
101 }
102
103 unsigned int CGUIListItemLayout::GetFocusedItem() const
104 {
105   return m_group.GetFocusedItem();
106 }
107
108 void CGUIListItemLayout::SetWidth(float width)
109 {
110   if (m_width != width)
111   {
112     m_group.EnlargeWidth(width - m_width);
113     m_width = width;
114     SetInvalid();
115   }
116 }
117
118 void CGUIListItemLayout::SetHeight(float height)
119 {
120   if (m_height != height)
121   {
122     m_group.EnlargeHeight(height - m_height);
123     m_height = height;
124     SetInvalid();
125   }
126 }
127
128 void CGUIListItemLayout::SelectItemFromPoint(const CPoint &point)
129 {
130   m_group.SelectItemFromPoint(point);
131 }
132
133 bool CGUIListItemLayout::MoveLeft()
134 {
135   return m_group.MoveLeft();
136 }
137
138 bool CGUIListItemLayout::MoveRight()
139 {
140   return m_group.MoveRight();
141 }
142
143 bool CGUIListItemLayout::CheckCondition()
144 {
145   return !m_condition || m_condition->Get();
146 }
147
148 void CGUIListItemLayout::LoadControl(TiXmlElement *child, CGUIControlGroup *group)
149 {
150   if (!group) return;
151
152   CRect rect(group->GetXPosition(), group->GetYPosition(), group->GetXPosition() + group->GetWidth(), group->GetYPosition() + group->GetHeight());
153
154   CGUIControlFactory factory;
155   CGUIControl *control = factory.Create(0, rect, child, true);  // true indicating we're inside a list for the
156                                                                 // different label control + defaults.
157   if (control)
158   {
159     group->AddControl(control);
160     if (control->IsGroup())
161     {
162       TiXmlElement *grandChild = child->FirstChildElement("control");
163       while (grandChild)
164       {
165         LoadControl(grandChild, (CGUIControlGroup *)control);
166         grandChild = grandChild->NextSiblingElement("control");
167       }
168     }
169   }
170 }
171
172 void CGUIListItemLayout::LoadLayout(TiXmlElement *layout, int context, bool focused)
173 {
174   m_focused = focused;
175   layout->QueryFloatAttribute("width", &m_width);
176   layout->QueryFloatAttribute("height", &m_height);
177   const char *condition = layout->Attribute("condition");
178   if (condition)
179     m_condition = g_infoManager.Register(condition, context);
180   m_isPlaying.Parse("listitem.isplaying", context);
181   TiXmlElement *child = layout->FirstChildElement("control");
182   m_group.SetWidth(m_width);
183   m_group.SetHeight(m_height);
184   while (child)
185   {
186     LoadControl(child, &m_group);
187     child = child->NextSiblingElement("control");
188   }
189   // ensure width and height are valid
190   m_width = std::max(1.0f, m_width);
191   m_height = std::max(1.0f, m_height);
192 }
193
194 //#ifdef PRE_SKIN_VERSION_9_10_COMPATIBILITY
195 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 CStdString &nofocusCondition, const CStdString &focusCondition)
196 {
197   m_width = width;
198   m_height = height;
199   m_focused = focused;
200   m_isPlaying.Parse("listitem.isplaying", 0);
201   CGUIImage *tex = new CGUIImage(0, 0, 0, 0, width, texHeight, texture);
202   tex->SetVisibleCondition(nofocusCondition);
203   m_group.AddControl(tex);
204   if (focused)
205   {
206     CGUIImage *tex = new CGUIImage(0, 0, 0, 0, width, texHeight, textureFocus);
207     tex->SetVisibleCondition(focusCondition);
208     m_group.AddControl(tex);
209   }
210   CGUIImage *image = new CGUIImage(0, 0, 8, 0, iconWidth, texHeight, CTextureInfo(""));
211   image->SetInfo(CGUIInfoLabel("$INFO[ListItem.Icon]", "", m_group.GetParentID()));
212   image->SetAspectRatio(CAspectRatio::AR_KEEP);
213   m_group.AddControl(image);
214   float x = iconWidth + labelInfo.offsetX + 10;
215   CGUIListLabel *label = new CGUIListLabel(0, 0, x, labelInfo.offsetY, width - x - 18, height, labelInfo, CGUIInfoLabel("$INFO[ListItem.Label]", "", m_group.GetParentID()), false);
216   m_group.AddControl(label);
217   x = labelInfo2.offsetX ? labelInfo2.offsetX : m_width - 16;
218   label = new CGUIListLabel(0, 0, x, labelInfo2.offsetY, x - iconWidth - 20, height, labelInfo2, CGUIInfoLabel("$INFO[ListItem.Label2]", "", m_group.GetParentID()), false);
219   m_group.AddControl(label);
220 }
221 //#endif
222
223 void CGUIListItemLayout::FreeResources(bool immediately)
224 {
225   m_group.FreeResources(immediately);
226 }
227
228 #ifdef _DEBUG
229 void CGUIListItemLayout::DumpTextureUse()
230 {
231   m_group.DumpTextureUse();
232 }
233 #endif