Bottom menu reorganized

This commit is contained in:
2025-12-17 19:23:16 +01:00
parent a671825502
commit 122de2b36f
3 changed files with 83 additions and 85 deletions

View File

@ -8,42 +8,51 @@ namespace ui {
std::array<SDL_FRect, 5> computeMenuButtonRects(const MenuLayoutParams& p) {
const float LOGICAL_W = static_cast<float>(p.logicalW);
const float LOGICAL_H = static_cast<float>(p.logicalH);
bool isSmall = ((LOGICAL_W * p.logicalScale) < MENU_SMALL_THRESHOLD);
float btnW = isSmall ? (LOGICAL_W * MENU_BTN_WIDTH_SMALL_FACTOR) : MENU_BTN_WIDTH_LARGE;
float btnH = isSmall ? MENU_BTN_HEIGHT_SMALL : MENU_BTN_HEIGHT_LARGE;
float contentOffsetX = (p.winW - LOGICAL_W * p.logicalScale) * 0.5f / p.logicalScale;
float contentOffsetY = (p.winH - LOGICAL_H * p.logicalScale) * 0.5f / p.logicalScale;
float btnCX = LOGICAL_W * 0.5f + contentOffsetX;
float btnCY = LOGICAL_H * 0.86f + contentOffsetY + MENU_BTN_Y_OFFSET;
float spacing = isSmall ? btnW * MENU_BTN_SPACING_FACTOR_SMALL : btnW * MENU_BTN_SPACING_FACTOR_LARGE;
// Guarantee the full 5-button group fits within the logical width so no options
// disappear in windowed mode. We shrink width + spacing proportionally when needed.
const float margin = std::max(18.0f, LOGICAL_W * 0.02f);
const float availableW = std::max(100.0f, LOGICAL_W - margin * 2.0f);
float totalW = btnW + (MENU_BTN_COUNT - 1) * spacing;
if (totalW > availableW) {
float scale = availableW / totalW;
btnW *= scale;
btnH *= scale;
spacing *= scale;
totalW = btnW + (MENU_BTN_COUNT - 1) * spacing;
// Cockpit HUD layout (matches main_screen art):
// - A big centered PLAY button
// - A second row of 4 smaller buttons: LEVEL / OPTIONS / HELP / EXIT
const float marginX = std::max(24.0f, LOGICAL_W * 0.03f);
const float marginBottom = std::max(26.0f, LOGICAL_H * 0.03f);
const float availableW = std::max(120.0f, LOGICAL_W - marginX * 2.0f);
float playW = std::min(230.0f, availableW * 0.27f);
float playH = 35.0f;
float smallW = std::min(220.0f, availableW * 0.23f);
float smallH = 34.0f;
float smallSpacing = 28.0f;
// Scale down for narrow windows so nothing goes offscreen.
float smallTotal = smallW * 4.0f + smallSpacing * 3.0f;
if (smallTotal > availableW) {
float s = availableW / smallTotal;
smallW *= s;
smallH *= s;
smallSpacing *= s;
playW = std::min(playW, availableW);
playH *= std::max(0.75f, s);
}
// Keep the group centered but ensure left/right edges respect margins.
float groupLeft = btnCX - totalW * 0.5f;
float minLeft = contentOffsetX + margin;
float maxRight = contentOffsetX + LOGICAL_W - margin;
float groupRight = groupLeft + totalW;
if (groupLeft < minLeft) {
btnCX += (minLeft - groupLeft);
} else if (groupRight > maxRight) {
btnCX -= (groupRight - maxRight);
}
float centerX = LOGICAL_W * 0.5f + contentOffsetX;
float bottomY = LOGICAL_H + contentOffsetY - marginBottom;
float smallCY = bottomY - smallH * 0.5f;
float playCY = smallCY - smallH * 0.5f - 16.0f - playH * 0.5f;
std::array<SDL_FRect, MENU_BTN_COUNT> rects{};
for (int i = 0; i < MENU_BTN_COUNT; ++i) {
float center = btnCX + (static_cast<float>(i) - MENU_BTN_CENTER) * spacing;
rects[i] = SDL_FRect{center - btnW / 2.0f, btnCY - btnH / 2.0f, btnW, btnH};
rects[0] = SDL_FRect{ centerX - playW * 0.5f, playCY - playH * 0.5f, playW, playH };
float rowW = smallW * 4.0f + smallSpacing * 3.0f;
float left = centerX - rowW * 0.5f;
float minLeft = contentOffsetX + marginX;
float maxRight = contentOffsetX + LOGICAL_W - marginX;
if (left < minLeft) left = minLeft;
if (left + rowW > maxRight) left = std::max(minLeft, maxRight - rowW);
for (int i = 0; i < 4; ++i) {
float x = left + i * (smallW + smallSpacing);
rects[i + 1] = SDL_FRect{ x, smallCY - smallH * 0.5f, smallW, smallH };
}
return rects;
}