Added support for arbitrary image aspect ratios to RatingComponent.

Also added an overlay property and fixed some potential crashes.
This commit is contained in:
Leon Styhre 2022-09-01 17:40:29 +02:00
parent 819d1b0341
commit 3a9c7b92e3
3 changed files with 49 additions and 20 deletions

View file

@ -247,6 +247,7 @@ std::map<std::string, std::map<std::string, ThemeData::ElementPropertyType>>
{"color", COLOR}, {"color", COLOR},
{"filledPath", PATH}, {"filledPath", PATH},
{"unfilledPath", PATH}, {"unfilledPath", PATH},
{"overlay", BOOLEAN},
{"opacity", FLOAT}, {"opacity", FLOAT},
{"visible", BOOLEAN}, {"visible", BOOLEAN},
{"zIndex", FLOAT}}}, {"zIndex", FLOAT}}},

View file

@ -15,11 +15,14 @@
RatingComponent::RatingComponent(bool colorizeChanges) RatingComponent::RatingComponent(bool colorizeChanges)
: mRenderer {Renderer::getInstance()} : mRenderer {Renderer::getInstance()}
, mValue {0.5f}
, mImageRatio {1.0f}
, mColorOriginalValue {DEFAULT_COLORSHIFT} , mColorOriginalValue {DEFAULT_COLORSHIFT}
, mColorChangedValue {DEFAULT_COLORSHIFT} , mColorChangedValue {DEFAULT_COLORSHIFT}
, mColorShift {DEFAULT_COLORSHIFT} , mColorShift {DEFAULT_COLORSHIFT}
, mColorShiftEnd {DEFAULT_COLORSHIFT} , mColorShiftEnd {DEFAULT_COLORSHIFT}
, mColorizeChanges {colorizeChanges} , mColorizeChanges {colorizeChanges}
, mOverlay {true}
{ {
mSize = glm::vec2 {std::round(mRenderer->getScreenHeight() * 0.06f) * NUM_RATING_STARS, mSize = glm::vec2 {std::round(mRenderer->getScreenHeight() * 0.06f) * NUM_RATING_STARS,
std::round(mRenderer->getScreenHeight() * 0.06f)}; std::round(mRenderer->getScreenHeight() * 0.06f)};
@ -32,8 +35,6 @@ RatingComponent::RatingComponent(bool colorizeChanges)
mIconFilled.setImage(std::string(":/graphics/star_filled.svg"), true); mIconFilled.setImage(std::string(":/graphics/star_filled.svg"), true);
mIconUnfilled.setImage(std::string(":/graphics/star_unfilled.svg"), true); mIconUnfilled.setImage(std::string(":/graphics/star_unfilled.svg"), true);
mValue = 0.5f;
} }
void RatingComponent::setValue(const std::string& value) void RatingComponent::setValue(const std::string& value)
@ -70,8 +71,10 @@ void RatingComponent::setValue(const std::string& value)
mValue = 0.0f; mValue = 0.0f;
} }
mIconFilled.setClipRegion( const float clipValue {std::round(mIconUnfilled.getSize().x * mValue)};
glm::vec4 {0.0f, 0.0f, std::round(mIconFilled.getSize().x * mValue), mSize.y}); if (!mOverlay)
mIconUnfilled.setClipRegion(glm::vec4 {clipValue, 0.0f, mSize.x, mSize.y});
mIconFilled.setClipRegion(glm::vec4 {0.0f, 0.0f, clipValue, mSize.y});
} }
std::string RatingComponent::getValue() const std::string RatingComponent::getValue() const
@ -105,10 +108,12 @@ void RatingComponent::onSizeChanged()
mSize.x = mSize.y * NUM_RATING_STARS; mSize.x = mSize.y * NUM_RATING_STARS;
mIconFilled.getTexture()->setSize(mSize.y, mSize.y); mIconFilled.getTexture()->setSize(mSize.y, mSize.y);
mIconFilled.setResize(glm::vec2 {mSize.y * NUM_RATING_STARS, mSize.y}, true); mIconFilled.setResize(glm::vec2 {std::round(mSize.y * mImageRatio) * NUM_RATING_STARS, mSize.y},
true);
mIconUnfilled.getTexture()->setSize(mSize.y, mSize.y); mIconUnfilled.getTexture()->setSize(mSize.y, mSize.y);
mIconUnfilled.setResize(glm::vec2 {mSize.y * NUM_RATING_STARS, mSize.y}, true); mIconUnfilled.setResize(
glm::vec2 {std::round(mSize.y * mImageRatio) * NUM_RATING_STARS, mSize.y}, true);
} }
void RatingComponent::render(const glm::mat4& parentTrans) void RatingComponent::render(const glm::mat4& parentTrans)
@ -141,8 +146,10 @@ bool RatingComponent::input(InputConfig* config, Input input)
mIconFilled.setColorShift(mColorChangedValue); mIconFilled.setColorShift(mColorChangedValue);
} }
mIconFilled.setClipRegion( const float clipValue {std::round(mIconUnfilled.getSize().x * mValue)};
glm::vec4 {0.0f, 0.0f, std::round(mIconFilled.getSize().x * mValue), mSize.y}); if (!mOverlay)
mIconUnfilled.setClipRegion(glm::vec4 {clipValue, 0.0f, mSize.x, mSize.y});
mIconFilled.setClipRegion(glm::vec4 {0.0f, 0.0f, clipValue, mSize.y});
} }
return GuiComponent::input(config, input); return GuiComponent::input(config, input);
@ -165,6 +172,20 @@ void RatingComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
getParent()->getSize() : getParent()->getSize() :
glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight())}; glm::vec2(Renderer::getScreenWidth(), Renderer::getScreenHeight())};
{
// Read the image file in order to retrieve the image dimensions needed to calculate
// the aspect ratio constant.
if (properties & PATH && elem->has("filledPath")) {
std::string path {std::string(elem->get<std::string>("filledPath"))};
if (Utils::FileSystem::isRegularFile(path) || Utils::FileSystem::isSymlink(path)) {
auto tempImage =
TextureResource::get(path, false, false, false, false, 0, 0, 0.0f, 0.0f);
mImageRatio = static_cast<float>(tempImage->getSize().x) /
static_cast<float>(tempImage->getSize().y);
}
}
}
if (elem->has("size")) { if (elem->has("size")) {
glm::vec2 ratingSize {elem->get<glm::vec2>("size")}; glm::vec2 ratingSize {elem->get<glm::vec2>("size")};
if (ratingSize == glm::vec2 {0.0f, 0.0f}) { if (ratingSize == glm::vec2 {0.0f, 0.0f}) {
@ -179,9 +200,9 @@ void RatingComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
ratingSize.y = glm::clamp(ratingSize.y, 0.01f, 0.5f); ratingSize.y = glm::clamp(ratingSize.y, 0.01f, 0.5f);
mSize = glm::round(ratingSize * scale); mSize = glm::round(ratingSize * scale);
if (mSize.y == 0.0f) if (mSize.y == 0.0f)
mSize.y = mSize.x / NUM_RATING_STARS; mSize.y = std::round(mSize.x / mImageRatio) / NUM_RATING_STARS;
else else
mSize.x = mSize.y * NUM_RATING_STARS; mSize.x = std::round(mSize.y * mImageRatio) * NUM_RATING_STARS;
} }
bool linearInterpolation {false}; bool linearInterpolation {false};
@ -204,36 +225,41 @@ void RatingComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
} }
} }
mIconFilled.setTileSize(mSize.y, mSize.y); mIconFilled.setTileSize(mSize.y * mImageRatio, mSize.y);
mIconFilled.setResize(glm::vec2 {mSize}, false); mIconFilled.setResize(glm::vec2 {mSize}, false);
if (properties & PATH && elem->has("filledPath")) { if (properties & PATH && elem->has("filledPath") &&
(Utils::FileSystem::isRegularFile(elem->get<std::string>("filledPath")) ||
Utils::FileSystem::isSymlink(elem->get<std::string>("filledPath")))) {
mIconFilled.setDynamic(true); mIconFilled.setDynamic(true);
mIconFilled.setLinearInterpolation(linearInterpolation); mIconFilled.setLinearInterpolation(linearInterpolation);
mIconFilled.setImage(std::string(elem->get<std::string>("filledPath")), true); mIconFilled.setImage(std::string(elem->get<std::string>("filledPath")), true);
mIconFilled.getTexture()->setSize(mSize.y, mSize.y); mIconFilled.getTexture()->setSize(std::round(mSize.y * mImageRatio), mSize.y);
if (!mIconFilled.getTexture()->getScalable()) mIconFilled.onSizeChanged();
mIconFilled.onSizeChanged();
} }
else { else {
mIconFilled.setImage(std::string(":/graphics/star_filled.svg"), true); mIconFilled.setImage(std::string(":/graphics/star_filled.svg"), true);
} }
mIconUnfilled.setTileSize(mSize.y, mSize.y); mIconUnfilled.setTileSize(mSize.y * mImageRatio, mSize.y);
mIconUnfilled.setResize(glm::vec2 {mSize}, false); mIconUnfilled.setResize(glm::vec2 {mSize}, false);
if (properties & PATH && elem->has("unfilledPath")) { if (properties & PATH && elem->has("unfilledPath") &&
(Utils::FileSystem::isRegularFile(elem->get<std::string>("unfilledPath")) ||
Utils::FileSystem::isSymlink(elem->get<std::string>("unfilledPath")))) {
mIconUnfilled.setDynamic(true); mIconUnfilled.setDynamic(true);
mIconUnfilled.setLinearInterpolation(linearInterpolation); mIconUnfilled.setLinearInterpolation(linearInterpolation);
mIconUnfilled.setImage(std::string(elem->get<std::string>("unfilledPath")), true); mIconUnfilled.setImage(std::string(elem->get<std::string>("unfilledPath")), true);
mIconUnfilled.getTexture()->setSize(mSize.y, mSize.y); mIconUnfilled.getTexture()->setSize(std::round(mSize.y * mImageRatio), mSize.y);
if (!mIconUnfilled.getTexture()->getScalable()) mIconUnfilled.onSizeChanged();
mIconUnfilled.onSizeChanged();
} }
else { else {
mIconUnfilled.setImage(std::string(":/graphics/star_unfilled.svg"), true); mIconUnfilled.setImage(std::string(":/graphics/star_unfilled.svg"), true);
} }
if (elem->has("overlay") && !elem->get<bool>("overlay"))
mOverlay = false;
if (properties & COLOR) { if (properties & COLOR) {
if (elem->has("color")) { if (elem->has("color")) {
mIconFilled.setColorShift(elem->get<unsigned int>("color")); mIconFilled.setColorShift(elem->get<unsigned int>("color"));

View file

@ -51,6 +51,7 @@ private:
ImageComponent mIconUnfilled; ImageComponent mIconUnfilled;
float mValue; float mValue;
float mImageRatio;
int mOriginalValue; int mOriginalValue;
unsigned int mColorOriginalValue; unsigned int mColorOriginalValue;
@ -59,6 +60,7 @@ private:
unsigned int mColorShiftEnd; unsigned int mColorShiftEnd;
bool mColorizeChanges; bool mColorizeChanges;
bool mOverlay;
}; };
#endif // ES_APP_COMPONENTS_RATING_COMPONENT_H #endif // ES_APP_COMPONENTS_RATING_COMPONENT_H