[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / guilib / GUIRangesControl.cpp
blob8c8c2f0dc51d30a7aafc4ccfb0dc82ca0fb6732b
1 /*
2 * Copyright (C) 2019 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.
7 */
9 #include "GUIRangesControl.h"
11 #include "GUIInfoManager.h"
12 #include "ServiceBroker.h"
13 #include "utils/StringUtils.h"
14 #include "utils/log.h"
16 #include <cmath>
18 CGUIRangesControl::CGUIRange::CGUIRange(float fPosX,
19 float fPosY,
20 float fWidth,
21 float fHeight,
22 const CTextureInfo& lowerTextureInfo,
23 const CTextureInfo& fillTextureInfo,
24 const CTextureInfo& upperTextureInfo,
25 const std::pair<float, float>& percentages)
26 : m_guiLowerTexture(CGUITexture::CreateTexture(fPosX, fPosY, fWidth, fHeight, lowerTextureInfo)),
27 m_guiFillTexture(CGUITexture::CreateTexture(fPosX, fPosY, fWidth, fHeight, fillTextureInfo)),
28 m_guiUpperTexture(CGUITexture::CreateTexture(fPosX, fPosY, fWidth, fHeight, upperTextureInfo)),
29 m_percentValues(percentages)
33 CGUIRangesControl::CGUIRange::CGUIRange(const CGUIRange& range)
34 : m_guiLowerTexture(range.m_guiLowerTexture->Clone()),
35 m_guiFillTexture(range.m_guiFillTexture->Clone()),
36 m_guiUpperTexture(range.m_guiUpperTexture->Clone()),
37 m_percentValues(range.m_percentValues)
41 void CGUIRangesControl::CGUIRange::AllocResources()
43 m_guiFillTexture->AllocResources();
44 m_guiUpperTexture->AllocResources();
45 m_guiLowerTexture->AllocResources();
47 m_guiFillTexture->SetHeight(20);
48 m_guiUpperTexture->SetHeight(20);
49 m_guiLowerTexture->SetHeight(20);
52 void CGUIRangesControl::CGUIRange::FreeResources(bool bImmediately)
54 m_guiFillTexture->FreeResources(bImmediately);
55 m_guiUpperTexture->FreeResources(bImmediately);
56 m_guiLowerTexture->FreeResources(bImmediately);
59 void CGUIRangesControl::CGUIRange::DynamicResourceAlloc(bool bOnOff)
61 m_guiFillTexture->DynamicResourceAlloc(bOnOff);
62 m_guiUpperTexture->DynamicResourceAlloc(bOnOff);
63 m_guiLowerTexture->DynamicResourceAlloc(bOnOff);
66 void CGUIRangesControl::CGUIRange::SetInvalid()
68 m_guiFillTexture->SetInvalid();
69 m_guiUpperTexture->SetInvalid();
70 m_guiLowerTexture->SetInvalid();
73 bool CGUIRangesControl::CGUIRange::SetDiffuseColor(const KODI::GUILIB::GUIINFO::CGUIInfoColor& color)
75 bool bChanged = false;
76 bChanged |= m_guiFillTexture->SetDiffuseColor(color);
77 bChanged |= m_guiUpperTexture->SetDiffuseColor(color);
78 bChanged |= m_guiLowerTexture->SetDiffuseColor(color);
79 return bChanged;
82 bool CGUIRangesControl::CGUIRange::Process(unsigned int currentTime)
84 bool bChanged = false;
85 bChanged |= m_guiFillTexture->Process(currentTime);
86 bChanged |= m_guiUpperTexture->Process(currentTime);
87 bChanged |= m_guiLowerTexture->Process(currentTime);
88 return bChanged;
91 void CGUIRangesControl::CGUIRange::Render()
93 if (m_guiLowerTexture->GetFileName().empty() && m_guiUpperTexture->GetFileName().empty())
95 if (m_guiFillTexture->GetWidth() > 0)
96 m_guiFillTexture->Render();
98 else
100 m_guiLowerTexture->Render();
102 if (m_guiFillTexture->GetWidth() > 0)
103 m_guiFillTexture->Render();
105 m_guiUpperTexture->Render();
109 bool CGUIRangesControl::CGUIRange::UpdateLayout(float fBackgroundTextureHeight,
110 float fPosX, float fPosY, float fWidth,
111 float fScaleX, float fScaleY)
113 bool bChanged = false;
115 if (m_guiLowerTexture->GetFileName().empty() && m_guiUpperTexture->GetFileName().empty())
117 // rendering without left and right image - fill the mid image completely
118 float width = (m_percentValues.second - m_percentValues.first) * fWidth * 0.01f;
119 float offsetX = m_percentValues.first * fWidth * 0.01f;
120 float offsetY = std::fabs(fScaleY * 0.5f *
121 (m_guiFillTexture->GetTextureHeight() - fBackgroundTextureHeight));
122 bChanged |= m_guiFillTexture->SetPosition(fPosX + (offsetX > 0 ? offsetX : 0),
123 fPosY + (offsetY > 0 ? offsetY : 0));
124 bChanged |= m_guiFillTexture->SetHeight(fScaleY * m_guiFillTexture->GetTextureHeight());
125 bChanged |= m_guiFillTexture->SetWidth(width);
127 else
129 float offsetX =
130 m_percentValues.first * fWidth * 0.01f - m_guiLowerTexture->GetTextureWidth() * 0.5f;
131 float offsetY = std::fabs(fScaleY * 0.5f *
132 (m_guiLowerTexture->GetTextureHeight() - fBackgroundTextureHeight));
133 bChanged |= m_guiLowerTexture->SetPosition(fPosX + (offsetX > 0 ? offsetX : 0),
134 fPosY + (offsetY > 0 ? offsetY : 0));
135 bChanged |= m_guiLowerTexture->SetHeight(fScaleY * m_guiLowerTexture->GetTextureHeight());
136 bChanged |= m_guiLowerTexture->SetWidth(m_percentValues.first == 0.0f
137 ? m_guiLowerTexture->GetTextureWidth() * 0.5f
138 : m_guiLowerTexture->GetTextureWidth());
140 if (m_percentValues.first != m_percentValues.second)
142 float width = (m_percentValues.second - m_percentValues.first) * fWidth * 0.01f -
143 m_guiLowerTexture->GetTextureWidth() * 0.5f -
144 m_guiUpperTexture->GetTextureWidth() * 0.5f;
146 offsetX += m_guiLowerTexture->GetTextureWidth();
147 offsetY = std::fabs(fScaleY * 0.5f *
148 (m_guiFillTexture->GetTextureHeight() - fBackgroundTextureHeight));
149 bChanged |=
150 m_guiFillTexture->SetPosition(fPosX + offsetX, fPosY + (offsetY > 0 ? offsetY : 0));
151 bChanged |= m_guiFillTexture->SetHeight(fScaleY * m_guiFillTexture->GetTextureHeight());
152 bChanged |= m_guiFillTexture->SetWidth(width);
154 offsetX += width;
155 offsetY = std::fabs(fScaleY * 0.5f *
156 (m_guiUpperTexture->GetTextureHeight() - fBackgroundTextureHeight));
157 bChanged |=
158 m_guiUpperTexture->SetPosition(fPosX + offsetX, fPosY + (offsetY > 0 ? offsetY : 0));
159 bChanged |= m_guiUpperTexture->SetHeight(fScaleY * m_guiUpperTexture->GetTextureHeight());
160 bChanged |= m_guiUpperTexture->SetWidth(m_percentValues.first == 100.0f
161 ? m_guiUpperTexture->GetTextureWidth() * 0.5f
162 : m_guiUpperTexture->GetTextureWidth());
164 else
166 // render only lower texture if range is zero
167 bChanged |= m_guiFillTexture->SetVisible(false);
168 bChanged |= m_guiUpperTexture->SetVisible(false);
171 return bChanged;
174 CGUIRangesControl::CGUIRangesControl(int iParentID,
175 int iControlID,
176 float fPosX,
177 float fPosY,
178 float fWidth,
179 float fHeight,
180 const CTextureInfo& backGroundTextureInfo,
181 const CTextureInfo& lowerTextureInfo,
182 const CTextureInfo& fillTextureInfo,
183 const CTextureInfo& upperTextureInfo,
184 const CTextureInfo& overlayTextureInfo,
185 int iInfo)
186 : CGUIControl(iParentID, iControlID, fPosX, fPosY, fWidth, fHeight),
187 m_guiBackground(
188 CGUITexture::CreateTexture(fPosX, fPosY, fWidth, fHeight, backGroundTextureInfo)),
189 m_guiOverlay(CGUITexture::CreateTexture(fPosX, fPosY, fWidth, fHeight, overlayTextureInfo)),
190 m_guiLowerTextureInfo(lowerTextureInfo),
191 m_guiFillTextureInfo(fillTextureInfo),
192 m_guiUpperTextureInfo(upperTextureInfo),
193 m_iInfoCode(iInfo)
195 ControlType = GUICONTROL_RANGES;
198 CGUIRangesControl::CGUIRangesControl(const CGUIRangesControl& control)
199 : CGUIControl(control),
200 m_guiBackground(control.m_guiBackground->Clone()),
201 m_guiOverlay(control.m_guiOverlay->Clone()),
202 m_guiLowerTextureInfo(control.m_guiLowerTextureInfo),
203 m_guiFillTextureInfo(control.m_guiFillTextureInfo),
204 m_guiUpperTextureInfo(control.m_guiUpperTextureInfo),
205 m_ranges(control.m_ranges),
206 m_iInfoCode(control.m_iInfoCode),
207 m_prevRanges(control.m_prevRanges)
211 void CGUIRangesControl::SetPosition(float fPosX, float fPosY)
213 // everything is positioned based on the background image position
214 CGUIControl::SetPosition(fPosX, fPosY);
215 m_guiBackground->SetPosition(fPosX, fPosY);
218 void CGUIRangesControl::Process(unsigned int iCurrentTime, CDirtyRegionList& dirtyregions)
220 bool bChanged = false;
222 if (!IsDisabled())
223 bChanged |= UpdateLayout();
225 bChanged |= m_guiBackground->Process(iCurrentTime);
226 bChanged |= m_guiOverlay->Process(iCurrentTime);
228 for (auto& range : m_ranges)
229 bChanged |= range.Process(iCurrentTime);
231 if (bChanged)
232 MarkDirtyRegion();
234 CGUIControl::Process(iCurrentTime, dirtyregions);
237 void CGUIRangesControl::Render()
239 if (!IsDisabled())
241 m_guiBackground->Render();
243 for (auto& range : m_ranges)
244 range.Render();
246 m_guiOverlay->Render();
249 CGUIControl::Render();
253 bool CGUIRangesControl::CanFocus() const
255 return false;
259 void CGUIRangesControl::SetRanges(const std::vector<std::pair<float, float>>& ranges)
261 ClearRanges();
262 for (const auto& range : ranges)
263 m_ranges.emplace_back(m_posX, m_posY, m_width, m_height, m_guiLowerTextureInfo,
264 m_guiFillTextureInfo, m_guiUpperTextureInfo, range);
266 for (auto& range : m_ranges)
267 range.AllocResources(); // note: we need to alloc the instance actually inserted into the vector; hence the second loop.
270 void CGUIRangesControl::ClearRanges()
272 for (auto& range : m_ranges)
273 range.FreeResources(true);
275 m_ranges.clear();
276 m_prevRanges.clear();
279 void CGUIRangesControl::FreeResources(bool bImmediately /* = false */)
281 CGUIControl::FreeResources(bImmediately);
283 m_guiBackground->FreeResources(bImmediately);
284 m_guiOverlay->FreeResources(bImmediately);
286 for (auto& range : m_ranges)
287 range.FreeResources(bImmediately);
290 void CGUIRangesControl::DynamicResourceAlloc(bool bOnOff)
292 CGUIControl::DynamicResourceAlloc(bOnOff);
294 m_guiBackground->DynamicResourceAlloc(bOnOff);
295 m_guiOverlay->DynamicResourceAlloc(bOnOff);
297 for (auto& range : m_ranges)
298 range.DynamicResourceAlloc(bOnOff);
301 void CGUIRangesControl::AllocResources()
303 CGUIControl::AllocResources();
305 m_guiBackground->AllocResources();
306 m_guiOverlay->AllocResources();
308 m_guiBackground->SetHeight(25);
309 m_guiOverlay->SetHeight(20);
311 for (auto& range : m_ranges)
312 range.AllocResources();
315 void CGUIRangesControl::SetInvalid()
317 CGUIControl::SetInvalid();
319 m_guiBackground->SetInvalid();
320 m_guiOverlay->SetInvalid();
322 for (auto& range : m_ranges)
323 range.SetInvalid();
326 bool CGUIRangesControl::UpdateColors(const CGUIListItem* item)
328 bool bChanged = CGUIControl::UpdateColors(nullptr);
330 bChanged |= m_guiBackground->SetDiffuseColor(m_diffuseColor);
331 bChanged |= m_guiOverlay->SetDiffuseColor(m_diffuseColor);
333 for (auto& range : m_ranges)
334 bChanged |= range.SetDiffuseColor(m_diffuseColor);
336 return bChanged;
339 bool CGUIRangesControl::UpdateLayout()
341 bool bChanged = false;
343 if (m_width == 0)
344 m_width = m_guiBackground->GetTextureWidth();
346 if (m_height == 0)
347 m_height = m_guiBackground->GetTextureHeight();
349 bChanged |= m_guiBackground->SetHeight(m_height);
350 bChanged |= m_guiBackground->SetWidth(m_width);
352 float fScaleX =
353 m_guiBackground->GetTextureWidth() ? m_width / m_guiBackground->GetTextureWidth() : 1.0f;
354 float fScaleY =
355 m_guiBackground->GetTextureHeight() ? m_height / m_guiBackground->GetTextureHeight() : 1.0f;
357 float posX = m_guiBackground->GetXPosition();
358 float posY = m_guiBackground->GetYPosition();
360 for (auto& range : m_ranges)
361 bChanged |= range.UpdateLayout(m_guiBackground->GetTextureHeight(), posX, posY, m_width,
362 fScaleX, fScaleY);
364 float offset = std::fabs(
365 fScaleY * 0.5f * (m_guiOverlay->GetTextureHeight() - m_guiBackground->GetTextureHeight()));
366 if (offset > 0) // Center texture to the background if necessary
367 bChanged |= m_guiOverlay->SetPosition(m_guiBackground->GetXPosition(),
368 m_guiBackground->GetYPosition() + offset);
369 else
370 bChanged |=
371 m_guiOverlay->SetPosition(m_guiBackground->GetXPosition(), m_guiBackground->GetYPosition());
373 bChanged |= m_guiOverlay->SetHeight(fScaleY * m_guiOverlay->GetTextureHeight());
374 bChanged |= m_guiOverlay->SetWidth(fScaleX * m_guiOverlay->GetTextureWidth());
376 return bChanged;
379 void CGUIRangesControl::UpdateInfo(const CGUIListItem* item /* = nullptr */)
381 if (!IsDisabled() && m_iInfoCode)
383 const std::string value = CServiceBroker::GetGUI()->GetInfoManager().GetLabel(m_iInfoCode, m_parentID);
384 if (value != m_prevRanges)
386 std::vector<std::pair<float, float>> ranges;
388 // Parse csv string into ranges...
389 const std::vector<std::string> values = StringUtils::Split(value, ',');
391 // we must have an even number of values
392 if (values.size() % 2 == 0)
394 for (auto it = values.begin(); it != values.end();)
396 float first = std::stof(*it, nullptr);
397 ++it;
398 float second = std::stof(*it, nullptr);
399 ++it;
401 if (first <= second)
402 ranges.emplace_back(first, second);
403 else
404 CLog::Log(LOGERROR, "CGUIRangesControl::UpdateInfo - malformed ranges csv string (end element must be larger or equal than start element)");
407 else
408 CLog::Log(LOGERROR, "CGUIRangesControl::UpdateInfo - malformed ranges csv string (string must contain even number of elements)");
410 SetRanges(ranges);
411 m_prevRanges = value;