mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 17:45:38 +00:00
Added a maxSize property to GIFAnimComponent and LottieAnimComponent.
Also refactored and cleaned up the code in general.
This commit is contained in:
parent
8ec39e6eac
commit
ff0f163de5
|
@ -327,6 +327,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
||||||
{"animation",
|
{"animation",
|
||||||
{{"pos", NORMALIZED_PAIR},
|
{{"pos", NORMALIZED_PAIR},
|
||||||
{"size", NORMALIZED_PAIR},
|
{"size", NORMALIZED_PAIR},
|
||||||
|
{"maxSize", NORMALIZED_PAIR},
|
||||||
{"origin", NORMALIZED_PAIR},
|
{"origin", NORMALIZED_PAIR},
|
||||||
{"rotation", FLOAT},
|
{"rotation", FLOAT},
|
||||||
{"rotationOrigin", NORMALIZED_PAIR},
|
{"rotationOrigin", NORMALIZED_PAIR},
|
||||||
|
@ -334,7 +335,6 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
|
||||||
{"path", PATH},
|
{"path", PATH},
|
||||||
{"speed", FLOAT},
|
{"speed", FLOAT},
|
||||||
{"direction", STRING},
|
{"direction", STRING},
|
||||||
{"keepAspectRatio", BOOLEAN},
|
|
||||||
{"interpolation", STRING},
|
{"interpolation", STRING},
|
||||||
{"brightness", FLOAT},
|
{"brightness", FLOAT},
|
||||||
{"opacity", FLOAT},
|
{"opacity", FLOAT},
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
GIFAnimComponent::GIFAnimComponent()
|
GIFAnimComponent::GIFAnimComponent()
|
||||||
: mRenderer {Renderer::getInstance()}
|
: mRenderer {Renderer::getInstance()}
|
||||||
|
, mTargetSize {0.0f, 0.0f}
|
||||||
, mFrameSize {0}
|
, mFrameSize {0}
|
||||||
, mAnimFile {nullptr}
|
, mAnimFile {nullptr}
|
||||||
, mAnimation {nullptr}
|
, mAnimation {nullptr}
|
||||||
|
@ -41,7 +42,7 @@ GIFAnimComponent::GIFAnimComponent()
|
||||||
, mPause {false}
|
, mPause {false}
|
||||||
, mExternalPause {false}
|
, mExternalPause {false}
|
||||||
, mAlternate {false}
|
, mAlternate {false}
|
||||||
, mKeepAspectRatio {true}
|
, mTargetIsMax {false}
|
||||||
{
|
{
|
||||||
// Get an empty texture for rendering the animation.
|
// Get an empty texture for rendering the animation.
|
||||||
mTexture = TextureResource::get("");
|
mTexture = TextureResource::get("");
|
||||||
|
@ -54,8 +55,8 @@ GIFAnimComponent::GIFAnimComponent()
|
||||||
// Set component defaults.
|
// Set component defaults.
|
||||||
setSize(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
|
setSize(Renderer::getScreenWidth() * 0.2f, Renderer::getScreenHeight() * 0.2f);
|
||||||
setPosition(Renderer::getScreenWidth() * 0.3f, Renderer::getScreenHeight() * 0.3f);
|
setPosition(Renderer::getScreenWidth() * 0.3f, Renderer::getScreenHeight() * 0.3f);
|
||||||
setDefaultZIndex(10.0f);
|
setDefaultZIndex(35.0f);
|
||||||
setZIndex(10.0f);
|
setZIndex(35.0f);
|
||||||
mTexture->setLinearMagnify(false);
|
mTexture->setLinearMagnify(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,11 +155,6 @@ void GIFAnimComponent::setAnimation(const std::string& path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mKeepAspectRatio && (mSize.x == 0.0f || mSize.y == 0.0f)) {
|
|
||||||
LOG(LogWarning) << "GIFAnimComponent: Width or height auto sizing is incompatible with "
|
|
||||||
"disabling of <keepAspectRatio> so ignoring this setting";
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t width {0};
|
size_t width {0};
|
||||||
size_t height {0};
|
size_t height {0};
|
||||||
|
|
||||||
|
@ -170,10 +166,36 @@ void GIFAnimComponent::setAnimation(const std::string& path)
|
||||||
mFileHeight = FreeImage_GetHeight(mFrame);
|
mFileHeight = FreeImage_GetHeight(mFrame);
|
||||||
filePitch = FreeImage_GetPitch(mFrame);
|
filePitch = FreeImage_GetPitch(mFrame);
|
||||||
|
|
||||||
if (mSize.x == 0.0f || mSize.y == 0.0f) {
|
if (mTargetIsMax || mSize.x == 0.0f || mSize.y == 0.0f) {
|
||||||
double sizeRatio {static_cast<double>(mFileWidth) / static_cast<double>(mFileHeight)};
|
const double sizeRatio {static_cast<double>(mFileWidth) / static_cast<double>(mFileHeight)};
|
||||||
|
|
||||||
if (mSize.x == 0) {
|
if (mTargetIsMax) {
|
||||||
|
// Just a precaution if FreeImage would return zero for some reason.
|
||||||
|
if (mFileWidth == 0)
|
||||||
|
mFileWidth = 1;
|
||||||
|
if (mFileHeight == 0)
|
||||||
|
mFileHeight = 1;
|
||||||
|
|
||||||
|
mSize.x = static_cast<float>(mFileWidth);
|
||||||
|
mSize.y = static_cast<float>(mFileHeight);
|
||||||
|
|
||||||
|
// Preserve aspect ratio.
|
||||||
|
const glm::vec2 resizeScale {mTargetSize.x / mSize.x, mTargetSize.y / mSize.y};
|
||||||
|
|
||||||
|
if (resizeScale.x < resizeScale.y) {
|
||||||
|
mSize.x *= resizeScale.x;
|
||||||
|
mSize.y = std::min(mSize.y * resizeScale.x, mTargetSize.y);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mSize.y *= resizeScale.y;
|
||||||
|
mSize.x = std::min((mSize.y / static_cast<float>(mFileHeight)) *
|
||||||
|
static_cast<float>(mFileWidth),
|
||||||
|
mTargetSize.x);
|
||||||
|
}
|
||||||
|
width = static_cast<size_t>(mSize.x);
|
||||||
|
height = static_cast<size_t>(mSize.y);
|
||||||
|
}
|
||||||
|
else if (mSize.x == 0) {
|
||||||
width = static_cast<size_t>(static_cast<double>(mSize.y) * sizeRatio);
|
width = static_cast<size_t>(static_cast<double>(mSize.y) * sizeRatio);
|
||||||
height = static_cast<size_t>(mSize.y);
|
height = static_cast<size_t>(mSize.y);
|
||||||
}
|
}
|
||||||
|
@ -190,6 +212,9 @@ void GIFAnimComponent::setAnimation(const std::string& path)
|
||||||
mSize.x = static_cast<float>(width);
|
mSize.x = static_cast<float>(width);
|
||||||
mSize.y = static_cast<float>(height);
|
mSize.y = static_cast<float>(height);
|
||||||
|
|
||||||
|
if (!mTargetIsMax)
|
||||||
|
mTargetSize = mSize;
|
||||||
|
|
||||||
FreeImage_PreMultiplyWithAlpha(mFrame);
|
FreeImage_PreMultiplyWithAlpha(mFrame);
|
||||||
mPictureRGBA.resize(mFileWidth * mFileHeight * 4);
|
mPictureRGBA.resize(mFileWidth * mFileHeight * 4);
|
||||||
|
|
||||||
|
@ -256,34 +281,40 @@ void GIFAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
unsigned int properties)
|
unsigned int properties)
|
||||||
{
|
{
|
||||||
using namespace ThemeFlags;
|
using namespace ThemeFlags;
|
||||||
|
GuiComponent::applyTheme(theme, view, element, properties ^ ThemeFlags::SIZE);
|
||||||
|
|
||||||
const ThemeData::ThemeElement* elem {theme->getElement(view, element, "animation")};
|
const ThemeData::ThemeElement* elem {theme->getElement(view, element, "animation")};
|
||||||
|
if (!elem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const glm::vec2 scale {glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight())};
|
||||||
|
|
||||||
if (elem->has("size")) {
|
if (elem->has("size")) {
|
||||||
glm::vec2 size = elem->get<glm::vec2>("size");
|
glm::vec2 animationSize {elem->get<glm::vec2>("size")};
|
||||||
if (size.x == 0.0f && size.y == 0.0f) {
|
if (animationSize == glm::vec2 {0.0f, 0.0f}) {
|
||||||
LOG(LogWarning) << "GIFAnimComponent: Invalid theme configuration, <size> defined as \""
|
LOG(LogWarning) << "GIFAnimComponent: Invalid theme configuration, property "
|
||||||
<< size.x << " " << size.y << "\"";
|
"\"size\" for element \""
|
||||||
return;
|
<< element.substr(10) << "\" is set to zero";
|
||||||
|
animationSize = {0.01f, 0.01f};
|
||||||
}
|
}
|
||||||
|
if (animationSize.x > 0.0f)
|
||||||
|
animationSize.x = glm::clamp(animationSize.x, 0.01f, 1.0f);
|
||||||
|
if (animationSize.y > 0.0f)
|
||||||
|
animationSize.y = glm::clamp(animationSize.y, 0.01f, 1.0f);
|
||||||
|
setSize(animationSize * scale);
|
||||||
|
}
|
||||||
|
else if (elem->has("maxSize")) {
|
||||||
|
const glm::vec2 animationMaxSize {glm::clamp(elem->get<glm::vec2>("maxSize"), 0.01f, 1.0f)};
|
||||||
|
setSize(animationMaxSize * scale);
|
||||||
|
mTargetIsMax = true;
|
||||||
|
mTargetSize = mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
||||||
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
|
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
|
||||||
|
|
||||||
if (elem->has("speed")) {
|
if (elem->has("speed"))
|
||||||
const float speed {elem->get<float>("speed")};
|
mSpeedModifier = glm::clamp(elem->get<float>("speed"), 0.2f, 3.0f);
|
||||||
if (speed < 0.2f || speed > 3.0f) {
|
|
||||||
LOG(LogWarning)
|
|
||||||
<< "GIFAnimComponent: Invalid theme configuration, <speed> defined as \""
|
|
||||||
<< std::fixed << std::setprecision(1) << speed << "\"";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mSpeedModifier = speed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elem->has("keepAspectRatio"))
|
|
||||||
mKeepAspectRatio = elem->get<bool>("keepAspectRatio");
|
|
||||||
|
|
||||||
if (elem->has("direction")) {
|
if (elem->has("direction")) {
|
||||||
const std::string& direction {elem->get<std::string>("direction")};
|
const std::string& direction {elem->get<std::string>("direction")};
|
||||||
|
@ -304,9 +335,9 @@ void GIFAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
mAlternate = true;
|
mAlternate = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(LogWarning)
|
LOG(LogWarning) << "GIFAnimComponent: Invalid theme configuration, property "
|
||||||
<< "GIFAnimComponent: Invalid theme configuration, <direction> defined as \""
|
"\"direction\" for element \""
|
||||||
<< direction << "\"";
|
<< element.substr(10) << "\" defined as \"" << direction << "\"";
|
||||||
mStartDirection = "normal";
|
mStartDirection = "normal";
|
||||||
mAlternate = false;
|
mAlternate = false;
|
||||||
}
|
}
|
||||||
|
@ -322,25 +353,14 @@ void GIFAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mTexture->setLinearMagnify(false);
|
mTexture->setLinearMagnify(false);
|
||||||
LOG(LogWarning)
|
LOG(LogWarning) << "GIFAnimComponent: Invalid theme configuration, property "
|
||||||
<< "GIFAnimComponent::applyTheme(): Invalid theme configuration, property "
|
"\"interpolation\" for element \""
|
||||||
"<interpolation> defined as \""
|
<< element.substr(10) << "\" defined as \"" << interpolation << "\"";
|
||||||
<< interpolation << "\"";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiComponent::applyTheme(theme, view, element, properties);
|
if (elem->has("path"))
|
||||||
|
setAnimation(elem->get<std::string>("path"));
|
||||||
if (elem->has("path")) {
|
|
||||||
const std::string& path {elem->get<std::string>("path")};
|
|
||||||
if (path != "") {
|
|
||||||
setAnimation(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG(LogWarning) << "GIFAnimComponent: Invalid theme configuration, <path> not set";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GIFAnimComponent::update(int deltaTime)
|
void GIFAnimComponent::update(int deltaTime)
|
||||||
|
@ -476,8 +496,15 @@ void GIFAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
|
|
||||||
mRenderer->setMatrix(trans);
|
mRenderer->setMatrix(trans);
|
||||||
|
|
||||||
if (Settings::getInstance()->getBool("DebugImage"))
|
if (Settings::getInstance()->getBool("DebugImage")) {
|
||||||
|
if (mTargetIsMax) {
|
||||||
|
const glm::vec2 targetSizePos {
|
||||||
|
glm::round((mTargetSize - mSize) * mOrigin * glm::vec2 {-1.0f})};
|
||||||
|
mRenderer->drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y,
|
||||||
|
0xFF000033, 0xFF000033);
|
||||||
|
}
|
||||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||||
|
}
|
||||||
|
|
||||||
if (mTexture->getSize().x != 0.0f) {
|
if (mTexture->getSize().x != 0.0f) {
|
||||||
mTexture->bind();
|
mTexture->bind();
|
||||||
|
|
|
@ -25,7 +25,6 @@ public:
|
||||||
~GIFAnimComponent();
|
~GIFAnimComponent();
|
||||||
|
|
||||||
void setAnimation(const std::string& path);
|
void setAnimation(const std::string& path);
|
||||||
void setKeepAspectRatio(bool value) { mKeepAspectRatio = value; }
|
|
||||||
void setPauseAnimation(bool state) { mExternalPause = state; }
|
void setPauseAnimation(bool state) { mExternalPause = state; }
|
||||||
|
|
||||||
void resetFileAnimation() override;
|
void resetFileAnimation() override;
|
||||||
|
@ -70,6 +69,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer* mRenderer;
|
Renderer* mRenderer;
|
||||||
|
glm::vec2 mTargetSize;
|
||||||
std::shared_ptr<TextureResource> mTexture;
|
std::shared_ptr<TextureResource> mTexture;
|
||||||
std::vector<uint8_t> mPictureRGBA;
|
std::vector<uint8_t> mPictureRGBA;
|
||||||
size_t mFrameSize;
|
size_t mFrameSize;
|
||||||
|
@ -100,7 +100,7 @@ private:
|
||||||
bool mPause;
|
bool mPause;
|
||||||
bool mExternalPause;
|
bool mExternalPause;
|
||||||
bool mAlternate;
|
bool mAlternate;
|
||||||
bool mKeepAspectRatio;
|
bool mTargetIsMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_CORE_COMPONENTS_GIF_ANIM_COMPONENT_H
|
#endif // ES_CORE_COMPONENTS_GIF_ANIM_COMPONENT_H
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
LottieAnimComponent::LottieAnimComponent()
|
LottieAnimComponent::LottieAnimComponent()
|
||||||
: mRenderer {Renderer::getInstance()}
|
: mRenderer {Renderer::getInstance()}
|
||||||
|
, mTargetSize {0.0f, 0.0f}
|
||||||
, mCacheFrames {true}
|
, mCacheFrames {true}
|
||||||
, mMaxCacheSize {0}
|
, mMaxCacheSize {0}
|
||||||
, mCacheSize {0}
|
, mCacheSize {0}
|
||||||
|
@ -36,7 +37,7 @@ LottieAnimComponent::LottieAnimComponent()
|
||||||
, mPause {false}
|
, mPause {false}
|
||||||
, mExternalPause {false}
|
, mExternalPause {false}
|
||||||
, mAlternate {false}
|
, mAlternate {false}
|
||||||
, mKeepAspectRatio {true}
|
, mTargetIsMax {false}
|
||||||
{
|
{
|
||||||
// Get an empty texture for rendering the animation.
|
// Get an empty texture for rendering the animation.
|
||||||
mTexture = TextureResource::get("");
|
mTexture = TextureResource::get("");
|
||||||
|
@ -55,8 +56,8 @@ LottieAnimComponent::LottieAnimComponent()
|
||||||
// Set component defaults.
|
// Set component defaults.
|
||||||
setSize(mRenderer->getScreenWidth() * 0.2f, mRenderer->getScreenHeight() * 0.2f);
|
setSize(mRenderer->getScreenWidth() * 0.2f, mRenderer->getScreenHeight() * 0.2f);
|
||||||
setPosition(mRenderer->getScreenWidth() * 0.3f, mRenderer->getScreenHeight() * 0.3f);
|
setPosition(mRenderer->getScreenWidth() * 0.3f, mRenderer->getScreenHeight() * 0.3f);
|
||||||
setDefaultZIndex(10.0f);
|
setDefaultZIndex(35.0f);
|
||||||
setZIndex(10.0f);
|
setZIndex(35.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
LottieAnimComponent::~LottieAnimComponent()
|
LottieAnimComponent::~LottieAnimComponent()
|
||||||
|
@ -117,22 +118,44 @@ void LottieAnimComponent::setAnimation(const std::string& path)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mKeepAspectRatio && (mSize.x == 0.0f || mSize.y == 0.0f)) {
|
|
||||||
LOG(LogWarning) << "LottieAnimComponent: Width or height auto sizing is incompatible with "
|
|
||||||
"disabling of <keepAspectRatio> so ignoring this setting";
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t width {0};
|
size_t width {0};
|
||||||
size_t height {0};
|
size_t height {0};
|
||||||
|
|
||||||
if (mSize.x == 0.0f || mSize.y == 0.0f) {
|
if (mTargetIsMax || mSize.x == 0.0f || mSize.y == 0.0f) {
|
||||||
size_t viewportWidth {0};
|
size_t viewportWidth {0};
|
||||||
size_t viewportHeight {0};
|
size_t viewportHeight {0};
|
||||||
|
|
||||||
mAnimation->size(viewportWidth, viewportHeight);
|
mAnimation->size(viewportWidth, viewportHeight);
|
||||||
double sizeRatio = static_cast<double>(viewportWidth) / static_cast<double>(viewportHeight);
|
const double sizeRatio {static_cast<double>(viewportWidth) /
|
||||||
|
static_cast<double>(viewportHeight)};
|
||||||
|
|
||||||
if (mSize.x == 0) {
|
if (mTargetIsMax) {
|
||||||
|
// Just a precaution if rlottie::Animation::size() would return zero for some reason.
|
||||||
|
if (viewportWidth == 0)
|
||||||
|
viewportWidth = 1;
|
||||||
|
if (viewportHeight == 0)
|
||||||
|
viewportHeight = 1;
|
||||||
|
|
||||||
|
mSize.x = static_cast<float>(viewportWidth);
|
||||||
|
mSize.y = static_cast<float>(viewportHeight);
|
||||||
|
|
||||||
|
// Preserve aspect ratio.
|
||||||
|
const glm::vec2 resizeScale {mTargetSize.x / mSize.x, mTargetSize.y / mSize.y};
|
||||||
|
|
||||||
|
if (resizeScale.x < resizeScale.y) {
|
||||||
|
mSize.x *= resizeScale.x;
|
||||||
|
mSize.y = std::min(mSize.y * resizeScale.x, mTargetSize.y);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mSize.y *= resizeScale.y;
|
||||||
|
mSize.x = std::min((mSize.y / static_cast<float>(viewportHeight)) *
|
||||||
|
static_cast<float>(viewportWidth),
|
||||||
|
mTargetSize.x);
|
||||||
|
}
|
||||||
|
width = static_cast<size_t>(mSize.x);
|
||||||
|
height = static_cast<size_t>(mSize.y);
|
||||||
|
}
|
||||||
|
else if (mSize.x == 0.0f) {
|
||||||
width = static_cast<size_t>(static_cast<double>(mSize.y) * sizeRatio);
|
width = static_cast<size_t>(static_cast<double>(mSize.y) * sizeRatio);
|
||||||
height = static_cast<size_t>(mSize.y);
|
height = static_cast<size_t>(mSize.y);
|
||||||
}
|
}
|
||||||
|
@ -149,6 +172,9 @@ void LottieAnimComponent::setAnimation(const std::string& path)
|
||||||
mSize.x = static_cast<float>(width);
|
mSize.x = static_cast<float>(width);
|
||||||
mSize.y = static_cast<float>(height);
|
mSize.y = static_cast<float>(height);
|
||||||
|
|
||||||
|
if (!mTargetIsMax)
|
||||||
|
mTargetSize = mSize;
|
||||||
|
|
||||||
mPictureRGBA.resize(width * height * 4);
|
mPictureRGBA.resize(width * height * 4);
|
||||||
mSurface = std::make_unique<rlottie::Surface>(reinterpret_cast<uint32_t*>(&mPictureRGBA[0]),
|
mSurface = std::make_unique<rlottie::Surface>(reinterpret_cast<uint32_t*>(&mPictureRGBA[0]),
|
||||||
width, height, width * sizeof(uint32_t));
|
width, height, width * sizeof(uint32_t));
|
||||||
|
@ -207,7 +233,7 @@ void LottieAnimComponent::resetFileAnimation()
|
||||||
if (mAnimation != nullptr) {
|
if (mAnimation != nullptr) {
|
||||||
if (mFuture.valid())
|
if (mFuture.valid())
|
||||||
mFuture.get();
|
mFuture.get();
|
||||||
mFuture = mAnimation->render(mFrameNum, *mSurface, mKeepAspectRatio);
|
mFuture = mAnimation->render(mFrameNum, *mSurface, false);
|
||||||
mLastRenderedFrame = static_cast<int>(mFrameNum);
|
mLastRenderedFrame = static_cast<int>(mFrameNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,35 +251,40 @@ void LottieAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
unsigned int properties)
|
unsigned int properties)
|
||||||
{
|
{
|
||||||
using namespace ThemeFlags;
|
using namespace ThemeFlags;
|
||||||
|
GuiComponent::applyTheme(theme, view, element, properties ^ ThemeFlags::SIZE);
|
||||||
|
|
||||||
const ThemeData::ThemeElement* elem {theme->getElement(view, element, "animation")};
|
const ThemeData::ThemeElement* elem {theme->getElement(view, element, "animation")};
|
||||||
|
if (!elem)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const glm::vec2 scale {glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight())};
|
||||||
|
|
||||||
if (elem->has("size")) {
|
if (elem->has("size")) {
|
||||||
glm::vec2 size {elem->get<glm::vec2>("size")};
|
glm::vec2 animationSize {elem->get<glm::vec2>("size")};
|
||||||
if (size.x == 0.0f && size.y == 0.0f) {
|
if (animationSize == glm::vec2 {0.0f, 0.0f}) {
|
||||||
LOG(LogWarning)
|
LOG(LogWarning) << "LottieAnimComponent: Invalid theme configuration, property "
|
||||||
<< "LottieAnimComponent: Invalid theme configuration, <size> defined as \""
|
"\"size\" for element \""
|
||||||
<< size.x << " " << size.y << "\"";
|
<< element.substr(10) << "\" is set to zero";
|
||||||
return;
|
animationSize = {0.01f, 0.01f};
|
||||||
}
|
}
|
||||||
|
if (animationSize.x > 0.0f)
|
||||||
|
animationSize.x = glm::clamp(animationSize.x, 0.01f, 1.0f);
|
||||||
|
if (animationSize.y > 0.0f)
|
||||||
|
animationSize.y = glm::clamp(animationSize.y, 0.01f, 1.0f);
|
||||||
|
setSize(animationSize * scale);
|
||||||
|
}
|
||||||
|
else if (elem->has("maxSize")) {
|
||||||
|
const glm::vec2 animationMaxSize {glm::clamp(elem->get<glm::vec2>("maxSize"), 0.01f, 1.0f)};
|
||||||
|
setSize(animationMaxSize * scale);
|
||||||
|
mTargetIsMax = true;
|
||||||
|
mTargetSize = mSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
if (elem->has("metadataElement") && elem->get<bool>("metadataElement"))
|
||||||
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
|
mComponentThemeFlags |= ComponentThemeFlags::METADATA_ELEMENT;
|
||||||
|
|
||||||
if (elem->has("speed")) {
|
if (elem->has("speed"))
|
||||||
const float speed {elem->get<float>("speed")};
|
mSpeedModifier = glm::clamp(elem->get<float>("speed"), 0.2f, 3.0f);
|
||||||
if (speed < 0.2f || speed > 3.0f) {
|
|
||||||
LOG(LogWarning)
|
|
||||||
<< "LottieAnimComponent: Invalid theme configuration, <speed> defined as \""
|
|
||||||
<< std::fixed << std::setprecision(1) << speed << "\"";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mSpeedModifier = speed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (elem->has("keepAspectRatio"))
|
|
||||||
mKeepAspectRatio = elem->get<bool>("keepAspectRatio");
|
|
||||||
|
|
||||||
if (elem->has("direction")) {
|
if (elem->has("direction")) {
|
||||||
const std::string& direction {elem->get<std::string>("direction")};
|
const std::string& direction {elem->get<std::string>("direction")};
|
||||||
|
@ -274,26 +305,16 @@ void LottieAnimComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
|
||||||
mAlternate = true;
|
mAlternate = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(LogWarning)
|
LOG(LogWarning) << "LottieAnimComponent: Invalid theme configuration, property "
|
||||||
<< "LottieAnimComponent: Invalid theme configuration, <direction> defined as \""
|
"\"direction\" for element \""
|
||||||
<< direction << "\"";
|
<< element.substr(10) << "\" defined as \"" << direction << "\"";
|
||||||
mStartDirection = "normal";
|
mStartDirection = "normal";
|
||||||
mAlternate = false;
|
mAlternate = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GuiComponent::applyTheme(theme, view, element, properties);
|
if (elem->has("path"))
|
||||||
|
setAnimation(elem->get<std::string>("path"));
|
||||||
if (elem->has("path")) {
|
|
||||||
std::string path {elem->get<std::string>("path")};
|
|
||||||
if (path != "") {
|
|
||||||
setAnimation(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
LOG(LogWarning) << "LottieAnimComponent: Invalid theme configuration, <path> not set";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LottieAnimComponent::update(int deltaTime)
|
void LottieAnimComponent::update(int deltaTime)
|
||||||
|
@ -403,7 +424,7 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
mAnimationStartTime = std::chrono::system_clock::now();
|
mAnimationStartTime = std::chrono::system_clock::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool renderNextFrame = false;
|
bool renderNextFrame {false};
|
||||||
|
|
||||||
if (mFuture.valid()) {
|
if (mFuture.valid()) {
|
||||||
if (mFuture.wait_for(std::chrono::milliseconds(1)) == std::future_status::ready) {
|
if (mFuture.wait_for(std::chrono::milliseconds(1)) == std::future_status::ready) {
|
||||||
|
@ -458,15 +479,23 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (renderNextFrame && !mHoldFrame) {
|
if (renderNextFrame && !mHoldFrame) {
|
||||||
mFuture = mAnimation->render(mFrameNum, *mSurface, mKeepAspectRatio);
|
mFuture = mAnimation->render(mFrameNum, *mSurface, false);
|
||||||
mLastRenderedFrame = static_cast<int>(mFrameNum);
|
mLastRenderedFrame = static_cast<int>(mFrameNum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mRenderer->setMatrix(trans);
|
mRenderer->setMatrix(trans);
|
||||||
|
|
||||||
if (Settings::getInstance()->getBool("DebugImage"))
|
if (Settings::getInstance()->getBool("DebugImage")) {
|
||||||
|
|
||||||
|
if (mTargetIsMax) {
|
||||||
|
const glm::vec2 targetSizePos {
|
||||||
|
glm::round((mTargetSize - mSize) * mOrigin * glm::vec2 {-1.0f})};
|
||||||
|
mRenderer->drawRect(targetSizePos.x, targetSizePos.y, mTargetSize.x, mTargetSize.y,
|
||||||
|
0xFF000033, 0xFF000033);
|
||||||
|
}
|
||||||
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
mRenderer->drawRect(0.0f, 0.0f, mSize.x, mSize.y, 0xFF000033, 0xFF000033);
|
||||||
|
}
|
||||||
|
|
||||||
if (mTexture->getSize().x != 0.0f) {
|
if (mTexture->getSize().x != 0.0f) {
|
||||||
mTexture->bind();
|
mTexture->bind();
|
||||||
|
@ -481,7 +510,7 @@ void LottieAnimComponent::render(const glm::mat4& parentTrans)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// Round vertices.
|
// Round vertices.
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i {0}; i < 4; ++i)
|
||||||
vertices[i].position = glm::round(vertices[i].position);
|
vertices[i].position = glm::round(vertices[i].position);
|
||||||
|
|
||||||
vertices->brightness = mBrightness;
|
vertices->brightness = mBrightness;
|
||||||
|
|
|
@ -32,7 +32,6 @@ public:
|
||||||
~LottieAnimComponent();
|
~LottieAnimComponent();
|
||||||
|
|
||||||
void setAnimation(const std::string& path);
|
void setAnimation(const std::string& path);
|
||||||
void setKeepAspectRatio(bool value) { mKeepAspectRatio = value; }
|
|
||||||
void setFrameCaching(bool value) { mCacheFrames = value; }
|
void setFrameCaching(bool value) { mCacheFrames = value; }
|
||||||
void setMaxCacheSize(int value)
|
void setMaxCacheSize(int value)
|
||||||
{
|
{
|
||||||
|
@ -54,6 +53,7 @@ private:
|
||||||
void render(const glm::mat4& parentTrans) override;
|
void render(const glm::mat4& parentTrans) override;
|
||||||
|
|
||||||
Renderer* mRenderer;
|
Renderer* mRenderer;
|
||||||
|
glm::vec2 mTargetSize;
|
||||||
std::shared_ptr<TextureResource> mTexture;
|
std::shared_ptr<TextureResource> mTexture;
|
||||||
std::vector<uint8_t> mPictureRGBA;
|
std::vector<uint8_t> mPictureRGBA;
|
||||||
std::unordered_map<size_t, std::vector<uint8_t>> mFrameCache;
|
std::unordered_map<size_t, std::vector<uint8_t>> mFrameCache;
|
||||||
|
@ -86,7 +86,7 @@ private:
|
||||||
bool mPause;
|
bool mPause;
|
||||||
bool mExternalPause;
|
bool mExternalPause;
|
||||||
bool mAlternate;
|
bool mAlternate;
|
||||||
bool mKeepAspectRatio;
|
bool mTargetIsMax;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ES_CORE_COMPONENTS_LOTTIE_ANIM_COMPONENT_H
|
#endif // ES_CORE_COMPONENTS_LOTTIE_ANIM_COMPONENT_H
|
||||||
|
|
Loading…
Reference in a new issue