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.
9 #include "GUIFadeLabelControl.h"
11 #include "GUIMessage.h"
12 #include "utils/Random.h"
14 using namespace KODI::GUILIB
;
16 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
)
17 : CGUIControl(parentID
, controlID
, posX
, posY
, width
, height
), m_label(labelInfo
), m_scrollInfo(50, labelInfo
.offsetX
, labelInfo
.scrollSpeed
)
18 , m_textLayout(labelInfo
.font
, false)
19 , m_fadeAnim(CAnimation::CreateFader(100, 0, timeToDelayAtEnd
, 200))
22 ControlType
= GUICONTROL_FADELABEL
;
23 m_scrollOut
= scrollOut
;
24 m_fadeAnim
.ApplyAnimation();
26 m_scrollSpeed
= labelInfo
.scrollSpeed
; // save it for later
27 m_resetOnLabelChange
= resetOnLabelChange
;
30 m_randomized
= randomized
;
33 CGUIFadeLabelControl::CGUIFadeLabelControl(const CGUIFadeLabelControl
&from
)
34 : CGUIControl(from
), m_infoLabels(from
.m_infoLabels
), m_label(from
.m_label
), m_scrollInfo(from
.m_scrollInfo
), m_textLayout(from
.m_textLayout
),
35 m_fadeAnim(from
.m_fadeAnim
)
37 m_scrollOut
= from
.m_scrollOut
;
38 m_scrollSpeed
= from
.m_scrollSpeed
;
39 m_resetOnLabelChange
= from
.m_resetOnLabelChange
;
41 m_fadeAnim
.ApplyAnimation();
44 ControlType
= GUICONTROL_FADELABEL
;
45 m_shortText
= from
.m_shortText
;
46 m_scroll
= from
.m_scroll
;
47 m_randomized
= from
.m_randomized
;
48 m_allLabelsShown
= from
.m_allLabelsShown
;
51 CGUIFadeLabelControl::~CGUIFadeLabelControl(void) = default;
53 void CGUIFadeLabelControl::SetInfo(const std::vector
<GUIINFO::CGUIInfoLabel
> &infoLabels
)
56 m_infoLabels
= infoLabels
;
57 m_allLabelsShown
= m_infoLabels
.empty();
59 KODI::UTILS::RandomShuffle(m_infoLabels
.begin(), m_infoLabels
.end());
62 void CGUIFadeLabelControl::AddLabel(const std::string
&label
)
64 m_infoLabels
.emplace_back(label
, "", GetParentID());
65 m_allLabelsShown
= false;
68 void CGUIFadeLabelControl::Process(unsigned int currentTime
, CDirtyRegionList
&dirtyregions
)
70 if (m_infoLabels
.empty() || !m_label
.font
)
72 CGUIControl::Process(currentTime
, dirtyregions
);
76 if (m_currentLabel
>= m_infoLabels
.size() )
79 if (m_textLayout
.Update(GetLabel()))
80 { // changed label - update our suffix based on length of available text
82 m_textLayout
.GetTextExtent(width
, height
);
83 float spaceWidth
= m_label
.font
->GetCharWidth(L
' ');
84 unsigned int numSpaces
= (unsigned int)(m_width
/ spaceWidth
) + 1;
85 if (width
< m_width
) // append spaces for scrolling
86 numSpaces
+= (unsigned int)((m_width
- width
) / spaceWidth
) + 1;
87 m_shortText
= (width
+ m_label
.offsetX
) < m_width
;
88 m_scrollInfo
.m_suffix
.assign(numSpaces
, ' ');
89 if (m_resetOnLabelChange
)
92 m_fadeAnim
.ResetAnimation();
97 if (m_shortText
&& m_infoLabels
.size() == 1)
98 m_allLabelsShown
= true;
100 if (m_currentLabel
!= m_lastLabel
)
101 { // new label - reset scrolling
102 m_scrollInfo
.Reset();
103 m_fadeAnim
.QueueAnimation(ANIM_PROCESS_REVERSE
);
104 m_lastLabel
= m_currentLabel
;
108 if (m_infoLabels
.size() > 1 || !m_shortText
)
109 { // have scrolling text
110 bool moveToNextLabel
= false;
113 if (m_scrollInfo
.m_pixelPos
+ m_width
> m_scrollInfo
.m_textWidth
)
115 if (m_fadeAnim
.GetProcess() != ANIM_PROCESS_NORMAL
)
116 m_fadeAnim
.QueueAnimation(ANIM_PROCESS_NORMAL
);
117 moveToNextLabel
= true;
120 else if (m_scrollInfo
.m_pixelPos
> m_scrollInfo
.m_textWidth
)
121 moveToNextLabel
= true;
123 if (m_scrollInfo
.m_pixelSpeed
|| m_fadeAnim
.GetState() == ANIM_STATE_IN_PROCESS
)
126 // apply the fading animation
127 TransformMatrix matrix
;
128 m_fadeAnim
.Animate(currentTime
, true);
129 m_fadeAnim
.RenderAnimation(matrix
);
130 m_fadeMatrix
= CServiceBroker::GetWinSystem()->GetGfxContext().AddTransform(matrix
);
131 m_fadeMatrix
.depth
= m_fadeDepth
;
133 if (m_fadeAnim
.GetState() == ANIM_STATE_APPLIED
)
134 m_fadeAnim
.ResetAnimation();
136 m_scrollInfo
.SetSpeed((m_fadeAnim
.GetProcess() == ANIM_PROCESS_NONE
) ? m_scrollSpeed
: 0);
139 { // increment the label and reset scrolling
140 if (m_fadeAnim
.GetProcess() != ANIM_PROCESS_NORMAL
)
142 if (++m_currentLabel
>= m_infoLabels
.size())
145 m_allLabelsShown
= true;
147 m_scrollInfo
.Reset();
148 m_fadeAnim
.QueueAnimation(ANIM_PROCESS_REVERSE
);
154 m_textLayout
.UpdateScrollinfo(m_scrollInfo
);
158 CServiceBroker::GetWinSystem()->GetGfxContext().RemoveTransform();
161 CGUIControl::Process(currentTime
, dirtyregions
);
164 bool CGUIFadeLabelControl::UpdateColors(const CGUIListItem
* item
)
166 bool changed
= CGUIControl::UpdateColors(nullptr);
167 changed
|= m_label
.UpdateColors();
172 void CGUIFadeLabelControl::Render()
174 if (CServiceBroker::GetWinSystem()->GetGfxContext().GetRenderOrder() ==
175 RENDER_ORDER_FRONT_TO_BACK
)
178 { // nothing to render
179 CGUIControl::Render();
184 if (m_label
.align
& XBFONT_CENTER_Y
)
185 posY
+= m_height
* 0.5f
;
186 if (m_infoLabels
.size() == 1 && m_shortText
)
187 { // single label set and no scrolling required - just display
188 float posX
= m_posX
+ m_label
.offsetX
;
189 if (m_label
.align
& XBFONT_CENTER_X
)
190 posX
= m_posX
+ m_width
* 0.5f
;
192 m_textLayout
.Render(posX
, posY
, m_label
.angle
, m_label
.textColor
, m_label
.shadowColor
, m_label
.align
, m_width
- m_label
.offsetX
);
193 CGUIControl::Render();
197 // render the scrolling text
198 CServiceBroker::GetWinSystem()->GetGfxContext().SetTransform(m_fadeMatrix
);
199 if (!m_scroll
|| (!m_scrollOut
&& m_shortText
))
201 float posX
= m_posX
+ m_label
.offsetX
;
202 if (m_label
.align
& XBFONT_CENTER_X
)
203 posX
= m_posX
+ m_width
* 0.5f
;
205 m_textLayout
.Render(posX
, posY
, 0, m_label
.textColor
, m_label
.shadowColor
, m_label
.align
, m_width
);
208 m_textLayout
.RenderScrolling(m_posX
, posY
, 0, m_label
.textColor
, m_label
.shadowColor
, (m_label
.align
& ~3), m_width
, m_scrollInfo
);
209 CServiceBroker::GetWinSystem()->GetGfxContext().RemoveTransform();
210 CGUIControl::Render();
214 bool CGUIFadeLabelControl::CanFocus() const
220 bool CGUIFadeLabelControl::OnMessage(CGUIMessage
& message
)
222 if ( message
.GetControlId() == GetID() )
224 if (message
.GetMessage() == GUI_MSG_LABEL_ADD
)
226 AddLabel(message
.GetLabel());
229 if (message
.GetMessage() == GUI_MSG_LABEL_RESET
)
232 m_infoLabels
.clear();
233 m_allLabelsShown
= true;
234 m_scrollInfo
.Reset();
237 if (message
.GetMessage() == GUI_MSG_LABEL_SET
)
240 m_infoLabels
.clear();
241 m_allLabelsShown
= true;
242 m_scrollInfo
.Reset();
243 AddLabel(message
.GetLabel());
247 return CGUIControl::OnMessage(message
);
250 void CGUIFadeLabelControl::AssignDepth()
252 CGUIControl::AssignDepth();
253 m_fadeDepth
= m_cachedTransform
.depth
;
256 std::string
CGUIFadeLabelControl::GetDescription() const
258 return (m_currentLabel
< m_infoLabels
.size()) ? m_infoLabels
[m_currentLabel
].GetLabel(m_parentID
) : "";
261 std::string
CGUIFadeLabelControl::GetLabel()
263 if (m_currentLabel
> m_infoLabels
.size())
266 unsigned int numTries
= 0;
267 std::string
label(m_infoLabels
[m_currentLabel
].GetLabel(m_parentID
));
268 while (label
.empty() && ++numTries
< m_infoLabels
.size())
270 if (++m_currentLabel
>= m_infoLabels
.size())
272 label
= m_infoLabels
[m_currentLabel
].GetLabel(m_parentID
);