float the selection panel over the game world instead of a side column

This commit is contained in:
2026-08-06 22:06:42 +02:00
parent 3b37b0ecf8
commit 603f8063e9
14 changed files with 320 additions and 129 deletions

View File

@@ -28,7 +28,7 @@
#include "RecipeSelectionDialog.h"
#include "SchematicChoiceDialog.h"
#include "HeaderBar.h"
#include "SelectedBuildingPanel.h"
#include "SelectionPanel.h"
#include "ShipLayoutBlueprintSerializer.h"
#include "ShipLayoutDialog.h"
#include "ItemIconCache.h"
@@ -66,7 +66,7 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir,
const std::string iconDir = QDir::cleanPath(
QString::fromStdString(m_configDir) + "/../icons/buildings").toStdString();
// Floats over the game world rather than living in the side panel column
// Floats over the game world at its bottom center, sized to its buttons
// (REQ-UI-BUILD-BAR). Creation order is the stacking order for siblings, so
// building it after the world view puts it above the world and its vignettes,
// and before the dim overlay keeps modals dimming it too (REQ-UI-MODAL-DIM).
@@ -80,23 +80,12 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir,
// world view because loading blueprints.toml may put a message box on screen.
m_blueprintLibrary = std::make_unique<BlueprintLibrary>(sim, &sim->getConfig(), this);
m_sidePanel = new QWidget(this);
QVBoxLayout* sideLayout = new QVBoxLayout(m_sidePanel);
sideLayout->setContentsMargins(1, 1, 1, 1);
sideLayout->setSpacing(1);
// The selected building panel is the column's only panel and fills its height
// (REQ-UI-PANEL-COLUMN).
m_selectedBuildingPanel = new SelectedBuildingPanel(sim, &sim->getConfig(), m_sidePanel);
sideLayout->addWidget(m_selectedBuildingPanel, 1);
// Draw a thin border around the side panel section. The class scoped selector keeps
// the border on the panel itself rather than cascading onto its child widgets;
// WA_StyledBackground lets the plain QWidget subclass honor the stylesheet box
// (border/background).
m_selectedBuildingPanel->setAttribute(Qt::WA_StyledBackground, true);
m_sidePanel->setStyleSheet(QStringLiteral(
"SelectedBuildingPanel { border: 1px solid palette(mid); }"));
// Floats over the game world at its right edge rather than occupying a column of
// its own, and hides itself while nothing is selected (REQ-UI-SELECTION-PANEL). Like
// the build button bar it is a sibling of the world view built after it, which is
// what puts it above the world and its vignettes and below the dim overlay. It
// brings its own chrome; its geometry comes from layoutPanels().
m_selectionPanel = new SelectionPanel(sim, &sim->getConfig(), this);
// Created last so it stacks above the other children; covers the whole window and
// dims the game behind modal dialogs/menus (REQ-UI-MODAL-DIM).
@@ -166,15 +155,20 @@ void MainWindow::layoutPanels()
const int totalH = height();
const int headerH = m_headerBar->sizeHint().height();
if (headerH <= 0) { return; }
const int mainW = totalW * 75 / 100;
const int sideW = totalW - mainW;
m_headerBar->setGeometry(0, 0, mainW, headerH);
m_gameWorldView->setGeometry(0, headerH, mainW, totalH - headerH);
m_sidePanel->setGeometry(mainW, 0, sideW, totalH);
// Header bar and game world view span the full window width; the two floating
// widgets below are the only things over the world (REQ-UI-HEADER,
// REQ-UI-WORLD-SIZE).
const QRect worldRect(0, headerH, totalW, totalH - headerH);
m_headerBar->setGeometry(0, 0, totalW, headerH);
m_gameWorldView->setGeometry(worldRect);
// Sizes itself to its buttons and centers along the bottom of the world view
// (REQ-UI-BUILD-BAR).
m_buildButtonBar->anchorTo(QRect(0, headerH, mainW, totalH - headerH));
m_buildButtonBar->anchorTo(worldRect);
// The panel confines itself to what the bar leaves free, so the bar never has to
// move for it (REQ-UI-SELECTION-PANEL, REQ-UI-BUILD-BAR).
m_selectionPanel->anchorTo(
worldRect.adjusted(0, 0, 0, -m_buildButtonBar->getStripHeightPx()));
m_dimOverlay->setGeometry(0, 0, totalW, totalH);
}