extract the world<->widget transform into WorldCoordinates

This commit is contained in:
2026-08-05 19:39:47 +02:00
parent 4f7fdb8a4c
commit 2af09d9eb1
8 changed files with 475 additions and 211 deletions

View File

@@ -49,6 +49,7 @@
#include "TickDriver.h"
#include "TunnelCompletion.h"
#include "VisualsConfig.h"
#include "WorldCoordinates.h"
struct Command;
struct ParsedReplay;
@@ -129,28 +130,32 @@ private:
// Used to pre-validate placements whose UI follow-up depends on success.
bool canAfford(BuildingType type) const;
void drawTiles(QPainter& painter);
void drawPortItems(QPainter& painter);
void drawBuildings(QPainter& painter);
void drawSelectionHighlights(QPainter& painter);
void drawCopyConfigFeedback(QPainter& painter);
void drawStations(QPainter& painter);
void drawBeltItems(QPainter& painter);
// World-space drawing takes the frame's transform (see getCoordinates()) rather
// than reaching for the scroll position and viewport size itself; the
// screen-space draws below need neither.
void drawTiles(QPainter& painter, const WorldCoordinates& coordinates);
void drawPortItems(QPainter& painter, const WorldCoordinates& coordinates);
void drawBuildings(QPainter& painter, const WorldCoordinates& coordinates);
void drawSelectionHighlights(QPainter& painter, const WorldCoordinates& coordinates);
void drawCopyConfigFeedback(QPainter& painter, const WorldCoordinates& coordinates);
void drawStations(QPainter& painter, const WorldCoordinates& coordinates);
void drawBeltItems(QPainter& painter, const WorldCoordinates& coordinates);
// 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.
void drawWorldItem(QPainter& painter, const std::string& itemId,
QPointF center, float halfPx);
void drawDebris(QPainter& painter);
void drawShips(QPainter& painter);
void drawHpBar(QPainter& painter, qreal left, qreal top, qreal width,
void drawDebris(QPainter& painter, const WorldCoordinates& coordinates);
void drawShips(QPainter& painter, const WorldCoordinates& coordinates);
void drawHpBar(QPainter& painter, const WorldCoordinates& coordinates,
qreal left, qreal top, qreal width,
float fraction, bool isEnemy);
void drawDebugSensorRanges(QPainter& painter);
void drawDebugTargetLines(QPainter& painter);
void drawDebugSensorRanges(QPainter& painter, const WorldCoordinates& coordinates);
void drawDebugTargetLines(QPainter& painter, const WorldCoordinates& coordinates);
void drawDebugOverlay(QPainter& painter);
void drawBeams(QPainter& painter);
void drawOverlays(QPainter& painter);
void drawBeams(QPainter& painter, const WorldCoordinates& coordinates);
void drawOverlays(QPainter& painter, const WorldCoordinates& coordinates);
void drawScreenSpace(QPainter& painter);
// Vignette-style border shown while the game is paused (speed 0x, REQ-UI-PAUSE-BORDER)
// to make the paused state hard to miss: a black frame whose alpha fades from 50% at
@@ -166,20 +171,16 @@ private:
void drawVignetteBorder(QPainter& painter, const QColor& edgeColor);
void drawReplayOverlay(QPainter& painter);
float getTilePx() const;
float getViewportWidthTiles() const;
// World-X (tiles) at the left edge of the viewport. m_scrollXTiles stores the
// view center; this derives the left edge the world<->widget conversions need.
float getViewLeftTiles() const;
QPointF worldToWidget(QVector2D worldPos) const;
QPointF tileToWidget(QPoint tile) const;
QPoint widgetToTile(QPoint widgetPt) const;
QRectF tileRect(QPoint tile) const;
QRect getViewportRect() const;
// The world <-> widget transform for the current viewport size and scroll
// position. Cheap to build and deliberately not cached: it is a snapshot that
// a resize or a scroll invalidates, so every user takes a fresh one.
WorldCoordinates getCoordinates() const;
// Widget-space rectangle covering a building or construction site's footprint,
// or nullopt if the id resolves to neither. Shared by the selection highlight
// and the copy-settings feedback (REQ-BLD-COPY-CONFIG-FEEDBACK).
std::optional<QRectF> footprintWidgetRect(BuildingId id) const;
std::optional<QRectF> footprintWidgetRect(const WorldCoordinates& coordinates,
BuildingId id) const;
float getAsteroidLeftEdge() const;
float getEnemyStationRightEdge() const;
@@ -193,13 +194,13 @@ private:
// Ids of all buildings and construction sites whose footprint intersects
// the tile box spanned by the two (unordered) corner tiles.
std::vector<BuildingId> buildingsInBox(QPoint cornerA, QPoint cornerB) const;
QVector2D widgetToWorld(QPoint widgetPt) const;
void drawPortGlyph(QPainter& painter, QPoint tile,
Rotation direction, const QColor& color,
void drawPortGlyph(QPainter& painter, const WorldCoordinates& coordinates,
QPoint tile, Rotation direction, const QColor& color,
bool centered);
void drawBuildingGhost(QPainter& painter, BuildingType type,
void drawBuildingGhost(QPainter& painter, const WorldCoordinates& coordinates,
BuildingType type,
QPoint anchorTile, Rotation rotation, bool valid,
bool showPortTargetGlyphs);
@@ -213,7 +214,8 @@ private:
// Draws a building's world icon glyph centered in box, choosing the white or
// dark pre-rendered variant by fill luminance so it stays legible. Returns
// false if the type has no world icon (caller falls back to the text glyph).
bool drawBuildingIcon(QPainter& painter, BuildingType type,
bool drawBuildingIcon(QPainter& painter, const WorldCoordinates& coordinates,
BuildingType type,
const QRectF& box, const QColor& fill) const;
void placeBlueprintAtTile(QPoint center);
@@ -254,7 +256,8 @@ private:
static TunnelLookup makeTunnelLookup(const TunnelTileMap& tunnels);
// Draws the green connection highlight for every selected tunnel end that has a
// matching end (REQ-BLD-TUNNEL-SELECT-HIGHLIGHT).
void drawSelectedTunnelConnections(QPainter& painter);
void drawSelectedTunnelConnections(QPainter& painter,
const WorldCoordinates& coordinates);
// Belt drag placement (REQ-BLD-BELT-DRAG).
// Per-path-tile decision, shared by ghost drawing and release-time placement.