#include "UIRenderer.h" #include "../ui/Font.h" #include #include void UIRenderer::drawSciFiPanel(SDL_Renderer* renderer, const SDL_FRect& rect, float alpha) { if (!renderer) return; SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); Uint8 alphaUint = static_cast(std::clamp(alpha * 255.0f, 0.0f, 255.0f)); // Drop shadow SDL_FRect shadow{rect.x + 6.0f, rect.y + 10.0f, rect.w, rect.h}; SDL_SetRenderDrawColor(renderer, 0, 0, 0, static_cast(120.0f * alpha)); SDL_RenderFillRect(renderer, &shadow); // Glow aura for (int i = 0; i < 5; ++i) { SDL_FRect glow{rect.x - float(i * 2), rect.y - float(i * 2), rect.w + float(i * 4), rect.h + float(i * 4)}; Uint8 glowAlpha = static_cast((42 - i * 8) * alpha); SDL_SetRenderDrawColor(renderer, 0, 180, 255, glowAlpha); SDL_RenderRect(renderer, &glow); } // Body SDL_SetRenderDrawColor(renderer, 18, 30, 52, alphaUint); SDL_RenderFillRect(renderer, &rect); // Border SDL_SetRenderDrawColor(renderer, 70, 120, 210, alphaUint); SDL_RenderRect(renderer, &rect); } void UIRenderer::drawButton(SDL_Renderer* renderer, FontAtlas* font, float cx, float cy, float w, float h, const std::string& label, bool isHovered, bool isSelected, SDL_Color bgColor, SDL_Color borderColor, bool textOnly, SDL_Texture* icon) { if (!renderer) return; float x = cx - w * 0.5f; float y = cy - h * 0.5f; if (!textOnly) { // Adjust colors based on state if (isSelected) { bgColor = {160, 190, 255, 255}; SDL_SetRenderDrawColor(renderer, 255, 220, 0, 110); SDL_FRect glow{x - 10, y - 10, w + 20, h + 20}; SDL_RenderFillRect(renderer, &glow); } else if (isHovered) { bgColor = {static_cast(std::min(255, bgColor.r + 40)), static_cast(std::min(255, bgColor.g + 40)), static_cast(std::min(255, bgColor.b + 40)), bgColor.a}; } // Draw button background with border SDL_SetRenderDrawColor(renderer, borderColor.r, borderColor.g, borderColor.b, borderColor.a); SDL_FRect borderRect{x - 2, y - 2, w + 4, h + 4}; SDL_RenderFillRect(renderer, &borderRect); SDL_SetRenderDrawColor(renderer, bgColor.r, bgColor.g, bgColor.b, bgColor.a); SDL_FRect bgRect{x, y, w, h}; SDL_RenderFillRect(renderer, &bgRect); } // Draw icon if provided, otherwise draw text if (icon) { // Get icon dimensions float iconW = 0.0f, iconH = 0.0f; SDL_GetTextureSize(icon, &iconW, &iconH); // Scale icon to fit nicely in button (60% of button height) float maxIconH = h * 0.6f; float scale = maxIconH / iconH; float scaledW = iconW * scale; float scaledH = iconH * scale; // Center icon in button float iconX = cx - scaledW * 0.5f; float iconY = cy - scaledH * 0.5f; // Apply yellow tint when selected if (isSelected) { SDL_SetTextureColorMod(icon, 255, 220, 0); } else { SDL_SetTextureColorMod(icon, 255, 255, 255); } SDL_FRect iconRect{iconX, iconY, scaledW, scaledH}; SDL_RenderTexture(renderer, icon, nullptr, &iconRect); // Reset color mod SDL_SetTextureColorMod(icon, 255, 255, 255); } else if (font) { // Draw text float textScale = 1.5f; int textW = 0, textH = 0; font->measure(label, textScale, textW, textH); float tx = x + (w - static_cast(textW)) * 0.5f; // Adjust vertical position for better alignment with background buttons float ty = y + (h - static_cast(textH)) * 0.5f + 2.0f; // Choose text color based on selection state SDL_Color textColor = {255, 255, 255, 255}; // Default white if (isSelected) { textColor = {255, 220, 0, 255}; // Yellow when selected } // Text shadow font->draw(renderer, tx + 2.0f, ty + 2.0f, label, textScale, {0, 0, 0, 200}); // Text font->draw(renderer, tx, ty, label, textScale, textColor); } } void UIRenderer::computeContentOffsets(float winW, float winH, float logicalW, float logicalH, float logicalScale, float& outOffsetX, float& outOffsetY) { float contentW = logicalW * logicalScale; float contentH = logicalH * logicalScale; outOffsetX = (winW - contentW) * 0.5f / logicalScale; outOffsetY = (winH - contentH) * 0.5f / logicalScale; } void UIRenderer::drawLogo(SDL_Renderer* renderer, SDL_Texture* logoTex, float logicalW, float logicalH, float contentOffsetX, float contentOffsetY, int texW, int texH) { if (!renderer || !logoTex) return; float w = 0.0f; float h = 0.0f; if (texW > 0 && texH > 0) { w = static_cast(texW); h = static_cast(texH); } else { SDL_GetTextureSize(logoTex, &w, &h); } if (w > 0.0f && h > 0.0f) { float maxWidth = logicalW * 0.6f; float scale = std::min(1.0f, maxWidth / w); float dw = w * scale; float dh = h * scale; float logoX = (logicalW - dw) * 0.5f + contentOffsetX; float logoY = logicalH * 0.05f + contentOffsetY; SDL_FRect dst{logoX, logoY, dw, dh}; SDL_RenderTexture(renderer, logoTex, nullptr, &dst); } } void UIRenderer::drawSettingsPopup(SDL_Renderer* renderer, FontAtlas* font, float logicalW, float logicalH, bool musicEnabled, bool soundEnabled) { if (!renderer || !font) return; float popupW = 350, popupH = 260; float popupX = (logicalW - popupW) / 2; float popupY = (logicalH - popupH) / 2; // Semi-transparent overlay SDL_SetRenderDrawColor(renderer, 0, 0, 0, 128); SDL_FRect overlay{0, 0, logicalW, logicalH}; SDL_RenderFillRect(renderer, &overlay); // Popup background SDL_SetRenderDrawColor(renderer, 100, 120, 160, 255); SDL_FRect bord{popupX-4, popupY-4, popupW+8, popupH+8}; SDL_RenderFillRect(renderer, &bord); SDL_SetRenderDrawColor(renderer, 40, 50, 70, 255); SDL_FRect body{popupX, popupY, popupW, popupH}; SDL_RenderFillRect(renderer, &body); // Title font->draw(renderer, popupX + 20, popupY + 20, "SETTINGS", 2.0f, {255, 220, 0, 255}); // Music toggle font->draw(renderer, popupX + 20, popupY + 70, "MUSIC:", 1.5f, {255, 255, 255, 255}); const char* musicStatus = musicEnabled ? "ON" : "OFF"; SDL_Color musicColor = musicEnabled ? SDL_Color{0, 255, 0, 255} : SDL_Color{255, 0, 0, 255}; font->draw(renderer, popupX + 120, popupY + 70, musicStatus, 1.5f, musicColor); // Sound effects toggle font->draw(renderer, popupX + 20, popupY + 100, "SOUND FX:", 1.5f, {255, 255, 255, 255}); const char* soundStatus = soundEnabled ? "ON" : "OFF"; SDL_Color soundColor = soundEnabled ? SDL_Color{0, 255, 0, 255} : SDL_Color{255, 0, 0, 255}; font->draw(renderer, popupX + 140, popupY + 100, soundStatus, 1.5f, soundColor); // Instructions font->draw(renderer, popupX + 20, popupY + 150, "M = TOGGLE MUSIC", 1.0f, {200, 200, 220, 255}); font->draw(renderer, popupX + 20, popupY + 170, "S = TOGGLE SOUND FX", 1.0f, {200, 200, 220, 255}); font->draw(renderer, popupX + 20, popupY + 190, "ESC = CLOSE", 1.0f, {200, 200, 220, 255}); }