allow to inspect balancing arena
This commit is contained in:
187
src/balancing/InspectWindow.cpp
Normal file
187
src/balancing/InspectWindow.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "InspectWindow.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QCloseEvent>
|
||||
#include <QHBoxLayout>
|
||||
#include <QKeyEvent>
|
||||
#include <QSignalMapper>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "ArenaView.h"
|
||||
|
||||
const double InspectWindow::kSpeeds[] = { 0.0, 0.5, 1.0, 2.0, 4.0 };
|
||||
const int InspectWindow::kSpeedCount = 5;
|
||||
|
||||
InspectWindow::InspectWindow(ArenaSimulation* sim, const VisualsConfig* visuals,
|
||||
const std::string& arenaName, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_sim(sim)
|
||||
{
|
||||
setWindowTitle(QString("Inspect \u2014 %1").arg(QString::fromStdString(arenaName)));
|
||||
resize(900, 700);
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
|
||||
QVBoxLayout* mainLayout = new QVBoxLayout(this);
|
||||
mainLayout->setContentsMargins(0, 0, 0, 0);
|
||||
mainLayout->setSpacing(0);
|
||||
|
||||
// Header: arena name + speed buttons
|
||||
{
|
||||
QWidget* header = new QWidget(this);
|
||||
QHBoxLayout* headerLayout = new QHBoxLayout(header);
|
||||
headerLayout->setContentsMargins(8, 4, 8, 4);
|
||||
headerLayout->setSpacing(8);
|
||||
|
||||
QLabel* nameLabel = new QLabel(QString::fromStdString(arenaName), header);
|
||||
QFont nameFont = nameLabel->font();
|
||||
nameFont.setBold(true);
|
||||
nameFont.setPointSize(nameFont.pointSize() + 2);
|
||||
nameLabel->setFont(nameFont);
|
||||
headerLayout->addWidget(nameLabel);
|
||||
|
||||
headerLayout->addStretch();
|
||||
|
||||
const char* labels[] = { "0x", "0.5x", "1x", "2x", "4x" };
|
||||
QSignalMapper* mapper = new QSignalMapper(this);
|
||||
for (int i = 0; i < kSpeedCount; ++i)
|
||||
{
|
||||
QPushButton* btn = new QPushButton(labels[i], header);
|
||||
btn->setCheckable(true);
|
||||
btn->setChecked(i == 2);
|
||||
headerLayout->addWidget(btn);
|
||||
m_speedButtons.push_back(btn);
|
||||
mapper->setMapping(btn, i);
|
||||
connect(btn, &QPushButton::clicked,
|
||||
mapper, qOverload<>(&QSignalMapper::map));
|
||||
}
|
||||
connect(mapper, qOverload<int>(&QSignalMapper::mapped),
|
||||
this, &InspectWindow::onSpeedButton);
|
||||
|
||||
header->setFixedHeight(header->sizeHint().height());
|
||||
mainLayout->addWidget(header);
|
||||
}
|
||||
|
||||
// Arena view (center, stretch)
|
||||
m_arenaView = new ArenaView(sim, visuals, this);
|
||||
mainLayout->addWidget(m_arenaView, 1);
|
||||
|
||||
connect(m_arenaView, &ArenaView::speedChanged,
|
||||
this, &InspectWindow::onSpeedChanged);
|
||||
|
||||
// Info panel (bottom)
|
||||
{
|
||||
QWidget* infoPanel = new QWidget(this);
|
||||
QHBoxLayout* infoLayout = new QHBoxLayout(infoPanel);
|
||||
infoLayout->setContentsMargins(8, 4, 8, 4);
|
||||
infoLayout->setSpacing(16);
|
||||
|
||||
QVBoxLayout* team1Layout = new QVBoxLayout();
|
||||
m_team1Header = new QLabel(infoPanel);
|
||||
QFont headerFont = m_team1Header->font();
|
||||
headerFont.setBold(true);
|
||||
m_team1Header->setFont(headerFont);
|
||||
team1Layout->addWidget(m_team1Header);
|
||||
m_team1Content = new QLabel(infoPanel);
|
||||
team1Layout->addWidget(m_team1Content);
|
||||
team1Layout->addStretch();
|
||||
infoLayout->addLayout(team1Layout);
|
||||
|
||||
QVBoxLayout* team2Layout = new QVBoxLayout();
|
||||
m_team2Header = new QLabel(infoPanel);
|
||||
m_team2Header->setFont(headerFont);
|
||||
team2Layout->addWidget(m_team2Header);
|
||||
m_team2Content = new QLabel(infoPanel);
|
||||
team2Layout->addWidget(m_team2Content);
|
||||
team2Layout->addStretch();
|
||||
infoLayout->addLayout(team2Layout);
|
||||
|
||||
mainLayout->addWidget(infoPanel);
|
||||
}
|
||||
|
||||
// Poll timer for info panel updates
|
||||
m_pollTimer = new QTimer(this);
|
||||
connect(m_pollTimer, &QTimer::timeout, this, &InspectWindow::pollStatus);
|
||||
m_pollTimer->start(100);
|
||||
|
||||
// Show initial status
|
||||
pollStatus();
|
||||
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
}
|
||||
|
||||
void InspectWindow::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
m_pollTimer->stop();
|
||||
emit closed();
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void InspectWindow::keyPressEvent(QKeyEvent* event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Space)
|
||||
{
|
||||
m_arenaView->togglePause();
|
||||
}
|
||||
else
|
||||
{
|
||||
QWidget::keyPressEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
void InspectWindow::onSpeedButton(int index)
|
||||
{
|
||||
if (index >= 0 && index < kSpeedCount)
|
||||
{
|
||||
m_arenaView->setGameSpeed(kSpeeds[index]);
|
||||
}
|
||||
}
|
||||
|
||||
void InspectWindow::onSpeedChanged(double multiplier)
|
||||
{
|
||||
for (int i = 0; i < kSpeedCount; ++i)
|
||||
{
|
||||
const bool active = (std::abs(kSpeeds[i] - multiplier) < 0.001);
|
||||
m_speedButtons[static_cast<std::size_t>(i)]->setChecked(active);
|
||||
}
|
||||
}
|
||||
|
||||
void InspectWindow::pollStatus()
|
||||
{
|
||||
const ArenaStatus status = m_sim->status();
|
||||
updateInfoPanel(status);
|
||||
}
|
||||
|
||||
void InspectWindow::updateInfoPanel(const ArenaStatus& status)
|
||||
{
|
||||
for (int ti = 0; ti < 2; ++ti)
|
||||
{
|
||||
const ArenaStatus::TeamStatus& team = status.teams[ti];
|
||||
QLabel* header = (ti == 0) ? m_team1Header : m_team2Header;
|
||||
QLabel* content = (ti == 0) ? m_team1Content : m_team2Content;
|
||||
|
||||
if (status.finished && status.winnerTeam == ti)
|
||||
{
|
||||
header->setText("[WON] " + QString::fromStdString(team.name));
|
||||
}
|
||||
else
|
||||
{
|
||||
header->setText(QString::fromStdString(team.name));
|
||||
}
|
||||
|
||||
QString lines;
|
||||
for (const ArenaStatus::Entry& entry : team.entries)
|
||||
{
|
||||
if (!lines.isEmpty())
|
||||
{
|
||||
lines += "\n";
|
||||
}
|
||||
lines += QString("%1/%2 %3 L%4")
|
||||
.arg(entry.surviving)
|
||||
.arg(entry.total)
|
||||
.arg(QString::fromStdString(entry.displayName))
|
||||
.arg(entry.level);
|
||||
}
|
||||
content->setText(lines);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user