[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / guilib / GUIButtonControl.cpp
blobbfa8da27b8051894915ad298f97e634f8f38136a
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 "GUIButtonControl.h"
11 #include "GUIFontManager.h"
12 #include "input/actions/Action.h"
13 #include "input/actions/ActionIDs.h"
14 #include "input/mouse/MouseEvent.h"
16 using namespace KODI;
18 CGUIButtonControl::CGUIButtonControl(int parentID,
19 int controlID,
20 float posX,
21 float posY,
22 float width,
23 float height,
24 const CTextureInfo& textureFocus,
25 const CTextureInfo& textureNoFocus,
26 const CLabelInfo& labelInfo,
27 bool wrapMultiline)
28 : CGUIControl(parentID, controlID, posX, posY, width, height),
29 m_imgFocus(CGUITexture::CreateTexture(posX, posY, width, height, textureFocus)),
30 m_imgNoFocus(CGUITexture::CreateTexture(posX, posY, width, height, textureNoFocus)),
31 m_label(posX,
32 posY,
33 width,
34 height,
35 labelInfo,
36 wrapMultiline ? CGUILabel::OVER_FLOW_WRAP : CGUILabel::OVER_FLOW_TRUNCATE),
37 m_label2(posX, posY, width, height, labelInfo)
39 m_bSelected = false;
40 m_alpha = 255;
41 m_focusCounter = 0;
42 m_minWidth = 0;
43 m_maxWidth = width;
44 ControlType = GUICONTROL_BUTTON;
47 CGUIButtonControl::CGUIButtonControl(const CGUIButtonControl& control)
48 : CGUIControl(control),
49 m_imgFocus(control.m_imgFocus->Clone()),
50 m_imgNoFocus(control.m_imgNoFocus->Clone()),
51 m_focusCounter(control.m_focusCounter),
52 m_alpha(control.m_alpha),
53 m_minWidth(control.m_minWidth),
54 m_maxWidth(control.m_maxWidth),
55 m_info(control.m_info),
56 m_info2(control.m_info2),
57 m_label(control.m_label),
58 m_label2(control.m_label2),
59 m_clickActions(control.m_clickActions),
60 m_focusActions(control.m_focusActions),
61 m_unfocusActions(control.m_unfocusActions),
62 m_bSelected(control.m_bSelected)
66 void CGUIButtonControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
68 ProcessText(currentTime);
69 if (m_bInvalidated)
71 m_imgFocus->SetWidth(GetWidth());
72 m_imgFocus->SetHeight(m_height);
74 m_imgNoFocus->SetWidth(GetWidth());
75 m_imgNoFocus->SetHeight(m_height);
78 if (HasFocus())
80 unsigned int alphaChannel = m_alpha;
81 if (m_pulseOnSelect)
83 unsigned int alphaCounter = m_focusCounter + 2;
84 if ((alphaCounter % 128) >= 64)
85 alphaChannel = alphaCounter % 64;
86 else
87 alphaChannel = 63 - (alphaCounter % 64);
89 alphaChannel += 192;
90 alphaChannel = (unsigned int)((float)m_alpha * (float)alphaChannel / 255.0f);
92 if (m_imgFocus->SetAlpha((unsigned char)alphaChannel))
93 MarkDirtyRegion();
95 m_imgFocus->SetVisible(true);
96 m_imgNoFocus->SetVisible(false);
97 m_focusCounter++;
99 else
101 m_imgFocus->SetVisible(false);
102 m_imgNoFocus->SetVisible(true);
105 m_imgFocus->Process(currentTime);
106 m_imgNoFocus->Process(currentTime);
108 CGUIControl::Process(currentTime, dirtyregions);
111 void CGUIButtonControl::Render()
113 if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
114 RENDER_ORDER_FRONT_TO_BACK)
116 m_imgNoFocus->Render();
117 m_imgFocus->Render(-1);
119 else
121 m_imgFocus->Render(-1);
122 m_imgNoFocus->Render();
123 RenderText();
126 CGUIControl::Render();
129 void CGUIButtonControl::RenderText()
131 if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
132 RENDER_ORDER_FRONT_TO_BACK)
133 return;
134 m_label.Render();
135 m_label2.Render();
138 CGUILabel::COLOR CGUIButtonControl::GetTextColor() const
140 if (IsDisabled())
141 return CGUILabel::COLOR_DISABLED;
142 if (HasFocus())
143 return CGUILabel::COLOR_FOCUSED;
144 return CGUILabel::COLOR_TEXT;
147 #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
148 float CGUIButtonControl::GetWidth() const
150 if (m_minWidth && m_minWidth != m_width)
152 float txtWidth = m_label.GetTextWidth() + 2 * m_label.GetLabelInfo().offsetX;
153 if (m_label2.GetTextWidth())
155 static const float min_space = 10;
156 txtWidth += m_label2.GetTextWidth() + 2 * m_label2.GetLabelInfo().offsetX + min_space;
158 float maxWidth = m_maxWidth ? m_maxWidth : txtWidth;
159 return CLAMP(txtWidth, m_minWidth, maxWidth);
161 return m_width;
164 void CGUIButtonControl::SetMinWidth(float minWidth)
166 if (m_minWidth != minWidth)
167 MarkDirtyRegion();
169 m_minWidth = minWidth;
172 void CGUIButtonControl::ProcessText(unsigned int currentTime)
174 CRect labelRenderRect = m_label.GetRenderRect();
175 CRect label2RenderRect = m_label2.GetRenderRect();
177 float renderWidth = GetWidth();
178 float renderTextWidth = renderWidth;
179 if (m_labelMaxWidth > 0 && m_labelMaxWidth < renderWidth)
180 renderTextWidth = m_labelMaxWidth;
182 bool changed = m_label.SetMaxRect(m_posX, m_posY, renderTextWidth, m_height);
183 changed |= m_label.SetText(m_info.GetLabel(m_parentID));
184 changed |= m_label.SetScrolling(HasFocus());
185 changed |= m_label2.SetMaxRect(m_posX, m_posY, renderTextWidth, m_height);
186 changed |= m_label2.SetText(m_info2.GetLabel(m_parentID));
188 // text changed - images need resizing
189 if (m_minWidth && (m_label.GetRenderRect() != labelRenderRect))
190 SetInvalid();
192 // auto-width - adjust hitrect
193 if (m_minWidth && m_width != renderWidth)
195 CRect rect{m_posX, m_posY, m_posX + renderWidth, m_posY + m_height};
196 SetHitRect(rect, m_hitColor);
199 // render the second label if it exists
200 if (!m_info2.GetLabel(m_parentID).empty())
202 changed |= m_label2.SetAlign(XBFONT_RIGHT | (m_label.GetLabelInfo().align & XBFONT_CENTER_Y) | XBFONT_TRUNCATED);
203 changed |= m_label2.SetScrolling(HasFocus());
205 // If overlapping was corrected - compare render rects to determine
206 // if they changed since last frame.
207 if (CGUILabel::CheckAndCorrectOverlap(m_label, m_label2))
208 changed |= (m_label.GetRenderRect() != labelRenderRect ||
209 m_label2.GetRenderRect() != label2RenderRect);
211 changed |= m_label2.SetColor(GetTextColor());
212 changed |= m_label2.Process(currentTime);
214 changed |= m_label.SetColor(GetTextColor());
215 changed |= m_label.Process(currentTime);
216 if (changed)
217 MarkDirtyRegion();
220 bool CGUIButtonControl::OnAction(const CAction &action)
222 if (action.GetID() == ACTION_SELECT_ITEM)
224 OnClick();
225 return true;
227 return CGUIControl::OnAction(action);
230 bool CGUIButtonControl::OnMessage(CGUIMessage& message)
232 if (message.GetControlId() == GetID())
234 if (message.GetMessage() == GUI_MSG_LABEL_SET)
236 SetLabel(message.GetLabel());
237 return true;
239 if (message.GetMessage() == GUI_MSG_LABEL2_SET)
241 SetLabel2(message.GetLabel());
242 return true;
244 if (message.GetMessage() == GUI_MSG_IS_SELECTED)
246 message.SetParam1(m_bSelected ? 1 : 0);
247 return true;
249 if (message.GetMessage() == GUI_MSG_SET_SELECTED)
251 if (!m_bSelected)
252 SetInvalid();
253 m_bSelected = true;
254 return true;
256 if (message.GetMessage() == GUI_MSG_SET_DESELECTED)
258 if (m_bSelected)
259 SetInvalid();
260 m_bSelected = false;
261 return true;
265 return CGUIControl::OnMessage(message);
268 void CGUIButtonControl::AllocResources()
270 CGUIControl::AllocResources();
271 m_focusCounter = 0;
272 m_imgFocus->AllocResources();
273 m_imgNoFocus->AllocResources();
274 if (!m_width)
275 m_width = m_imgFocus->GetWidth();
276 if (!m_height)
277 m_height = m_imgFocus->GetHeight();
280 void CGUIButtonControl::FreeResources(bool immediately)
282 CGUIControl::FreeResources(immediately);
283 m_imgFocus->FreeResources(immediately);
284 m_imgNoFocus->FreeResources(immediately);
287 void CGUIButtonControl::DynamicResourceAlloc(bool bOnOff)
289 CGUIControl::DynamicResourceAlloc(bOnOff);
290 m_imgFocus->DynamicResourceAlloc(bOnOff);
291 m_imgNoFocus->DynamicResourceAlloc(bOnOff);
294 void CGUIButtonControl::SetInvalid()
296 CGUIControl::SetInvalid();
297 m_label.SetInvalid();
298 m_label2.SetInvalid();
299 m_imgFocus->SetInvalid();
300 m_imgNoFocus->SetInvalid();
303 void CGUIButtonControl::SetLabel(const std::string &label)
304 { // NOTE: No fallback for buttons at this point
305 if (m_info.GetLabel(GetParentID(), false) != label)
307 m_info.SetLabel(label, "", GetParentID());
308 SetInvalid();
312 void CGUIButtonControl::SetLabel2(const std::string &label2)
313 { // NOTE: No fallback for buttons at this point
314 if (m_info2.GetLabel(GetParentID(), false) != label2)
316 m_info2.SetLabel(label2, "", GetParentID());
317 SetInvalid();
321 void CGUIButtonControl::SetPosition(float posX, float posY)
323 CGUIControl::SetPosition(posX, posY);
324 m_imgFocus->SetPosition(posX, posY);
325 m_imgNoFocus->SetPosition(posX, posY);
328 void CGUIButtonControl::SetAlpha(unsigned char alpha)
330 if (m_alpha != alpha)
331 MarkDirtyRegion();
332 m_alpha = alpha;
335 bool CGUIButtonControl::UpdateColors(const CGUIListItem* item)
337 bool changed = CGUIControl::UpdateColors(nullptr);
338 changed |= m_label.UpdateColors();
339 changed |= m_label2.UpdateColors();
340 changed |= m_imgFocus->SetDiffuseColor(m_diffuseColor);
341 changed |= m_imgNoFocus->SetDiffuseColor(m_diffuseColor);
343 return changed;
346 CRect CGUIButtonControl::CalcRenderRegion() const
348 CRect buttonRect = CGUIControl::CalcRenderRegion();
349 CRect textRect = m_label.GetRenderRect();
350 buttonRect.Union(textRect);
351 return buttonRect;
354 EVENT_RESULT CGUIButtonControl::OnMouseEvent(const CPoint& point, const MOUSE::CMouseEvent& event)
356 if (event.m_id == ACTION_MOUSE_LEFT_CLICK)
358 OnAction(CAction(ACTION_SELECT_ITEM));
359 return EVENT_RESULT_HANDLED;
361 return EVENT_RESULT_UNHANDLED;
364 std::string CGUIButtonControl::GetDescription() const
366 std::string strLabel(m_info.GetLabel(m_parentID));
367 return strLabel;
370 std::string CGUIButtonControl::GetLabel2() const
372 std::string strLabel(m_info2.GetLabel(m_parentID));
373 return strLabel;
376 void CGUIButtonControl::PythonSetLabel(const std::string& strFont,
377 const std::string& strText,
378 KODI::UTILS::COLOR::Color textColor,
379 KODI::UTILS::COLOR::Color shadowColor,
380 KODI::UTILS::COLOR::Color focusedColor)
382 m_label.GetLabelInfo().font = g_fontManager.GetFont(strFont);
383 m_label.GetLabelInfo().textColor = textColor;
384 m_label.GetLabelInfo().focusedColor = focusedColor;
385 m_label.GetLabelInfo().shadowColor = shadowColor;
386 SetLabel(strText);
389 void CGUIButtonControl::PythonSetDisabledColor(KODI::UTILS::COLOR::Color disabledColor)
391 m_label.GetLabelInfo().disabledColor = disabledColor;
394 void CGUIButtonControl::OnClick()
396 // Save values, as the click message may deactivate the window
397 int controlID = GetID();
398 int parentID = GetParentID();
399 CGUIAction clickActions = m_clickActions;
401 // button selected, send a message
402 CGUIMessage msg(GUI_MSG_CLICKED, controlID, parentID, 0);
403 SendWindowMessage(msg);
405 clickActions.ExecuteActions(controlID, parentID);
408 void CGUIButtonControl::OnFocus()
410 m_focusActions.ExecuteActions(GetID(), GetParentID());
413 void CGUIButtonControl::OnUnFocus()
415 m_unfocusActions.ExecuteActions(GetID(), GetParentID());
418 void CGUIButtonControl::SetSelected(bool bSelected)
420 if (m_bSelected != bSelected)
422 m_bSelected = bSelected;
423 SetInvalid();