implement ui
This commit is contained in:
129
src/ui/BuildButtonGrid.cpp
Normal file
129
src/ui/BuildButtonGrid.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
#include "BuildButtonGrid.h"
|
||||
|
||||
#include <cctype>
|
||||
#include <string>
|
||||
|
||||
#include <QGridLayout>
|
||||
#include <QPushButton>
|
||||
#include <QSignalMapper>
|
||||
|
||||
#include "BuildingType.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
QString displayName(const std::string& id)
|
||||
{
|
||||
QString result;
|
||||
bool nextUpper = true;
|
||||
for (char c : id)
|
||||
{
|
||||
if (c == '_')
|
||||
{
|
||||
result += ' ';
|
||||
nextUpper = true;
|
||||
}
|
||||
else if (nextUpper)
|
||||
{
|
||||
result += static_cast<char>(std::toupper(static_cast<unsigned char>(c)));
|
||||
nextUpper = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += c;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
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 = displayName(def.id)
|
||||
+ "\n" + QString::number(def.cost) + " Blocks";
|
||||
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, SIGNAL(clicked()), mapper, SLOT(map()));
|
||||
|
||||
++col;
|
||||
if (col >= kCols)
|
||||
{
|
||||
col = 0;
|
||||
++row;
|
||||
}
|
||||
}
|
||||
connect(mapper, SIGNAL(mapped(int)), this, SLOT(onBuildButton(int)));
|
||||
}
|
||||
|
||||
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();
|
||||
emit builderModeExited();
|
||||
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);
|
||||
emit buildingTypeSelected(m_types[static_cast<std::size_t>(index)]);
|
||||
}
|
||||
Reference in New Issue
Block a user