split the selection panel into one card per kind of selection
This commit is contained in:
90
src/ui/selection/MultiBuildingContent.cpp
Normal file
90
src/ui/selection/MultiBuildingContent.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
#include "MultiBuildingContent.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <QLabel>
|
||||
#include <QStringList>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Building.h"
|
||||
#include "ClearBeltControl.h"
|
||||
#include "FactoryQueries.h"
|
||||
#include "GameConfig.h"
|
||||
#include "SelectionNames.h"
|
||||
#include "Simulation.h"
|
||||
|
||||
MultiBuildingContent::MultiBuildingContent(const SelectionContext& context,
|
||||
const SelectionRequest& request,
|
||||
QWidget* parent)
|
||||
: SelectionContent(context, std::nullopt, parent)
|
||||
, m_ids(request.buildings)
|
||||
{
|
||||
m_countsLabel = new QLabel(this);
|
||||
m_totalCostLabel = new QLabel(this);
|
||||
getRuntimeLayout()->addWidget(m_countsLabel);
|
||||
getRuntimeLayout()->addWidget(m_totalCostLabel);
|
||||
|
||||
// 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));
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
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]++;
|
||||
}
|
||||
}
|
||||
|
||||
QStringList lines;
|
||||
int totalCost = 0;
|
||||
for (const std::pair<const BuildingType, int>& entry : counts)
|
||||
{
|
||||
lines << tr("%1 x %2").arg(getBuildingTypeName(entry.first)).arg(entry.second);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
m_countsLabel->setText(lines.join('\n'));
|
||||
m_totalCostLabel->setText(tr("Total: %1 Building Blocks").arg(totalCost));
|
||||
}
|
||||
Reference in New Issue
Block a user