Files
dota_factory/src/ui/RecipeSelectionDialog.cpp

173 lines
4.5 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "RecipeSelectionDialog.h"
#include <cstddef>
#include <QGridLayout>
#include <QPushButton>
#include <QStringList>
#include <QVBoxLayout>
#include "Building.h"
#include "BuildingType.h"
#include "DisplayName.h"
#include "GameConfig.h"
#include "RecipesConfig.h"
#include "ShipsConfig.h"
#include "Simulation.h"
namespace
{
QString itemLine(const std::string& itemId, int amount)
{
return QStringLiteral(" ")
+ QString::fromStdString(toDisplayName(itemId))
+ QStringLiteral(" ×") + QString::number(amount);
}
QString recipeTooltip(const RecipeDef& recipe)
{
QStringList lines;
lines << QObject::tr("Recipe: %1")
.arg(QString::fromStdString(toDisplayName(recipe.id)));
if (recipe.inputs.empty())
{
lines << QObject::tr("Inputs: none");
}
else
{
lines << QObject::tr("Inputs:");
for (const RecipeIngredient& ingredient : recipe.inputs)
{
lines << itemLine(ingredient.item, ingredient.amount);
}
}
lines << QObject::tr("Completion time: %1 s").arg(recipe.durationSeconds);
if (!recipe.outputs.empty())
{
lines << QObject::tr("Produces:");
for (const RecipeOutput& output : recipe.outputs)
{
lines << itemLine(output.item, output.amount);
}
}
return lines.join('\n');
}
QString shipTooltip(const ShipDef& def)
{
const QString name = QString::fromStdString(toDisplayName(def.id));
QStringList lines;
lines << QObject::tr("Ship: %1").arg(name);
if (def.schematic.materials.empty())
{
lines << QObject::tr("Materials: none");
}
else
{
lines << QObject::tr("Materials:");
for (const RecipeIngredient& material : def.schematic.materials)
{
lines << itemLine(material.item, material.amount);
}
}
lines << QObject::tr("Completion time: %1 s")
.arg(def.schematic.productionTimeSeconds);
lines << QObject::tr("Produces: 1 %1").arg(name);
return lines.join('\n');
}
} // namespace
std::vector<RecipeSelectionOption> buildRecipeSelectionOptions(
BuildingType type, Simulation& sim, const GameConfig& config)
{
std::vector<RecipeSelectionOption> options;
options.push_back({std::string(), QObject::tr("(None)"), QString()});
if (type == BuildingType::Shipyard)
{
for (const ShipDef& def : config.ships.ships)
{
if (!sim.isSchematicUnlocked(def.id)) { continue; }
options.push_back({def.id,
QString::fromStdString(toDisplayName(def.id)),
shipTooltip(def)});
}
}
else
{
for (const RecipeDef& recipe : config.recipes.recipes)
{
if (recipe.building != type) { continue; }
if ((type == BuildingType::Miner
|| type == BuildingType::Assembler)
&& !sim.isRecipeUnlocked(recipe.id))
{
continue;
}
options.push_back({recipe.id,
QString::fromStdString(toDisplayName(recipe.id)),
recipeTooltip(recipe)});
}
}
return options;
}
RecipeSelectionDialog::RecipeSelectionDialog(
const std::vector<RecipeSelectionOption>& options,
const QString& title, QWidget* parent)
: QDialog(parent)
{
setWindowTitle(title);
setModal(true);
QVBoxLayout* mainLayout = new QVBoxLayout(this);
QGridLayout* grid = new QGridLayout();
mainLayout->addLayout(grid);
const int columnCount = 2;
for (int i = 0; i < static_cast<int>(options.size()); ++i)
{
const RecipeSelectionOption& option = options[static_cast<std::size_t>(i)];
QPushButton* button = new QPushButton(option.caption, this);
if (!option.tooltip.isEmpty())
{
button->setToolTip(option.tooltip);
}
button->setMinimumHeight(40);
grid->addWidget(button, i / columnCount, i % columnCount);
m_optionIds.push_back(option.id);
const int index = i;
connect(button, &QPushButton::clicked, this, [this, index]()
{
onOptionClicked(index);
});
}
}
std::optional<std::string> RecipeSelectionDialog::getChosenId() const
{
return m_chosenId;
}
void RecipeSelectionDialog::onOptionClicked(int index)
{
if (index >= 0 && index < static_cast<int>(m_optionIds.size()))
{
m_chosenId = m_optionIds[static_cast<std::size_t>(index)];
}
accept();
}