begin refactoring undo history
This commit is contained in:
parent
90aba5e433
commit
fb1eec1755
16 changed files with 558 additions and 174 deletions
|
@ -2711,8 +2711,6 @@
|
|||
<property name="title">
|
||||
<string>Edit</string>
|
||||
</property>
|
||||
<addaction name="actionUndo"/>
|
||||
<addaction name="actionRedo"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuView">
|
||||
<property name="title">
|
||||
|
@ -2832,25 +2830,6 @@
|
|||
<string>Ctrl+N</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionUndo">
|
||||
<property name="text">
|
||||
<string>Undo</string>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Z</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionRedo">
|
||||
<property name="text">
|
||||
<string>Redo</string>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font/>
|
||||
</property>
|
||||
<property name="shortcut">
|
||||
<string>Ctrl+Y</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="action_Export_Map_Image">
|
||||
<property name="text">
|
||||
<string>Export Map Image...</string>
|
||||
|
|
168
include/core/editcommands.h
Normal file
168
include/core/editcommands.h
Normal file
|
@ -0,0 +1,168 @@
|
|||
#ifndef EDITCOMMANDS_H
|
||||
#define EDITCOMMANDS_H
|
||||
|
||||
#include <QUndoCommand>
|
||||
|
||||
class MapPixmapItem;
|
||||
class Map;
|
||||
class Blockdata;
|
||||
|
||||
enum CommandId {
|
||||
ID_PaintMetatile, // - done
|
||||
ID_BucketFillMetatile, // - done
|
||||
ID_MagicFillMetatile, // - done
|
||||
ID_ShiftMetatiles, // - done
|
||||
ID_ResizeMap, // - done
|
||||
ID_PaintBorder, // - done
|
||||
ID_EventMove, // -
|
||||
ID_EventCreate, // -
|
||||
ID_EventDelete, // -
|
||||
ID_EventSetData, // -
|
||||
// Tileset editor history commands
|
||||
// Region map editor history commands
|
||||
};
|
||||
|
||||
|
||||
|
||||
/// TODO
|
||||
class PaintMetatile : public QUndoCommand {
|
||||
public:
|
||||
PaintMetatile(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent = nullptr);
|
||||
~PaintMetatile();
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
bool mergeWith(const QUndoCommand *command) override;
|
||||
int id() const override { return CommandId::ID_PaintMetatile; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
|
||||
Blockdata *newMetatiles;
|
||||
Blockdata *oldMetatiles;
|
||||
|
||||
unsigned eventId;
|
||||
};
|
||||
|
||||
|
||||
|
||||
///
|
||||
class PaintBorder : public QUndoCommand {
|
||||
public:
|
||||
PaintBorder(Map *map,
|
||||
Blockdata *oldBorder, Blockdata *newBorder,
|
||||
unsigned eventId, QUndoCommand *parent = nullptr);
|
||||
~PaintBorder();
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
bool mergeWith(const QUndoCommand *command) override { return false; };
|
||||
int id() const override { return CommandId::ID_PaintBorder; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
|
||||
Blockdata *newBorder;
|
||||
Blockdata *oldBorder;
|
||||
|
||||
unsigned eventId;
|
||||
};
|
||||
|
||||
|
||||
|
||||
///
|
||||
class BucketFillMetatile : public PaintMetatile {
|
||||
public:
|
||||
BucketFillMetatile(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent = nullptr);
|
||||
~BucketFillMetatile();
|
||||
|
||||
bool mergeWith(const QUndoCommand *command) override { return false; }
|
||||
int id() const override { return CommandId::ID_BucketFillMetatile; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
///
|
||||
class MagicFillMetatile : public PaintMetatile {
|
||||
public:
|
||||
MagicFillMetatile(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent = nullptr);
|
||||
~MagicFillMetatile();
|
||||
|
||||
bool mergeWith(const QUndoCommand *command) override { return false; }
|
||||
int id() const override { return CommandId::ID_BucketFillMetatile; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
class ShiftMetatiles : public QUndoCommand {
|
||||
public:
|
||||
ShiftMetatiles(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent = nullptr);
|
||||
~ShiftMetatiles();
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
bool mergeWith(const QUndoCommand *command) override;
|
||||
int id() const override { return CommandId::ID_ShiftMetatiles; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
|
||||
Blockdata *newMetatiles;
|
||||
Blockdata *oldMetatiles;
|
||||
|
||||
unsigned eventId;
|
||||
bool mergeable = false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
///
|
||||
class ResizeMap : public QUndoCommand {
|
||||
public:
|
||||
ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||
Blockdata *oldBorder, Blockdata *newBorder,
|
||||
QUndoCommand *parent = nullptr);
|
||||
~ResizeMap();
|
||||
|
||||
void undo() override;
|
||||
void redo() override;
|
||||
|
||||
bool mergeWith(const QUndoCommand *command) override { return false; }
|
||||
int id() const override { return CommandId::ID_ResizeMap; }
|
||||
|
||||
private:
|
||||
Map *map;
|
||||
|
||||
int oldMapWidth;
|
||||
int oldMapHeight;
|
||||
int newMapWidth;
|
||||
int newMapHeight;
|
||||
|
||||
int oldBorderWidth;
|
||||
int oldBorderHeight;
|
||||
int newBorderWidth;
|
||||
int newBorderHeight;
|
||||
|
||||
Blockdata *newMetatiles;
|
||||
Blockdata *oldMetatiles;
|
||||
|
||||
Blockdata *newBorder;
|
||||
Blockdata *oldBorder;
|
||||
};
|
||||
|
||||
#endif // EDITCOMMANDS_H
|
|
@ -9,6 +9,7 @@
|
|||
#include "tileset.h"
|
||||
#include "event.h"
|
||||
|
||||
#include <QUndoStack>
|
||||
#include <QPixmap>
|
||||
#include <QObject>
|
||||
#include <QGraphicsPixmapItem>
|
||||
|
@ -21,6 +22,9 @@
|
|||
// 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 BorderMetatilesPixmapItem;
|
||||
|
||||
class Map : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -80,9 +84,6 @@ public:
|
|||
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);
|
||||
void undo();
|
||||
void redo();
|
||||
void commit();
|
||||
QList<Event*> getAllEvents();
|
||||
void removeEvent(Event*);
|
||||
void addEvent(Event*);
|
||||
|
@ -93,6 +94,16 @@ public:
|
|||
void cacheBorder();
|
||||
bool hasUnsavedChanges();
|
||||
|
||||
MapPixmapItem *mapItem = nullptr;
|
||||
void setMapItem(MapPixmapItem *item) { mapItem = item; }
|
||||
|
||||
BorderMetatilesPixmapItem *borderItem = nullptr;
|
||||
void setBorderItem(BorderMetatilesPixmapItem *item) { borderItem = item; }
|
||||
|
||||
void commit(); // TODO: delete this
|
||||
|
||||
QUndoStack editHistory;
|
||||
|
||||
private:
|
||||
void setNewDimensionsBlockdata(int newWidth, int newHeight);
|
||||
void setNewBorderDimensionsBlockdata(int newWidth, int newHeight);
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
QString tileset_secondary_label;
|
||||
Tileset *tileset_primary = nullptr;
|
||||
Tileset *tileset_secondary = nullptr;
|
||||
Blockdata* blockdata = nullptr;
|
||||
Blockdata *blockdata = nullptr;
|
||||
QImage border_image;
|
||||
QPixmap border_pixmap;
|
||||
Blockdata *border = nullptr;
|
||||
|
|
|
@ -16,7 +16,7 @@ struct WildMonInfo {
|
|||
};
|
||||
|
||||
struct WildPokemonHeader {
|
||||
QMap<QString, WildMonInfo> wildMons;
|
||||
QHash<QString, WildMonInfo> wildMons;
|
||||
};
|
||||
|
||||
struct EncounterField {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QComboBox>
|
||||
#include <QCheckBox>
|
||||
#include <QCursor>
|
||||
#include <QUndoGroup>
|
||||
|
||||
#include "mapconnection.h"
|
||||
#include "metatileselector.h"
|
||||
|
@ -45,8 +46,6 @@ public:
|
|||
Settings *settings;
|
||||
void saveProject();
|
||||
void save();
|
||||
void undo();
|
||||
void redo();
|
||||
void closeProject();
|
||||
bool setMap(QString map_name);
|
||||
void saveUiFields();
|
||||
|
@ -144,6 +143,8 @@ public:
|
|||
|
||||
int getBorderDrawDistance(int dimension);
|
||||
|
||||
QUndoGroup editGroup; // Manages the undo history for each map
|
||||
|
||||
private:
|
||||
void setConnectionItemsVisible(bool);
|
||||
void setBorderItemsVisible(bool, qreal = 1);
|
||||
|
|
|
@ -121,8 +121,6 @@ private slots:
|
|||
void on_action_Save_Project_triggered();
|
||||
void openWarpMap(QString map_name, QString warp_num);
|
||||
|
||||
void undo();
|
||||
void redo();
|
||||
void duplicate();
|
||||
|
||||
void openInTextEditor();
|
||||
|
@ -157,9 +155,6 @@ private slots:
|
|||
|
||||
void on_mainTabBar_tabBarClicked(int index);
|
||||
|
||||
void on_actionUndo_triggered();
|
||||
void on_actionRedo_triggered();
|
||||
|
||||
void on_actionZoom_In_triggered();
|
||||
void on_actionZoom_Out_triggered();
|
||||
void on_actionBetter_Cursors_triggered();
|
||||
|
@ -252,6 +247,9 @@ private:
|
|||
QIcon* mapEditedIcon;
|
||||
QIcon* mapOpenedIcon;
|
||||
|
||||
QAction *undoAction;
|
||||
QAction *redoAction;
|
||||
|
||||
QWidget *eventTabObjectWidget;
|
||||
QWidget *eventTabWarpWidget;
|
||||
QWidget *eventTabTriggerWidget;
|
||||
|
|
|
@ -10,11 +10,12 @@ class BorderMetatilesPixmapItem : public QObject, public QGraphicsPixmapItem {
|
|||
public:
|
||||
BorderMetatilesPixmapItem(Map *map_, MetatileSelector *metatileSelector) {
|
||||
this->map = map_;
|
||||
this->map->setBorderItem(this);
|
||||
this->metatileSelector = metatileSelector;
|
||||
setAcceptHoverEvents(true);
|
||||
}
|
||||
MetatileSelector *metatileSelector;
|
||||
Map* map;
|
||||
Map *map;
|
||||
void draw();
|
||||
signals:
|
||||
void borderMetatilesChanged();
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
};
|
||||
MapPixmapItem(Map *map_, MetatileSelector *metatileSelector, Settings *settings) {
|
||||
this->map = map_;
|
||||
this->map->setMapItem(this);
|
||||
this->metatileSelector = metatileSelector;
|
||||
this->settings = settings;
|
||||
this->paintingMode = PaintMode::Metatiles;
|
||||
|
@ -68,6 +69,8 @@ private:
|
|||
void paintSmartPath(int x, int y, bool fromScriptCall = false);
|
||||
static QList<int> smartPathTable;
|
||||
|
||||
unsigned eventId_ = 0;
|
||||
|
||||
signals:
|
||||
void startPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
|
||||
void endPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *);
|
||||
|
|
|
@ -30,6 +30,7 @@ SOURCES += src/core/block.cpp \
|
|||
src/core/tileset.cpp \
|
||||
src/core/regionmap.cpp \
|
||||
src/core/wildmoninfo.cpp \
|
||||
src/core/editcommands.cpp \
|
||||
src/lib/orderedjson.cpp \
|
||||
src/mainwindow_scriptapi.cpp \
|
||||
src/ui/aboutporymap.cpp \
|
||||
|
@ -95,6 +96,7 @@ HEADERS += include/core/block.h \
|
|||
include/core/tileset.h \
|
||||
include/core/regionmap.h \
|
||||
include/core/wildmoninfo.h \
|
||||
include/core/editcommands.h \
|
||||
include/lib/orderedmap.h \
|
||||
include/lib/orderedjson.h \
|
||||
include/ui/aboutporymap.h \
|
||||
|
|
268
src/core/editcommands.cpp
Normal file
268
src/core/editcommands.cpp
Normal file
|
@ -0,0 +1,268 @@
|
|||
#include "editcommands.h"
|
||||
#include "mappixmapitem.h"
|
||||
#include "bordermetatilespixmapitem.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
|
||||
PaintMetatile::PaintMetatile(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Paint Metatiles");
|
||||
|
||||
this->map = map;
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
this->newMetatiles = newMetatiles;
|
||||
|
||||
this->eventId = eventId;
|
||||
}
|
||||
|
||||
PaintMetatile::~PaintMetatile() {
|
||||
if (newMetatiles) delete newMetatiles;
|
||||
if (oldMetatiles) delete oldMetatiles;
|
||||
}
|
||||
|
||||
void PaintMetatile::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->blockdata) {
|
||||
map->layout->blockdata->copyFrom(newMetatiles);
|
||||
}
|
||||
|
||||
map->mapItem->draw();
|
||||
}
|
||||
|
||||
void PaintMetatile::undo() {
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->blockdata) {
|
||||
map->layout->blockdata->copyFrom(oldMetatiles);
|
||||
}
|
||||
|
||||
map->mapItem->draw();
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
|
||||
bool PaintMetatile::mergeWith(const QUndoCommand *command) {
|
||||
// does an up merge
|
||||
const PaintMetatile *other = static_cast<const PaintMetatile *>(command);
|
||||
|
||||
if (this->map != other->map)
|
||||
return false;
|
||||
|
||||
if (eventId != other->eventId)
|
||||
return false;
|
||||
|
||||
this->newMetatiles->copyFrom(other->newMetatiles);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
PaintBorder::PaintBorder(Map *map,
|
||||
Blockdata *oldBorder, Blockdata *newBorder,
|
||||
unsigned eventId, QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Paint Border");
|
||||
|
||||
this->map = map;
|
||||
this->oldBorder = oldBorder;
|
||||
this->newBorder = newBorder;
|
||||
|
||||
this->eventId = eventId;
|
||||
}
|
||||
|
||||
PaintBorder::~PaintBorder() {
|
||||
if (newBorder) delete newBorder;
|
||||
if (oldBorder) delete oldBorder;
|
||||
}
|
||||
|
||||
void PaintBorder::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->border) {
|
||||
map->layout->border->copyFrom(newBorder);
|
||||
}
|
||||
|
||||
map->borderItem->draw();
|
||||
}
|
||||
|
||||
void PaintBorder::undo() {
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->border) {
|
||||
map->layout->border->copyFrom(oldBorder);
|
||||
}
|
||||
|
||||
map->borderItem->draw();
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
BucketFillMetatile::BucketFillMetatile(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent)
|
||||
: PaintMetatile(map, oldMetatiles, newMetatiles, eventId, parent) {
|
||||
setText("Bucket Fill Metatiles");
|
||||
}
|
||||
|
||||
BucketFillMetatile::~BucketFillMetatile() {
|
||||
PaintMetatile::~PaintMetatile();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
MagicFillMetatile::MagicFillMetatile(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent)
|
||||
: PaintMetatile(map, oldMetatiles, newMetatiles, eventId, parent) {
|
||||
setText("Magic Fill Metatiles");
|
||||
}
|
||||
|
||||
MagicFillMetatile::~MagicFillMetatile() {
|
||||
PaintMetatile::~PaintMetatile();
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
ShiftMetatiles::ShiftMetatiles(Map *map,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
unsigned eventId, QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Shift Metatiles");
|
||||
|
||||
this->map = map;
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
this->newMetatiles = newMetatiles;
|
||||
|
||||
this->eventId = eventId;
|
||||
}
|
||||
|
||||
ShiftMetatiles::~ShiftMetatiles() {
|
||||
if (newMetatiles) delete newMetatiles;
|
||||
if (oldMetatiles) delete oldMetatiles;
|
||||
}
|
||||
|
||||
void ShiftMetatiles::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->blockdata) {
|
||||
map->layout->blockdata->copyFrom(newMetatiles);
|
||||
}
|
||||
|
||||
map->mapItem->draw(true);
|
||||
}
|
||||
|
||||
void ShiftMetatiles::undo() {
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->blockdata) {
|
||||
map->layout->blockdata->copyFrom(oldMetatiles);
|
||||
}
|
||||
|
||||
map->mapItem->draw(true);
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
|
||||
bool ShiftMetatiles::mergeWith(const QUndoCommand *command) {
|
||||
const ShiftMetatiles *other = static_cast<const ShiftMetatiles *>(command);
|
||||
|
||||
if (this->map != other->map)
|
||||
return false;
|
||||
|
||||
if (eventId != other->eventId)
|
||||
return false;
|
||||
|
||||
this->newMetatiles->copyFrom(other->newMetatiles);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
************************************************************************
|
||||
******************************************************************************/
|
||||
|
||||
ResizeMap::ResizeMap(Map *map, QSize oldMapDimensions, QSize newMapDimensions,
|
||||
Blockdata *oldMetatiles, Blockdata *newMetatiles,
|
||||
QSize oldBorderDimensions, QSize newBorderDimensions,
|
||||
Blockdata *oldBorder, Blockdata *newBorder,
|
||||
QUndoCommand *parent) : QUndoCommand(parent) {
|
||||
setText("Resize Map");
|
||||
|
||||
this->map = map;
|
||||
|
||||
this->oldMapWidth = oldMapDimensions.width();
|
||||
this->oldMapHeight = oldMapDimensions.height();
|
||||
|
||||
this->newMapWidth = newMapDimensions.width();
|
||||
this->newMapHeight = newMapDimensions.height();
|
||||
|
||||
this->oldMetatiles = oldMetatiles;
|
||||
this->newMetatiles = newMetatiles;
|
||||
|
||||
this->oldBorderWidth = oldBorderDimensions.width();
|
||||
this->oldBorderHeight = oldBorderDimensions.height();
|
||||
|
||||
this->newBorderWidth = newBorderDimensions.width();
|
||||
this->newBorderHeight = newBorderDimensions.height();
|
||||
|
||||
this->oldBorder = oldBorder;
|
||||
this->newBorder = newBorder;
|
||||
}
|
||||
|
||||
ResizeMap::~ResizeMap() {
|
||||
if (newMetatiles) delete newMetatiles;
|
||||
if (oldMetatiles) delete oldMetatiles;
|
||||
}
|
||||
|
||||
void ResizeMap::redo() {
|
||||
QUndoCommand::redo();
|
||||
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->blockdata) {
|
||||
map->layout->blockdata->copyFrom(newMetatiles);
|
||||
map->setDimensions(newMapWidth, newMapHeight, false);
|
||||
}
|
||||
|
||||
if (map->layout->border) {
|
||||
map->layout->border->copyFrom(newBorder);
|
||||
map->setBorderDimensions(newBorderWidth, newBorderHeight, false);
|
||||
}
|
||||
}
|
||||
|
||||
void ResizeMap::undo() {
|
||||
if (!map) return;
|
||||
|
||||
if (map->layout->blockdata) {
|
||||
map->layout->blockdata->copyFrom(oldMetatiles);
|
||||
map->setDimensions(oldMapWidth, oldMapHeight, false);
|
||||
}
|
||||
|
||||
if (map->layout->border) {
|
||||
map->layout->border->copyFrom(oldBorder);
|
||||
map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false);
|
||||
}
|
||||
|
||||
QUndoCommand::undo();
|
||||
}
|
||||
|
||||
|
|
@ -4,6 +4,8 @@
|
|||
#include "imageproviders.h"
|
||||
#include "scripting.h"
|
||||
|
||||
#include "editcommands.h"
|
||||
|
||||
#include <QTime>
|
||||
#include <QPainter>
|
||||
#include <QImage>
|
||||
|
@ -343,6 +345,7 @@ void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
|
|||
layout->height = QString::number(newHeight);
|
||||
|
||||
emit mapChanged(this);
|
||||
emit mapNeedsRedrawing();
|
||||
}
|
||||
|
||||
void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata) {
|
||||
|
@ -354,6 +357,7 @@ void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata)
|
|||
layout->border_height = QString::number(newHeight);
|
||||
|
||||
emit mapChanged(this);
|
||||
emit mapNeedsRedrawing();
|
||||
}
|
||||
|
||||
Block* Map::getBlock(int x, int y) {
|
||||
|
@ -413,93 +417,8 @@ void Map::_floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_
|
|||
}
|
||||
}
|
||||
|
||||
void Map::undo() {
|
||||
bool redraw = false, changed = false;
|
||||
HistoryItem *commit = metatileHistory.back();
|
||||
if (!commit)
|
||||
return;
|
||||
|
||||
if (layout->blockdata) {
|
||||
layout->blockdata->copyFrom(commit->metatiles);
|
||||
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
|
||||
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (layout->border) {
|
||||
layout->border->copyFrom(commit->border);
|
||||
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
|
||||
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
emit mapNeedsRedrawing();
|
||||
}
|
||||
if (changed) {
|
||||
emit mapChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::redo() {
|
||||
bool redraw = false, changed = false;
|
||||
HistoryItem *commit = metatileHistory.next();
|
||||
if (!commit)
|
||||
return;
|
||||
|
||||
if (layout->blockdata) {
|
||||
layout->blockdata->copyFrom(commit->metatiles);
|
||||
if (commit->layoutWidth != this->getWidth() || commit->layoutHeight != this->getHeight()) {
|
||||
this->setDimensions(commit->layoutWidth, commit->layoutHeight, false);
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (layout->border) {
|
||||
layout->border->copyFrom(commit->border);
|
||||
if (commit->borderWidth != this->getBorderWidth() || commit->borderHeight != this->getBorderHeight()) {
|
||||
this->setBorderDimensions(commit->borderWidth, commit->borderHeight, false);
|
||||
redraw = true;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
emit mapNeedsRedrawing();
|
||||
}
|
||||
if (changed) {
|
||||
emit mapChanged(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::commit() {
|
||||
if (!layout) {
|
||||
return;
|
||||
}
|
||||
|
||||
int layoutWidth = this->getWidth();
|
||||
int layoutHeight = this->getHeight();
|
||||
int borderWidth = this->getBorderWidth();
|
||||
int borderHeight = this->getBorderHeight();
|
||||
|
||||
if (layout->blockdata) {
|
||||
HistoryItem *item = metatileHistory.current();
|
||||
bool atCurrentHistory = item
|
||||
&& layout->blockdata->equals(item->metatiles)
|
||||
&& layout->border->equals(item->border)
|
||||
&& layoutWidth == item->layoutWidth
|
||||
&& layoutHeight == item->layoutHeight
|
||||
&& borderWidth == item->borderWidth
|
||||
&& borderHeight == item->borderHeight;
|
||||
if (!atCurrentHistory) {
|
||||
HistoryItem *commit = new HistoryItem(layout->blockdata->copy(), layout->border->copy(), layoutWidth, layoutHeight, borderWidth, borderHeight);
|
||||
metatileHistory.push(commit);
|
||||
emit mapChanged(this);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void Map::floodFillCollisionElevation(int x, int y, uint16_t collision, uint16_t elevation) {
|
||||
|
|
|
@ -53,26 +53,6 @@ void Editor::saveUiFields() {
|
|||
saveEncounterTabData();
|
||||
}
|
||||
|
||||
void Editor::undo() {
|
||||
if (current_view && map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
|
||||
map->undo();
|
||||
map_item->draw();
|
||||
collision_item->draw();
|
||||
selected_border_metatiles_item->draw();
|
||||
onBorderMetatilesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::redo() {
|
||||
if (current_view && map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles) {
|
||||
map->redo();
|
||||
map_item->draw();
|
||||
collision_item->draw();
|
||||
selected_border_metatiles_item->draw();
|
||||
onBorderMetatilesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::closeProject() {
|
||||
if (this->project) {
|
||||
delete this->project;
|
||||
|
@ -981,6 +961,9 @@ bool Editor::setMap(QString map_name) {
|
|||
}
|
||||
|
||||
map = loadedMap;
|
||||
|
||||
editGroup.addStack(&map->editHistory);
|
||||
editGroup.setActiveStack(&map->editHistory);
|
||||
selected_events->clear();
|
||||
if (!displayMap()) {
|
||||
return false;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "customattributestable.h"
|
||||
#include "scripting.h"
|
||||
#include "adjustingstackedwidget.h"
|
||||
#include "editcommands.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QDirIterator>
|
||||
|
@ -146,6 +147,21 @@ void MainWindow::initEditor() {
|
|||
connect(this->editor, &Editor::wheelZoom, this, &MainWindow::onWheelZoom);
|
||||
|
||||
this->loadUserSettings();
|
||||
|
||||
undoAction = editor->editGroup.createUndoAction(this, tr("&Undo"));
|
||||
undoAction->setShortcut(QKeySequence("Ctrl+Z"));
|
||||
|
||||
redoAction = editor->editGroup.createRedoAction(this, tr("&Redo"));
|
||||
redoAction->setShortcut(QKeySequence("Ctrl+Y"));
|
||||
|
||||
ui->menuEdit->addAction(undoAction);
|
||||
ui->menuEdit->addAction(redoAction);
|
||||
|
||||
// TODO: show history UndoView here
|
||||
QUndoView *undoView = new QUndoView(&editor->editGroup);
|
||||
undoView->setWindowTitle(tr("Edit History"));
|
||||
undoView->show();
|
||||
undoView->setAttribute(Qt::WA_QuitOnClose, false);
|
||||
}
|
||||
|
||||
void MainWindow::initMiscHeapObjects() {
|
||||
|
@ -1255,14 +1271,6 @@ void MainWindow::on_action_Save_Project_triggered()
|
|||
updateMapList();
|
||||
}
|
||||
|
||||
void MainWindow::undo() {
|
||||
editor->undo();
|
||||
}
|
||||
|
||||
void MainWindow::redo() {
|
||||
editor->redo();
|
||||
}
|
||||
|
||||
void MainWindow::duplicate() {
|
||||
editor->duplicateSelectedEvents();
|
||||
}
|
||||
|
@ -1322,16 +1330,6 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index)
|
|||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_actionUndo_triggered()
|
||||
{
|
||||
undo();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionRedo_triggered()
|
||||
{
|
||||
redo();
|
||||
}
|
||||
|
||||
void MainWindow::on_actionZoom_In_triggered() {
|
||||
scaleMapView(1);
|
||||
}
|
||||
|
@ -2498,10 +2496,23 @@ void MainWindow::on_pushButton_ChangeDimensions_clicked()
|
|||
form.addRow(errorLabel);
|
||||
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
editor->map->setDimensions(widthSpinBox->value(), heightSpinBox->value());
|
||||
editor->map->setBorderDimensions(bwidthSpinBox->value(), bheightSpinBox->value());
|
||||
editor->map->commit();
|
||||
onMapNeedsRedrawing();
|
||||
Map *map = editor->map;
|
||||
Blockdata *oldMetatiles = map->layout->blockdata->copy();
|
||||
Blockdata *oldBorder = map->layout->border->copy();
|
||||
QSize oldMapDimensions(map->getWidth(), map->getHeight());
|
||||
QSize oldBorderDimensions(map->getBorderWidth(), map->getBorderHeight());
|
||||
QSize newMapDimensions(widthSpinBox->value(), heightSpinBox->value());
|
||||
QSize newBorderDimensions(bwidthSpinBox->value(), bheightSpinBox->value());
|
||||
if (oldMapDimensions != newMapDimensions || oldBorderDimensions != newBorderDimensions) {
|
||||
editor->map->setDimensions(newMapDimensions.width(), newMapDimensions.height());
|
||||
editor->map->setBorderDimensions(newBorderDimensions.width(), newBorderDimensions.height());
|
||||
editor->map->editHistory.push(new ResizeMap(map,
|
||||
oldMapDimensions, newMapDimensions,
|
||||
oldMetatiles, map->layout->blockdata->copy(),
|
||||
oldBorderDimensions, newBorderDimensions,
|
||||
oldBorder, map->layout->border->copy()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "bordermetatilespixmapitem.h"
|
||||
#include "imageproviders.h"
|
||||
#include "editcommands.h"
|
||||
#include <QPainter>
|
||||
|
||||
void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
|
||||
|
@ -11,6 +12,8 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
int width = map->getBorderWidth();
|
||||
int height = map->getBorderHeight();
|
||||
|
||||
Blockdata *oldBorder = map->layout->border->copy();
|
||||
|
||||
for (int i = 0; i < selectionDimensions.x() && (i + x) < width; i++) {
|
||||
for (int j = 0; j < selectionDimensions.y() && (j + y) < height; j++) {
|
||||
int blockIndex = (j + y) * width + (i + x);
|
||||
|
@ -19,11 +22,15 @@ void BorderMetatilesPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||
}
|
||||
}
|
||||
|
||||
draw();
|
||||
Blockdata *newBorder = map->layout->border->copy();
|
||||
map->editHistory.push(new PaintBorder(map, oldBorder, newBorder, 0));
|
||||
|
||||
emit borderMetatilesChanged();
|
||||
}
|
||||
|
||||
void BorderMetatilesPixmapItem::draw() {
|
||||
map->setBorderItem(this);
|
||||
|
||||
int width = map->getBorderWidth();
|
||||
int height = map->getBorderHeight();
|
||||
QImage image(16 * width, 16 * height, QImage::Format_RGBA8888);
|
||||
|
@ -49,4 +56,6 @@ void BorderMetatilesPixmapItem::draw() {
|
|||
painter.end();
|
||||
map->commit();
|
||||
this->setPixmap(QPixmap::fromImage(image));
|
||||
|
||||
emit borderMetatilesChanged();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
#include "mappixmapitem.h"
|
||||
#include "log.h"
|
||||
|
||||
#include "editcommands.h"
|
||||
|
||||
#define SWAP(a, b) do { if (a != b) { a ^= b; b ^= a; a ^= b; } } while (0)
|
||||
|
||||
void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
|
||||
if (map) {
|
||||
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
|
||||
map->commit();
|
||||
eventId_++;
|
||||
} else {
|
||||
QPointF pos = event->pos();
|
||||
int x = static_cast<int>(pos.x()) / 16;
|
||||
|
@ -21,15 +23,13 @@ void MapPixmapItem::paint(QGraphicsSceneMouseEvent *event) {
|
|||
paintNormal(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void MapPixmapItem::shift(QGraphicsSceneMouseEvent *event) {
|
||||
if (map) {
|
||||
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
|
||||
map->commit();
|
||||
eventId_++;
|
||||
} else {
|
||||
QPointF pos = event->pos();
|
||||
int x = static_cast<int>(pos.x()) / 16;
|
||||
|
@ -70,7 +70,9 @@ void MapPixmapItem::shift(int xDelta, int yDelta) {
|
|||
map->setBlock(destX, destY, srcBlock);
|
||||
}
|
||||
|
||||
delete backupBlockdata;
|
||||
Blockdata *newMetatiles = map->layout->blockdata->copy();
|
||||
ShiftMetatiles *paintEvent = new ShiftMetatiles(map, backupBlockdata, newMetatiles, eventId_);
|
||||
map->editHistory.push(paintEvent);
|
||||
}
|
||||
|
||||
void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
|
||||
|
@ -90,6 +92,9 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
|
|||
x = initialX + (xDiff / selectionDimensions.x()) * selectionDimensions.x();
|
||||
y = initialY + (yDiff / selectionDimensions.y()) * selectionDimensions.y();
|
||||
|
||||
// for edit history
|
||||
Blockdata *oldMetatiles = map->layout->blockdata->copy();
|
||||
|
||||
for (int i = 0; i < selectionDimensions.x() && i + x < map->getWidth(); i++)
|
||||
for (int j = 0; j < selectionDimensions.y() && j + y < map->getHeight(); j++) {
|
||||
int actualX = i + x;
|
||||
|
@ -105,6 +110,10 @@ void MapPixmapItem::paintNormal(int x, int y, bool fromScriptCall) {
|
|||
map->setBlock(actualX, actualY, *block, !fromScriptCall);
|
||||
}
|
||||
}
|
||||
|
||||
Blockdata *newMetatiles = map->layout->blockdata->copy();
|
||||
PaintMetatile *paintEvent = new PaintMetatile(map, oldMetatiles, newMetatiles, eventId_);
|
||||
map->editHistory.push(paintEvent);
|
||||
}
|
||||
|
||||
// These are tile offsets from the top-left tile in the 3x3 smart path selection.
|
||||
|
@ -150,6 +159,9 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
|
|||
setCollisions = true;
|
||||
}
|
||||
|
||||
// for edit history
|
||||
Blockdata *oldMetatiles = map->layout->blockdata->copy();
|
||||
|
||||
// Fill the region with the open tile.
|
||||
for (int i = 0; i <= 1; i++)
|
||||
for (int j = 0; j <= 1; j++) {
|
||||
|
@ -211,6 +223,10 @@ void MapPixmapItem::paintSmartPath(int x, int y, bool fromScriptCall) {
|
|||
}
|
||||
map->setBlock(actualX, actualY, *block, !fromScriptCall);
|
||||
}
|
||||
|
||||
Blockdata *newMetatiles = map->layout->blockdata->copy();
|
||||
PaintMetatile *paintEvent = new PaintMetatile(map, oldMetatiles, newMetatiles, eventId_);
|
||||
map->editHistory.push(paintEvent);
|
||||
}
|
||||
|
||||
void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
|
||||
|
@ -263,7 +279,7 @@ void MapPixmapItem::updateMetatileSelection(QGraphicsSceneMouseEvent *event) {
|
|||
void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
|
||||
if (map) {
|
||||
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
|
||||
map->commit();
|
||||
eventId_++;
|
||||
} else {
|
||||
QPointF pos = event->pos();
|
||||
int x = static_cast<int>(pos.x()) / 16;
|
||||
|
@ -280,23 +296,19 @@ void MapPixmapItem::floodFill(QGraphicsSceneMouseEvent *event) {
|
|||
this->floodFill(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
void MapPixmapItem::magicFill(QGraphicsSceneMouseEvent *event) {
|
||||
if (map) {
|
||||
if (event->type() == QEvent::GraphicsSceneMouseRelease) {
|
||||
map->commit();
|
||||
eventId_++;
|
||||
} else {
|
||||
QPointF pos = event->pos();
|
||||
int initialX = static_cast<int>(pos.x()) / 16;
|
||||
int initialY = static_cast<int>(pos.y()) / 16;
|
||||
this->magicFill(initialX, initialY);
|
||||
}
|
||||
|
||||
draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,6 +339,8 @@ void MapPixmapItem::magicFill(
|
|||
return;
|
||||
}
|
||||
|
||||
Blockdata *oldMetatiles = map->layout->blockdata->copy();
|
||||
|
||||
bool setCollisions = selectedCollisions && selectedCollisions->length() == selectedMetatiles->length();
|
||||
uint16_t tile = block->tile;
|
||||
for (int y = 0; y < map->getHeight(); y++) {
|
||||
|
@ -349,6 +363,10 @@ void MapPixmapItem::magicFill(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
Blockdata *newMetatiles = map->layout->blockdata->copy();
|
||||
MagicFillMetatile *paintEvent = new MagicFillMetatile(map, oldMetatiles, newMetatiles, eventId_);
|
||||
map->editHistory.push(paintEvent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,6 +397,8 @@ void MapPixmapItem::floodFill(
|
|||
for (int i = 0; i < numMetatiles; i++)
|
||||
visited[i] = false;
|
||||
|
||||
Blockdata *oldMetatiles = map->layout->blockdata->copy();
|
||||
|
||||
QList<QPoint> todo;
|
||||
todo.append(QPoint(initialX, initialY));
|
||||
while (todo.length()) {
|
||||
|
@ -427,6 +447,10 @@ void MapPixmapItem::floodFill(
|
|||
}
|
||||
}
|
||||
|
||||
Blockdata *newMetatiles = map->layout->blockdata->copy();
|
||||
BucketFillMetatile *paintEvent = new BucketFillMetatile(map, oldMetatiles, newMetatiles, eventId_);
|
||||
map->editHistory.push(paintEvent);
|
||||
|
||||
delete[] visited;
|
||||
}
|
||||
|
||||
|
@ -449,6 +473,8 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
|
|||
setCollisions = true;
|
||||
}
|
||||
|
||||
Blockdata *oldMetatiles = map->layout->blockdata->copy();
|
||||
|
||||
// Flood fill the region with the open tile.
|
||||
QList<QPoint> todo;
|
||||
todo.append(QPoint(initialX, initialY));
|
||||
|
@ -548,6 +574,10 @@ void MapPixmapItem::floodFillSmartPath(int initialX, int initialY, bool fromScri
|
|||
}
|
||||
}
|
||||
|
||||
Blockdata *newMetatiles = map->layout->blockdata->copy();
|
||||
BucketFillMetatile *paintEvent = new BucketFillMetatile(map, oldMetatiles, newMetatiles, eventId_);
|
||||
map->editHistory.push(paintEvent);
|
||||
|
||||
delete[] visited;
|
||||
}
|
||||
|
||||
|
@ -595,6 +625,7 @@ void MapPixmapItem::select(QGraphicsSceneMouseEvent *event) {
|
|||
|
||||
void MapPixmapItem::draw(bool ignoreCache) {
|
||||
if (map) {
|
||||
map->setMapItem(this);
|
||||
setPixmap(map->render(ignoreCache));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue