Reapply build button grid icons
Revert of "Undo build button grid icons" (614dda8): restore the per-building
SVG icons, the QtSvg-based icon loading in BuildButtonGrid, the icon dir
plumbing in MainWindow, and the Qt5::Svg dependency.
This returns the unlock-groups branch to having the icons. The preceding
undo commit exists only so the Demolish -> Deconstruct rename can be
cherry-picked on its own (rename+icons commit together with the undo).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y7N59FsLA5e2kuVdqe4Uhc
This commit is contained in:
@@ -117,6 +117,7 @@ target_link_libraries(${TARGET_UI_NAME}
|
||||
Qt5::Network
|
||||
Qt5::Multimedia
|
||||
Qt5::Charts
|
||||
Qt5::Svg
|
||||
)
|
||||
target_compile_definitions(${TARGET_UI_NAME} PRIVATE TOML_FLOAT_CHARCONV=0)
|
||||
|
||||
|
||||
@@ -2,9 +2,18 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QFile>
|
||||
#include <QGridLayout>
|
||||
#include <QIcon>
|
||||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QSignalMapper>
|
||||
#include <QSize>
|
||||
#include <QString>
|
||||
#include <QSvgRenderer>
|
||||
|
||||
#include "BuildingType.h"
|
||||
#include "BuildingTypeSelectedEvent.h"
|
||||
@@ -14,11 +23,60 @@
|
||||
#include "ExitBuilderModeRequestedEvent.h"
|
||||
#include "Simulation.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
// Pixel size the SVG chips are rasterized at; downscaled to the button icon size.
|
||||
const int kIconRenderSize = 64;
|
||||
const QSize kIconSize(28, 28);
|
||||
|
||||
BuildButtonGrid::BuildButtonGrid(Simulation* sim, const GameConfig* config, QWidget* parent)
|
||||
QPixmap renderChip(const QByteArray& svg)
|
||||
{
|
||||
QSvgRenderer renderer(svg);
|
||||
QPixmap pixmap(kIconRenderSize, kIconRenderSize);
|
||||
pixmap.fill(Qt::transparent);
|
||||
QPainter painter(&pixmap);
|
||||
renderer.render(&painter);
|
||||
return pixmap;
|
||||
}
|
||||
|
||||
// Builds a build-button icon from a "<id>.svg" chip file. The returned QIcon also
|
||||
// carries a Disabled-mode pixmap whose chip background is recolored grey, so an
|
||||
// unaffordable (disabled) button shows the grey variant automatically
|
||||
// (REQ-UI-BUILD-DISABLED) without any extra work in updateAffordability().
|
||||
QIcon loadBuildingIcon(const QString& path)
|
||||
{
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
{
|
||||
return QIcon();
|
||||
}
|
||||
const QByteArray svg = file.readAll();
|
||||
|
||||
QIcon icon;
|
||||
icon.addPixmap(renderChip(svg), QIcon::Normal);
|
||||
|
||||
// Recolor only the chip background: the first "#rrggbb" fill in the file is the
|
||||
// rounded background rect; the white glyph uses fill="none" and is left alone.
|
||||
QString greyed = QString::fromUtf8(svg);
|
||||
static const QRegularExpression fillPattern(QStringLiteral("fill=\"#[0-9a-fA-F]{6}\""));
|
||||
const QRegularExpressionMatch match = fillPattern.match(greyed);
|
||||
if (match.hasMatch())
|
||||
{
|
||||
greyed.replace(match.capturedStart(), match.capturedLength(),
|
||||
QStringLiteral("fill=\"#5f636e\""));
|
||||
}
|
||||
icon.addPixmap(renderChip(greyed.toUtf8()), QIcon::Disabled);
|
||||
return icon;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BuildButtonGrid::BuildButtonGrid(Simulation* sim, const GameConfig* config,
|
||||
const std::string& iconDir, QWidget* parent)
|
||||
: QWidget(parent)
|
||||
, m_sim(sim)
|
||||
, m_config(config)
|
||||
, m_iconDir(iconDir)
|
||||
{
|
||||
QGridLayout* layout = new QGridLayout(this);
|
||||
layout->setSpacing(4);
|
||||
@@ -53,6 +111,12 @@ BuildButtonGrid::BuildButtonGrid(Simulation* sim, const GameConfig* config, QWid
|
||||
QPushButton* btn = new QPushButton(label, this);
|
||||
btn->setCheckable(true);
|
||||
btn->setFixedHeight(48);
|
||||
// Icon file name matches the building id (REQ-UI-BUILD-GRID); Tunnel Entry's
|
||||
// "tunnel_entry.svg" serves the shared Tunnel button.
|
||||
const QString iconPath = QString::fromStdString(m_iconDir) + "/"
|
||||
+ QString::fromStdString(def.id) + ".svg";
|
||||
btn->setIcon(loadBuildingIcon(iconPath));
|
||||
btn->setIconSize(kIconSize);
|
||||
if (def.tooltip)
|
||||
{
|
||||
btn->setToolTip(QString::fromStdString(*def.tooltip));
|
||||
@@ -76,6 +140,9 @@ BuildButtonGrid::BuildButtonGrid(Simulation* sim, const GameConfig* config, QWid
|
||||
m_deconstructButton = new QPushButton(tr("Deconstruct"), this);
|
||||
m_deconstructButton->setCheckable(true);
|
||||
m_deconstructButton->setFixedHeight(48);
|
||||
m_deconstructButton->setIcon(loadBuildingIcon(
|
||||
QString::fromStdString(m_iconDir) + "/deconstruct.svg"));
|
||||
m_deconstructButton->setIconSize(kIconSize);
|
||||
layout->addWidget(m_deconstructButton, row, col);
|
||||
connect(m_deconstructButton, &QPushButton::clicked, this, [this]() {
|
||||
EventManager::getInstance()->sendEventImmediately(
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QWidget>
|
||||
@@ -28,7 +29,10 @@ class BuildButtonGrid : public QWidget,
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BuildButtonGrid(Simulation* sim, const GameConfig* config, QWidget* parent = nullptr);
|
||||
// iconDir is the directory holding the per-building "<id>.svg" chip icons
|
||||
// (REQ-UI-BUILD-GRID); read from disk at runtime, like the config files.
|
||||
BuildButtonGrid(Simulation* sim, const GameConfig* config,
|
||||
const std::string& iconDir, QWidget* parent = nullptr);
|
||||
~BuildButtonGrid() override;
|
||||
|
||||
void clearActiveButton();
|
||||
@@ -55,6 +59,7 @@ private slots:
|
||||
private:
|
||||
Simulation* m_sim;
|
||||
const GameConfig* m_config;
|
||||
std::string m_iconDir;
|
||||
std::vector<BuildingType> m_types;
|
||||
std::vector<QPushButton*> m_buttons;
|
||||
std::map<BuildingType, int> m_costs;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCloseEvent>
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
@@ -51,8 +52,13 @@ MainWindow::MainWindow(Simulation* sim, const std::string& configDir,
|
||||
sideLayout->setContentsMargins(1, 1, 1, 1);
|
||||
sideLayout->setSpacing(1);
|
||||
|
||||
// Building icons live alongside the config (a sibling of the config dir), read
|
||||
// from disk at runtime the same way visuals.toml is.
|
||||
const std::string iconDir = QDir::cleanPath(
|
||||
QString::fromStdString(m_configDir) + "/../icons/buildings").toStdString();
|
||||
|
||||
m_selectedBuildingPanel = new SelectedBuildingPanel(sim, &sim->getConfig(), m_sidePanel);
|
||||
m_buildButtonGrid = new BuildButtonGrid(sim, &sim->getConfig(), m_sidePanel);
|
||||
m_buildButtonGrid = new BuildButtonGrid(sim, &sim->getConfig(), iconDir, m_sidePanel);
|
||||
m_blueprintPanel = new BlueprintPanel(sim, &sim->getConfig(), m_sidePanel);
|
||||
|
||||
sideLayout->addWidget(m_selectedBuildingPanel, 1);
|
||||
|
||||
Reference in New Issue
Block a user