Files
dota_factory/src/ui/selection/ItemChipRow.cpp

85 lines
2.7 KiB
C++

#include "ItemChipRow.h"
#include <QGridLayout>
#include "ItemChip.h"
#include "ItemIconCache.h"
namespace
{
// Size the item's colored square is drawn at inside a chip, in device-independent
// pixels. Larger than the artwork it carries, which the square insets (REQ-UI-ITEM-ICON).
const int kChipIconSizePx = 22;
// Chips per row. Two fit the panel's capped width side by side; a third would force the
// counts to shrink.
const int kChipsPerRow = 2;
} // namespace
ItemChipRow::ItemChipRow(const SelectionContext& context, QWidget* parent)
: QWidget(parent)
, m_context(context)
{
m_layout = new QGridLayout(this);
m_layout->setContentsMargins(0, 0, 0, 0);
m_layout->setSpacing(4);
}
void ItemChipRow::setEntries(const std::vector<Entry>& entries)
{
std::vector<std::string> itemIds;
itemIds.reserve(entries.size());
for (const Entry& entry : entries)
{
itemIds.push_back(entry.itemId);
}
// Only the set of items changing is a structural change; the counts change every
// tick and must not cost a widget rebuild.
if (itemIds != m_itemIds)
{
m_itemIds = std::move(itemIds);
rebuildChips(entries);
}
for (std::size_t index = 0; index < entries.size(); ++index)
{
m_chips[index]->setCount(entries[index].countText);
m_chips[index]->setSubLine(entries[index].subLine);
}
setVisible(!entries.empty());
}
void ItemChipRow::rebuildChips(const std::vector<Entry>& entries)
{
for (ItemChip* chip : m_chips)
{
m_layout->removeWidget(chip);
chip->deleteLater();
}
m_chips.clear();
for (std::size_t index = 0; index < entries.size(); ++index)
{
const std::string& itemId = entries[index].itemId;
// The item's icon on its colored square (REQ-UI-ITEM-ICON). A missing icon file
// is not an error: the chip then carries the square alone, and only an item with
// no square either leaves the chip laid out around its count alone.
const QPixmap icon =
m_context.itemIcons->getSquarePixmap(itemId, kChipIconSizePx);
ItemChip* chip = new ItemChip(m_context, itemId, icon, this);
m_layout->addWidget(chip, static_cast<int>(index) / kChipsPerRow,
static_cast<int>(index) % kChipsPerRow);
// Shown right away, because the panel measures itself as soon as this returns. A
// widget created under an already-visible parent starts hidden, and a layout
// treats a hidden item as empty, so an unshown chip would add nothing to the
// size hint and the panel would be fitted to a buffer section that looks empty.
chip->show();
m_chips.push_back(chip);
}
}