100 lines
3.0 KiB
C++
100 lines
3.0 KiB
C++
#include "MultiBuildingContent.h"
|
|
|
|
#include <map>
|
|
|
|
#include <QVBoxLayout>
|
|
|
|
#include "Building.h"
|
|
#include "BuildingIconCache.h"
|
|
#include "ClearBeltControl.h"
|
|
#include "CountRow.h"
|
|
#include "FactoryQueries.h"
|
|
#include "GameConfig.h"
|
|
#include "SelectionNames.h"
|
|
#include "Simulation.h"
|
|
#include "StatRow.h"
|
|
|
|
namespace
|
|
{
|
|
|
|
// Size the type symbol is drawn at on a count row, matching the card header's chip.
|
|
const int kCountSymbolSizePx = 20;
|
|
|
|
} // namespace
|
|
|
|
|
|
MultiBuildingContent::MultiBuildingContent(const SelectionContext& context,
|
|
const SelectionRequest& request,
|
|
QWidget* parent)
|
|
: SelectionContent(context, std::nullopt, parent)
|
|
, m_ids(request.buildings)
|
|
{
|
|
// The header names the size of the selection instead of an object
|
|
// (REQ-UI-MULTI-SELECTION).
|
|
setIdentity(QPixmap(), tr("%1 buildings").arg(static_cast<int>(m_ids.size())));
|
|
|
|
buildSummary();
|
|
|
|
// A selection holding any belt-subsystem tile can still be cleared as a whole
|
|
// (REQ-UI-BELT-CLEAR), even though the mixture is what kept it from aggregating.
|
|
bool hasBeltTile = false;
|
|
for (BuildingId id : m_ids)
|
|
{
|
|
const Building* building = findBuilding(context.sim->getFactoryState(), id);
|
|
if (building && isBeltSubsystemType(building->type))
|
|
{
|
|
hasBeltTile = true;
|
|
break;
|
|
}
|
|
}
|
|
if (hasBeltTile)
|
|
{
|
|
getRuntimeLayout()->addWidget(new ClearBeltControl(context, m_ids, this));
|
|
}
|
|
}
|
|
|
|
void MultiBuildingContent::buildSummary()
|
|
{
|
|
std::map<BuildingType, int> counts;
|
|
for (BuildingId id : m_ids)
|
|
{
|
|
const Building* building =
|
|
findBuilding(getContext().sim->getFactoryState(), id);
|
|
if (building)
|
|
{
|
|
counts[building->type]++;
|
|
continue;
|
|
}
|
|
const ConstructionSite* site =
|
|
findSite(getContext().sim->getFactoryState(), id);
|
|
if (site)
|
|
{
|
|
counts[site->type]++;
|
|
}
|
|
}
|
|
|
|
int totalCost = 0;
|
|
for (const std::pair<const BuildingType, int>& entry : counts)
|
|
{
|
|
getRuntimeLayout()->addWidget(new CountRow(
|
|
getContext().buildingIcons->getChip(buildingTypeId(entry.first),
|
|
kCountSymbolSizePx),
|
|
getBuildingTypeName(entry.first), entry.second, this));
|
|
|
|
// Only player-placeable buildings count toward the total; the HQ and defence
|
|
// stations are excluded (REQ-UI-MULTI-SELECTION). A construction site counts at
|
|
// its type's full placement cost regardless of progress.
|
|
const BuildingDef* def =
|
|
getContext().config->buildings.findBuildingDef(entry.first);
|
|
if (def && def->playerPlaceable)
|
|
{
|
|
totalCost += def->cost * entry.second;
|
|
}
|
|
}
|
|
|
|
StatRow* totalRow = new StatRow(tr("Total cost"), this);
|
|
totalRow->setValue(QString::number(totalCost));
|
|
totalRow->setValueEmphasized(true);
|
|
getRuntimeLayout()->addWidget(totalRow);
|
|
}
|