diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 18:07:22 +0000 |
commit | c04dcc2e7d834218ef2d4194331e383402495ae1 (patch) | |
tree | 7333e38d10d75386e60f336b80c2443c1166031d /xbmc/guilib/GUIButtonControl.cpp | |
parent | Initial commit. (diff) | |
download | kodi-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.cpp | 409 |
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(); + } +} |