summaryrefslogtreecommitdiffstats
path: root/xbmc/guilib/GUIFadeLabelControl.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xbmc/guilib/GUIFadeLabelControl.cpp267
1 files changed, 267 insertions, 0 deletions
diff --git a/xbmc/guilib/GUIFadeLabelControl.cpp b/xbmc/guilib/GUIFadeLabelControl.cpp
new file mode 100644
index 0000000..5855f3c
--- /dev/null
+++ b/xbmc/guilib/GUIFadeLabelControl.cpp
@@ -0,0 +1,267 @@
+/*
+ * 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 "GUIFadeLabelControl.h"
+
+#include "GUIMessage.h"
+#include "utils/Random.h"
+
+using namespace KODI::GUILIB;
+
+CGUIFadeLabelControl::CGUIFadeLabelControl(int parentID, int controlID, float posX, float posY, float width, float height, const CLabelInfo& labelInfo, bool scrollOut, unsigned int timeToDelayAtEnd, bool resetOnLabelChange, bool randomized)
+ : CGUIControl(parentID, controlID, posX, posY, width, height), m_label(labelInfo), m_scrollInfo(50, labelInfo.offsetX, labelInfo.scrollSpeed)
+ , m_textLayout(labelInfo.font, false)
+ , m_fadeAnim(CAnimation::CreateFader(100, 0, timeToDelayAtEnd, 200))
+{
+ m_currentLabel = 0;
+ ControlType = GUICONTROL_FADELABEL;
+ m_scrollOut = scrollOut;
+ m_fadeAnim.ApplyAnimation();
+ m_lastLabel = -1;
+ m_scrollSpeed = labelInfo.scrollSpeed; // save it for later
+ m_resetOnLabelChange = resetOnLabelChange;
+ m_shortText = true;
+ m_scroll = true;
+ m_randomized = randomized;
+}
+
+CGUIFadeLabelControl::CGUIFadeLabelControl(const CGUIFadeLabelControl &from)
+: CGUIControl(from), m_infoLabels(from.m_infoLabels), m_label(from.m_label), m_scrollInfo(from.m_scrollInfo), m_textLayout(from.m_textLayout),
+ m_fadeAnim(from.m_fadeAnim)
+{
+ m_scrollOut = from.m_scrollOut;
+ m_scrollSpeed = from.m_scrollSpeed;
+ m_resetOnLabelChange = from.m_resetOnLabelChange;
+
+ m_fadeAnim.ApplyAnimation();
+ m_currentLabel = 0;
+ m_lastLabel = -1;
+ ControlType = GUICONTROL_FADELABEL;
+ m_shortText = from.m_shortText;
+ m_scroll = from.m_scroll;
+ m_randomized = from.m_randomized;
+ m_allLabelsShown = from.m_allLabelsShown;
+}
+
+CGUIFadeLabelControl::~CGUIFadeLabelControl(void) = default;
+
+void CGUIFadeLabelControl::SetInfo(const std::vector<GUIINFO::CGUIInfoLabel> &infoLabels)
+{
+ m_lastLabel = -1;
+ m_infoLabels = infoLabels;
+ m_allLabelsShown = m_infoLabels.empty();
+ if (m_randomized)
+ KODI::UTILS::RandomShuffle(m_infoLabels.begin(), m_infoLabels.end());
+}
+
+void CGUIFadeLabelControl::AddLabel(const std::string &label)
+{
+ m_infoLabels.emplace_back(label, "", GetParentID());
+ m_allLabelsShown = false;
+}
+
+void CGUIFadeLabelControl::Process(unsigned int currentTime, CDirtyRegionList &dirtyregions)
+{
+ if (m_infoLabels.empty() || !m_label.font)
+ {
+ CGUIControl::Process(currentTime, dirtyregions);
+ return;
+ }
+
+ if (m_currentLabel >= m_infoLabels.size() )
+ m_currentLabel = 0;
+
+ if (m_textLayout.Update(GetLabel()))
+ { // changed label - update our suffix based on length of available text
+ float width, height;
+ m_textLayout.GetTextExtent(width, height);
+ float spaceWidth = m_label.font->GetCharWidth(L' ');
+ unsigned int numSpaces = (unsigned int)(m_width / spaceWidth) + 1;
+ if (width < m_width) // append spaces for scrolling
+ numSpaces += (unsigned int)((m_width - width) / spaceWidth) + 1;
+ m_shortText = (width + m_label.offsetX) < m_width;
+ m_scrollInfo.m_suffix.assign(numSpaces, ' ');
+ if (m_resetOnLabelChange)
+ {
+ m_scrollInfo.Reset();
+ m_fadeAnim.ResetAnimation();
+ }
+ MarkDirtyRegion();
+ }
+
+ if (m_shortText && m_infoLabels.size() == 1)
+ m_allLabelsShown = true;
+
+ if (m_currentLabel != m_lastLabel)
+ { // new label - reset scrolling
+ m_scrollInfo.Reset();
+ m_fadeAnim.QueueAnimation(ANIM_PROCESS_REVERSE);
+ m_lastLabel = m_currentLabel;
+ MarkDirtyRegion();
+ }
+
+ if (m_infoLabels.size() > 1 || !m_shortText)
+ { // have scrolling text
+ bool moveToNextLabel = false;
+ if (!m_scrollOut)
+ {
+ if (m_scrollInfo.m_pixelPos + m_width > m_scrollInfo.m_textWidth)
+ {
+ if (m_fadeAnim.GetProcess() != ANIM_PROCESS_NORMAL)
+ m_fadeAnim.QueueAnimation(ANIM_PROCESS_NORMAL);
+ moveToNextLabel = true;
+ }
+ }
+ else if (m_scrollInfo.m_pixelPos > m_scrollInfo.m_textWidth)
+ moveToNextLabel = true;
+
+ if (m_scrollInfo.m_pixelSpeed || m_fadeAnim.GetState() == ANIM_STATE_IN_PROCESS)
+ MarkDirtyRegion();
+
+ // apply the fading animation
+ TransformMatrix matrix;
+ m_fadeAnim.Animate(currentTime, true);
+ m_fadeAnim.RenderAnimation(matrix);
+ m_fadeMatrix = CServiceBroker::GetWinSystem()->GetGfxContext().AddTransform(matrix);
+
+ if (m_fadeAnim.GetState() == ANIM_STATE_APPLIED)
+ m_fadeAnim.ResetAnimation();
+
+ m_scrollInfo.SetSpeed((m_fadeAnim.GetProcess() == ANIM_PROCESS_NONE) ? m_scrollSpeed : 0);
+
+ if (moveToNextLabel)
+ { // increment the label and reset scrolling
+ if (m_fadeAnim.GetProcess() != ANIM_PROCESS_NORMAL)
+ {
+ if (++m_currentLabel >= m_infoLabels.size())
+ {
+ m_currentLabel = 0;
+ m_allLabelsShown = true;
+ }
+ m_scrollInfo.Reset();
+ m_fadeAnim.QueueAnimation(ANIM_PROCESS_REVERSE);
+ }
+ }
+
+ if (m_scroll)
+ {
+ m_textLayout.UpdateScrollinfo(m_scrollInfo);
+ MarkDirtyRegion();
+ }
+
+ CServiceBroker::GetWinSystem()->GetGfxContext().RemoveTransform();
+ }
+
+ CGUIControl::Process(currentTime, dirtyregions);
+}
+
+bool CGUIFadeLabelControl::UpdateColors(const CGUIListItem* item)
+{
+ bool changed = CGUIControl::UpdateColors(nullptr);
+ changed |= m_label.UpdateColors();
+
+ return changed;
+}
+
+void CGUIFadeLabelControl::Render()
+{
+ if (!m_label.font)
+ { // nothing to render
+ CGUIControl::Render();
+ return ;
+ }
+
+ float posY = m_posY;
+ if (m_label.align & XBFONT_CENTER_Y)
+ posY += m_height * 0.5f;
+ if (m_infoLabels.size() == 1 && m_shortText)
+ { // single label set and no scrolling required - just display
+ float posX = m_posX + m_label.offsetX;
+ if (m_label.align & XBFONT_CENTER_X)
+ posX = m_posX + m_width * 0.5f;
+ else if (m_label.align & XBFONT_RIGHT)
+ posX = m_posX + m_width;
+ m_textLayout.Render(posX, posY, m_label.angle, m_label.textColor, m_label.shadowColor, m_label.align, m_width - m_label.offsetX);
+ CGUIControl::Render();
+ return;
+ }
+
+ // render the scrolling text
+ CServiceBroker::GetWinSystem()->GetGfxContext().SetTransform(m_fadeMatrix);
+ if (!m_scroll || (!m_scrollOut && m_shortText))
+ {
+ float posX = m_posX + m_label.offsetX;
+ if (m_label.align & XBFONT_CENTER_X)
+ posX = m_posX + m_width * 0.5f;
+ else if (m_label.align & XBFONT_RIGHT)
+ posX = m_posX + m_width;
+ m_textLayout.Render(posX, posY, 0, m_label.textColor, m_label.shadowColor, m_label.align, m_width);
+ }
+ else
+ m_textLayout.RenderScrolling(m_posX, posY, 0, m_label.textColor, m_label.shadowColor, (m_label.align & ~3), m_width, m_scrollInfo);
+ CServiceBroker::GetWinSystem()->GetGfxContext().RemoveTransform();
+ CGUIControl::Render();
+}
+
+
+bool CGUIFadeLabelControl::CanFocus() const
+{
+ return false;
+}
+
+
+bool CGUIFadeLabelControl::OnMessage(CGUIMessage& message)
+{
+ if ( message.GetControlId() == GetID() )
+ {
+ if (message.GetMessage() == GUI_MSG_LABEL_ADD)
+ {
+ AddLabel(message.GetLabel());
+ return true;
+ }
+ if (message.GetMessage() == GUI_MSG_LABEL_RESET)
+ {
+ m_lastLabel = -1;
+ m_infoLabels.clear();
+ m_allLabelsShown = true;
+ m_scrollInfo.Reset();
+ return true;
+ }
+ if (message.GetMessage() == GUI_MSG_LABEL_SET)
+ {
+ m_lastLabel = -1;
+ m_infoLabels.clear();
+ m_allLabelsShown = true;
+ m_scrollInfo.Reset();
+ AddLabel(message.GetLabel());
+ return true;
+ }
+ }
+ return CGUIControl::OnMessage(message);
+}
+
+std::string CGUIFadeLabelControl::GetDescription() const
+{
+ return (m_currentLabel < m_infoLabels.size()) ? m_infoLabels[m_currentLabel].GetLabel(m_parentID) : "";
+}
+
+std::string CGUIFadeLabelControl::GetLabel()
+{
+ if (m_currentLabel > m_infoLabels.size())
+ m_currentLabel = 0;
+
+ unsigned int numTries = 0;
+ std::string label(m_infoLabels[m_currentLabel].GetLabel(m_parentID));
+ while (label.empty() && ++numTries < m_infoLabels.size())
+ {
+ if (++m_currentLabel >= m_infoLabels.size())
+ m_currentLabel = 0;
+ label = m_infoLabels[m_currentLabel].GetLabel(m_parentID);
+ }
+ return label;
+}