// SPDX-License-Identifier: MIT // // ES-DE Frontend // GuiInfoPopup.cpp // // Popup window used for user notifications. // #include "guis/GuiInfoPopup.h" #include "components/ComponentGrid.h" #include "components/NinePatchComponent.h" #include "components/TextComponent.h" #include GuiInfoPopup::GuiInfoPopup(std::string message, int duration) : mRenderer {Renderer::getInstance()} , mMessage {message} , mDuration {duration} , mAlpha {1.0f} , mRunning {true} { mFrame = new NinePatchComponent; float maxWidth {Renderer::getScreenWidth() * 0.9f}; float maxHeight {Renderer::getScreenHeight() * 0.2f}; std::shared_ptr s {std::make_shared( "", Font::get(FONT_SIZE_MINI), mMenuColorPopupText, ALIGN_CENTER)}; // We do this to force the text container to resize and return the actual expected popup size. s->setSize(0.0f, 0.0f); s->setText(message); mSize = s->getSize(); // Confirm that the size isn't larger than the screen width, otherwise cap it. if (mSize.x > maxWidth) { s->setSize(maxWidth, mSize.y); mSize.x = maxWidth; } if (mSize.y > maxHeight) { s->setSize(mSize.x, maxHeight); mSize.y = maxHeight; } // Add a padding to the box. int paddingX {static_cast(Renderer::getScreenWidth() * 0.03f)}; int paddingY {static_cast(Renderer::getScreenHeight() * 0.02f)}; mSize.x += paddingX; mSize.y += paddingY; float posX {Renderer::getScreenWidth() * 0.5f - mSize.x * 0.5f}; float posY {Renderer::getScreenHeight() * 0.02f}; setPosition(posX, posY, 0); mFrame->setImagePath(":/graphics/frame.svg"); mFrame->fitTo(mSize); addChild(mFrame); // We only initialize the actual time when we first start to render. mStartTime = 0; mGrid = new ComponentGrid(glm::ivec2 {1, 3}); mGrid->setEntry(s, glm::ivec2 {0, 1}, false, true); mGrid->setRowHeightPerc(1, s->getSize().y / mSize.y); mGrid->setSize(mSize); addChild(mGrid); } GuiInfoPopup::~GuiInfoPopup() { delete mGrid; delete mFrame; } void GuiInfoPopup::render(const glm::mat4& /*parentTrans*/) { // We use getIdentity() as we want to render on a specific window position, not on the view. const glm::mat4 trans {getTransform() * Renderer::getIdentity()}; if (mRunning && updateState()) { // If we're still supposed to be rendering it. mRenderer->setMatrix(trans); renderChildren(trans); } } bool GuiInfoPopup::updateState() { const int curTime {static_cast(SDL_GetTicks())}; // We only initialize the actual time when we first start to render. if (mStartTime == 0) mStartTime = curTime; // Compute fade-in effect. if (curTime - mStartTime > mDuration) { // We're past the popup duration, no need to render. mRunning = false; return false; } else if (curTime < mStartTime) { // If SDL reset. mRunning = false; return false; } else if (curTime - mStartTime <= 500) { mAlpha = static_cast((curTime - mStartTime) / 500.0f); } else if (curTime - mStartTime < mDuration - 500) { mAlpha = 1.0f; } else { mAlpha = static_cast((-(curTime - mStartTime - mDuration)) / 500.0f); } mGrid->setOpacity(mAlpha); // Apply fade-in effect to popup frame. mFrame->setFrameColor((mMenuColorFrame & 0xFFFFFF00) | static_cast(mAlpha * 255.0f)); return true; }