diff options
Diffstat (limited to 'xbmc/guilib/GUIProgressControl.cpp')
-rw-r--r-- | xbmc/guilib/GUIProgressControl.cpp | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/xbmc/guilib/GUIProgressControl.cpp b/xbmc/guilib/GUIProgressControl.cpp new file mode 100644 index 0000000..1167d64 --- /dev/null +++ b/xbmc/guilib/GUIProgressControl.cpp @@ -0,0 +1,348 @@ +/* + * 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 "GUIProgressControl.h" + +#include "GUIInfoManager.h" +#include "GUIListItem.h" +#include "GUIMessage.h" +#include "utils/StringUtils.h" + +CGUIProgressControl::CGUIProgressControl(int parentID, + int controlID, + float posX, + float posY, + float width, + float height, + const CTextureInfo& backGroundTexture, + const CTextureInfo& leftTexture, + const CTextureInfo& midTexture, + const CTextureInfo& rightTexture, + const CTextureInfo& overlayTexture, + bool reveal) + : CGUIControl(parentID, controlID, posX, posY, width, height), + m_guiBackground(CGUITexture::CreateTexture(posX, posY, width, height, backGroundTexture)), + m_guiLeft(CGUITexture::CreateTexture(posX, posY, width, height, leftTexture)), + m_guiMid(CGUITexture::CreateTexture(posX, posY, width, height, midTexture)), + m_guiRight(CGUITexture::CreateTexture(posX, posY, width, height, rightTexture)), + m_guiOverlay(CGUITexture::CreateTexture(posX, posY, width, height, overlayTexture)) +{ + m_fPercent = 0; + m_iInfoCode = 0; + ControlType = GUICONTROL_PROGRESS; + m_bReveal = reveal; + m_bChanged = false; +} + +CGUIProgressControl::CGUIProgressControl(const CGUIProgressControl& control) + : CGUIControl(control), + m_guiBackground(control.m_guiBackground->Clone()), + m_guiLeft(control.m_guiLeft->Clone()), + m_guiMid(control.m_guiMid->Clone()), + m_guiRight(control.m_guiRight->Clone()), + m_guiOverlay(control.m_guiOverlay->Clone()), + m_guiMidClipRect(control.m_guiMidClipRect), + m_iInfoCode(control.m_iInfoCode), + m_iInfoCode2(control.m_iInfoCode2), + m_fPercent(control.m_fPercent), + m_fPercent2(control.m_fPercent2), + m_bReveal(control.m_bReveal), + m_bChanged(control.m_bChanged) +{ +} + +void CGUIProgressControl::SetPosition(float posX, float posY) +{ + // everything is positioned based on the background image position + CGUIControl::SetPosition(posX, posY); + m_guiBackground->SetPosition(posX, posY); +} + +void CGUIProgressControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions) +{ + bool changed = false; + + if (!IsDisabled()) + changed |= UpdateLayout(); + changed |= m_guiBackground->Process(currentTime); + changed |= m_guiMid->Process(currentTime); + changed |= m_guiLeft->Process(currentTime); + changed |= m_guiRight->Process(currentTime); + changed |= m_guiOverlay->Process(currentTime); + + if (changed) + MarkDirtyRegion(); + + CGUIControl::Process(currentTime, dirtyregions); +} + +void CGUIProgressControl::Render() +{ + if (!IsDisabled()) + { + m_guiBackground->Render(); + + if (m_guiLeft->GetFileName().empty() && m_guiRight->GetFileName().empty()) + { + if (m_bReveal && !m_guiMidClipRect.IsEmpty()) + { + bool restore = CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_guiMidClipRect.x1, m_guiMidClipRect.y1, m_guiMidClipRect.Width(), m_guiMidClipRect.Height()); + m_guiMid->Render(); + if (restore) + CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion(); + } + else if (!m_bReveal && m_guiMid->GetWidth() > 0) + m_guiMid->Render(); + } + else + { + m_guiLeft->Render(); + + if (m_bReveal && !m_guiMidClipRect.IsEmpty()) + { + bool restore = CServiceBroker::GetWinSystem()->GetGfxContext().SetClipRegion(m_guiMidClipRect.x1, m_guiMidClipRect.y1, m_guiMidClipRect.Width(), m_guiMidClipRect.Height()); + m_guiMid->Render(); + if (restore) + CServiceBroker::GetWinSystem()->GetGfxContext().RestoreClipRegion(); + } + else if (!m_bReveal && m_guiMid->GetWidth() > 0) + m_guiMid->Render(); + + m_guiRight->Render(); + } + + m_guiOverlay->Render(); + } + + CGUIControl::Render(); +} + + +bool CGUIProgressControl::CanFocus() const +{ + return false; +} + + +bool CGUIProgressControl::OnMessage(CGUIMessage& message) +{ + if (message.GetMessage() == GUI_MSG_ITEM_SELECT) + { + SetPercentage((float)message.GetParam1()); + return true; + } + return CGUIControl::OnMessage(message); +} + +void CGUIProgressControl::SetPercentage(float fPercent) +{ + fPercent = std::max(0.0f, std::min(fPercent, 100.0f)); + if (m_fPercent != fPercent) + SetInvalid(); + m_fPercent = fPercent; +} + +float CGUIProgressControl::GetPercentage() const +{ + return m_fPercent; +} +void CGUIProgressControl::FreeResources(bool immediately) +{ + CGUIControl::FreeResources(immediately); + m_guiBackground->FreeResources(immediately); + m_guiMid->FreeResources(immediately); + m_guiRight->FreeResources(immediately); + m_guiLeft->FreeResources(immediately); + m_guiOverlay->FreeResources(immediately); +} + +void CGUIProgressControl::DynamicResourceAlloc(bool bOnOff) +{ + CGUIControl::DynamicResourceAlloc(bOnOff); + m_guiBackground->DynamicResourceAlloc(bOnOff); + m_guiMid->DynamicResourceAlloc(bOnOff); + m_guiRight->DynamicResourceAlloc(bOnOff); + m_guiLeft->DynamicResourceAlloc(bOnOff); + m_guiOverlay->DynamicResourceAlloc(bOnOff); +} + +void CGUIProgressControl::AllocResources() +{ + CGUIControl::AllocResources(); + m_guiBackground->AllocResources(); + m_guiMid->AllocResources(); + m_guiRight->AllocResources(); + m_guiLeft->AllocResources(); + m_guiOverlay->AllocResources(); + + m_guiBackground->SetHeight(25); + m_guiRight->SetHeight(20); + m_guiLeft->SetHeight(20); + m_guiMid->SetHeight(20); + m_guiOverlay->SetHeight(20); +} + +void CGUIProgressControl::SetInvalid() +{ + CGUIControl::SetInvalid(); + m_guiBackground->SetInvalid(); + m_guiMid->SetInvalid(); + m_guiRight->SetInvalid(); + m_guiLeft->SetInvalid(); + m_guiOverlay->SetInvalid(); +} + +void CGUIProgressControl::SetInfo(int iInfo, int iInfo2) +{ + m_iInfoCode = iInfo; + m_iInfoCode2 = iInfo2; +} + +bool CGUIProgressControl::UpdateColors(const CGUIListItem* item) +{ + bool changed = CGUIControl::UpdateColors(nullptr); + changed |= m_guiBackground->SetDiffuseColor(m_diffuseColor); + changed |= m_guiRight->SetDiffuseColor(m_diffuseColor); + changed |= m_guiLeft->SetDiffuseColor(m_diffuseColor); + changed |= m_guiMid->SetDiffuseColor(m_diffuseColor); + changed |= m_guiOverlay->SetDiffuseColor(m_diffuseColor); + + return changed; +} + +std::string CGUIProgressControl::GetDescription() const +{ + return StringUtils::Format("{:1.0f}", m_fPercent); +} + +bool CGUIProgressControl::UpdateLayout(void) +{ + bool bChanged(false); + + if (m_width == 0) + m_width = m_guiBackground->GetTextureWidth(); + if (m_height == 0) + m_height = m_guiBackground->GetTextureHeight(); + + bChanged |= m_guiBackground->SetHeight(m_height); + bChanged |= m_guiBackground->SetWidth(m_width); + + float fScaleX, fScaleY; + fScaleY = + m_guiBackground->GetTextureHeight() ? m_height / m_guiBackground->GetTextureHeight() : 1.0f; + fScaleX = + m_guiBackground->GetTextureWidth() ? m_width / m_guiBackground->GetTextureWidth() : 1.0f; + + float posX = m_guiBackground->GetXPosition(); + float posY = m_guiBackground->GetYPosition(); + + if (m_guiLeft->GetFileName().empty() && m_guiRight->GetFileName().empty()) + { // rendering without left and right image - fill the mid image completely + float width = (m_fPercent - m_fPercent2) * m_width * 0.01f; + float offsetX = m_fPercent2 * m_width * 0.01f;; + float offsetY = + fabs(fScaleY * 0.5f * (m_guiMid->GetTextureHeight() - m_guiBackground->GetTextureHeight())); + bChanged |= m_guiMid->SetPosition(posX + (offsetX > 0 ? offsetX : 0), + posY + (offsetY > 0 ? offsetY : 0)); + bChanged |= m_guiMid->SetHeight(fScaleY * m_guiMid->GetTextureHeight()); + if (m_bReveal) + { + bChanged |= m_guiMid->SetWidth(m_width); + float x = posX + offsetX, y = posY + offsetY, w = width, + h = fScaleY * m_guiMid->GetTextureHeight(); + CRect rect(x, y, x + w, y + h); + if (rect != m_guiMidClipRect) + { + m_guiMidClipRect = rect; + bChanged = true; + } + } + else + { + bChanged |= m_guiMid->SetWidth(width); + m_guiMidClipRect = CRect(); + } + } + else + { + float fWidth = m_fPercent - m_fPercent2; + float fFullWidth = m_guiBackground->GetTextureWidth() - m_guiLeft->GetTextureWidth() - + m_guiRight->GetTextureWidth(); + fWidth /= 100.0f; + fWidth *= fFullWidth; + + float offsetY = fabs(fScaleY * 0.5f * + (m_guiLeft->GetTextureHeight() - m_guiBackground->GetTextureHeight())); + bChanged |= m_guiLeft->SetPosition(posX, posY + (offsetY > 0 ? offsetY : 0)); + bChanged |= m_guiLeft->SetHeight(fScaleY * m_guiLeft->GetTextureHeight()); + bChanged |= m_guiLeft->SetWidth(fScaleX * m_guiLeft->GetTextureWidth()); + + posX += fScaleX * m_guiLeft->GetTextureWidth(); + float offsetX = m_fPercent2 * fWidth * 0.01f;; + offsetY = + fabs(fScaleY * 0.5f * (m_guiMid->GetTextureHeight() - m_guiBackground->GetTextureHeight())); + bChanged |= m_guiMid->SetPosition(posX + offsetX, posY + (offsetY > 0 ? offsetY : 0)); + bChanged |= m_guiMid->SetHeight(fScaleY * m_guiMid->GetTextureHeight()); + if (m_bReveal) + { + bChanged |= m_guiMid->SetWidth(fScaleX * fFullWidth); + float x = posX + offsetX, y = posY + offsetY, w = fScaleX * fWidth, + h = fScaleY * m_guiMid->GetTextureHeight(); + CRect rect(x, y, x + w, y + h); + if (rect != m_guiMidClipRect) + { + m_guiMidClipRect = rect; + bChanged = true; + } + } + else + { + bChanged |= m_guiMid->SetWidth(fScaleX * fWidth); + m_guiMidClipRect = CRect(); + } + + posX += fWidth * fScaleX; + + offsetY = fabs(fScaleY * 0.5f * + (m_guiRight->GetTextureHeight() - m_guiBackground->GetTextureHeight())); + bChanged |= m_guiRight->SetPosition(posX, posY + (offsetY > 0 ? offsetY : 0)); + bChanged |= m_guiRight->SetHeight(fScaleY * m_guiRight->GetTextureHeight()); + bChanged |= m_guiRight->SetWidth(fScaleX * m_guiRight->GetTextureWidth()); + } + float offset = fabs(fScaleY * 0.5f * + (m_guiOverlay->GetTextureHeight() - m_guiBackground->GetTextureHeight())); + if (offset > 0) // Center texture to the background if necessary + bChanged |= m_guiOverlay->SetPosition(m_guiBackground->GetXPosition(), + m_guiBackground->GetYPosition() + offset); + else + bChanged |= + m_guiOverlay->SetPosition(m_guiBackground->GetXPosition(), m_guiBackground->GetYPosition()); + bChanged |= m_guiOverlay->SetHeight(fScaleY * m_guiOverlay->GetTextureHeight()); + bChanged |= m_guiOverlay->SetWidth(fScaleX * m_guiOverlay->GetTextureWidth()); + + return bChanged; +} + +void CGUIProgressControl::UpdateInfo(const CGUIListItem *item) +{ + if (!IsDisabled()) + { + if (m_iInfoCode) + { + int value; + if (CServiceBroker::GetGUI()->GetInfoManager().GetInt(value, m_iInfoCode, m_parentID, item)) + m_fPercent = std::max(0.0f, std::min(static_cast<float>(value), 100.0f)); + } + if (m_iInfoCode2) + { + int value; + if (CServiceBroker::GetGUI()->GetInfoManager().GetInt(value, m_iInfoCode2, m_parentID, item)) + m_fPercent2 = std::max(0.0f, std::min(static_cast<float>(value), 100.0f)); + } + } +} |