diff --git a/include/editor.h b/include/editor.h index 60ead193..07a5dc68 100644 --- a/include/editor.h +++ b/include/editor.h @@ -122,6 +122,8 @@ public: void updateCursorRectPos(int x, int y); void setCursorRectVisible(bool visible); + void onEventDragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition); + void onEventReleased(Event *event, const QPoint &position); void updateWarpEventWarning(Event *event); void updateWarpEventWarnings(); @@ -172,10 +174,7 @@ public: static QList> collisionIcons; int eventShiftActionId = 0; - - void eventsView_onMousePress(QMouseEvent *event); - - bool selectingEvent = false; + int eventMoveActionId = 0; void deleteSelectedEvents(); void shouldReselectEvents(); diff --git a/include/ui/eventpixmapitem.h b/include/ui/eventpixmapitem.h index 18813bc0..c44fc6bf 100644 --- a/include/ui/eventpixmapitem.h +++ b/include/ui/eventpixmapitem.h @@ -39,10 +39,12 @@ private: bool releaseSelectionQueued = false; signals: - void positionChanged(Event *event); void xChanged(int); void yChanged(int); void spriteChanged(const QPixmap &pixmap); + void selected(Event *event, bool toggle); + void dragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition); + void released(Event *event, const QPoint &position); void doubleClicked(Event *event); protected: diff --git a/include/ui/graphicsview.h b/include/ui/graphicsview.h index 92771cf7..cac812b2 100644 --- a/include/ui/graphicsview.h +++ b/include/ui/graphicsview.h @@ -32,25 +32,4 @@ signals: void clicked(QMouseEvent *event); }; -class Editor; - -// TODO: This should just be MapView. It makes map-based assumptions, and no other class inherits GraphicsView. -class GraphicsView : public QGraphicsView -{ -public: - GraphicsView() : QGraphicsView() {} - GraphicsView(QWidget *parent) : QGraphicsView(parent) {} - -public: -// GraphicsView_Object object; - Editor *editor; -protected: - virtual void mousePressEvent(QMouseEvent *event) override; - virtual void mouseMoveEvent(QMouseEvent *event) override; - virtual void mouseReleaseEvent(QMouseEvent *event) override; - virtual void moveEvent(QMoveEvent *event) override; -}; - -//Q_DECLARE_METATYPE(GraphicsView) - #endif // GRAPHICSVIEW_H diff --git a/include/ui/mapview.h b/include/ui/mapview.h index aa271757..d53e5cce 100644 --- a/include/ui/mapview.h +++ b/include/ui/mapview.h @@ -5,13 +5,17 @@ #include "graphicsview.h" #include "overlay.h" -class MapView : public GraphicsView +class Editor; + +class MapView : public QGraphicsView { Q_OBJECT public: - MapView() : GraphicsView() {} - MapView(QWidget *parent) : GraphicsView(parent) {} + MapView() : QGraphicsView() {} + MapView(QWidget *parent) : QGraphicsView(parent) {} + + Editor *editor; Overlay * getOverlay(int layer); void clearOverlayMap(); @@ -73,6 +77,7 @@ public: protected: virtual void drawForeground(QPainter *painter, const QRectF &rect) override; virtual void keyPressEvent(QKeyEvent*) override; + virtual void moveEvent(QMoveEvent *event) override; private: QMap overlayMap; diff --git a/src/editor.cpp b/src/editor.cpp index f618361c..cf9dd632 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1289,7 +1289,6 @@ void Editor::setStraightPathCursorMode(QGraphicsSceneMouseEvent *event) { } void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item) { - // TODO: add event tab event painting tool buttons stuff here if (!item->getEditsEnabled()) { return; } @@ -1363,8 +1362,11 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i if (event && event->getPixmapItem()) event->getPixmapItem()->moveTo(pos); } - } else if (eventEditAction == EditAction::Select) { - // do nothing here, at least for now + } else if (eventEditAction == EditAction::Select && event->type() == QEvent::GraphicsSceneMousePress) { + if (!(event->modifiers() & Qt::ControlModifier) && this->selectedEvents.length() > 1) { + // User is clearing group selection by clicking on the background + selectMapEvent(this->selectedEvents.first()); + } } else if (eventEditAction == EditAction::Shift) { static QPoint selection_origin; @@ -1696,6 +1698,9 @@ EventPixmapItem *Editor::addEventPixmapItem(Event *event) { this->project->loadEventPixmap(event); auto item = new EventPixmapItem(event, this); connect(item, &EventPixmapItem::doubleClicked, this, &Editor::openEventMap); + connect(item, &EventPixmapItem::dragged, this, &Editor::onEventDragged); + connect(item, &EventPixmapItem::released, this, &Editor::onEventReleased); + connect(item, &EventPixmapItem::selected, this, &Editor::selectMapEvent); redrawEventPixmapItem(item); this->events_group->addToGroup(item); return item; @@ -2004,6 +2009,28 @@ void Editor::redrawEventPixmapItem(EventPixmapItem *item) { item->updatePosition(); } +void Editor::onEventDragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition) { + if (!this->map || !this->map_item) + return; + + this->map_item->hoveredMapMetatileChanged(newPosition); + + // Drag all the other selected events (if any) with it + QList draggedEvents; + if (this->selectedEvents.contains(event)) { + draggedEvents = this->selectedEvents; + } else { + draggedEvents.append(event); + } + + QPoint moveDistance = newPosition - oldPosition; + this->map->commit(new EventMove(draggedEvents, moveDistance.x(), moveDistance.y(), this->eventMoveActionId)); +} + +void Editor::onEventReleased(Event *, const QPoint &) { + this->eventMoveActionId++; +} + // Warp events display a warning if they're not positioned on a metatile with a warp behavior. void Editor::updateWarpEventWarning(Event *event) { if (porymapConfig.warpBehaviorWarningDisabled) @@ -2286,32 +2313,6 @@ bool Editor::startDetachedProcess(const QString &command, const QString &working return process.startDetached(pid); } -// It doesn't seem to be possible to prevent the mousePress event -// from triggering both event's EventPixmapItem and the background mousePress. -// Since the EventPixmapItem's event fires first, we can set a temp -// variable "selectingEvent" so that we can detect whether or not the user -// is clicking on the background instead of an event. -void Editor::eventsView_onMousePress(QMouseEvent *event) { - // make sure we are in event editing mode - if (map_item && this->editMode != EditMode::Events) { - return; - } - if (this->eventEditAction == EditAction::Paint && event->buttons() & Qt::RightButton) { - this->eventEditAction = EditAction::Select; - this->settings->mapCursor = QCursor(); - this->cursorMapTileRect->setSingleTileMode(); - this->ui->toolButton_Paint->setChecked(false); - this->ui->toolButton_Select->setChecked(true); - } - - bool multiSelect = event->modifiers() & Qt::ControlModifier; - if (!selectingEvent && !multiSelect && this->selectedEvents.length() > 1) { - // User is clearing group selection by clicking on the background - this->selectMapEvent(this->selectedEvents.first()); - } - selectingEvent = false; -} - void Editor::setCollisionTabSpinBoxes(uint16_t collision, uint16_t elevation) { const QSignalBlocker blocker1(ui->spinBox_SelectedCollision); const QSignalBlocker blocker2(ui->spinBox_SelectedElevation); diff --git a/src/ui/eventpixmapitem.cpp b/src/ui/eventpixmapitem.cpp index cc0d76e1..1face67c 100644 --- a/src/ui/eventpixmapitem.cpp +++ b/src/ui/eventpixmapitem.cpp @@ -4,8 +4,19 @@ #include "mapruler.h" #include "metatile.h" -static unsigned currentActionId = 0; +void EventPixmapItem::move(int dx, int dy) { + event->setX(event->getX() + dx); + event->setY(event->getY() + dy); + updatePosition(); + emitPositionChanged(); +} +void EventPixmapItem::moveTo(const QPoint &pos) { + event->setX(pos.x()); + event->setY(pos.y()); + updatePosition(); + emitPositionChanged(); +} void EventPixmapItem::updatePosition() { int x = this->event->getPixelX(); @@ -25,17 +36,17 @@ void EventPixmapItem::updatePixmap() { emit spriteChanged(event->getPixmap()); } -void EventPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { +void EventPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (this->active) return; this->active = true; - this->lastPos = Metatile::coordFromPixmapCoord(mouse->scenePos()); + this->lastPos = Metatile::coordFromPixmapCoord(mouseEvent->scenePos()); - bool selectionToggle = mouse->modifiers() & Qt::ControlModifier; + bool selectionToggle = mouseEvent->modifiers() & Qt::ControlModifier; if (selectionToggle || !this->editor->selectedEvents.contains(this->event)) { // User is either toggling this selection on/off as part of a group selection, // or they're newly selecting just this item. - this->editor->selectMapEvent(this->event, selectionToggle); + emit selected(this->event, selectionToggle); } else { // This item is already selected and the user isn't toggling the selection, so there are 4 possibilities: // 1. This is the only selected event, and the selection is pointless. @@ -46,53 +57,30 @@ void EventPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { // To support #4 we set the flag below, and we only call 'selectMapEvent' on mouse release if no move occurred. this->releaseSelectionQueued = true; } - this->editor->selectingEvent = true; + mouseEvent->accept(); } -void EventPixmapItem::move(int dx, int dy) { - event->setX(event->getX() + dx); - event->setY(event->getY() + dy); - updatePosition(); - emitPositionChanged(); -} - -void EventPixmapItem::moveTo(const QPoint &pos) { - event->setX(pos.x()); - event->setY(pos.y()); - updatePosition(); - emitPositionChanged(); -} - -void EventPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { +void EventPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (!this->active) return; - QPoint pos = Metatile::coordFromPixmapCoord(mouse->scenePos()); + QPoint pos = Metatile::coordFromPixmapCoord(mouseEvent->scenePos()); if (pos == this->lastPos) return; - QPoint moveDistance = pos - this->lastPos; - this->lastPos = pos; - emit this->editor->map_item->hoveredMapMetatileChanged(pos); - - QList selectedEvents; - if (this->editor->selectedEvents.contains(this->event)) { - selectedEvents = this->editor->selectedEvents; - } else { - selectedEvents.append(this->event); - } - editor->map->commit(new EventMove(selectedEvents, moveDistance.x(), moveDistance.y(), currentActionId)); this->releaseSelectionQueued = false; + emit dragged(this->event, this->lastPos, pos); + this->lastPos = pos; } -void EventPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) { +void EventPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent) { if (!this->active) return; this->active = false; - currentActionId++; if (this->releaseSelectionQueued) { this->releaseSelectionQueued = false; - if (Metatile::coordFromPixmapCoord(mouse->scenePos()) == this->lastPos) - this->editor->selectMapEvent(this->event); + if (Metatile::coordFromPixmapCoord(mouseEvent->scenePos()) == this->lastPos) + emit selected(this->event, false); } + emit released(this->event, this->lastPos); } diff --git a/src/ui/graphicsview.cpp b/src/ui/graphicsview.cpp index 68479e98..6c4ccdb3 100644 --- a/src/ui/graphicsview.cpp +++ b/src/ui/graphicsview.cpp @@ -2,22 +2,7 @@ #include "mapview.h" #include "editor.h" -void GraphicsView::mousePressEvent(QMouseEvent *event) { - QGraphicsView::mousePressEvent(event); - if (editor) { - editor->eventsView_onMousePress(event); - } -} - -void GraphicsView::mouseMoveEvent(QMouseEvent *event) { - QGraphicsView::mouseMoveEvent(event); -} - -void GraphicsView::mouseReleaseEvent(QMouseEvent *event) { - QGraphicsView::mouseReleaseEvent(event); -} - -void GraphicsView::moveEvent(QMoveEvent *event) { +void MapView::moveEvent(QMoveEvent *event) { QGraphicsView::moveEvent(event); QLabel *label_MapRulerStatus = findChild("label_MapRulerStatus", Qt::FindDirectChildrenOnly); if (label_MapRulerStatus && label_MapRulerStatus->isVisible()) diff --git a/src/ui/layoutpixmapitem.cpp b/src/ui/layoutpixmapitem.cpp index f53cf275..3417a4ce 100644 --- a/src/ui/layoutpixmapitem.cpp +++ b/src/ui/layoutpixmapitem.cpp @@ -714,19 +714,20 @@ void LayoutPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { } void LayoutPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { - QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - this->paint_tile_initial_x = this->straight_path_initial_x = pos.x(); - this->paint_tile_initial_y = this->straight_path_initial_y = pos.y(); + this->metatilePos = Metatile::coordFromPixmapCoord(event->pos()); + this->paint_tile_initial_x = this->straight_path_initial_x = this->metatilePos.x(); + this->paint_tile_initial_y = this->straight_path_initial_y = this->metatilePos.y(); emit startPaint(event, this); emit mouseEvent(event, this); } void LayoutPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - if (pos != this->metatilePos) { - this->metatilePos = pos; - emit this->hoveredMapMetatileChanged(pos); - } + if (pos == this->metatilePos) + return; + + this->metatilePos = pos; + emit hoveredMapMetatileChanged(pos); emit mouseEvent(event, this); }