From e27d1b60b13e2da57ab1a433737bcc445111a020 Mon Sep 17 00:00:00 2001 From: Gregor Klevze Date: Sun, 7 Dec 2025 18:25:13 +0100 Subject: [PATCH] fixed statistics panel --- src/graphics/GameRenderer.cpp | 14 ++++- src/graphics/renderers/GameRenderer.cpp | 75 ++++++++++++++----------- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/src/graphics/GameRenderer.cpp b/src/graphics/GameRenderer.cpp index 63198a9..c1f7652 100644 --- a/src/graphics/GameRenderer.cpp +++ b/src/graphics/GameRenderer.cpp @@ -348,14 +348,20 @@ void GameRenderer::renderPlayingState( snprintf(countStr, sizeof(countStr), "%d", count); int countW = 0, countH = 0; pixelFont->measure(countStr, 1.0f, countW, countH); - float countX = previewX + rowWidth - static_cast(countW); + // Horizontal shift to push the counts/percent a bit more to the right + const float statsNumbersShift = 20.0f; + // Small left shift for progress bar so the track aligns better with the design + const float statsBarShift = -10.0f; + float countX = previewX + rowWidth - static_cast(countW) + statsNumbersShift; float countY = previewY + 9.0f; int perc = (totalBlocks > 0) ? int(std::round(100.0 * double(count) / double(totalBlocks))) : 0; char percStr[16]; snprintf(percStr, sizeof(percStr), "%d%%", perc); + int percW = 0, percH = 0; + pixelFont->measure(percStr, 0.8f, percW, percH); - float barX = previewX; + float barX = previewX + statsBarShift; float barY = previewY + pieceHeight + 12.0f; float barH = 6.0f; float barW = rowWidth; @@ -378,7 +384,9 @@ void GameRenderer::renderPlayingState( drawSmallPiece(renderer, blocksTex, static_cast(i), previewX, previewY, previewSize); pixelFont->draw(renderer, countX, countY, countStr, 1.0f, {245, 245, 255, 255}); - pixelFont->draw(renderer, previewX, percY, percStr, 0.8f, {215, 225, 240, 255}); + // Draw percent right-aligned near the same right edge as the count + float percX = previewX + rowWidth - static_cast(percW) + statsNumbersShift; + pixelFont->draw(renderer, percX, percY, percStr, 0.8f, {215, 225, 240, 255}); SDL_SetRenderDrawColor(renderer, 110, 120, 140, 200); SDL_FRect track{barX, barY, barW, barH}; diff --git a/src/graphics/renderers/GameRenderer.cpp b/src/graphics/renderers/GameRenderer.cpp index 5c15cd4..f25b78c 100644 --- a/src/graphics/renderers/GameRenderer.cpp +++ b/src/graphics/renderers/GameRenderer.cpp @@ -616,28 +616,27 @@ void GameRenderer::renderPlayingState( GRID_H + blocksPanelPadY * 2.0f }; if (statisticsPanelTex) { - // Use the dedicated statistics panel image for the left panel when available. - // Preserve aspect ratio by scaling to the panel width and center/crop vertically if needed. + // Use the dedicated statistics panel image; scale it to fit the panel while + // preserving aspect ratio (no crop) so very tall source images don't overflow. float texWf = 0.0f, texHf = 0.0f; - if (SDL_GetTextureSize(statisticsPanelTex, &texWf, &texHf) == 0) { + if (SDL_GetTextureSize(statisticsPanelTex, &texWf, &texHf)) { + if (texWf > 0.0f && texHf > 0.0f) { const float destW = blocksPanelBg.w; const float destH = blocksPanelBg.h; - const float scale = destW / texWf; + const float scale = std::min(destW / texWf, destH / texHf); + const float scaledW = texWf * scale; const float scaledH = texHf * scale; - - if (scaledH <= destH) { - // Fits vertically: draw full texture centered vertically - SDL_FRect srcF{0.0f, 0.0f, texWf, texHf}; - SDL_RenderTexture(renderer, statisticsPanelTex, &srcF, &blocksPanelBg); - } else { - // Texture is taller when scaled to width: crop vertically from texture - float srcHf = destH / scale; - float srcYf = std::max(0.0f, (texHf - srcHf) * 0.5f); - SDL_FRect srcF{0.0f, srcYf, texWf, srcHf}; - SDL_RenderTexture(renderer, statisticsPanelTex, &srcF, &blocksPanelBg); + // Center the scaled texture inside the panel + SDL_FRect dstF{ + blocksPanelBg.x + (destW - scaledW) * 0.5f, + blocksPanelBg.y + (destH - scaledH) * 0.5f, + scaledW, + scaledH + }; + SDL_RenderTexture(renderer, statisticsPanelTex, nullptr, &dstF); } } else { - // Fallback: render entire texture if query failed + // Fallback: render entire texture stretched to panel SDL_RenderTexture(renderer, statisticsPanelTex, nullptr, &blocksPanelBg); } } else if (scorePanelTex) { @@ -1090,19 +1089,26 @@ void GameRenderer::renderPlayingState( const SDL_Color headerColor{255, 220, 0, 255}; const SDL_Color textColor{200, 220, 235, 200}; const SDL_Color mutedColor{150, 180, 200, 180}; - pixelFont->draw(renderer, statsX + 12.0f, statsY + 8.0f, "STATISTICS", 0.46f, headerColor); + // Small vertical shift to push text further into the statistics panel + // Increased from 20 to 80 to move text down by ~60px more (within 50-100px range) + const float statsTextShift = 80.0f; + pixelFont->draw(renderer, statsX + 12.0f, statsY + 8.0f + statsTextShift, "STATISTICS", 0.70f, headerColor); // Tighter spacing and smaller icons/text for compact analytics console - float yCursor = statsY + 34.0f; + float yCursor = statsY + 34.0f + statsTextShift; const float leftPad = 2.0f; const float rightPad = 14.0f; + // Horizontal shift to nudge the count/percent group closer to the right edge + const float statsNumbersShift = 20.0f; + // Horizontal shift to move the progress bar slightly left + const float statsBarShift = -10.0f; // Increase row gap to avoid icon overlap on smaller scales (bumped up) const float rowGap = 28.0f; const float barHeight = 2.0f; // Text scales for per-row numbers (slightly larger than before) - const float countScale = 0.45f; - const float percScale = 0.43f; + const float countScale = 0.60f; + const float percScale = 0.60f; // Determine max percent to highlight top used piece int maxPerc = 0; @@ -1157,7 +1163,7 @@ void GameRenderer::renderPlayingState( int maxTextH = std::max(countH, percH); float numbersW = numbersPadX * 2.0f + countW + numbersGap + percW; float numbersH = numbersPadY * 2.0f + static_cast(maxTextH); - float numbersX = rowRight - numbersW; + float numbersX = rowRight - numbersW + statsNumbersShift; float numbersY = yCursor - (numbersH - static_cast(maxTextH)) * 0.5f; float textY = numbersY + (numbersH - static_cast(maxTextH)) * 0.5f; @@ -1168,7 +1174,7 @@ void GameRenderer::renderPlayingState( pixelFont->draw(renderer, percX, textY, percStr, percScale, mutedColor); // Progress bar anchored to the numbers width - float barX = numbersX; + float barX = numbersX + statsBarShift; float barW = numbersW; float barY = numbersY + numbersH + 8.0f; @@ -1196,8 +1202,11 @@ void GameRenderer::renderPlayingState( yCursor = barY + barHeight + rowGap + 6.0f; } - // Bottom summary stats - float summaryY = statsY + statsH - 90.0f; // move summary slightly up + // Bottom summary stats: prefer to place summary right after last row + // but clamp it so it never goes below the reserved bottom area. + float preferredSummaryY = yCursor + 24.0f; // space below last row + float maxSummaryY = statsY + statsH - 90.0f; // original lower bound + float summaryY = std::min(preferredSummaryY, maxSummaryY); const SDL_Color summaryValueColor{220, 235, 250, 255}; const SDL_Color labelMuted{160, 180, 200, 200}; @@ -1210,20 +1219,20 @@ void GameRenderer::renderPlayingState( const float valueRightPad = 12.0f; // pad from right edge int valW=0, valH=0; - pixelFont->measure(totalStr, 0.41f, valW, valH); + pixelFont->measure(totalStr, 0.55f, valW, valH); float totalX = statsX + statsW - valueRightPad - (float)valW; - pixelFont->draw(renderer, labelX, summaryY + 0.0f, "TOTAL PIECES", 0.36f, labelMuted); - pixelFont->draw(renderer, totalX, summaryY + 0.0f, totalStr, 0.41f, summaryValueColor); + pixelFont->draw(renderer, labelX, summaryY + 0.0f, "TOTAL PIECES", 0.46f, labelMuted); + pixelFont->draw(renderer, totalX, summaryY + 0.0f, totalStr, 0.55f, summaryValueColor); - pixelFont->measure(tetrisesStr, 0.41f, valW, valH); + pixelFont->measure(tetrisesStr, 0.55f, valW, valH); float tetrisesX = statsX + statsW - valueRightPad - (float)valW; - pixelFont->draw(renderer, labelX, summaryY + 22.0f, "TETRISES MADE", 0.36f, labelMuted); - pixelFont->draw(renderer, tetrisesX, summaryY + 22.0f, tetrisesStr, 0.41f, summaryValueColor); + pixelFont->draw(renderer, labelX, summaryY + 22.0f, "TETRISES MADE", 0.46f, labelMuted); + pixelFont->draw(renderer, tetrisesX, summaryY + 22.0f, tetrisesStr, 0.55f, summaryValueColor); - pixelFont->measure(maxComboStr, 0.41f, valW, valH); + pixelFont->measure(maxComboStr, 0.55f, valW, valH); float comboX = statsX + statsW - valueRightPad - (float)valW; - pixelFont->draw(renderer, labelX, summaryY + 44.0f, "MAX COMBO", 0.36f, labelMuted); - pixelFont->draw(renderer, comboX, summaryY + 44.0f, maxComboStr, 0.41f, summaryValueColor); + pixelFont->draw(renderer, labelX, summaryY + 44.0f, "MAX COMBO", 0.46f, labelMuted); + pixelFont->draw(renderer, comboX, summaryY + 44.0f, maxComboStr, 0.55f, summaryValueColor); // Draw score panel (right side) const float contentTopOffset = 0.0f;