[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / guilib / GUILabelControl.cpp
blobd4da4f81b1a8e915c18cd504842d4dcdc5ce19b9
1 /*
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.
7 */
9 #include "GUILabelControl.h"
11 #include "GUIFont.h"
12 #include "GUIMessage.h"
13 #include "utils/CharsetConverter.h"
14 #include "utils/ColorUtils.h"
15 #include "utils/StringUtils.h"
17 using namespace KODI::GUILIB;
19 CGUILabelControl::CGUILabelControl(int parentID, int controlID, float posX, float posY, float width, float height, const CLabelInfo& labelInfo, bool wrapMultiLine, bool bHasPath)
20 : CGUIControl(parentID, controlID, posX, posY, width, height)
21 , m_label(posX, posY, width, height, labelInfo, wrapMultiLine ? CGUILabel::OVER_FLOW_WRAP : CGUILabel::OVER_FLOW_TRUNCATE)
23 m_bHasPath = bHasPath;
24 m_iCursorPos = 0;
25 m_bShowCursor = false;
26 m_dwCounter = 0;
27 ControlType = GUICONTROL_LABEL;
28 m_startHighlight = m_endHighlight = 0;
29 m_startSelection = m_endSelection = 0;
30 m_minWidth = 0;
31 m_label.SetScrollLoopCount(2);
34 CGUILabelControl::~CGUILabelControl(void) = default;
36 void CGUILabelControl::ShowCursor(bool bShow)
38 m_bShowCursor = bShow;
41 void CGUILabelControl::SetCursorPos(int iPos)
43 std::string labelUTF8 = m_infoLabel.GetLabel(m_parentID);
44 std::wstring label;
45 g_charsetConverter.utf8ToW(labelUTF8, label);
46 if (iPos > (int)label.length()) iPos = label.length();
47 if (iPos < 0) iPos = 0;
49 if (m_iCursorPos != iPos)
50 MarkDirtyRegion();
52 m_iCursorPos = iPos;
55 void CGUILabelControl::SetInfo(const GUIINFO::CGUIInfoLabel &infoLabel)
57 m_infoLabel = infoLabel;
60 bool CGUILabelControl::UpdateColors(const CGUIListItem* item)
62 bool changed = CGUIControl::UpdateColors(nullptr);
63 changed |= m_label.UpdateColors();
65 return changed;
68 void CGUILabelControl::UpdateInfo(const CGUIListItem *item)
70 std::string label(m_infoLabel.GetLabel(m_parentID));
72 bool changed = false;
73 if (m_startHighlight < m_endHighlight || m_startSelection < m_endSelection || m_bShowCursor)
75 std::wstring utf16;
76 g_charsetConverter.utf8ToW(label, utf16);
77 vecText text; text.reserve(utf16.size()+1);
78 std::vector<KODI::UTILS::COLOR::Color> colors;
79 colors.push_back(m_label.GetLabelInfo().textColor);
80 colors.push_back(m_label.GetLabelInfo().disabledColor);
81 KODI::UTILS::COLOR::Color select = m_label.GetLabelInfo().selectedColor;
82 if (!select)
83 select = 0xFFFF0000;
84 colors.push_back(select);
85 colors.push_back(0xFF000000);
87 CGUIFont* font = m_label.GetLabelInfo().font;
88 uint32_t style = (font ? font->GetStyle() : (FONT_STYLE_NORMAL & FONT_STYLE_MASK)) << 24;
90 for (unsigned int i = 0; i < utf16.size(); i++)
92 uint32_t ch = utf16[i] | style;
93 if ((m_startSelection < m_endSelection) && (m_startSelection <= i && i < m_endSelection))
94 ch |= (2 << 16);
95 else if ((m_startHighlight < m_endHighlight) && (i < m_startHighlight || i >= m_endHighlight))
96 ch |= (1 << 16);
97 text.push_back(ch);
99 if (m_bShowCursor && m_iCursorPos >= 0 && (unsigned int)m_iCursorPos <= utf16.size())
101 uint32_t ch = L'|' | style;
102 if ((++m_dwCounter % 50) <= 25)
103 ch |= (3 << 16);
104 text.insert(text.begin() + m_iCursorPos, ch);
106 changed |= m_label.SetMaxRect(m_posX, m_posY, GetMaxWidth(), m_height);
107 changed |= m_label.SetStyledText(text, colors);
109 else
111 if (m_bHasPath)
112 label = ShortenPath(label);
114 changed |= m_label.SetMaxRect(m_posX, m_posY, GetMaxWidth(), m_height);
115 changed |= m_label.SetText(label);
117 if (changed)
118 MarkDirtyRegion();
121 void CGUILabelControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
123 bool changed = false;
125 changed |= m_label.SetColor(IsDisabled() ? CGUILabel::COLOR_DISABLED : CGUILabel::COLOR_TEXT);
126 changed |= m_label.SetMaxRect(m_posX, m_posY, GetMaxWidth(), m_height);
127 changed |= m_label.Process(currentTime);
129 if (changed)
130 MarkDirtyRegion();
132 CGUIControl::Process(currentTime, dirtyregions);
135 CRect CGUILabelControl::CalcRenderRegion() const
137 return m_label.GetRenderRect();
140 void CGUILabelControl::Render()
142 if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
143 RENDER_ORDER_FRONT_TO_BACK)
144 return;
145 m_label.Render();
146 CGUIControl::Render();
150 bool CGUILabelControl::CanFocus() const
152 return false;
155 void CGUILabelControl::SetLabel(const std::string &strLabel)
157 // NOTE: this optimization handles fixed labels only (i.e. not info labels).
158 // One way it might be extended to all labels would be for GUIInfoLabel ( or here )
159 // to store the label prior to parsing, and then compare that against what you're setting.
160 if (m_infoLabel.GetLabel(GetParentID(), false) != strLabel)
162 m_infoLabel.SetLabel(strLabel, "", GetParentID());
163 if (m_iCursorPos > (int)strLabel.size())
164 m_iCursorPos = strLabel.size();
166 SetInvalid();
170 void CGUILabelControl::SetWidthControl(float minWidth, bool bScroll)
172 if (m_label.SetScrolling(bScroll) || m_minWidth != minWidth)
173 MarkDirtyRegion();
175 m_minWidth = minWidth;
178 void CGUILabelControl::SetAlignment(uint32_t align)
180 if (m_label.GetLabelInfo().align != align)
182 MarkDirtyRegion();
183 m_label.GetLabelInfo().align = align;
187 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
189 float CGUILabelControl::GetWidth() const
191 if (m_minWidth && m_minWidth != m_width)
192 return CLAMP(m_label.GetTextWidth(), m_minWidth, GetMaxWidth());
193 return m_width;
196 void CGUILabelControl::SetWidth(float width)
198 m_width = width;
199 m_label.SetMaxRect(m_posX, m_posY, m_width, m_height);
200 CGUIControl::SetWidth(m_width);
203 bool CGUILabelControl::OnMessage(CGUIMessage& message)
205 if (message.GetControlId() == GetID())
207 if (message.GetMessage() == GUI_MSG_LABEL_SET)
209 SetLabel(message.GetLabel());
210 return true;
213 if (message.GetMessage() == GUI_MSG_REFRESH_TIMER && IsVisible())
215 UpdateInfo();
217 else if (message.GetMessage() == GUI_MSG_WINDOW_RESIZE && IsVisible())
219 m_label.SetInvalid();
222 return CGUIControl::OnMessage(message);
225 std::string CGUILabelControl::ShortenPath(const std::string &path)
227 if (m_width == 0 || path.empty())
228 return path;
230 char cDelim = '\0';
231 size_t nPos;
233 nPos = path.find_last_of( '\\' );
234 if ( nPos != std::string::npos )
235 cDelim = '\\';
236 else
238 nPos = path.find_last_of( '/' );
239 if ( nPos != std::string::npos )
240 cDelim = '/';
242 if ( cDelim == '\0' )
243 return path;
245 std::string workPath(path);
246 // remove trailing slashes
247 if (workPath.size() > 3)
248 if (!StringUtils::EndsWith(workPath, "://") &&
249 !StringUtils::EndsWith(workPath, ":\\"))
250 if (nPos == workPath.size() - 1)
252 workPath.erase(workPath.size() - 1);
253 nPos = workPath.find_last_of( cDelim );
256 if (m_label.SetText(workPath))
257 MarkDirtyRegion();
259 float textWidth = m_label.GetTextWidth();
261 while ( textWidth > m_width )
263 size_t nGreaterDelim = workPath.find_last_of( cDelim, nPos );
264 if (nGreaterDelim == std::string::npos)
265 break;
267 nPos = workPath.find_last_of( cDelim, nGreaterDelim - 1 );
268 if ( nPos == std::string::npos )
269 break;
271 workPath.replace( nPos + 1, nGreaterDelim - nPos - 1, "..." );
273 if (m_label.SetText(workPath))
274 MarkDirtyRegion();
276 textWidth = m_label.GetTextWidth();
278 return workPath;
281 void CGUILabelControl::SetHighlight(unsigned int start, unsigned int end)
283 m_startHighlight = start;
284 m_endHighlight = end;
287 void CGUILabelControl::SetSelection(unsigned int start, unsigned int end)
289 m_startSelection = start;
290 m_endSelection = end;
293 std::string CGUILabelControl::GetDescription() const
295 return m_infoLabel.GetLabel(m_parentID);