summaryrefslogtreecommitdiffstats
path: root/xbmc/guilib/GUIButtonControl.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 18:07:22 +0000
commitc04dcc2e7d834218ef2d4194331e383402495ae1 (patch)
tree7333e38d10d75386e60f336b80c2443c1166031d /xbmc/guilib/GUIButtonControl.cpp
parentInitial commit. (diff)
downloadkodi-c04dcc2e7d834218ef2d4194331e383402495ae1.tar.xz
kodi-c04dcc2e7d834218ef2d4194331e383402495ae1.zip
Adding upstream version 2:20.4+dfsg.upstream/2%20.4+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'xbmc/guilib/GUIButtonControl.cpp')
-rw-r--r--xbmc/guilib/GUIButtonControl.cpp409
1 files changed, 409 insertions, 0 deletions
diff --git a/xbmc/guilib/GUIButtonControl.cpp b/xbmc/guilib/GUIButtonControl.cpp
new file mode 100644
index 0000000..0e7f757
--- /dev/null
+++ b/xbmc/guilib/GUIButtonControl.cpp
@@ -0,0 +1,409 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#include "GUIButtonControl.h"
+
+#include "GUIFontManager.h"
+#include "input/Key.h"
+
+CGUIButtonControl::CGUIButtonControl(int parentID,
+ int controlID,
+ float posX,
+ float posY,
+ float width,
+ float height,
+ const CTextureInfo& textureFocus,
+ const CTextureInfo& textureNoFocus,
+ const CLabelInfo& labelInfo,
+ bool wrapMultiline)
+ : CGUIControl(parentID, controlID, posX, posY, width, height),
+ m_imgFocus(CGUITexture::CreateTexture(posX, posY, width, height, textureFocus)),
+ m_imgNoFocus(CGUITexture::CreateTexture(posX, posY, width, height, textureNoFocus)),
+ m_label(posX,
+ posY,
+ width,
+ height,
+ labelInfo,
+ wrapMultiline ? CGUILabel::OVER_FLOW_WRAP : CGUILabel::OVER_FLOW_TRUNCATE),
+ m_label2(posX, posY, width, height, labelInfo)
+{
+ m_bSelected = false;
+ m_alpha = 255;
+ m_focusCounter = 0;
+ m_minWidth = 0;
+ m_maxWidth = width;
+ ControlType = GUICONTROL_BUTTON;
+}
+
+CGUIButtonControl::CGUIButtonControl(const CGUIButtonControl& control)
+ : CGUIControl(control),
+ m_imgFocus(control.m_imgFocus->Clone()),
+ m_imgNoFocus(control.m_imgNoFocus->Clone()),
+ m_focusCounter(control.m_focusCounter),
+ m_alpha(control.m_alpha),
+ m_minWidth(control.m_minWidth),
+ m_maxWidth(control.m_maxWidth),
+ m_info(control.m_info),
+ m_info2(control.m_info2),
+ m_label(control.m_label),
+ m_label2(control.m_label2),
+ m_clickActions(control.m_clickActions),
+ m_focusActions(control.m_focusActions),
+ m_unfocusActions(control.m_unfocusActions),
+ m_bSelected(control.m_bSelected)
+{
+}
+
+void CGUIButtonControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
+{
+ ProcessText(currentTime);
+ if (m_bInvalidated)
+ {
+ m_imgFocus->SetWidth(GetWidth());
+ m_imgFocus->SetHeight(m_height);
+
+ m_imgNoFocus->SetWidth(GetWidth());
+ m_imgNoFocus->SetHeight(m_height);
+ }
+
+ if (HasFocus())
+ {
+ unsigned int alphaChannel = m_alpha;
+ if (m_pulseOnSelect)
+ {
+ unsigned int alphaCounter = m_focusCounter + 2;
+ if ((alphaCounter % 128) >= 64)
+ alphaChannel = alphaCounter % 64;
+ else
+ alphaChannel = 63 - (alphaCounter % 64);
+
+ alphaChannel += 192;
+ alphaChannel = (unsigned int)((float)m_alpha * (float)alphaChannel / 255.0f);
+ }
+ if (m_imgFocus->SetAlpha((unsigned char)alphaChannel))
+ MarkDirtyRegion();
+
+ m_imgFocus->SetVisible(true);
+ m_imgNoFocus->SetVisible(false);
+ m_focusCounter++;
+ }
+ else
+ {
+ m_imgFocus->SetVisible(false);
+ m_imgNoFocus->SetVisible(true);
+ }
+
+ m_imgFocus->Process(currentTime);
+ m_imgNoFocus->Process(currentTime);
+
+ CGUIControl::Process(currentTime, dirtyregions);
+}
+
+void CGUIButtonControl::Render()
+{
+ m_imgFocus->Render();
+ m_imgNoFocus->Render();
+
+ RenderText();
+ CGUIControl::Render();
+}
+
+void CGUIButtonControl::RenderText()
+{
+ m_label.Render();
+ m_label2.Render();
+}
+
+CGUILabel::COLOR CGUIButtonControl::GetTextColor() const
+{
+ if (IsDisabled())
+ return CGUILabel::COLOR_DISABLED;
+ if (HasFocus())
+ return CGUILabel::COLOR_FOCUSED;
+ return CGUILabel::COLOR_TEXT;
+}
+
+#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+float CGUIButtonControl::GetWidth() const
+{
+ if (m_minWidth && m_minWidth != m_width)
+ {
+ float txtWidth = m_label.GetTextWidth() + 2 * m_label.GetLabelInfo().offsetX;
+ if (m_label2.GetTextWidth())
+ {
+ static const float min_space = 10;
+ txtWidth += m_label2.GetTextWidth() + 2 * m_label2.GetLabelInfo().offsetX + min_space;
+ }
+ float maxWidth = m_maxWidth ? m_maxWidth : txtWidth;
+ return CLAMP(txtWidth, m_minWidth, maxWidth);
+ }
+ return m_width;
+}
+
+void CGUIButtonControl::SetMinWidth(float minWidth)
+{
+ if (m_minWidth != minWidth)
+ MarkDirtyRegion();
+
+ m_minWidth = minWidth;
+}
+
+void CGUIButtonControl::ProcessText(unsigned int currentTime)
+{
+ CRect labelRenderRect = m_label.GetRenderRect();
+ CRect label2RenderRect = m_label2.GetRenderRect();
+
+ float renderWidth = GetWidth();
+ float renderTextWidth = renderWidth;
+ if (m_labelMaxWidth > 0 && m_labelMaxWidth < renderWidth)
+ renderTextWidth = m_labelMaxWidth;
+
+ bool changed = m_label.SetMaxRect(m_posX, m_posY, renderTextWidth, m_height);
+ changed |= m_label.SetText(m_info.GetLabel(m_parentID));
+ changed |= m_label.SetScrolling(HasFocus());
+ changed |= m_label2.SetMaxRect(m_posX, m_posY, renderTextWidth, m_height);
+ changed |= m_label2.SetText(m_info2.GetLabel(m_parentID));
+
+ // text changed - images need resizing
+ if (m_minWidth && (m_label.GetRenderRect() != labelRenderRect))
+ SetInvalid();
+
+ // auto-width - adjust hitrect
+ if (m_minWidth && m_width != renderWidth)
+ {
+ CRect rect{m_posX, m_posY, m_posX + renderWidth, m_posY + m_height};
+ SetHitRect(rect, m_hitColor);
+ }
+
+ // render the second label if it exists
+ if (!m_info2.GetLabel(m_parentID).empty())
+ {
+ changed |= m_label2.SetAlign(XBFONT_RIGHT | (m_label.GetLabelInfo().align & XBFONT_CENTER_Y) | XBFONT_TRUNCATED);
+ changed |= m_label2.SetScrolling(HasFocus());
+
+ // If overlapping was corrected - compare render rects to determine
+ // if they changed since last frame.
+ if (CGUILabel::CheckAndCorrectOverlap(m_label, m_label2))
+ changed |= (m_label.GetRenderRect() != labelRenderRect ||
+ m_label2.GetRenderRect() != label2RenderRect);
+
+ changed |= m_label2.SetColor(GetTextColor());
+ changed |= m_label2.Process(currentTime);
+ }
+ changed |= m_label.SetColor(GetTextColor());
+ changed |= m_label.Process(currentTime);
+ if (changed)
+ MarkDirtyRegion();
+}
+
+bool CGUIButtonControl::OnAction(const CAction &action)
+{
+ if (action.GetID() == ACTION_SELECT_ITEM)
+ {
+ OnClick();
+ return true;
+ }
+ return CGUIControl::OnAction(action);
+}
+
+bool CGUIButtonControl::OnMessage(CGUIMessage& message)
+{
+ if (message.GetControlId() == GetID())
+ {
+ if (message.GetMessage() == GUI_MSG_LABEL_SET)
+ {
+ SetLabel(message.GetLabel());
+ return true;
+ }
+ if (message.GetMessage() == GUI_MSG_LABEL2_SET)
+ {
+ SetLabel2(message.GetLabel());
+ return true;
+ }
+ if (message.GetMessage() == GUI_MSG_IS_SELECTED)
+ {
+ message.SetParam1(m_bSelected ? 1 : 0);
+ return true;
+ }
+ if (message.GetMessage() == GUI_MSG_SET_SELECTED)
+ {
+ if (!m_bSelected)
+ SetInvalid();
+ m_bSelected = true;
+ return true;
+ }
+ if (message.GetMessage() == GUI_MSG_SET_DESELECTED)
+ {
+ if (m_bSelected)
+ SetInvalid();
+ m_bSelected = false;
+ return true;
+ }
+ }
+
+ return CGUIControl::OnMessage(message);
+}
+
+void CGUIButtonControl::AllocResources()
+{
+ CGUIControl::AllocResources();
+ m_focusCounter = 0;
+ m_imgFocus->AllocResources();
+ m_imgNoFocus->AllocResources();
+ if (!m_width)
+ m_width = m_imgFocus->GetWidth();
+ if (!m_height)
+ m_height = m_imgFocus->GetHeight();
+}
+
+void CGUIButtonControl::FreeResources(bool immediately)
+{
+ CGUIControl::FreeResources(immediately);
+ m_imgFocus->FreeResources(immediately);
+ m_imgNoFocus->FreeResources(immediately);
+}
+
+void CGUIButtonControl::DynamicResourceAlloc(bool bOnOff)
+{
+ CGUIControl::DynamicResourceAlloc(bOnOff);
+ m_imgFocus->DynamicResourceAlloc(bOnOff);
+ m_imgNoFocus->DynamicResourceAlloc(bOnOff);
+}
+
+void CGUIButtonControl::SetInvalid()
+{
+ CGUIControl::SetInvalid();
+ m_label.SetInvalid();
+ m_label2.SetInvalid();
+ m_imgFocus->SetInvalid();
+ m_imgNoFocus->SetInvalid();
+}
+
+void CGUIButtonControl::SetLabel(const std::string &label)
+{ // NOTE: No fallback for buttons at this point
+ if (m_info.GetLabel(GetParentID(), false) != label)
+ {
+ m_info.SetLabel(label, "", GetParentID());
+ SetInvalid();
+ }
+}
+
+void CGUIButtonControl::SetLabel2(const std::string &label2)
+{ // NOTE: No fallback for buttons at this point
+ if (m_info2.GetLabel(GetParentID(), false) != label2)
+ {
+ m_info2.SetLabel(label2, "", GetParentID());
+ SetInvalid();
+ }
+}
+
+void CGUIButtonControl::SetPosition(float posX, float posY)
+{
+ CGUIControl::SetPosition(posX, posY);
+ m_imgFocus->SetPosition(posX, posY);
+ m_imgNoFocus->SetPosition(posX, posY);
+}
+
+void CGUIButtonControl::SetAlpha(unsigned char alpha)
+{
+ if (m_alpha != alpha)
+ MarkDirtyRegion();
+ m_alpha = alpha;
+}
+
+bool CGUIButtonControl::UpdateColors(const CGUIListItem* item)
+{
+ bool changed = CGUIControl::UpdateColors(nullptr);
+ changed |= m_label.UpdateColors();
+ changed |= m_label2.UpdateColors();
+ changed |= m_imgFocus->SetDiffuseColor(m_diffuseColor);
+ changed |= m_imgNoFocus->SetDiffuseColor(m_diffuseColor);
+
+ return changed;
+}
+
+CRect CGUIButtonControl::CalcRenderRegion() const
+{
+ CRect buttonRect = CGUIControl::CalcRenderRegion();
+ CRect textRect = m_label.GetRenderRect();
+ buttonRect.Union(textRect);
+ return buttonRect;
+}
+
+EVENT_RESULT CGUIButtonControl::OnMouseEvent(const CPoint &point, const CMouseEvent &event)
+{
+ if (event.m_id == ACTION_MOUSE_LEFT_CLICK)
+ {
+ OnAction(CAction(ACTION_SELECT_ITEM));
+ return EVENT_RESULT_HANDLED;
+ }
+ return EVENT_RESULT_UNHANDLED;
+}
+
+std::string CGUIButtonControl::GetDescription() const
+{
+ std::string strLabel(m_info.GetLabel(m_parentID));
+ return strLabel;
+}
+
+std::string CGUIButtonControl::GetLabel2() const
+{
+ std::string strLabel(m_info2.GetLabel(m_parentID));
+ return strLabel;
+}
+
+void CGUIButtonControl::PythonSetLabel(const std::string& strFont,
+ const std::string& strText,
+ UTILS::COLOR::Color textColor,
+ UTILS::COLOR::Color shadowColor,
+ UTILS::COLOR::Color focusedColor)
+{
+ m_label.GetLabelInfo().font = g_fontManager.GetFont(strFont);
+ m_label.GetLabelInfo().textColor = textColor;
+ m_label.GetLabelInfo().focusedColor = focusedColor;
+ m_label.GetLabelInfo().shadowColor = shadowColor;
+ SetLabel(strText);
+}
+
+void CGUIButtonControl::PythonSetDisabledColor(UTILS::COLOR::Color disabledColor)
+{
+ m_label.GetLabelInfo().disabledColor = disabledColor;
+}
+
+void CGUIButtonControl::OnClick()
+{
+ // Save values, as the click message may deactivate the window
+ int controlID = GetID();
+ int parentID = GetParentID();
+ CGUIAction clickActions = m_clickActions;
+
+ // button selected, send a message
+ CGUIMessage msg(GUI_MSG_CLICKED, controlID, parentID, 0);
+ SendWindowMessage(msg);
+
+ clickActions.ExecuteActions(controlID, parentID);
+}
+
+void CGUIButtonControl::OnFocus()
+{
+ m_focusActions.ExecuteActions(GetID(), GetParentID());
+}
+
+void CGUIButtonControl::OnUnFocus()
+{
+ m_unfocusActions.ExecuteActions(GetID(), GetParentID());
+}
+
+void CGUIButtonControl::SetSelected(bool bSelected)
+{
+ if (m_bSelected != bSelected)
+ {
+ m_bSelected = bSelected;
+ SetInvalid();
+ }
+}