Files
dota_factory/src/ui/BuildButtonGrid.cpp

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);
}