extract the world<->widget transform into WorldCoordinates
The nine coordinate helpers on GameWorldView were the first seam of the planned decomposition: stateless math that every draw method, the placement validation, and the belt-drag code reached into private state to get at. WorldCoordinates is an immutable value built from the viewport size, the world height, and the scroll center. It lives in lib/core rather than ui, following BeltDragPath and TunnelCompletion — UI-only helpers kept there so Catch2 can reach them. That is what lets the transform math be unit-tested at all, since the test target links lib only. Rather than leave delegating one-liners behind, the snapshot is threaded through the call graph: paintGL builds one per frame, every world-space draw takes a const WorldCoordinates&, and the screen-space draws (vignettes, replay overlay, debug text) take none. Those methods no longer touch m_scrollXTiles, width(), or height(), which is most of the groundwork for extracting WorldRenderer later. The mouse handlers each take their own snapshot. The snapshot is deliberately not cached in a member: a resize or a scroll would silently invalidate it, and a stale transform surfaces as misaligned hit-testing rather than as a visible failure. widgetToTile and widgetToWorld had the same arithmetic inlined separately; the former now goes through the latter. The architecture doc's coordinate section was already stale — it described a painter.translate approach and a hardcoded tilePx = 20, neither of which was true — so it is rewritten to match the code. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JcReq7hVk4KUPhTDKWAG7K
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user