Render produced-item icons in recipe dialog and game world
Implements REQ-UI-ITEM-ICON and REQ-UI-RECIPE-ICON. Adds an optional recipes.toml `icon` field (an item id; defaults to the recipe's first output). New ItemIconCache loads per-item SVGs from icons/items and caches pixmaps per target pixel size, shared by: - the Miner/Assembler recipe-selection dialog, which now shows icon-only option buttons (name-caption fallback when no icon file exists), and - GameWorldView belt/port item rendering via a shared drawWorldItem helper (colored-square fallback preserved). Shipyard schematic dialog is unchanged. No icon art is shipped; every path falls back cleanly when an item has no SVG. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7N59FsLA5e2kuVdqe4Uhc
This commit is contained in:
45
src/ui/ItemIconCache.h
Normal file
45
src/ui/ItemIconCache.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QPixmap>
|
||||
#include <QString>
|
||||
|
||||
// Rasterizes and caches per-item icon SVGs (REQ-UI-ITEM-ICON). Item icons are
|
||||
// self-contained, full-color SVGs loaded from a directory, one file per item type
|
||||
// named after the item's id (e.g. "iron_ore.svg"). Shared by the recipe-selection
|
||||
// dialog (REQ-UI-RECIPE-ICON) and the game world's belt/port item rendering so the
|
||||
// rasterization is not duplicated.
|
||||
//
|
||||
// A missing icon file is not an error: hasIcon() returns false for it and the caller
|
||||
// falls back (a colored square in the world, a name caption in the dialog).
|
||||
class ItemIconCache
|
||||
{
|
||||
public:
|
||||
// iconDir is the directory holding the "<item_id>.svg" icon files
|
||||
// (typically "<configDir>/../icons/items").
|
||||
explicit ItemIconCache(const QString& iconDir);
|
||||
|
||||
// True if an icon SVG file exists for the given item id. Loads the file's bytes
|
||||
// on first query and remembers the result (including absence) so repeated calls
|
||||
// are cheap.
|
||||
bool hasIcon(const std::string& itemId);
|
||||
|
||||
// Returns the item's icon rasterized to a transparent sizePx*sizePx pixmap,
|
||||
// cached per (item id, size) so it is rendered once and reused across frames and
|
||||
// only re-rasterized when the target size changes (REQ-UI-ITEM-ICON). Returns a
|
||||
// null pixmap if the item has no icon file (callers should gate on hasIcon()).
|
||||
QPixmap getPixmap(const std::string& itemId, int sizePx);
|
||||
|
||||
private:
|
||||
// Returns the raw SVG bytes for an item id, loading and caching them on first
|
||||
// access. An absent file caches an empty QByteArray so it is not retried.
|
||||
const QByteArray& getSvg(const std::string& itemId);
|
||||
|
||||
QString m_iconDir;
|
||||
std::map<std::string, QByteArray> m_svgById;
|
||||
std::map<std::pair<std::string, int>, QPixmap> m_pixmapCache;
|
||||
};
|
||||
Reference in New Issue
Block a user