move map pixmap item and metatile rendering from Map to Layout

This commit is contained in:
garak
2023-02-01 10:09:50 -05:00
parent 917e61b98a
commit 2bc51f1c29
27 changed files with 1115 additions and 444 deletions

View File

@@ -16,9 +16,9 @@
#define CONFIG_BACKWARDS_COMPATABILITY
enum MapSortOrder {
Group = 0,
Area = 1,
Layout = 2,
SortByGroup = 0,
SortByArea = 1,
SortByLayout = 2,
};
class KeyValueConfigBase
@@ -51,7 +51,7 @@ public:
virtual void reset() override {
this->recentProject = "";
this->reopenOnLaunch = true;
this->mapSortOrder = MapSortOrder::Group;
this->mapSortOrder = MapSortOrder::SortByGroup;
this->prettyCursors = true;
this->collisionOpacity = 50;
this->metatilesZoom = 30;

View File

@@ -7,8 +7,8 @@
#include <QUndoCommand>
#include <QList>
class MapPixmapItem;
class Map;
class Layout;
class Blockdata;
class Event;
class DraggablePixmapItem;
@@ -43,7 +43,7 @@ enum CommandId {
/// onto the map using the pencil tool.
class PaintMetatile : public QUndoCommand {
public:
PaintMetatile(Map *map,
PaintMetatile(Layout *layout,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr);
@@ -54,7 +54,7 @@ public:
int id() const override { return CommandId::ID_PaintMetatile; }
private:
Map *map;
Layout *layout;
Blockdata newMetatiles;
Blockdata oldMetatiles;
@@ -68,10 +68,10 @@ private:
/// on the metatile collision and elevation.
class PaintCollision : public PaintMetatile {
public:
PaintCollision(Map *map,
PaintCollision(Layout *layout,
const Blockdata &oldCollision, const Blockdata &newCollision,
unsigned actionId, QUndoCommand *parent = nullptr)
: PaintMetatile(map, oldCollision, newCollision, actionId, parent) {
: PaintMetatile(layout, oldCollision, newCollision, actionId, parent) {
setText("Paint Collision");
}
@@ -83,7 +83,7 @@ public:
/// Implements a command to commit paint actions on the map border.
class PaintBorder : public QUndoCommand {
public:
PaintBorder(Map *map,
PaintBorder(Layout *layout,
const Blockdata &oldBorder, const Blockdata &newBorder,
unsigned actionId, QUndoCommand *parent = nullptr);
@@ -94,7 +94,7 @@ public:
int id() const override { return CommandId::ID_PaintBorder; }
private:
Map *map;
Layout *layout;
Blockdata newBorder;
Blockdata oldBorder;
@@ -108,10 +108,10 @@ private:
/// with the bucket tool onto the map.
class BucketFillMetatile : public PaintMetatile {
public:
BucketFillMetatile(Map *map,
BucketFillMetatile(Layout *layout,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr)
: PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) {
: PaintMetatile(layout, oldMetatiles, newMetatiles, actionId, parent) {
setText("Bucket Fill Metatiles");
}
@@ -124,10 +124,10 @@ public:
/// on the metatile collision and elevation.
class BucketFillCollision : public PaintCollision {
public:
BucketFillCollision(Map *map,
BucketFillCollision(Layout *layout,
const Blockdata &oldCollision, const Blockdata &newCollision,
QUndoCommand *parent = nullptr)
: PaintCollision(map, oldCollision, newCollision, -1, parent) {
: PaintCollision(layout, oldCollision, newCollision, -1, parent) {
setText("Flood Fill Collision");
}
@@ -141,10 +141,10 @@ public:
/// with the bucket or paint tool onto the map.
class MagicFillMetatile : public PaintMetatile {
public:
MagicFillMetatile(Map *map,
MagicFillMetatile(Layout *layout,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr)
: PaintMetatile(map, oldMetatiles, newMetatiles, actionId, parent) {
: PaintMetatile(layout, oldMetatiles, newMetatiles, actionId, parent) {
setText("Magic Fill Metatiles");
}
@@ -156,10 +156,10 @@ public:
/// Implements a command to commit magic fill collision actions.
class MagicFillCollision : public PaintCollision {
public:
MagicFillCollision(Map *map,
MagicFillCollision(Layout *layout,
const Blockdata &oldCollision, const Blockdata &newCollision,
QUndoCommand *parent = nullptr)
: PaintCollision(map, oldCollision, newCollision, -1, parent) {
: PaintCollision(layout, oldCollision, newCollision, -1, parent) {
setText("Magic Fill Collision");
}
@@ -172,7 +172,7 @@ public:
/// Implements a command to commit metatile shift actions.
class ShiftMetatiles : public QUndoCommand {
public:
ShiftMetatiles(Map *map,
ShiftMetatiles(Layout *layout,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
unsigned actionId, QUndoCommand *parent = nullptr);
@@ -183,7 +183,7 @@ public:
int id() const override { return CommandId::ID_ShiftMetatiles; }
private:
Map *map;
Layout *layout= nullptr;
Blockdata newMetatiles;
Blockdata oldMetatiles;
@@ -196,7 +196,7 @@ private:
/// Implements a command to commit a map or border resize action.
class ResizeMap : public QUndoCommand {
public:
ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
ResizeMap(Layout *layout, QSize oldMapDimensions, QSize newMapDimensions,
const Blockdata &oldMetatiles, const Blockdata &newMetatiles,
QSize oldBorderDimensions, QSize newBorderDimensions,
const Blockdata &oldBorder, const Blockdata &newBorder,
@@ -209,7 +209,7 @@ public:
int id() const override { return CommandId::ID_ResizeMap; }
private:
Map *map;
Layout *layout = nullptr;
int oldMapWidth;
int oldMapHeight;
@@ -342,6 +342,7 @@ public:
// !TODO
/// Implements a command to commit map edits from the scripting API.
/// The scripting api can edit map/border blocks and dimensions.
class ScriptEditMap : public QUndoCommand {

View File

@@ -25,7 +25,7 @@
// porymap will reflect changes to it, but the value is hard-coded in the projects at the moment
#define BORDER_DISTANCE 7
class MapPixmapItem;
class LayoutPixmapItem;
class CollisionPixmapItem;
class BorderMetatilesPixmapItem;
@@ -58,7 +58,7 @@ public:
QMap<QString, QJsonValue> customHeaders;
MapLayout *layout;
Layout *layout = nullptr;
bool isPersistedToFile = true;
bool hasUnsavedDataChanges = false;
@@ -76,6 +76,7 @@ public:
QList<MapConnection*> connections;
// !TODO
QList<int> metatileLayerOrder;
QList<float> metatileLayerOpacity;
@@ -92,17 +93,19 @@ public:
void modify();
void clean();
QPixmap render(bool ignoreCache = false, MapLayout *fromLayout = nullptr, QRect bounds = QRect(0, 0, -1, -1));
QPixmap render(bool ignoreCache = false, Layout *fromLayout = nullptr, QRect bounds = QRect(0, 0, -1, -1));
QPixmap renderCollision(bool ignoreCache);
QPixmap renderConnection(MapConnection, MapLayout *);
QPixmap renderConnection(MapConnection, Layout *);
QPixmap renderBorder(bool ignoreCache = false);
bool mapBlockChanged(int i, const Blockdata &cache);
bool borderBlockChanged(int i, const Blockdata &cache);
// !TODO: remove
void cacheBlockdata();
void cacheCollision();
/// !TODO: remove this
bool getBlock(int x, int y, Block *out);
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
@@ -133,8 +136,11 @@ public:
void openScript(QString label);
MapPixmapItem *mapItem = nullptr;
void setMapItem(MapPixmapItem *item) { mapItem = item; }
private:
LayoutPixmapItem *mapItem = nullptr;
public:
void setMapItem(LayoutPixmapItem *item) { mapItem = item; }
CollisionPixmapItem *collisionItem = nullptr;
void setCollisionItem(CollisionPixmapItem *item) { collisionItem = item; }

View File

@@ -7,12 +7,17 @@
#include <QImage>
#include <QPixmap>
#include <QString>
#include <QUndoStack>
class Map;
class LayoutPixmapItem;
class CollisionPixmapItem;
class BorderMetatilesPixmapItem;
class MapLayout {
class Layout : public QObject {
Q_OBJECT
public:
MapLayout() {}
Layout() {}
static QString layoutConstantFromName(QString mapName);
@@ -39,8 +44,12 @@ public:
Blockdata blockdata;
QImage image;
QPixmap pixmap;
QImage border_image;
QPixmap border_pixmap;
QImage collision_image;
QPixmap collision_pixmap;
Blockdata border;
Blockdata cached_blockdata;
@@ -53,10 +62,67 @@ public:
QSize borderDimensions;
} lastCommitBlocks; // to track map changes
QList<int> metatileLayerOrder;
QList<float> metatileLayerOpacity;
LayoutPixmapItem *layoutItem = nullptr;
CollisionPixmapItem *collisionItem = nullptr;
BorderMetatilesPixmapItem *borderItem = nullptr;
QUndoStack editHistory;
public:
int getWidth();
int getHeight();
int getBorderWidth();
int getBorderHeight();
bool isWithinBounds(int x, int y) {
return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight());
}
bool getBlock(int x, int y, Block *out);
void setBlock(int x, int y, Block block, bool enableScriptCallback = false);
void setBlockdata(Blockdata blockdata, bool enableScriptCallback = false);
void setDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
void setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata = true, bool enableScriptCallback = false);
void cacheBlockdata();
void cacheCollision();
void clearBorderCache();
void cacheBorder();
bool layoutBlockChanged(int i, const Blockdata &cache);
uint16_t getBorderMetatileId(int x, int y);
void setBorderMetatileId(int x, int y, uint16_t metatileId, bool enableScriptCallback = false);
void setBorderBlockData(Blockdata blockdata, bool enableScriptCallback = false);
void floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void _floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
void magicFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation);
QPixmap render(bool ignoreCache = false, Layout *fromLayout = nullptr, QRect bounds = QRect(0, 0, -1, -1));
QPixmap renderCollision(bool ignoreCache);
// QPixmap renderConnection(MapConnection, Layout *);
QPixmap renderBorder(bool ignoreCache = false);
void setLayoutItem(LayoutPixmapItem *item) { layoutItem = item; }
void setCollisionItem(CollisionPixmapItem *item) { collisionItem = item; }
void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; }
private:
void setNewDimensionsBlockdata(int newWidth, int newHeight);
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
signals:
void layoutChanged(Layout *layout);
void modified();
void layoutDimensionsChanged(const QSize &size);
void needsRedrawing();
};
using MapLayout = Layout;
#endif // MAPLAYOUT_H

View File

@@ -10,7 +10,7 @@ class MapParser
{
public:
MapParser();
MapLayout *parse(QString filepath, bool *error, Project *project);
Layout *parse(QString filepath, bool *error, Project *project);
};
#endif // MAPPARSER_H

View File

@@ -20,7 +20,7 @@
#include "connectionpixmapitem.h"
#include "currentselectedmetatilespixmapitem.h"
#include "collisionpixmapitem.h"
#include "mappixmapitem.h"
#include "layoutpixmapitem.h"
#include "settings.h"
#include "movablerect.h"
#include "cursortilerect.h"
@@ -46,7 +46,7 @@ public:
Project *project = nullptr;
Map *map = nullptr;
MapLayout *layout = nullptr; /* NEW */
Layout *layout = nullptr; /* NEW */
QUndoGroup editGroup; // Manages the undo history for each map
@@ -60,6 +60,7 @@ public:
void closeProject();
bool setMap(QString map_name);
void unsetMap();
Tileset *getCurrentMapPrimaryTileset();
@@ -123,7 +124,7 @@ public:
QGraphicsScene *scene = nullptr;
QGraphicsPixmapItem *current_view = nullptr;
MapPixmapItem *map_item = nullptr;
LayoutPixmapItem *map_item = nullptr;
ConnectionPixmapItem* selected_connection_item = nullptr;
QList<ConnectionPixmapItem*> connection_items;
QGraphicsPathItem *connection_mask = nullptr;
@@ -201,11 +202,11 @@ private:
qint64 *pid = nullptr);
private slots:
void onMapStartPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
void onMapEndPaint(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
void onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
void onMapEndPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
void setSmartPathCursorMode(QGraphicsSceneMouseEvent *event);
void setStraightPathCursorMode(QGraphicsSceneMouseEvent *event);
void mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item);
void mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
void onConnectionMoved(MapConnection*);
void onConnectionItemSelected(ConnectionPixmapItem* connectionItem);

View File

@@ -164,8 +164,13 @@ public slots:
private slots:
void on_action_Open_Project_triggered();
void on_action_Reload_Project_triggered();
void on_mapList_activated(const QModelIndex &index);
void on_areaList_activated(const QModelIndex &index);
void on_layoutList_activated(const QModelIndex &index);
void on_action_Save_Project_triggered();
void openWarpMap(QString map_name, int event_id, Event::Group event_group);
void duplicate();
@@ -229,6 +234,7 @@ private slots:
void on_toolButton_Move_clicked();
void on_toolButton_Shift_clicked();
void on_mapListContainer_currentChanged(int index);
void onOpenMapListContextMenu(const QPoint &point);
void onAddNewMapToGroupClick(QAction* triggeredAction);
void onAddNewMapToAreaClick(QAction* triggeredAction);
@@ -310,6 +316,11 @@ private:
FilterChildrenProxyModel *groupListProxyModel;
MapGroupModel *mapGroupModel;
FilterChildrenProxyModel *layoutListProxyModel;
LayoutTreeModel *layoutTreeModel;
// QStandardItemModel *mapListModel;
// QList<QStandardItem*> *mapGroupItemsList;
// QMap<QString, QModelIndex> mapListIndexes;
@@ -342,10 +353,14 @@ private:
bool newMapDefaultsSet = false;
MapSortOrder mapSortOrder;
enum MapListTab { Groups, Areas, Layouts };
bool tilesetNeedsRedraw = false;
bool setLayout(QString layoutName);
bool setMap(QString, bool scrollTreeView = false);
void unsetMap();
void redrawMapScene();
void refreshMapScene();
bool loadDataStructures();

View File

@@ -56,8 +56,9 @@ public:
QStringList mapLayoutsTable;
QStringList mapLayoutsTableMaster;
QString layoutsLabel;
QMap<QString, MapLayout*> mapLayouts;
QMap<QString, MapLayout*> mapLayoutsMaster;
QMap<QString, QString> layoutIdsToNames;
QMap<QString, Layout*> mapLayouts;
QMap<QString, Layout*> mapLayoutsMaster;
QMap<QString, QString> mapSecToMapHoverName;
QMap<QString, int> mapSectionNameToValue;
QMap<int, QString> mapSectionValueToName;
@@ -115,8 +116,8 @@ public:
QStringList tilesetLabelsOrdered;
Blockdata readBlockdata(QString);
bool loadBlockdata(MapLayout*);
bool loadLayoutBorder(MapLayout*);
bool loadBlockdata(Layout *);
bool loadLayoutBorder(Layout *);
void saveTextFile(QString path, QString text);
void appendTextFile(QString path, QString text);
@@ -128,6 +129,7 @@ public:
QString getProjectTitle();
QString readMapLayoutId(QString map_name);
QString readMapLayoutName(QString mapName);
QString readMapLocation(QString map_name);
bool readWildMonData();
@@ -143,9 +145,9 @@ public:
QSet<QString> getTopLevelMapFields();
bool loadMapData(Map*);
bool readMapLayouts();
bool loadLayout(MapLayout *);
bool loadLayout(Layout *);
bool loadMapLayout(Map*);
bool loadLayoutTilesets(MapLayout*);
bool loadLayoutTilesets(Layout *);
void loadTilesetAssets(Tileset*);
void loadTilesetTiles(Tileset*, QImage);
void loadTilesetMetatiles(Tileset*);

View File

@@ -1,21 +1,21 @@
#ifndef BORDERMETATILESPIXMAPITEM_H
#define BORDERMETATILESPIXMAPITEM_H
#include "map.h"
#include "maplayout.h"
#include "metatileselector.h"
#include <QGraphicsPixmapItem>
class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
BorderMetatilesPixmapItem(Map *map_, MetatileSelector *metatileSelector) {
this->map = map_;
this->map->setBorderItem(this);
BorderMetatilesPixmapItem(Layout *layout, MetatileSelector *metatileSelector) {
this->layout = layout;
this->layout->setBorderItem(this);
this->metatileSelector = metatileSelector;
setAcceptHoverEvents(true);
}
MetatileSelector *metatileSelector;
Map *map;
Layout *layout;
void draw();
signals:
void hoveredBorderMetatileSelectionChanged(uint16_t);

View File

@@ -3,18 +3,18 @@
#include "metatileselector.h"
#include "movementpermissionsselector.h"
#include "mappixmapitem.h"
#include "layoutpixmapitem.h"
#include "map.h"
#include "settings.h"
class CollisionPixmapItem : public MapPixmapItem {
class CollisionPixmapItem : public LayoutPixmapItem {
Q_OBJECT
public:
CollisionPixmapItem(Map *map, MovementPermissionsSelector *movementPermissionsSelector, MetatileSelector *metatileSelector, Settings *settings, qreal *opacity)
: MapPixmapItem(map, metatileSelector, settings){
CollisionPixmapItem(Layout *layout, MovementPermissionsSelector *movementPermissionsSelector, MetatileSelector *metatileSelector, Settings *settings, qreal *opacity)
: LayoutPixmapItem(layout, metatileSelector, settings){
this->movementPermissionsSelector = movementPermissionsSelector;
this->opacity = opacity;
map->setCollisionItem(this);
layout->setCollisionItem(this);
}
MovementPermissionsSelector *movementPermissionsSelector;
qreal *opacity;

View File

@@ -1,12 +1,13 @@
#ifndef MAPPIXMAPITEM_H
#define MAPPIXMAPITEM_H
#include "map.h"
#include "settings.h"
#include "metatileselector.h"
#include <QGraphicsPixmapItem>
class MapPixmapItem : public QObject, public QGraphicsPixmapItem {
class Layout;
class LayoutPixmapItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
private:
@@ -18,37 +19,49 @@ public:
Metatiles,
EventObjects
};
MapPixmapItem(Map *map_, MetatileSelector *metatileSelector, Settings *settings) {
this->map = map_;
this->map->setMapItem(this);
LayoutPixmapItem(Layout *layout, MetatileSelector *metatileSelector, Settings *settings) {
this->layout = layout;
// this->map->setMapItem(this);
this->metatileSelector = metatileSelector;
this->settings = settings;
this->paintingMode = PaintMode::Metatiles;
this->lockedAxis = MapPixmapItem::Axis::None;
this->lockedAxis = LayoutPixmapItem::Axis::None;
this->prevStraightPathState = false;
setAcceptHoverEvents(true);
}
MapPixmapItem::PaintMode paintingMode;
Map *map;
LayoutPixmapItem::PaintMode paintingMode;
Layout *layout;
MetatileSelector *metatileSelector;
Settings *settings;
bool active;
bool has_mouse = false;
bool right_click;
int paint_tile_initial_x;
int paint_tile_initial_y;
bool prevStraightPathState;
int straight_path_initial_x;
int straight_path_initial_y;
QPoint metatilePos;
enum Axis {
None = 0,
X,
Y
};
MapPixmapItem::Axis lockedAxis;
LayoutPixmapItem::Axis lockedAxis;
QPoint selection_origin;
QList<QPoint> selection;
virtual void paint(QGraphicsSceneMouseEvent*);
virtual void floodFill(QGraphicsSceneMouseEvent*);
virtual void magicFill(QGraphicsSceneMouseEvent*);
@@ -70,11 +83,13 @@ public:
QList<CollisionSelectionItem> selectedCollisions,
bool fromScriptCall = false);
void floodFillSmartPath(int initialX, int initialY, bool fromScriptCall = false);
virtual void pick(QGraphicsSceneMouseEvent*);
virtual void select(QGraphicsSceneMouseEvent*);
virtual void shift(QGraphicsSceneMouseEvent*);
void shift(int xDelta, int yDelta, bool fromScriptCall = false);
virtual void draw(bool ignoreCache = false);
void updateMetatileSelection(QGraphicsSceneMouseEvent *event);
void paintNormal(int x, int y, bool fromScriptCall = false);
void lockNondominantAxis(QGraphicsSceneMouseEvent *event);
@@ -87,9 +102,9 @@ private:
unsigned actionId_ = 0;
signals:
void startPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void endPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void mouseEvent(QGraphicsSceneMouseEvent *, MapPixmapItem *);
void startPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
void endPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
void mouseEvent(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
void hoveredMapMetatileChanged(const QPoint &pos);
void hoveredMapMetatileCleared();

View File

@@ -46,10 +46,40 @@ private:
QString openMap;
// QIcon *mapIcon = nullptr;
// QIcon *mapEditedIcon = nullptr;
// QIcon *mapOpenedIcon = nullptr;
// QIcon *mapFolderIcon = nullptr;
signals:
void edited();
};
class LayoutTreeModel : public QStandardItemModel {
Q_OBJECT
public:
LayoutTreeModel(Project *project, QObject *parent = nullptr);
~LayoutTreeModel() {}
QVariant data(const QModelIndex &index, int role) const override;
public:
void setLayout(QString layoutName) { this->openLayout = layoutName; }
QStandardItem *createLayoutItem(QString layoutName);
QStandardItem *createMapItem(QString mapName);
QStandardItem *getItem(const QModelIndex &index) const;
QModelIndex indexOfLayout(QString layoutName);
void initialize();
private:
Project *project;
QStandardItem *root = nullptr;
QMap<QString, QStandardItem *> layoutItems;
QMap<QString, QStandardItem *> mapItems;
QString openLayout;
signals:
void edited();

View File

@@ -24,7 +24,7 @@ public:
QString layoutId;
void init();
void init(MapSortOrder type, QVariant data);
void init(MapLayout *);
void init(Layout *);
static void setDefaultSettings(Project *project);
signals:
@@ -37,7 +37,7 @@ private:
bool checkNewMapGroup();
void saveSettings();
void useLayout(QString layoutId);
void useLayoutSettings(MapLayout *mapLayout);
void useLayoutSettings(Layout *mapLayout);
struct Settings {
QString group;