85 lines
2.7 KiB
C++
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);
|
|
}
|
|
}
|