1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
|
#include "ScrollingTextElement.h"
#include "globalincs/pstypes.h"
#include "gamesnd/gamesnd.h"
#include "scpui/RocketRenderingInterface.h"
// Our Assert conflicts with the definitions inside libRocket
#pragma push_macro("Assert")
#undef Assert
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
#endif
#include <Rocket/Core.h>
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#pragma pop_macro("Assert")
namespace scpui {
namespace elements {
ScrollingTextElement::ScrollingTextElement(const String& tag_in) : Element(tag_in) {
// Need to focce a local stacking context so that all elements are rendered without our Render() call. This allows
// us to set up the rendering context and reset it again once all our children have been rendered.
ForceLocalStackingContext();
}
ScrollingTextElement::~ScrollingTextElement() = default;
void ScrollingTextElement::OnAttributeChange(const AttributeNameList& changed_attributes)
{
Element::OnAttributeChange(changed_attributes);
if (changed_attributes.find("duration") == changed_attributes.end()) {
_duration = GetAttribute<float>("duration", _duration);
}
}
void ScrollingTextElement::OnChildAdd(Element* child)
{
Element::OnChildAdd(child);
_animation_start_time = Rocket::Core::GetSystemInterface()->GetElapsedTime();
}
void ScrollingTextElement::OnChildRemove(Element* child)
{
Element::OnChildRemove(child);
_animation_start_time = Rocket::Core::GetSystemInterface()->GetElapsedTime();
}
void ScrollingTextElement::OnBeforeRender()
{
if (_animation_start_time >= 0.0f) {
Assertion(dynamic_cast<RocketRenderingInterface*>(GetRenderInterface()) != nullptr,
"This element can only be used with out custom render interface!");
auto* renderInterface = static_cast<RocketRenderingInterface*>(GetRenderInterface());
const auto timeSince = Rocket::Core::GetSystemInterface()->GetElapsedTime() - _animation_start_time;
const auto progress = timeSince / _duration;
if (progress > 1.0f) {
renderInterface->setHorizontalSwipeOffset(std::numeric_limits<float>::infinity());
} else {
const auto left = GetParentNode()->GetAbsoluteLeft() + GetParentNode()->GetClientLeft();
const auto swipeLocation = left + progress * GetParentNode()->GetClientWidth();
// Swipe across in quantized steps to emulate the character by character effect the normal scrolling system
// does
const auto quantizedLocation = swipeLocation - std::fmod(swipeLocation, 15.f);
renderInterface->setHorizontalSwipeOffset(quantizedLocation);
}
}
}
void ScrollingTextElement::OnAfterRender()
{
Assertion(dynamic_cast<RocketRenderingInterface*>(GetRenderInterface()) != nullptr,
"This element can only be used with out custom render interface!");
auto* renderInterface = static_cast<RocketRenderingInterface*>(GetRenderInterface());
// NOTE: This means that we currently do not support nesting these swipe effects but we don't need that at the
// moment
renderInterface->setHorizontalSwipeOffset(std::numeric_limits<float>::infinity());
}
} // namespace elements
} // namespace scpui
|