show recipes visually instead of describing them in text
This commit is contained in:
98
src/ui/RecipeLineRow.h
Normal file
98
src/ui/RecipeLineRow.h
Normal file
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <QString>
|
||||
#include <QWidget>
|
||||
|
||||
#include "BuildingType.h"
|
||||
|
||||
class BuildingIconCache;
|
||||
class ItemIconCache;
|
||||
class QHBoxLayout;
|
||||
|
||||
// One recipe drawn on a line: what it consumes, an arrow, what it produces, and how
|
||||
// long a cycle takes (REQ-UI-RECIPE-SUMMARY). Every place the UI states what something
|
||||
// makes draws this same line, so a recipe reads alike wherever it is shown:
|
||||
//
|
||||
// * beneath the selection button, for the recipe a building is running
|
||||
// (REQ-UI-RECIPE-SUMMARY);
|
||||
// * on a selection dialog's option buttons, under the option's name
|
||||
// (REQ-UI-SELECT-OPTIONS);
|
||||
// * in an item's production tooltip and in the unlock-choice dialog, there led by the
|
||||
// icon of the building that runs the recipe and its name
|
||||
// (REQ-UI-ITEM-TOOLTIP, REQ-DEF-SCHEMATIC-DROP);
|
||||
// * on a module button and in the layout dialog's build cost, where there is a price
|
||||
// and a time but nothing produced (REQ-MOD-UI-DIALOG, REQ-MOD-UI-STATS-PANEL).
|
||||
class RecipeLineRow : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
// One item and how many of it the line states.
|
||||
struct Amount
|
||||
{
|
||||
std::string itemId;
|
||||
int amount = 0;
|
||||
|
||||
bool operator==(const Amount& other) const
|
||||
{
|
||||
return itemId == other.itemId && amount == other.amount;
|
||||
}
|
||||
};
|
||||
|
||||
// What the line says. Everything but the inputs is optional, which is what lets the
|
||||
// one widget serve the summary, the option buttons, the tooltip lines and the cost
|
||||
// lines.
|
||||
struct Spec
|
||||
{
|
||||
// Drawn as a leading chip when the line has to say which building runs the
|
||||
// recipe -- an item may have several producers (REQ-UI-ITEM-TOOLTIP). Unset
|
||||
// wherever the surrounding widget already establishes the building.
|
||||
std::optional<BuildingType> building;
|
||||
// Leading recipe name, for the same reason. Empty where the name is the
|
||||
// caption above the line instead.
|
||||
QString name;
|
||||
std::vector<Amount> inputs;
|
||||
// Empty for a line that produces no item of its own: a ship schematic, or a
|
||||
// module's price. No arrow is drawn then.
|
||||
std::vector<Amount> outputs;
|
||||
std::optional<double> durationSeconds;
|
||||
// True where the time is added to something else rather than being a cycle of
|
||||
// its own, and so reads "+3.0 s" (REQ-MOD-UI-DIALOG).
|
||||
bool durationIsAddition = false;
|
||||
|
||||
bool operator==(const Spec& other) const
|
||||
{
|
||||
return building == other.building && name == other.name
|
||||
&& inputs == other.inputs && outputs == other.outputs
|
||||
&& durationSeconds == other.durationSeconds
|
||||
&& durationIsAddition == other.durationIsAddition;
|
||||
}
|
||||
|
||||
bool isEmpty() const { return inputs.empty() && outputs.empty(); }
|
||||
};
|
||||
|
||||
// Both caches may be null, which leaves the icons off: an item with no square and
|
||||
// no icon falls back to its id, and a building with no chip to its name alone.
|
||||
// Neither is owned.
|
||||
RecipeLineRow(ItemIconCache* itemIcons, BuildingIconCache* buildingIcons,
|
||||
QWidget* parent = nullptr);
|
||||
|
||||
// Hides the row when the spec has nothing to state, which is how a building with no
|
||||
// recipe shows no summary at all (REQ-UI-RECIPE-SUMMARY).
|
||||
void setLine(const Spec& spec);
|
||||
|
||||
private:
|
||||
void rebuild(const Spec& spec);
|
||||
void addAmounts(const std::vector<Amount>& amounts);
|
||||
|
||||
ItemIconCache* m_itemIcons;
|
||||
BuildingIconCache* m_buildingIcons;
|
||||
QHBoxLayout* m_layout;
|
||||
// What the row currently shows, so a refresh at tick rate rebuilds it only when the
|
||||
// recipe actually changed.
|
||||
Spec m_spec;
|
||||
};
|
||||
Reference in New Issue
Block a user