// SPDX-License-Identifier: MIT // // EmulationStation Desktop Edition // 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( Window* window, std::string message, int duration) : GuiComponent(window), mMessage(message), mDuration(duration), running(true) { mFrame = new NinePatchComponent(window); float maxWidth = Renderer::getScreenWidth() * 0.9f; float maxHeight = Renderer::getScreenHeight() * 0.2f; std::shared_ptr s = std::make_shared(mWindow, "", Font::get(FONT_SIZE_MINI), 0x444444FF, ALIGN_CENTER); // We do this to force the text container to resize and return the actual expected popup size. s->setSize(0,0); 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[1]); mSize[0] = maxWidth; } if (mSize.y() > maxHeight) { s->setSize(mSize[0], maxHeight); mSize[1] = maxHeight; } // Add a padding to the box. int paddingX = static_cast(Renderer::getScreenWidth() * 0.03f); int paddingY = static_cast(Renderer::getScreenHeight() * 0.02f); mSize[0] = mSize.x() + paddingX; mSize[1] = 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, Vector3f::Zero(), Vector2f(-32, -32)); addChild(mFrame); // We only initialize the actual time when we first start to render. mStartTime = 0; mGrid = new ComponentGrid(window, Vector2i(1, 3)); mGrid->setSize(mSize); mGrid->setEntry(s, Vector2i(0, 1), false, true); addChild(mGrid); } GuiInfoPopup::~GuiInfoPopup() { delete mGrid; delete mFrame; } void GuiInfoPopup::render(const Transform4x4f& /*parentTrans*/) { // We use Identity() as we want to render on a specific window position, not on the view. Transform4x4f trans = getTransform() * Transform4x4f::Identity(); if (running && updateState()) { // If we're still supposed to be rendering it. Renderer::setMatrix(trans); renderChildren(trans); } } bool GuiInfoPopup::updateState() { int curTime = 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. running = false; return false; } else if (curTime < mStartTime) { // If SDL reset. running = false; return false; } else if (curTime - mStartTime <= 500) { alpha = ((curTime - mStartTime) * 255 / 500); } else if (curTime - mStartTime < mDuration - 500) { alpha = 255; } else { alpha = ((-(curTime - mStartTime - mDuration) * 255) / 500); } mGrid->setOpacity(static_cast(alpha)); // Apply fade-in effect to popup frame. mFrame->setEdgeColor(0xFFFFFF00 | static_cast(alpha)); mFrame->setCenterColor(0xFFFFFF00 | static_cast(alpha)); return true; }