List unlocked recipes with tooltips in schematic choice dialog

Implement REQ-DEF-SCHEMATIC-DROP: the schematic option's per-option list now
shows the miner/assembler recipes that would newly become implicitly unlocked
(labeled "Unlocks recipes:") rather than a deduplicated list of output items.
Each recipe entry shows the recipe info tooltip (REQ-UI-SELECT-TOOLTIP) on
hover.

- Extract the recipe tooltip builder from RecipeSelectionDialog's anonymous
  namespace into a shared RecipeTooltip.h/.cpp so both dialogs render identical
  tooltips.
- SchematicChoiceOption carries newlyUnlockedRecipeIds (sorted by display name)
  instead of newlyUnlockedItemNames; Simulation collects recipe ids directly.
- SchematicChoiceDialog takes the RecipesConfig to render one label per recipe
  with its tooltip.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VGNNLeFWhVzvxkK9qVXP2K
This commit is contained in:
2026-07-09 13:34:55 +02:00
parent 410c9646b8
commit 44c3c83080
11 changed files with 134 additions and 78 deletions

View File

@@ -3,11 +3,29 @@
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QStringList>
#include <QVBoxLayout>
#include "DisplayName.h"
#include "RecipeTooltip.h"
#include "RecipesConfig.h"
namespace
{
const RecipeDef* findRecipe(const RecipesConfig& recipes, const std::string& id)
{
for (const RecipeDef& recipe : recipes.recipes)
{
if (recipe.id == id) { return &recipe; }
}
return nullptr;
}
} // namespace
SchematicChoiceDialog::SchematicChoiceDialog(
const std::vector<SchematicChoiceOption>& options,
const RecipesConfig& recipes,
QWidget* parent)
: QDialog(parent)
, m_chosenIndex(0)
@@ -70,30 +88,33 @@ SchematicChoiceDialog::SchematicChoiceDialog(
typeLabel->setAlignment(Qt::AlignCenter);
cardLayout->addWidget(typeLabel);
QLabel* unlocksHeaderLabel = new QLabel(tr("Unlocks recipes for:"), card);
QLabel* unlocksHeaderLabel = new QLabel(tr("Unlocks recipes:"), card);
QFont unlocksHeaderFont = unlocksHeaderLabel->font();
unlocksHeaderFont.setBold(true);
unlocksHeaderLabel->setFont(unlocksHeaderFont);
unlocksHeaderLabel->setAlignment(Qt::AlignCenter);
cardLayout->addWidget(unlocksHeaderLabel);
QString unlocksText;
if (option.newlyUnlockedItemNames.empty())
if (option.newlyUnlockedRecipeIds.empty())
{
unlocksText = tr("None");
QLabel* noneLabel = new QLabel(tr("None"), card);
noneLabel->setAlignment(Qt::AlignCenter);
cardLayout->addWidget(noneLabel);
}
else
{
QStringList itemLines;
for (const std::string& itemName : option.newlyUnlockedItemNames)
for (const std::string& recipeId : option.newlyUnlockedRecipeIds)
{
itemLines << QString::fromStdString(itemName);
QLabel* recipeLabel = new QLabel(
QString::fromStdString(toDisplayName(recipeId)), card);
recipeLabel->setAlignment(Qt::AlignCenter);
if (const RecipeDef* def = findRecipe(recipes, recipeId))
{
recipeLabel->setToolTip(buildRecipeTooltip(*def));
}
cardLayout->addWidget(recipeLabel);
}
unlocksText = itemLines.join("\n");
}
QLabel* unlocksLabel = new QLabel(unlocksText, card);
unlocksLabel->setAlignment(Qt::AlignCenter);
cardLayout->addWidget(unlocksLabel);
}
QPushButton* selectButton = new QPushButton(tr("Select"), card);