diff --git a/include/core/editcommands.h b/include/core/editcommands.h index 45ac1346..207da57d 100644 --- a/include/core/editcommands.h +++ b/include/core/editcommands.h @@ -2,10 +2,13 @@ #define EDITCOMMANDS_H #include +#include class MapPixmapItem; class Map; class Blockdata; +class Event; +class DraggablePixmapItem; enum CommandId { ID_PaintMetatile, // - done @@ -14,10 +17,11 @@ enum CommandId { ID_ShiftMetatiles, // - done ID_ResizeMap, // - done ID_PaintBorder, // - done - ID_EventMove, // - + ID_EventMove, // - done + ID_EventShift, // - ID_EventCreate, // - ID_EventDelete, // - - ID_EventSetData, // - + ID_EventSetData, // - ? // Tileset editor history commands // Region map editor history commands }; @@ -165,4 +169,28 @@ private: Blockdata *oldBorder; }; + + +/// +class EventMove : public QUndoCommand { +public: + EventMove(QList events, + int deltaX, int deltaY, unsigned actionId, + QUndoCommand *parent = nullptr); + ~EventMove(); + + void undo() override; + void redo() override; + + bool mergeWith(const QUndoCommand *command) override; + int id() const override { return CommandId::ID_EventMove; } + +private: + QList events; + int deltaX; + int deltaY; + + unsigned actionId; +}; + #endif // EDITCOMMANDS_H diff --git a/include/core/event.h b/include/core/event.h index eb56dfbd..48d13253 100644 --- a/include/core/event.h +++ b/include/core/event.h @@ -22,6 +22,7 @@ public: static QString HealLocation; }; +class DraggablePixmapItem; class Project; class Event { @@ -97,6 +98,9 @@ public: int frame = 0; bool hFlip = false; bool usingSprite; + + DraggablePixmapItem *pixmapItem = nullptr; + void setPixmapItem(DraggablePixmapItem *item) { pixmapItem = item; } }; #endif // EVENT_H diff --git a/include/editor.h b/include/editor.h index 7edabbbb..d3a6be55 100644 --- a/include/editor.h +++ b/include/editor.h @@ -145,6 +145,8 @@ public: QUndoGroup editGroup; // Manages the undo history for each map + bool selectingEvent = false; + private: void setConnectionItemsVisible(bool); void setBorderItemsVisible(bool, qreal = 1); @@ -204,104 +206,4 @@ signals: void wheelZoom(int delta); }; - - -class DraggablePixmapItem : public QObject, public QGraphicsPixmapItem { - Q_OBJECT -public: - DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) { - } - Editor *editor = nullptr; - Event *event = nullptr; - QGraphicsItemAnimation *pos_anim = nullptr; - DraggablePixmapItem(Event *event_, Editor *editor_) : QGraphicsPixmapItem(event_->pixmap) { - event = event_; - editor = editor_; - updatePosition(); - } - bool active; - int last_x; - int last_y; - void updatePosition() { - int x = event->getPixelX(); - int y = event->getPixelY(); - setX(x); - setY(y); - if (editor->selected_events && editor->selected_events->contains(this)) { - setZValue(event->y() + 1); - } else { - setZValue(event->y()); - } - } - void move(int x, int y); - void emitPositionChanged() { - emit xChanged(event->x()); - emit yChanged(event->y()); - emit elevationChanged(event->elevation()); - } - void updatePixmap() { - QList objects; - objects.append(event); - event->pixmap = QPixmap(); - editor->project->loadEventPixmaps(objects); - this->updatePosition(); - editor->redrawObject(this); - emit spriteChanged(event->pixmap); - } - void bind(QComboBox *combo, QString key) { - connect(combo, static_cast(&QComboBox::currentTextChanged), - this, [this, key](QString value){ - this->event->put(key, value); - }); - connect(this, &DraggablePixmapItem::onPropertyChanged, - this, [combo, key](QString key2, QString value){ - if (key2 == key) { - combo->addItem(value); - combo->setCurrentText(value); - } - }); - } - void bindToUserData(QComboBox *combo, QString key) { - connect(combo, static_cast(&QComboBox::currentIndexChanged), - this, [this, combo, key](int index) { - this->event->put(key, combo->itemData(index).toString()); - }); - } - -signals: - void positionChanged(Event *event); - void xChanged(int); - void yChanged(int); - void elevationChanged(int); - void spriteChanged(QPixmap pixmap); - void onPropertyChanged(QString key, QString value); - -public slots: - void set_x(const QString &text) { - event->put("x", text); - updatePosition(); - } - void set_y(const QString &text) { - event->put("y", text); - updatePosition(); - } - void set_elevation(const QString &text) { - event->put("elevation", text); - updatePosition(); - } - void set_sprite(const QString &text) { - event->put("sprite", text); - updatePixmap(); - } - void set_script(const QString &text) { - event->put("script_label", text); - } - -protected: - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); - void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*); -}; - #endif // EDITOR_H diff --git a/include/ui/draggablepixmapitem.h b/include/ui/draggablepixmapitem.h new file mode 100644 index 00000000..4bbdf982 --- /dev/null +++ b/include/ui/draggablepixmapitem.h @@ -0,0 +1,78 @@ +#ifndef DRAGGABLEPIXMAPITEM_H +#define DRAGGABLEPIXMAPITEM_H + +#include +#include +#include +#include + +#include + +#include "event.h" + +class Editor; + +class DraggablePixmapItem : public QObject, public QGraphicsPixmapItem { + Q_OBJECT +public: + DraggablePixmapItem(QPixmap pixmap): QGraphicsPixmapItem(pixmap) {} + + DraggablePixmapItem(Event *event_, Editor *editor_) : QGraphicsPixmapItem(event_->pixmap) { + event = event_; + event->setPixmapItem(this); + editor = editor_; + updatePosition(); + } + + Editor *editor = nullptr; + Event *event = nullptr; + QGraphicsItemAnimation *pos_anim = nullptr; + + bool active; + int last_x; + int last_y; + + void updatePosition(); + void move(int x, int y); + void emitPositionChanged(); + void updatePixmap(); + void bind(QComboBox *combo, QString key); + void bindToUserData(QComboBox *combo, QString key); + +signals: + void positionChanged(Event *event); + void xChanged(int); + void yChanged(int); + void elevationChanged(int); + void spriteChanged(QPixmap pixmap); + void onPropertyChanged(QString key, QString value); + +public slots: + void set_x(const QString &text) { + event->put("x", text); + updatePosition(); + } + void set_y(const QString &text) { + event->put("y", text); + updatePosition(); + } + void set_elevation(const QString &text) { + event->put("elevation", text); + updatePosition(); + } + void set_sprite(const QString &text) { + event->put("sprite", text); + updatePixmap(); + } + void set_script(const QString &text) { + event->put("script_label", text); + } + +protected: + void mousePressEvent(QGraphicsSceneMouseEvent*); + void mouseMoveEvent(QGraphicsSceneMouseEvent*); + void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent*); +}; + +#endif // DRAGGABLEPIXMAPITEM_H diff --git a/porymap.pro b/porymap.pro index 2f411ed4..ca8a687f 100644 --- a/porymap.pro +++ b/porymap.pro @@ -34,6 +34,7 @@ SOURCES += src/core/block.cpp \ src/lib/orderedjson.cpp \ src/mainwindow_scriptapi.cpp \ src/ui/aboutporymap.cpp \ + src/ui/draggablepixmapitem.cpp \ src/ui/bordermetatilespixmapitem.cpp \ src/ui/collisionpixmapitem.cpp \ src/ui/connectionpixmapitem.cpp \ @@ -100,6 +101,7 @@ HEADERS += include/core/block.h \ include/lib/orderedmap.h \ include/lib/orderedjson.h \ include/ui/aboutporymap.h \ + include/ui/draggablepixmapitem.h \ include/ui/bordermetatilespixmapitem.h \ include/ui/collisionpixmapitem.h \ include/ui/connectionpixmapitem.h \ diff --git a/src/core/editcommands.cpp b/src/core/editcommands.cpp index 8c492aed..d619b5a5 100644 --- a/src/core/editcommands.cpp +++ b/src/core/editcommands.cpp @@ -1,5 +1,6 @@ #include "editcommands.h" #include "mappixmapitem.h" +#include "draggablepixmapitem.h" #include "bordermetatilespixmapitem.h" #include @@ -247,6 +248,8 @@ void ResizeMap::redo() { map->layout->border->copyFrom(newBorder); map->setBorderDimensions(newBorderWidth, newBorderHeight, false); } + + map->mapNeedsRedrawing(); } void ResizeMap::undo() { @@ -262,7 +265,60 @@ void ResizeMap::undo() { map->setBorderDimensions(oldBorderWidth, oldBorderHeight, false); } + map->mapNeedsRedrawing(); + QUndoCommand::undo(); } +/****************************************************************************** + ************************************************************************ + ******************************************************************************/ + +EventMove::EventMove(QList events, + int deltaX, int deltaY, unsigned actionId, + QUndoCommand *parent) : QUndoCommand(parent) { + setText("Move Event"); + + this->events = events; + + this->deltaX = deltaX; + this->deltaY = deltaY; + + this->actionId = actionId; +} + +EventMove::~EventMove() {} + +void EventMove::redo() { + QUndoCommand::redo(); + + for (Event *event : events) { + event->pixmapItem->move(deltaX, deltaY); + } +} + +void EventMove::undo() { + for (Event *event : events) { + event->pixmapItem->move(-deltaX, -deltaY); + } + + QUndoCommand::undo(); +} + +bool EventMove::mergeWith(const QUndoCommand *command) { + const EventMove *other = static_cast(command); + + if (actionId != other->actionId) + return false; + + this->deltaX += other->deltaX; + this->deltaY += other->deltaY; + + return true; +} + +/****************************************************************************** + ************************************************************************ + ******************************************************************************/ + diff --git a/src/core/map.cpp b/src/core/map.cpp index d21a38de..3b61a874 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -345,7 +345,6 @@ 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) { @@ -357,7 +356,6 @@ 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) { diff --git a/src/editor.cpp b/src/editor.cpp index 5f85242c..f0c67e7f 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1,4 +1,5 @@ #include "editor.h" +#include "draggablepixmapitem.h" #include "event.h" #include "imageproviders.h" #include "log.h" @@ -1751,62 +1752,6 @@ Tileset* Editor::getCurrentMapPrimaryTileset() return project->getTileset(tilesetLabel); } -void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { - active = true; - last_x = static_cast(mouse->pos().x() + this->pos().x()) / 16; - last_y = static_cast(mouse->pos().y() + this->pos().y()) / 16; - this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier); - //this->editor->updateSelectedEvents(); - selectingEvent = true; -} - -void DraggablePixmapItem::move(int x, int y) { - event->setX(event->x() + x); - event->setY(event->y() + y); - updatePosition(); - emitPositionChanged(); -} - -void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { - if (active) { - int x = static_cast(mouse->pos().x() + this->pos().x()) / 16; - int y = static_cast(mouse->pos().y() + this->pos().y()) / 16; - this->editor->playerViewRect->updateLocation(x, y); - this->editor->cursorMapTileRect->updateLocation(x, y); - if (x != last_x || y != last_y) { - if (editor->selected_events->contains(this)) { - for (DraggablePixmapItem *item : *editor->selected_events) { - item->move(x - last_x, y - last_y); - } - } else { - move(x - last_x, y - last_y); - } - last_x = x; - last_y = y; - } - } -} - -void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { - active = false; -} - -void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) { - if (this->event->get("event_type") == EventType::Warp) { - QString destMap = this->event->get("destination_map_name"); - if (destMap != NONE_MAP_NAME) { - emit editor->warpEventDoubleClicked(this->event->get("destination_map_name"), this->event->get("destination_warp")); - } - } - else if (this->event->get("event_type") == EventType::SecretBase) { - QString baseId = this->event->get("secret_base_id"); - QString destMap = editor->project->mapConstantsToMapNames->value("MAP_" + baseId.left(baseId.lastIndexOf("_"))); - if (destMap != NONE_MAP_NAME) { - emit editor->warpEventDoubleClicked(destMap, "0"); - } - } -} - QList *Editor::getObjects() { QList *list = new QList; for (Event *event : map->getAllEvents()) { @@ -1944,6 +1889,7 @@ void Editor::objectsView_onMousePress(QMouseEvent *event) { this->ui->toolButton_Paint->setChecked(false); this->ui->toolButton_Select->setChecked(true); } + bool multiSelect = event->modifiers() & Qt::ControlModifier; if (!selectingEvent && !multiSelect && selected_events->length() > 1) { DraggablePixmapItem *first = selected_events->first(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index d1a7c6e4..555be39f 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -11,6 +11,7 @@ #include "customattributestable.h" #include "scripting.h" #include "adjustingstackedwidget.h" +#include "draggablepixmapitem.h" #include "editcommands.h" #include diff --git a/src/ui/draggablepixmapitem.cpp b/src/ui/draggablepixmapitem.cpp new file mode 100644 index 00000000..432a3ba2 --- /dev/null +++ b/src/ui/draggablepixmapitem.cpp @@ -0,0 +1,115 @@ +#include "draggablepixmapitem.h" + +#include "editor.h" + +#include "editcommands.h" + +static unsigned currentActionId = 0; + + +void DraggablePixmapItem::updatePosition() { + int x = event->getPixelX(); + int y = event->getPixelY(); + setX(x); + setY(y); + if (editor->selected_events && editor->selected_events->contains(this)) { + setZValue(event->y() + 1); + } else { + setZValue(event->y()); + } +} + +void DraggablePixmapItem::emitPositionChanged() { + emit xChanged(event->x()); + emit yChanged(event->y()); + emit elevationChanged(event->elevation()); +} + +void DraggablePixmapItem::updatePixmap() { + QList objects; + objects.append(event); + event->pixmap = QPixmap(); + editor->project->loadEventPixmaps(objects); + this->updatePosition(); + editor->redrawObject(this); + emit spriteChanged(event->pixmap); +} + +void DraggablePixmapItem::bind(QComboBox *combo, QString key) { + connect(combo, static_cast(&QComboBox::currentTextChanged), + this, [this, key](QString value){ + this->event->put(key, value); + }); + connect(this, &DraggablePixmapItem::onPropertyChanged, + this, [combo, key](QString key2, QString value){ + if (key2 == key) { + combo->addItem(value); + combo->setCurrentText(value); + } + }); +} + +void DraggablePixmapItem::bindToUserData(QComboBox *combo, QString key) { + connect(combo, static_cast(&QComboBox::currentIndexChanged), + this, [this, combo, key](int index) { + this->event->put(key, combo->itemData(index).toString()); + }); +} + +void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { + active = true; + last_x = static_cast(mouse->pos().x() + this->pos().x()) / 16; + last_y = static_cast(mouse->pos().y() + this->pos().y()) / 16; + this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier); + this->editor->selectingEvent = true; +} + +void DraggablePixmapItem::move(int x, int y) { + event->setX(event->x() + x); + event->setY(event->y() + y); + updatePosition(); + emitPositionChanged(); +} + +void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { + if (active) { + int x = static_cast(mouse->pos().x() + this->pos().x()) / 16; + int y = static_cast(mouse->pos().y() + this->pos().y()) / 16; + this->editor->playerViewRect->updateLocation(x, y); + this->editor->cursorMapTileRect->updateLocation(x, y); + if (x != last_x || y != last_y) { + QList selectedEvents; + if (editor->selected_events->contains(this)) { + for (DraggablePixmapItem *item : *editor->selected_events) { + selectedEvents.append(item->event); + } + } else { + selectedEvents.append(this->event); + } + editor->map->editHistory.push(new EventMove(selectedEvents, x - last_x, y - last_y, currentActionId)); + last_x = x; + last_y = y; + } + } +} + +void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { + active = false; + currentActionId++; +} + +void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) { + if (this->event->get("event_type") == EventType::Warp) { + QString destMap = this->event->get("destination_map_name"); + if (destMap != NONE_MAP_NAME) { + emit editor->warpEventDoubleClicked(this->event->get("destination_map_name"), this->event->get("destination_warp")); + } + } + else if (this->event->get("event_type") == EventType::SecretBase) { + QString baseId = this->event->get("secret_base_id"); + QString destMap = editor->project->mapConstantsToMapNames->value("MAP_" + baseId.left(baseId.lastIndexOf("_"))); + if (destMap != NONE_MAP_NAME) { + emit editor->warpEventDoubleClicked(destMap, "0"); + } + } +}