133 lines
3.8 KiB
C++
133 lines
3.8 KiB
C++
#include "BuildButtonGrid.h"
|
|
|
|
#include <string>
|
|
|
|
#include <QGridLayout>
|
|
#include <QPushButton>
|
|
#include <QSignalMapper>
|
|
|
|
#include "BuildingType.h"
|
|
#include "BuildingTypeSelectedEvent.h"
|
|
#include "DemolishModeToggleRequestedEvent.h"
|
|
#include "DisplayName.h"
|
|
#include "EventManager.h"
|
|
#include "ExitBuilderModeRequestedEvent.h"
|
|
|
|
|
|
BuildButtonGrid::BuildButtonGrid(const GameConfig* config, QWidget* parent)
|
|
: QWidget(parent)
|
|
, m_config(config)
|
|
, m_activeIndex(-1)
|
|
{
|
|
QGridLayout* layout = new QGridLayout(this);
|
|
layout->setSpacing(4);
|
|
layout->setContentsMargins(4, 4, 4, 4);
|
|
|
|
QSignalMapper* mapper = new QSignalMapper(this);
|
|
int col = 0;
|
|
int row = 0;
|
|
const int kCols = 3;
|
|
|
|
for (const BuildingDef& def : config->buildings.buildings)
|
|
{
|
|
if (!def.playerPlaceable)
|
|
{
|
|
continue;
|
|
}
|
|
m_types.push_back(def.type);
|
|
m_costs[def.type] = def.cost;
|
|
|
|
const QString label = QString::fromStdString(toDisplayName(def.id))
|
|
+ "\n" + tr("%1 Blocks").arg(def.cost);
|
|
QPushButton* btn = new QPushButton(label, this);
|
|
btn->setCheckable(true);
|
|
btn->setFixedHeight(48);
|
|
layout->addWidget(btn, row, col);
|
|
|
|
const int idx = static_cast<int>(m_buttons.size());
|
|
m_buttons.push_back(btn);
|
|
mapper->setMapping(btn, idx);
|
|
connect(btn, &QPushButton::clicked, mapper, qOverload<>(&QSignalMapper::map));
|
|
|
|
++col;
|
|
if (col >= kCols)
|
|
{
|
|
col = 0;
|
|
++row;
|
|
}
|
|
}
|
|
connect(mapper, qOverload<int>(&QSignalMapper::mapped), this, &BuildButtonGrid::onBuildButton);
|
|
|
|
m_demolishButton = new QPushButton(tr("Demolish"), this);
|
|
m_demolishButton->setCheckable(true);
|
|
m_demolishButton->setFixedHeight(48);
|
|
layout->addWidget(m_demolishButton, row, col);
|
|
connect(m_demolishButton, &QPushButton::clicked, this, [this]() {
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<DemolishModeToggleRequestedEvent>());
|
|
});
|
|
|
|
registerForEvents();
|
|
}
|
|
|
|
BuildButtonGrid::~BuildButtonGrid()
|
|
{
|
|
unregisterForEvents();
|
|
}
|
|
|
|
void BuildButtonGrid::updateAffordability(int buildingBlocks)
|
|
{
|
|
for (std::size_t i = 0; i < m_buttons.size(); ++i)
|
|
{
|
|
const BuildingType type = m_types[i];
|
|
const std::map<BuildingType, int>::const_iterator it = m_costs.find(type);
|
|
const int cost = (it != m_costs.end()) ? it->second : 0;
|
|
m_buttons[i]->setEnabled(buildingBlocks >= cost || m_activeIndex == static_cast<int>(i));
|
|
}
|
|
}
|
|
|
|
void BuildButtonGrid::clearActiveButton()
|
|
{
|
|
if (m_activeIndex >= 0 && m_activeIndex < static_cast<int>(m_buttons.size()))
|
|
{
|
|
m_buttons[static_cast<std::size_t>(m_activeIndex)]->setChecked(false);
|
|
}
|
|
m_activeIndex = -1;
|
|
}
|
|
|
|
void BuildButtonGrid::onBuildButton(int index)
|
|
{
|
|
if (index < 0 || index >= static_cast<int>(m_buttons.size()))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (m_activeIndex == index)
|
|
{
|
|
clearActiveButton();
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<ExitBuilderModeRequestedEvent>());
|
|
return;
|
|
}
|
|
|
|
if (m_activeIndex >= 0 && m_activeIndex < static_cast<int>(m_buttons.size()))
|
|
{
|
|
m_buttons[static_cast<std::size_t>(m_activeIndex)]->setChecked(false);
|
|
}
|
|
|
|
m_activeIndex = index;
|
|
m_buttons[static_cast<std::size_t>(index)]->setChecked(true);
|
|
EventManager::getInstance()->sendEventImmediately(
|
|
std::make_shared<BuildingTypeSelectedEvent>(m_types[static_cast<std::size_t>(index)]));
|
|
}
|
|
|
|
void BuildButtonGrid::handleEvent(std::shared_ptr<const BuilderModeExitedEvent> /*event*/)
|
|
{
|
|
clearActiveButton();
|
|
}
|
|
|
|
void BuildButtonGrid::handleEvent(std::shared_ptr<const DemolishModeChangedEvent> event)
|
|
{
|
|
m_demolishButton->setChecked(event->active);
|
|
}
|