Fixed multiple issues in CarouselComponent.

This commit is contained in:
Leon Styhre 2022-02-09 18:22:06 +01:00
parent 98e265413e
commit b9e9178169
3 changed files with 115 additions and 127 deletions

View file

@ -24,8 +24,8 @@
namespace namespace
{ {
// Buffer values for scrolling velocity (left, stopped, right). // Buffer values for scrolling velocity (left, stopped, right).
const int logoBuffersLeft[] = {-5, -2, -1}; const int logoBuffersLeft[] {-5, -2, -1};
const int logoBuffersRight[] = {1, 2, 5}; const int logoBuffersRight[] {1, 2, 5};
} // namespace } // namespace
@ -120,70 +120,21 @@ void SystemView::render(const glm::mat4& parentTrans)
if (mCarousel->getNumEntries() == 0) if (mCarousel->getNumEntries() == 0)
return; // Nothing to render. return; // Nothing to render.
renderElements(parentTrans, false);
glm::mat4 trans {getTransform() * parentTrans}; glm::mat4 trans {getTransform() * parentTrans};
// Adding texture loading buffers depending on scrolling speed and status. // During fade transitions draw a black rectangle above all elements placed below the carousel.
int bufferIndex {mCarousel->getScrollingVelocity() + 1}; if (mFadeOpacity != 0.0f) {
unsigned int fadeColor {0x00000000 | static_cast<unsigned int>(mFadeOpacity * 255.0f)};
Renderer::pushClipRect(glm::ivec2 {}, Renderer::setMatrix(trans);
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)}); Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, fadeColor, fadeColor);
for (int i = static_cast<int>(mCamOffset) + logoBuffersLeft[bufferIndex];
i <= static_cast<int>(mCamOffset) + logoBuffersRight[bufferIndex]; ++i) {
int index {i};
while (index < 0)
index += static_cast<int>(mCarousel->getNumEntries());
while (index >= static_cast<int>(mCarousel->getNumEntries()))
index -= static_cast<int>(mCarousel->getNumEntries());
if (mCarousel->isAnimationPlaying(0) || index == mCarousel->getCursor()) {
glm::mat4 elementTrans {trans};
if (mCarousel->getType() == CarouselComponent::HORIZONTAL ||
mCarousel->getType() == CarouselComponent::HORIZONTAL_WHEEL)
elementTrans = glm::translate(elementTrans,
glm::vec3 {(i - mCamOffset) * mSize.x, 0.0f, 0.0f});
else
elementTrans = glm::translate(elementTrans,
glm::vec3 {0.0f, (i - mCamOffset) * mSize.y, 0.0f});
Renderer::pushClipRect(
glm::ivec2 {static_cast<int>(elementTrans[3].x),
static_cast<int>(elementTrans[3].y)},
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)});
if (mLegacyMode && mSystemElements.size() > static_cast<size_t>(index)) {
for (auto element : mSystemElements[index].legacyExtras)
element->render(elementTrans);
}
else if (mSystemElements.size() > static_cast<size_t>(index)) {
for (auto child : mSystemElements[index].children) {
if (child == mCarousel.get()) {
// Render black above anything lower than the zIndex of the carousel
// if fade transitions are in use and we're transitioning.
if (mFadeOpacity)
renderFade(trans);
child->render(trans);
}
else {
child->render(elementTrans);
}
}
} }
if (mLegacyMode)
mLegacySystemInfo->render(elementTrans);
Renderer::popClipRect();
}
}
if (mLegacyMode) {
if (mFadeOpacity)
renderFade(trans);
mCarousel->render(trans); mCarousel->render(trans);
}
Renderer::popClipRect(); // For legacy themes the carousel is always rendered on top of all other elements.
if (!mLegacyMode)
renderElements(parentTrans, true);
} }
void SystemView::onThemeChanged(const std::shared_ptr<ThemeData>& /*theme*/) void SystemView::onThemeChanged(const std::shared_ptr<ThemeData>& /*theme*/)
@ -264,24 +215,24 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
anim = new LambdaAnimation( anim = new LambdaAnimation(
[this, startFade, startPos, endPos, posMax](float t) { [this, startFade, startPos, endPos, posMax](float t) {
t -= 1; t -= 1;
float f = glm::mix(startPos, endPos, t * t * t + 1); float f {glm::mix(startPos, endPos, t * t * t + 1.0f)};
if (f < 0) if (f < 0.0f)
f += posMax; f += posMax;
if (f >= posMax) if (f >= posMax)
f -= posMax; f -= posMax;
t += 1; t += 1;
if (t < 0.3f) if (t < 0.3f)
this->mFadeOpacity = mFadeOpacity =
glm::mix(0.0f, 1.0f, glm::clamp(t / 0.2f + startFade, 0.0f, 1.0f)); glm::mix(0.0f, 1.0f, glm::clamp(t / 0.2f + startFade, 0.0f, 1.0f));
else if (t < 0.7f) else if (t < 0.7f)
this->mFadeOpacity = 1.0f; mFadeOpacity = 1.0f;
else else
this->mFadeOpacity = mFadeOpacity = glm::mix(1.0f, 0.0f, glm::clamp((t - 0.6f) / 0.3f, 0.0f, 1.0f));
glm::mix(1.0f, 0.0f, glm::clamp((t - 0.6f) / 0.3f, 0.0f, 1.0f));
if (t > 0.5f) if (t > 0.5f)
this->mCamOffset = endPos; mCamOffset = endPos;
// Update the game count when the entire animation has been completed. // Update the game count when the entire animation has been completed.
if (mFadeOpacity == 1.0f) if (mFadeOpacity == 1.0f)
@ -294,13 +245,13 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
anim = new LambdaAnimation( anim = new LambdaAnimation(
[this, startPos, endPos, posMax](float t) { [this, startPos, endPos, posMax](float t) {
t -= 1; t -= 1;
float f = glm::mix(startPos, endPos, t * t * t + 1); float f {glm::mix(startPos, endPos, t * t * t + 1.0f)};
if (f < 0) if (f < 0.0f)
f += posMax; f += posMax;
if (f >= posMax) if (f >= posMax)
f -= posMax; f -= posMax;
this->mCamOffset = f; mCamOffset = f;
// Hack to make the game count being updated in the middle of the animation. // Hack to make the game count being updated in the middle of the animation.
bool update {false}; bool update {false};
@ -329,13 +280,13 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
anim = new LambdaAnimation( anim = new LambdaAnimation(
[this, startPos, endPos, posMax](float t) { [this, startPos, endPos, posMax](float t) {
t -= 1; t -= 1;
float f = glm::mix(startPos, endPos, t * t * t + 1); float f {glm::mix(startPos, endPos, t * t * t + 1.0f)};
if (f < 0) if (f < 0.0f)
f += posMax; f += posMax;
if (f >= posMax) if (f >= posMax)
f -= posMax; f -= posMax;
this->mCamOffset = endPos; mCamOffset = endPos;
}, },
500); 500);
} }
@ -345,6 +296,8 @@ void SystemView::onCursorChanged(const CursorState& /*state*/)
void SystemView::populate() void SystemView::populate()
{ {
LOG(LogDebug) << "SystemView::populate(): Populating carousel";
auto themeSets = ThemeData::getThemeSets(); auto themeSets = ThemeData::getThemeSets();
std::map<std::string, ThemeData::ThemeSet>::const_iterator selectedSet { std::map<std::string, ThemeData::ThemeSet>::const_iterator selectedSet {
themeSets.find(Settings::getInstance()->getString("ThemeSet"))}; themeSets.find(Settings::getInstance()->getString("ThemeSet"))};
@ -362,8 +315,8 @@ void SystemView::populate()
std::string logoPath; std::string logoPath;
std::string defaultLogoPath; std::string defaultLogoPath;
if (mViewNeedsReload) if (mLegacyMode && mViewNeedsReload)
getViewElements(theme); legacyApplyTheme(theme);
if (mLegacyMode) { if (mLegacyMode) {
SystemViewElements elements; SystemViewElements elements;
@ -424,8 +377,10 @@ void SystemView::populate()
} }
} }
} }
else {
elements.children.emplace_back(mCarousel.get()); // Apply default carousel configuration.
mCarousel->applyTheme(theme, "system", "", ThemeFlags::ALL);
}
std::stable_sort( std::stable_sort(
elements.children.begin(), elements.children.end(), elements.children.begin(), elements.children.end(),
@ -535,16 +490,13 @@ void SystemView::updateGameCount()
} }
} }
void SystemView::getViewElements(const std::shared_ptr<ThemeData>& theme) void SystemView::legacyApplyTheme(const std::shared_ptr<ThemeData>& theme)
{ {
LOG(LogDebug) << "SystemView::getViewElements()";
if (theme->hasView("system")) if (theme->hasView("system"))
mViewNeedsReload = false; mViewNeedsReload = false;
else else
mViewNeedsReload = true; mViewNeedsReload = true;
if (mLegacyMode) {
mCarousel->applyTheme(theme, "system", "carousel_systemcarousel", ThemeFlags::ALL); mCarousel->applyTheme(theme, "system", "carousel_systemcarousel", ThemeFlags::ALL);
mLegacySystemInfo->setSize(mSize.x, mLegacySystemInfo->getFont()->getLetterHeight() * 2.2f); mLegacySystemInfo->setSize(mSize.x, mLegacySystemInfo->getFont()->getLetterHeight() * 2.2f);
@ -564,11 +516,56 @@ void SystemView::getViewElements(const std::shared_ptr<ThemeData>& theme)
if (sysInfoElem) if (sysInfoElem)
mLegacySystemInfo->applyTheme(theme, "system", "text_systemInfo", ThemeFlags::ALL); mLegacySystemInfo->applyTheme(theme, "system", "text_systemInfo", ThemeFlags::ALL);
} }
void SystemView::renderElements(const glm::mat4& parentTrans, bool abovePrimary)
{
glm::mat4 trans {getTransform() * parentTrans};
// Adding texture loading buffers depending on scrolling speed and status.
int bufferIndex {mCarousel->getScrollingVelocity() + 1};
const float primaryZIndex {mCarousel->getZIndex()};
for (int i = static_cast<int>(mCamOffset) + logoBuffersLeft[bufferIndex];
i <= static_cast<int>(mCamOffset) + logoBuffersRight[bufferIndex]; ++i) {
int index {i};
while (index < 0)
index += static_cast<int>(mCarousel->getNumEntries());
while (index >= static_cast<int>(mCarousel->getNumEntries()))
index -= static_cast<int>(mCarousel->getNumEntries());
if (mCarousel->isAnimationPlaying(0) || index == mCarousel->getCursor()) {
glm::mat4 elementTrans {trans};
if (mCarousel->getType() == CarouselComponent::HORIZONTAL ||
mCarousel->getType() == CarouselComponent::HORIZONTAL_WHEEL)
elementTrans = glm::translate(elementTrans,
glm::vec3 {(i - mCamOffset) * mSize.x, 0.0f, 0.0f});
else
elementTrans = glm::translate(elementTrans,
glm::vec3 {0.0f, (i - mCamOffset) * mSize.y, 0.0f});
Renderer::pushClipRect(
glm::ivec2 {static_cast<int>(glm::round(elementTrans[3].x)),
static_cast<int>(glm::round(elementTrans[3].y))},
glm::ivec2 {static_cast<int>(mSize.x), static_cast<int>(mSize.y)});
if (mLegacyMode && mSystemElements.size() > static_cast<size_t>(index)) {
for (auto element : mSystemElements[index].legacyExtras)
element->render(elementTrans);
}
else if (!mLegacyMode && mSystemElements.size() > static_cast<size_t>(index)) {
for (auto child : mSystemElements[index].children) {
if (abovePrimary && child->getZIndex() > primaryZIndex && mFadeOpacity == 0.0f)
child->render(elementTrans);
else if (!abovePrimary && child->getZIndex() <= primaryZIndex)
child->render(elementTrans);
}
} }
void SystemView::renderFade(const glm::mat4& trans) if (mLegacyMode)
{ mLegacySystemInfo->render(elementTrans);
unsigned int fadeColor {0x00000000 | static_cast<unsigned int>(mFadeOpacity * 255.0f)};
Renderer::setMatrix(trans); Renderer::popClipRect();
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, fadeColor, fadeColor); }
}
} }

View file

@ -78,14 +78,11 @@ protected:
private: private:
void populate(); void populate();
void updateGameCount(); void updateGameCount();
// Get the ThemeElements that make up the SystemView. void legacyApplyTheme(const std::shared_ptr<ThemeData>& theme);
void getViewElements(const std::shared_ptr<ThemeData>& theme); void renderElements(const glm::mat4& parentTrans, bool abovePrimary);
void renderFade(const glm::mat4& trans);
std::unique_ptr<CarouselComponent> mCarousel; std::unique_ptr<CarouselComponent> mCarousel;
std::unique_ptr<TextComponent> mLegacySystemInfo; std::unique_ptr<TextComponent> mLegacySystemInfo;
std::vector<SystemViewElements> mSystemElements; std::vector<SystemViewElements> mSystemElements;
float mCamOffset; float mCamOffset;

View file

@ -14,8 +14,8 @@
namespace namespace
{ {
// Buffer values for scrolling velocity (left, stopped, right). // Buffer values for scrolling velocity (left, stopped, right).
const int logoBuffersLeft[] = {-5, -2, -1}; const int logoBuffersLeft[] {-5, -2, -1};
const int logoBuffersRight[] = {1, 2, 5}; const int logoBuffersRight[] {1, 2, 5};
} // namespace } // namespace
@ -138,12 +138,6 @@ void CarouselComponent::addEntry(const std::shared_ptr<ThemeData>& theme,
add(entry); add(entry);
} }
void CarouselComponent::update(int deltaTime)
{
listUpdate(deltaTime);
GuiComponent::update(deltaTime);
}
bool CarouselComponent::input(InputConfig* config, Input input) bool CarouselComponent::input(InputConfig* config, Input input)
{ {
if (input.value != 0) { if (input.value != 0) {
@ -191,21 +185,23 @@ bool CarouselComponent::input(InputConfig* config, Input input)
return GuiComponent::input(config, input); return GuiComponent::input(config, input);
} }
void CarouselComponent::update(int deltaTime)
{
listUpdate(deltaTime);
GuiComponent::update(deltaTime);
}
void CarouselComponent::render(const glm::mat4& parentTrans) void CarouselComponent::render(const glm::mat4& parentTrans)
{ {
// Background box behind logos.
glm::mat4 carouselTrans {parentTrans}; glm::mat4 carouselTrans {parentTrans};
carouselTrans = glm::translate(carouselTrans, glm::vec3 {mPosition.x, mPosition.y, 0.0f}); carouselTrans = glm::translate(carouselTrans, glm::vec3 {mPosition.x, mPosition.y, 0.0f});
carouselTrans = glm::translate( carouselTrans = glm::translate(
carouselTrans, glm::vec3 {mOrigin.x * mSize.x * -1.0f, mOrigin.y * mSize.y * -1.0f, 0.0f}); carouselTrans, glm::vec3 {mOrigin.x * mSize.x * -1.0f, mOrigin.y * mSize.y * -1.0f, 0.0f});
glm::vec2 clipPos {carouselTrans[3].x, carouselTrans[3].y}; glm::vec2 clipPos {carouselTrans[3].x, carouselTrans[3].y};
Renderer::pushClipRect(
glm::ivec2 {static_cast<int>(std::round(clipPos.x)),
static_cast<int>(std::round(clipPos.y))},
glm::ivec2 {static_cast<int>(std::round(mSize.x)), static_cast<int>(std::round(mSize.y))});
Renderer::setMatrix(carouselTrans); Renderer::setMatrix(carouselTrans);
// Background box behind logos.
Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, mCarouselColor, mCarouselColorEnd, Renderer::drawRect(0.0f, 0.0f, mSize.x, mSize.y, mCarouselColor, mCarouselColorEnd,
mColorGradientHorizontal); mColorGradientHorizontal);
@ -303,8 +299,6 @@ void CarouselComponent::render(const glm::mat4& parentTrans)
comp->setOpacity(static_cast<unsigned char>(opacity)); comp->setOpacity(static_cast<unsigned char>(opacity));
comp->render(logoTrans); comp->render(logoTrans);
} }
Renderer::popClipRect();
} }
void CarouselComponent::applyTheme(const std::shared_ptr<ThemeData>& theme, void CarouselComponent::applyTheme(const std::shared_ptr<ThemeData>& theme,
@ -456,13 +450,13 @@ void CarouselComponent::onCursorChanged(const CursorState& state)
Animation* anim = new LambdaAnimation( Animation* anim = new LambdaAnimation(
[this, startPos, endPos, posMax](float t) { [this, startPos, endPos, posMax](float t) {
t -= 1; t -= 1;
float f = glm::mix(startPos, endPos, t * t * t + 1); float f {glm::mix(startPos, endPos, t * t * t + 1)};
if (f < 0) if (f < 0)
f += posMax; f += posMax;
if (f >= posMax) if (f >= posMax)
f -= posMax; f -= posMax;
this->mCamOffset = f; mCamOffset = f;
}, },
500); 500);