implement ui

This commit is contained in:
2026-04-20 20:33:37 +02:00
parent 498b97db20
commit 94123e93d6
19 changed files with 2312 additions and 19 deletions

109
src/ui/MainWindow.cpp Normal file
View File

@@ -0,0 +1,109 @@
#include "MainWindow.h"
#include <QHBoxLayout>
#include <QMessageBox>
#include <QResizeEvent>
#include <QVBoxLayout>
#include "BuildButtonGrid.h"
#include "GameWorldView.h"
#include "HeaderBar.h"
#include "SelectedBuildingPanel.h"
#include "Simulation.h"
#include "Tick.h"
MainWindow::MainWindow(Simulation* sim, const GameConfig* config,
const VisualsConfig* visuals, QWidget* parent)
: QWidget(parent)
, m_sim(sim)
{
setWindowTitle("Dota Factory");
resize(1280, 768);
m_headerBar = new HeaderBar(this);
m_gameWorldView = new GameWorldView(sim, config, visuals, this);
m_bottomPanel = new QWidget(this);
QHBoxLayout* bottomLayout = new QHBoxLayout(m_bottomPanel);
bottomLayout->setContentsMargins(0, 0, 0, 0);
bottomLayout->setSpacing(0);
m_selectedBuildingPanel = new SelectedBuildingPanel(sim, config, m_bottomPanel);
m_buildButtonGrid = new BuildButtonGrid(config, m_bottomPanel);
bottomLayout->addWidget(m_selectedBuildingPanel, 1);
bottomLayout->addWidget(m_buildButtonGrid, 1);
// Signals: game world → other panels
connect(m_gameWorldView, SIGNAL(selectionChanged(std::vector<EntityId>)),
m_selectedBuildingPanel, SLOT(onSelectionChanged(std::vector<EntityId>)));
connect(m_gameWorldView, SIGNAL(stateUpdated(Tick, int, double)),
m_headerBar, SLOT(onStateUpdated(Tick, int, double)));
connect(m_gameWorldView, SIGNAL(stateUpdated(Tick, int, double)),
this, SLOT(onStateUpdated(Tick, int, double))); // for affordability
connect(m_gameWorldView, SIGNAL(gameOver()),
this, SLOT(onGameOver()));
// Signals: build grid → game world
connect(m_buildButtonGrid, SIGNAL(buildingTypeSelected(BuildingType)),
m_gameWorldView, SLOT(enterBuilderMode(BuildingType)));
connect(m_buildButtonGrid, SIGNAL(builderModeExited()),
m_gameWorldView, SLOT(exitBuilderMode()));
connect(m_gameWorldView, SIGNAL(builderModeExited()),
m_buildButtonGrid, SLOT(clearActiveButton()));
// Signals: header bar → game world
connect(m_headerBar, SIGNAL(speedChanged(double)),
m_gameWorldView, SLOT(setGameSpeed(double)));
m_gameWorldView->setFocus();
}
void MainWindow::resizeEvent(QResizeEvent* event)
{
QWidget::resizeEvent(event);
layoutPanels();
}
void MainWindow::layoutPanels()
{
const int totalW = width();
const int totalH = height();
const int headerH = m_headerBar->sizeHint().height();
if (headerH <= 0) { return; }
const int remaining = totalH - headerH;
const int gameH = remaining * 70 / 100;
const int panelH = remaining - gameH;
m_headerBar->setGeometry(0, 0, totalW, headerH);
m_gameWorldView->setGeometry(0, headerH, totalW, gameH);
m_bottomPanel->setGeometry(0, headerH + gameH, totalW, panelH);
}
void MainWindow::onStateUpdated(Tick /*tick*/, int blocks, double /*speed*/)
{
m_buildButtonGrid->updateAffordability(blocks);
}
void MainWindow::onGameOver()
{
const Tick tick = m_sim->currentTick();
const int totalSeconds = static_cast<int>(ticksToSeconds(tick));
const int minutes = totalSeconds / 60;
const int seconds = totalSeconds % 60;
QMessageBox box(this);
box.setWindowTitle("Game Over");
box.setText(QString("HQ destroyed!\nSurvival time: %1:%2")
.arg(minutes, 2, 10, QChar('0'))
.arg(seconds, 2, 10, QChar('0')));
box.addButton("Quit", QMessageBox::RejectRole);
box.exec();
close();
}