draw boxes around item icons

This commit is contained in:
2026-08-09 21:20:47 +02:00
parent 09858f4b62
commit 5794a51c9a
3 changed files with 33 additions and 24 deletions

View File

@@ -520,8 +520,8 @@ void WorldRenderer::drawPortItems(QPainter& painter, const WorldCoordinates& coo
}
}
// Shared with belt items (REQ-GW-TILE-SIZE): a half-tile item icon, or the
// colored-square fallback (REQ-UI-ITEM-ICON), via the same draw path.
// Shared with belt items (REQ-GW-TILE-SIZE): a half-tile colored square carrying the
// item's icon (REQ-UI-ITEM-ICON), via the same draw path.
const std::function<void(const ItemType&, QPointF)> drawItem =
[&](const ItemType& type, QPointF worldPos)
{
@@ -544,25 +544,34 @@ void WorldRenderer::drawWorldItem(QPainter& painter, const std::string& itemId,
const QRectF itemRect(center.x() - halfPx, center.y() - halfPx,
halfPx * 2, halfPx * 2);
// Prefer the item's icon (REQ-UI-ITEM-ICON); it is rasterized once at the current
// half-tile pixel size and cached, so this is a plain pixmap blit per frame.
if (m_itemIcons && m_itemIcons->hasIcon(itemId))
{
int sizePx = qRound(static_cast<qreal>(halfPx * 2.0f));
if (sizePx < 1) { sizePx = 1; }
painter.drawPixmap(itemRect, m_itemIcons->getPixmap(itemId, sizePx),
QRectF(0, 0, sizePx, sizePx));
return;
}
// Fallback: the colored square from visuals.toml (REQ-GW-TILE-SIZE).
// The colored square from visuals.toml (REQ-GW-TILE-SIZE) backs every item, icon or
// not: it is what gives the item contrast against the tile beneath it, and its dark
// outline is what separates neighbouring items where they overlap on a belt.
const std::map<std::string, ItemVisuals>::const_iterator it =
m_visuals.items.find(itemId);
if (it == m_visuals.items.end()) { return; }
painter.fillRect(itemRect, it->second.fill);
painter.setPen(QPen(it->second.outline, 1));
painter.setBrush(Qt::NoBrush);
painter.drawRect(itemRect);
if (it != m_visuals.items.end())
{
painter.fillRect(itemRect, it->second.fill);
painter.setPen(QPen(it->second.outline, 1));
painter.setBrush(Qt::NoBrush);
painter.drawRect(itemRect);
}
if (!m_itemIcons || !m_itemIcons->hasIcon(itemId)) { return; }
// The icon goes on top, inset so a frame of the square's color stays visible all
// around it (REQ-UI-ITEM-ICON). The inset is needed because each icon's viewBox is
// cropped tight to its artwork: drawn at the full rect, a solid icon would cover the
// square entirely. It is rasterized once at the inset pixel size and cached, so this
// is a plain pixmap blit per frame.
constexpr double kIconInsetFraction = 0.15;
const double inset = kIconInsetFraction * static_cast<double>(halfPx * 2.0f);
const QRectF iconRect = itemRect.adjusted(inset, inset, -inset, -inset);
int sizePx = qRound(iconRect.width());
if (sizePx < 1) { sizePx = 1; }
painter.drawPixmap(iconRect, m_itemIcons->getPixmap(itemId, sizePx),
QRectF(0, 0, sizePx, sizePx));
}
void WorldRenderer::drawBeltItems(QPainter& painter, const WorldCoordinates& coordinates,

View File

@@ -113,9 +113,9 @@ private:
void drawOverlays(QPainter& painter, const WorldCoordinates& coordinates,
const WorldRenderFrame& frame);
// Draws a single item centered at widget-space `center`, spanning `halfPx` in
// each direction (a half-tile). Uses the item's icon when one exists
// (REQ-UI-ITEM-ICON), otherwise falls back to the colored square from
// visuals.toml. Shared by drawBeltItems and drawPortItems.
// each direction (a half-tile): the colored square from visuals.toml, carrying
// the item's icon inset on top of it when one exists (REQ-UI-ITEM-ICON).
// Shared by drawBeltItems and drawPortItems.
void drawWorldItem(QPainter& painter, const std::string& itemId,
QPointF center, float halfPx);
void drawPortGlyph(QPainter& painter, const WorldCoordinates& coordinates,