From 513ba158386f0997551112f23b23748dee06a547 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sun, 15 Jun 2025 19:17:07 -0400 Subject: [PATCH 1/7] Remove tile rectangle from non-tile tools --- src/editor.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/editor.cpp b/src/editor.cpp index 5fb3ef80..298f4ae0 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -169,7 +169,6 @@ void Editor::setEditMode(EditMode editMode) { editStack = &this->layout->editHistory; } - this->cursorMapTileRect->setActive(editingLayout); this->playerViewRect->setActive(editingLayout); this->editGroup.setActiveStack(editStack); this->ui->toolButton_Fill->setEnabled(editingLayout); @@ -204,6 +203,10 @@ void Editor::setEditAction(EditAction editAction) { this->map_ruler->setEnabled(false); } + // Only show the tile cursor for tools that apply at a specific tile + this->cursorMapTileRect->setActive(getEditingLayout() && editAction != EditAction::Select && editAction != EditAction::Move); + + // The tile cursor can only grow while painting metatiles this->cursorMapTileRect->setSingleTileMode(!(editAction == EditAction::Paint && this->editMode == EditMode::Metatiles)); // Update cursor From d1142d244e6bdd11647578f37c6c3de1a7bedd54 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 16 Jun 2025 14:36:18 -0400 Subject: [PATCH 2/7] Refactor cursor rectangles --- include/core/maplayout.h | 1 + include/editor.h | 14 +-- include/ui/collisionpixmapitem.h | 27 ++--- include/ui/cursortilerect.h | 87 ++++++--------- include/ui/layoutpixmapitem.h | 17 +-- include/ui/movablerect.h | 9 +- src/core/maplayout.cpp | 4 + src/editor.cpp | 175 +++++++++++++++---------------- src/mainwindow.cpp | 13 +-- src/ui/collisionpixmapitem.cpp | 10 +- src/ui/cursortilerect.cpp | 116 ++++++++------------ src/ui/layoutpixmapitem.cpp | 10 +- src/ui/movablerect.cpp | 24 ++--- src/ui/resizelayoutpopup.cpp | 4 +- 14 files changed, 221 insertions(+), 290 deletions(-) diff --git a/include/core/maplayout.h b/include/core/maplayout.h index 5a2e23b3..c7790ad3 100644 --- a/include/core/maplayout.h +++ b/include/core/maplayout.h @@ -100,6 +100,7 @@ public: QRect getVisibleRect() const; bool isWithinBounds(int x, int y) const; + bool isWithinBounds(const QPoint &pos) const; bool isWithinBounds(const QRect &rect) const; bool isWithinBorderBounds(int x, int y) const; diff --git a/include/editor.h b/include/editor.h index a5601196..10891e4c 100644 --- a/include/editor.h +++ b/include/editor.h @@ -122,9 +122,10 @@ public: void updateEventPixmapItemZValue(EventPixmapItem *item); qreal getEventOpacity(const Event *event) const; + bool isMouseInMap() const; void setPlayerViewRect(const QRectF &rect); - void updateCursorRectPos(int x, int y); - void setCursorRectVisible(bool visible); + void setCursorRectPos(const QPoint &pos); + void updateCursorRectVisibility(); void onEventDragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition); void onEventReleased(Event *event, const QPoint &position); @@ -251,6 +252,7 @@ private: QString getMovementPermissionText(uint16_t collision, uint16_t elevation); QString getMetatileDisplayMessage(uint16_t metatileId); void setCollisionTabSpinBoxes(uint16_t collision, uint16_t elevation); + void adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item, QPoint *pos) const; static bool startDetachedProcess(const QString &command, const QString &workingDirectory = QString(), qint64 *pid = nullptr); @@ -259,7 +261,6 @@ private slots: 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, LayoutPixmapItem *item); void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item); void setSelectedConnectionItem(ConnectionPixmapItem *connectionItem); @@ -267,10 +268,9 @@ private slots: void onHoveredMovementPermissionCleared(); void onHoveredMetatileSelectionChanged(uint16_t); void onHoveredMetatileSelectionCleared(); - void onHoveredMapMetatileChanged(const QPoint &pos); - void onHoveredMapMetatileCleared(); - void onHoveredMapMovementPermissionChanged(int, int); - void onHoveredMapMovementPermissionCleared(); + void onMapHoverEntered(const QPoint &pos); + void onMapHoverChanged(const QPoint &pos); + void onMapHoverCleared(); void onSelectedMetatilesChanged(); void onWheelZoom(int); diff --git a/include/ui/collisionpixmapitem.h b/include/ui/collisionpixmapitem.h index 1419f2e4..90376c34 100644 --- a/include/ui/collisionpixmapitem.h +++ b/include/ui/collisionpixmapitem.h @@ -23,11 +23,11 @@ public: QSpinBox * selectedElevation; qreal *opacity; void updateMovementPermissionSelection(QGraphicsSceneMouseEvent *event); - virtual void paint(QGraphicsSceneMouseEvent*); - virtual void floodFill(QGraphicsSceneMouseEvent*); - virtual void magicFill(QGraphicsSceneMouseEvent*); - virtual void pick(QGraphicsSceneMouseEvent*); - void draw(bool ignoreCache = false); + virtual void paint(QGraphicsSceneMouseEvent*) override; + virtual void floodFill(QGraphicsSceneMouseEvent*) override; + virtual void magicFill(QGraphicsSceneMouseEvent*) override; + virtual void pick(QGraphicsSceneMouseEvent*) override; + void draw(bool ignoreCache = false) override; private: unsigned actionId_ = 0; @@ -36,16 +36,17 @@ private: signals: void mouseEvent(QGraphicsSceneMouseEvent *, CollisionPixmapItem *); - void hoveredMapMovementPermissionChanged(int, int); - void hoveredMapMovementPermissionCleared(); + void hoverEntered(const QPoint &pos); + void hoverChanged(const QPoint &pos); + void hoverCleared(); protected: - void hoverMoveEvent(QGraphicsSceneHoverEvent*); - void hoverEnterEvent(QGraphicsSceneHoverEvent*); - void hoverLeaveEvent(QGraphicsSceneHoverEvent*); - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*) override; + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; + virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; }; #endif // COLLISIONPIXMAPITEM_H diff --git a/include/ui/cursortilerect.h b/include/ui/cursortilerect.h index f53ae5aa..92f37f96 100644 --- a/include/ui/cursortilerect.h +++ b/include/ui/cursortilerect.h @@ -8,78 +8,55 @@ class CursorTileRect : public QGraphicsItem { public: - CursorTileRect(bool *enabled, QRgb color); - QRectF boundingRect() const override - { - int width = this->width; - int height = this->height; - if (this->singleTileMode) { - width = 16; - height = 16; - } else if (!this->rightClickSelectionAnchored && this->smartPathMode && this->selectionHeight == 3 && this->selectionWidth == 3) { - width = 32; - height = 32; - } + CursorTileRect(const QSize &tileSize, const QRgb &color, QGraphicsItem *parent = nullptr); + + QSize size() const; + + QRectF boundingRect() const override { + auto s = size(); qreal penWidth = 4; return QRectF(-penWidth, -penWidth, - width + penWidth * 2, - height + penWidth * 2); + s.width() + penWidth * 2, + s.height() + penWidth * 2); } - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override - { - if (!(*enabled)) return; - int width = this->width; - int height = this->height; - if (this->singleTileMode) { - width = 16; - height = 16; - } else if (this->smartPathInEffect()) { - width = 32; - height = 32; - } - - painter->setPen(this->color); - painter->drawRect(x() - 1, y() - 1, width + 2, height + 2); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override { + if (!isVisible()) return; + auto rect = QRectF(pos(), size()); + painter->setPen(m_color); + painter->drawRect(rect + QMargins(1,1,1,1)); // Fill painter->setPen(QColor(0, 0, 0)); - painter->drawRect(x() - 2, y() - 2, width + 4, height + 4); - painter->drawRect(x(), y(), width, height); + painter->drawRect(rect + QMargins(2,2,2,2)); // Outer border + painter->drawRect(rect); // Inner border } + void initAnchor(int coordX, int coordY); void stopAnchor(); void initRightClickSelectionAnchor(int coordX, int coordY); void stopRightClickSelectionAnchor(); - void setSmartPathMode(bool enable) { this->smartPathMode = enable; } - bool getSmartPathMode() const { return this->smartPathMode; } + void setSmartPathMode(bool enable) { m_smartPathMode = enable; } + bool getSmartPathMode() const { return m_smartPathMode; } - void setStraightPathMode(bool enable) { this->straightPathMode = enable; } - bool getStraightPathMode() const { return this->straightPathMode; } - - void setSingleTileMode(bool enable) { this->singleTileMode = enable; } - bool getSingleTileMode() const { return this->singleTileMode; } + void setSingleTileMode(bool enable) { m_singleTileMode = enable; } + bool getSingleTileMode() const { return m_singleTileMode; } void updateLocation(int x, int y); void updateSelectionSize(int width, int height); - void setActive(bool active); - bool getActive(); - bool *enabled; + private: - bool active; - int width; - int height; - bool anchored; - bool rightClickSelectionAnchored; - bool smartPathMode; - bool straightPathMode; - bool singleTileMode; - int anchorCoordX; - int anchorCoordY; - int selectionWidth; - int selectionHeight; - QRgb color; - bool smartPathInEffect(); + const QSize m_tileSize; + QSize m_selectionSize; + QPoint m_anchorCoord; + QRgb m_color; + + bool m_anchored = false; + bool m_rightClickSelectionAnchored = false; + bool m_smartPathMode = false; + bool m_singleTileMode = false; + + bool smartPathInEffect() const; }; diff --git a/include/ui/layoutpixmapitem.h b/include/ui/layoutpixmapitem.h index 695472a5..bed0ce8b 100644 --- a/include/ui/layoutpixmapitem.h +++ b/include/ui/layoutpixmapitem.h @@ -102,16 +102,17 @@ signals: void startPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); void endPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); void mouseEvent(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); - void hoveredMapMetatileChanged(const QPoint &pos); - void hoveredMapMetatileCleared(); + void hoverEntered(const QPoint &pos); + void hoverChanged(const QPoint &pos); + void hoverCleared(); protected: - void hoverMoveEvent(QGraphicsSceneHoverEvent*); - void hoverEnterEvent(QGraphicsSceneHoverEvent*); - void hoverLeaveEvent(QGraphicsSceneHoverEvent*); - void mousePressEvent(QGraphicsSceneMouseEvent*); - void mouseMoveEvent(QGraphicsSceneMouseEvent*); - void mouseReleaseEvent(QGraphicsSceneMouseEvent*); + virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*) override; + virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override; + virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override; + virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override; + virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override; + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override; }; #endif // MAPPIXMAPITEM_H diff --git a/include/ui/movablerect.h b/include/ui/movablerect.h index 92dd43f7..552ad6f5 100644 --- a/include/ui/movablerect.h +++ b/include/ui/movablerect.h @@ -10,7 +10,7 @@ class MovableRect : public QGraphicsRectItem { public: - MovableRect(bool *enabled, const QRectF &rect, const QRgb &color); + MovableRect(const QRectF &rect, const QRgb &color); QRectF boundingRect() const override { qreal penWidth = 4; return QRectF(-penWidth, @@ -29,12 +29,7 @@ public: } void updateLocation(int x, int y); - void setActive(bool active); - bool getActive() const { return this->active; } - protected: - bool *enabled = nullptr; - bool active = true; QRectF baseRect; QRgb color; @@ -48,7 +43,7 @@ class ResizableRect : public QObject, public MovableRect { Q_OBJECT public: - ResizableRect(QObject *parent, bool *enabled, int width, int height, QRgb color); + ResizableRect(QObject *parent, int width, int height, QRgb color); QRectF boundingRect() const override { return QRectF(this->rect() + QMargins(lineWidth, lineWidth, lineWidth, lineWidth)); diff --git a/src/core/maplayout.cpp b/src/core/maplayout.cpp index 4108400f..4ddb3b75 100644 --- a/src/core/maplayout.cpp +++ b/src/core/maplayout.cpp @@ -55,6 +55,10 @@ bool Layout::isWithinBounds(int x, int y) const { return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight()); } +bool Layout::isWithinBounds(const QPoint &pos) const { + return isWithinBounds(pos.x(), pos.y()); +} + bool Layout::isWithinBounds(const QRect &rect) const { return rect.left() >= 0 && rect.right() < this->getWidth() && rect.top() >= 0 && rect.bottom() < this->getHeight(); } diff --git a/src/editor.cpp b/src/editor.cpp index 298f4ae0..0d4f7482 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -30,7 +30,7 @@ Editor::Editor(Ui::MainWindow* ui) { this->ui = ui; this->settings = new Settings(); - this->cursorMapTileRect = new CursorTileRect(&this->settings->cursorTileRectEnabled, qRgb(255, 255, 255)); + this->cursorMapTileRect = new CursorTileRect(QSize(16,16), qRgb(255, 255, 255)); this->map_ruler = new MapRuler(4); connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged); @@ -169,7 +169,6 @@ void Editor::setEditMode(EditMode editMode) { editStack = &this->layout->editHistory; } - this->playerViewRect->setActive(editingLayout); this->editGroup.setActiveStack(editStack); this->ui->toolButton_Fill->setEnabled(editingLayout); this->ui->toolButton_Dropper->setEnabled(editingLayout); @@ -203,8 +202,7 @@ void Editor::setEditAction(EditAction editAction) { this->map_ruler->setEnabled(false); } - // Only show the tile cursor for tools that apply at a specific tile - this->cursorMapTileRect->setActive(getEditingLayout() && editAction != EditAction::Select && editAction != EditAction::Move); + updateCursorRectVisibility(); // The tile cursor can only grow while painting metatiles this->cursorMapTileRect->setSingleTileMode(!(editAction == EditAction::Paint && this->editMode == EditMode::Metatiles)); @@ -1139,15 +1137,20 @@ void Editor::scaleMapView(int s) { ui->graphicsView_Connections->setTransform(transform); } -void Editor::setPlayerViewRect(const QRectF &rect) { - delete this->playerViewRect; - this->playerViewRect = new MovableRect(&this->settings->playerViewRectEnabled, rect, qRgb(255, 255, 255)); - this->playerViewRect->setActive(getEditingLayout()); - if (ui->graphicsView_Map->scene()) - ui->graphicsView_Map->scene()->update(); +bool Editor::isMouseInMap() const { + return (this->map_item && this->map_item->has_mouse) || (this->collision_item && this->collision_item->has_mouse); } -void Editor::updateCursorRectPos(int x, int y) { +void Editor::setPlayerViewRect(const QRectF &rect) { + delete this->playerViewRect; + this->playerViewRect = new MovableRect(rect, qRgb(255, 255, 255)); + updateCursorRectVisibility(); +} + +void Editor::setCursorRectPos(const QPoint &pos) { + int x = qMax(0, qMin(pos.x(), this->layout ? this->layout->getWidth() - 1 : 0)); + int y = qMax(0, qMin(pos.y(), this->layout ? this->layout->getHeight() - 1 : 0)); + if (this->playerViewRect) this->playerViewRect->updateLocation(x, y); if (this->cursorMapTileRect) @@ -1156,23 +1159,55 @@ void Editor::updateCursorRectPos(int x, int y) { ui->graphicsView_Map->scene()->update(); } -void Editor::setCursorRectVisible(bool visible) { - if (this->playerViewRect) - this->playerViewRect->setVisible(visible); - if (this->cursorMapTileRect) - this->cursorMapTileRect->setVisible(visible); - if (ui->graphicsView_Map->scene()) +void Editor::updateCursorRectVisibility() { + bool mouseInMap = isMouseInMap(); + bool changed = false; + + if (this->playerViewRect) { + bool visible = this->settings->playerViewRectEnabled + && mouseInMap + && this->editMode != EditMode::Connections; + + if (visible != this->playerViewRect->isVisible()) { + this->playerViewRect->setVisible(visible); + changed = true; + } + } + + if (this->cursorMapTileRect) { + auto editAction = getEditAction(); + bool visible = this->settings->cursorTileRectEnabled + && mouseInMap + && getEditingLayout() + // Only show the tile cursor for tools that apply at a specific tile + && editAction != EditAction::Select + && editAction != EditAction::Move; + + if (visible != this->cursorMapTileRect->isVisible()) { + this->cursorMapTileRect->setVisible(visible); + changed = true; + } + } + + // TODO: Investigate whether it'd be worth limiting the scene update to the old and new areas of the cursor rectangles. + if (ui->graphicsView_Map->scene() && changed) { ui->graphicsView_Map->scene()->update(); + } } -void Editor::onHoveredMapMetatileChanged(const QPoint &pos) { - int x = pos.x(); - int y = pos.y(); - if (!layout || !layout->isWithinBounds(x, y)) +void Editor::onMapHoverEntered(const QPoint &pos) { + updateCursorRectVisibility(); + onMapHoverChanged(pos); +} + +void Editor::onMapHoverChanged(const QPoint &pos) { + this->setCursorRectPos(pos); + if (!layout || !layout->isWithinBounds(pos)) return; - this->updateCursorRectPos(x, y); - if (this->getEditingLayout()) { + int x = pos.x(); + int y = pos.y(); + if (this->editMode == EditMode::Metatiles) { int blockIndex = y * layout->getWidth() + x; int metatileId = layout->blockdata.at(blockIndex).metatileId(); this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x") @@ -1180,8 +1215,15 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) { .arg(y) .arg(getMetatileDisplayMessage(metatileId)) .arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2))); - } - else if (this->editMode == EditMode::Events) { + } else if (this->editMode == EditMode::Collision) { + int blockIndex = y * layout->getWidth() + x; + uint16_t collision = layout->blockdata.at(blockIndex).collision(); + uint16_t elevation = layout->blockdata.at(blockIndex).elevation(); + this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3") + .arg(x) + .arg(y) + .arg(this->getMovementPermissionText(collision, elevation))); + } else if (this->editMode == EditMode::Events) { this->ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x") .arg(x) .arg(y) @@ -1191,36 +1233,10 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) { Scripting::cb_BlockHoverChanged(x, y); } -void Editor::onHoveredMapMetatileCleared() { - this->setCursorRectVisible(false); - if (map_item->getEditsEnabled()) { - this->ui->statusBar->clearMessage(); - } - Scripting::cb_BlockHoverCleared(); -} - -void Editor::onHoveredMapMovementPermissionChanged(int x, int y) { - if (!layout || !layout->isWithinBounds(x, y)) - return; - - this->updateCursorRectPos(x, y); - if (this->getEditingLayout()) { - int blockIndex = y * layout->getWidth() + x; - uint16_t collision = layout->blockdata.at(blockIndex).collision(); - uint16_t elevation = layout->blockdata.at(blockIndex).elevation(); - QString message = QString("X: %1, Y: %2, %3") - .arg(x) - .arg(y) - .arg(this->getMovementPermissionText(collision, elevation)); - this->ui->statusBar->showMessage(message); - } - Scripting::cb_BlockHoverChanged(x, y); -} - -void Editor::onHoveredMapMovementPermissionCleared() { - this->setCursorRectVisible(false); - if (this->getEditingLayout()) { - this->ui->statusBar->clearMessage(); +void Editor::onMapHoverCleared() { + updateCursorRectVisibility(); + if (getEditingLayout()) { + ui->statusBar->clearMessage(); } Scripting::cb_BlockHoverCleared(); } @@ -1371,11 +1387,10 @@ void Editor::setSmartPathCursorMode(QGraphicsSceneMouseEvent *event) } } -void Editor::setStraightPathCursorMode(QGraphicsSceneMouseEvent *event) { +void Editor::adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item, QPoint *pos) const { if (event->modifiers() & Qt::ControlModifier) { - this->cursorMapTileRect->setStraightPathMode(true); - } else { - this->cursorMapTileRect->setStraightPathMode(false); + item->lockNondominantAxis(event); + *pos = item->adjustCoords(*pos); } } @@ -1399,14 +1414,10 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i } else { if (event->type() == QEvent::GraphicsSceneMouseRelease) { // Update the tile rectangle at the end of a click-drag selection - this->updateCursorRectPos(pos.x(), pos.y()); - } - this->setSmartPathCursorMode(event); - this->setStraightPathCursorMode(event); - if (this->cursorMapTileRect->getStraightPathMode()) { - item->lockNondominantAxis(event); - pos = item->adjustCoords(pos); + setCursorRectPos(pos); } + setSmartPathCursorMode(event); + adjustStraightPathPos(event, item, &pos); item->paint(event); } } else if (mapEditAction == EditAction::Select) { @@ -1426,11 +1437,7 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i item->pick(event); } } else if (mapEditAction == EditAction::Shift) { - this->setStraightPathCursorMode(event); - if (this->cursorMapTileRect->getStraightPathMode()) { - item->lockNondominantAxis(event); - pos = item->adjustCoords(pos); - } + adjustStraightPathPos(event, item, &pos); item->shift(event); } } else if (this->editMode == EditMode::Events) { @@ -1493,11 +1500,7 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm item->floodFill(event); } } else { - this->setStraightPathCursorMode(event); - if (this->cursorMapTileRect->getStraightPathMode()) { - item->lockNondominantAxis(event); - pos = item->adjustCoords(pos); - } + adjustStraightPathPos(event, item, &pos); item->paint(event); } } else if (mapEditAction == EditAction::Select) { @@ -1513,11 +1516,7 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm } else if (mapEditAction == EditAction::Pick) { item->pick(event); } else if (mapEditAction == EditAction::Shift) { - this->setStraightPathCursorMode(event); - if (this->cursorMapTileRect->getStraightPathMode()) { - item->lockNondominantAxis(event); - pos = item->adjustCoords(pos); - } + adjustStraightPathPos(event, item, &pos); item->shift(event); } } @@ -1643,8 +1642,9 @@ void Editor::displayMapMetatiles() { connect(map_item, &LayoutPixmapItem::mouseEvent, this, &Editor::mouseEvent_map); connect(map_item, &LayoutPixmapItem::startPaint, this, &Editor::onMapStartPaint); connect(map_item, &LayoutPixmapItem::endPaint, this, &Editor::onMapEndPaint); - connect(map_item, &LayoutPixmapItem::hoveredMapMetatileChanged, this, &Editor::onHoveredMapMetatileChanged); - connect(map_item, &LayoutPixmapItem::hoveredMapMetatileCleared, this, &Editor::onHoveredMapMetatileCleared); + connect(map_item, &LayoutPixmapItem::hoverEntered, this, &Editor::onMapHoverEntered); + connect(map_item, &LayoutPixmapItem::hoverChanged, this, &Editor::onMapHoverChanged); + connect(map_item, &LayoutPixmapItem::hoverCleared, this, &Editor::onMapHoverCleared); map_item->draw(true); scene->addItem(map_item); @@ -1666,10 +1666,9 @@ void Editor::displayMapMovementPermissions() { collision_item = new CollisionPixmapItem(this->layout, ui->spinBox_SelectedCollision, ui->spinBox_SelectedElevation, this->metatile_selector_item, this->settings, &this->collisionOpacity); connect(collision_item, &CollisionPixmapItem::mouseEvent, this, &Editor::mouseEvent_collision); - connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionChanged, - this, &Editor::onHoveredMapMovementPermissionChanged); - connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionCleared, - this, &Editor::onHoveredMapMovementPermissionCleared); + connect(collision_item, &CollisionPixmapItem::hoverEntered, this, &Editor::onMapHoverEntered); + connect(collision_item, &CollisionPixmapItem::hoverChanged, this, &Editor::onMapHoverChanged); + connect(collision_item, &CollisionPixmapItem::hoverCleared, this, &Editor::onMapHoverCleared); collision_item->draw(true); scene->addItem(collision_item); @@ -2092,7 +2091,7 @@ void Editor::onEventDragged(Event *event, const QPoint &oldPosition, const QPoin if (!this->map || !this->map_item) return; - this->map_item->hoveredMapMetatileChanged(newPosition); + this->map_item->hoverChanged(newPosition); // Drag all the other selected events (if any) with it QList draggedEvents; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8259c315..a7b7d165 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2176,7 +2176,6 @@ void MainWindow::on_mapViewTab_tabBarClicked(int index) prefab.updatePrefabUi(this->editor->layout); } } - editor->setCursorRectVisible(false); } void MainWindow::on_mainTabBar_tabBarClicked(int index) @@ -2240,11 +2239,7 @@ void MainWindow::on_actionPlayer_View_Rectangle_triggered() bool enabled = ui->actionPlayer_View_Rectangle->isChecked(); porymapConfig.showPlayerView = enabled; this->editor->settings->playerViewRectEnabled = enabled; - if ((this->editor->map_item && this->editor->map_item->has_mouse) - || (this->editor->collision_item && this->editor->collision_item->has_mouse)) { - this->editor->playerViewRect->setVisible(enabled && this->editor->playerViewRect->getActive()); - ui->graphicsView_Map->scene()->update(); - } + this->editor->updateCursorRectVisibility(); } void MainWindow::on_actionCursor_Tile_Outline_triggered() @@ -2252,11 +2247,7 @@ void MainWindow::on_actionCursor_Tile_Outline_triggered() bool enabled = ui->actionCursor_Tile_Outline->isChecked(); porymapConfig.showCursorTile = enabled; this->editor->settings->cursorTileRectEnabled = enabled; - if ((this->editor->map_item && this->editor->map_item->has_mouse) - || (this->editor->collision_item && this->editor->collision_item->has_mouse)) { - this->editor->cursorMapTileRect->setVisible(enabled && this->editor->cursorMapTileRect->getActive()); - ui->graphicsView_Map->scene()->update(); - } + this->editor->updateCursorRectVisibility(); } void MainWindow::on_actionShow_Events_In_Map_View_triggered() { diff --git a/src/ui/collisionpixmapitem.cpp b/src/ui/collisionpixmapitem.cpp index e0587b08..7774ee16 100644 --- a/src/ui/collisionpixmapitem.cpp +++ b/src/ui/collisionpixmapitem.cpp @@ -6,7 +6,7 @@ void CollisionPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); if (pos != this->previousPos) { this->previousPos = pos; - emit this->hoveredMapMovementPermissionChanged(pos.x(), pos.y()); + emit this->hoverChanged(pos); } if (this->settings->betterCursors && this->getEditsEnabled()) { setCursor(this->settings->mapCursor); @@ -15,16 +15,16 @@ void CollisionPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { void CollisionPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { this->has_mouse = true; - QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - emit this->hoveredMapMovementPermissionChanged(pos.x(), pos.y()); + this->previousPos = Metatile::coordFromPixmapCoord(event->pos()); + emit this->hoverEntered(this->previousPos); } void CollisionPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { - emit this->hoveredMapMovementPermissionCleared(); if (this->settings->betterCursors && this->getEditsEnabled()){ unsetCursor(); } this->has_mouse = false; + emit this->hoverCleared(); } void CollisionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { @@ -38,7 +38,7 @@ void CollisionPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); if (pos != this->previousPos) { this->previousPos = pos; - emit this->hoveredMapMovementPermissionChanged(pos.x(), pos.y()); + emit this->hoverChanged(pos); } emit mouseEvent(event, this); } diff --git a/src/ui/cursortilerect.cpp b/src/ui/cursortilerect.cpp index 511f0fda..ef1de285 100644 --- a/src/ui/cursortilerect.cpp +++ b/src/ui/cursortilerect.cpp @@ -1,94 +1,70 @@ #include "cursortilerect.h" #include "log.h" -CursorTileRect::CursorTileRect(bool *enabled, QRgb color) -{ - this->enabled = enabled; - this->active = true; - this->color = color; - this->width = 16; - this->height = 16; - this->smartPathMode = false; - this->straightPathMode = false; - this->singleTileMode = false; - this->anchored = false; - this->rightClickSelectionAnchored = false; - this->anchorCoordX = 0; - this->anchorCoordY = 0; - this->selectionWidth = 1; - this->selectionHeight = 1; +CursorTileRect::CursorTileRect(const QSize &tileSize, const QRgb &color, QGraphicsItem *parent) + : QGraphicsItem(parent), + m_tileSize(tileSize), + m_selectionSize(QSize(1,1)), + m_anchorCoord(QPoint(0,0)), + m_color(color) +{ } + +// Size of the cursor may be explicitly enforced depending on settings. +QSize CursorTileRect::size() const { + if (m_singleTileMode) + return m_tileSize; + + if (smartPathInEffect()) + return m_tileSize * 2; + + return QSize(m_tileSize.width() * m_selectionSize.width(), + m_tileSize.height() * m_selectionSize.height()); } -void CursorTileRect::setActive(bool active) -{ - this->active = active; +void CursorTileRect::initAnchor(int coordX, int coordY) { + m_anchorCoord = QPoint(coordX, coordY); + m_anchored = true; } -bool CursorTileRect::getActive() -{ - return active; +void CursorTileRect::stopAnchor() { + m_anchored = false; } -void CursorTileRect::initAnchor(int coordX, int coordY) -{ - this->anchorCoordX = coordX; - this->anchorCoordY = coordY; - this->anchored = true; +void CursorTileRect::initRightClickSelectionAnchor(int coordX, int coordY) { + m_anchorCoord = QPoint(coordX, coordY); + m_rightClickSelectionAnchored = true; } -void CursorTileRect::stopAnchor() -{ - this->anchored = false; +void CursorTileRect::stopRightClickSelectionAnchor() { + m_rightClickSelectionAnchored = false; } -void CursorTileRect::initRightClickSelectionAnchor(int coordX, int coordY) -{ - this->anchorCoordX = coordX; - this->anchorCoordY = coordY; - this->rightClickSelectionAnchored = true; +void CursorTileRect::updateSelectionSize(int width, int height) { + m_selectionSize = QSize(width, height).expandedTo(QSize(1,1)); + prepareGeometryChange(); + update(); } -void CursorTileRect::stopRightClickSelectionAnchor() -{ - this->rightClickSelectionAnchored = false; +bool CursorTileRect::smartPathInEffect() const { + return !m_rightClickSelectionAnchored && m_smartPathMode && m_selectionSize == QSize(3,3); } -void CursorTileRect::updateSelectionSize(int width, int height) -{ - this->selectionWidth = width; - this->selectionHeight = height; - this->width = width * 16; - this->height = height * 16; - this->prepareGeometryChange(); - this->update(); -} +void CursorTileRect::updateLocation(int coordX, int coordY) { + if (!m_singleTileMode) { + if (m_rightClickSelectionAnchored) { + coordX = qMin(coordX, m_anchorCoord.x()); + coordY = qMin(coordY, m_anchorCoord.y()); + } else if (m_anchored && !smartPathInEffect()) { + int xDiff = coordX - m_anchorCoord.x(); + int yDiff = coordY - m_anchorCoord.y(); + if (xDiff < 0 && xDiff % m_selectionSize.width() != 0) xDiff -= m_selectionSize.width(); + if (yDiff < 0 && yDiff % m_selectionSize.height() != 0) yDiff -= m_selectionSize.height(); -bool CursorTileRect::smartPathInEffect() -{ - return !this->rightClickSelectionAnchored && this->smartPathMode && this->selectionHeight == 3 && this->selectionWidth == 3; -} - -void CursorTileRect::updateLocation(int coordX, int coordY) -{ - if (!this->singleTileMode) { - if (this->rightClickSelectionAnchored) { - coordX = qMin(coordX, this->anchorCoordX); - coordY = qMin(coordY, this->anchorCoordY); - } - else if (this->anchored && !this->smartPathInEffect()) { - int xDiff = coordX - this->anchorCoordX; - int yDiff = coordY - this->anchorCoordY; - if (xDiff < 0 && xDiff % this->selectionWidth != 0) xDiff -= this->selectionWidth; - if (yDiff < 0 && yDiff % this->selectionHeight != 0) yDiff -= this->selectionHeight; - - coordX = this->anchorCoordX + (xDiff / this->selectionWidth) * this->selectionWidth; - coordY = this->anchorCoordY + (yDiff / this->selectionHeight) * this->selectionHeight; + coordX = m_anchorCoord.x() + (xDiff / m_selectionSize.width()) * m_selectionSize.width(); + coordY = m_anchorCoord.y() + (yDiff / m_selectionSize.height()) * m_selectionSize.height(); } } - coordX = qMax(coordX, 0); - coordY = qMax(coordY, 0); this->setX(coordX * 16); this->setY(coordY * 16); - this->setVisible(*this->enabled && this->active); } diff --git a/src/ui/layoutpixmapitem.cpp b/src/ui/layoutpixmapitem.cpp index 2fb89171..915cfad7 100644 --- a/src/ui/layoutpixmapitem.cpp +++ b/src/ui/layoutpixmapitem.cpp @@ -695,7 +695,7 @@ void LayoutPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); if (pos != this->metatilePos) { this->metatilePos = pos; - emit this->hoveredMapMetatileChanged(pos); + emit this->hoverChanged(pos); } if (this->settings->betterCursors && this->editsEnabled) { setCursor(this->settings->mapCursor); @@ -704,16 +704,16 @@ void LayoutPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { void LayoutPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { this->has_mouse = true; - QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - emit this->hoveredMapMetatileChanged(pos); + this->metatilePos = Metatile::coordFromPixmapCoord(event->pos()); + emit this->hoverEntered(this->metatilePos); } void LayoutPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { - emit this->hoveredMapMetatileCleared(); if (this->settings->betterCursors && this->editsEnabled) { unsetCursor(); } this->has_mouse = false; + emit this->hoverCleared(); } void LayoutPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { @@ -730,7 +730,7 @@ void LayoutPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { return; this->metatilePos = pos; - emit hoveredMapMetatileChanged(pos); + emit hoverChanged(pos); emit mouseEvent(event, this); } diff --git a/src/ui/movablerect.cpp b/src/ui/movablerect.cpp index e02222df..3fc73934 100644 --- a/src/ui/movablerect.cpp +++ b/src/ui/movablerect.cpp @@ -5,14 +5,11 @@ #include "movablerect.h" #include "utility.h" -MovableRect::MovableRect(bool *enabled, const QRectF &rect, const QRgb &color) +MovableRect::MovableRect(const QRectF &rect, const QRgb &color) : QGraphicsRectItem(rect), - enabled(enabled), baseRect(rect), color(color) -{ - updateVisibility(); -} +{ } /// Center rect on grid position (x, y) void MovableRect::updateLocation(int x, int y) { @@ -20,28 +17,19 @@ void MovableRect::updateLocation(int x, int y) { this->baseRect.y() + (y * 16), this->baseRect.width(), this->baseRect.height()); - updateVisibility(); } -void MovableRect::setActive(bool active) { - this->active = active; - updateVisibility(); -} - -void MovableRect::updateVisibility() { - setVisible(*this->enabled && this->active); -} /****************************************************************************** ************************************************************************ ******************************************************************************/ -ResizableRect::ResizableRect(QObject *parent, bool *enabled, int width, int height, QRgb color) +ResizableRect::ResizableRect(QObject *parent, int width, int height, QRgb color) : QObject(parent), - MovableRect(enabled, QRect(0, 0, width * 16, height * 16), color) + MovableRect(QRect(0, 0, width * 16, height * 16), color) { - setAcceptHoverEvents(true); - setFlags(this->flags() | QGraphicsItem::ItemIsMovable); + setAcceptHoverEvents(true); + setFlags(this->flags() | QGraphicsItem::ItemIsMovable); } ResizableRect::Edge ResizableRect::detectEdge(int x, int y) { diff --git a/src/ui/resizelayoutpopup.cpp b/src/ui/resizelayoutpopup.cpp index 189ba4af..7f11836f 100644 --- a/src/ui/resizelayoutpopup.cpp +++ b/src/ui/resizelayoutpopup.cpp @@ -136,9 +136,7 @@ void ResizeLayoutPopup::setupLayoutView() { this->ui->spinBox_height->setMinimum(1); this->ui->spinBox_height->setMaximum(maxHeight); - static bool layoutSizeRectVisible = true; - - this->outline = new ResizableRect(this, &layoutSizeRectVisible, this->layout->getWidth(), this->layout->getHeight(), qRgb(255, 0, 255)); + this->outline = new ResizableRect(this, this->layout->getWidth(), this->layout->getHeight(), qRgb(255, 0, 255)); this->outline->setZValue(Editor::ZValue::ResizeLayoutPopup); // Ensure on top of view this->outline->setLimit(cover->rect().toAlignedRect()); connect(outline, &ResizableRect::rectUpdated, [=](QRect rect){ From 440c0f9d5c106e64cbdd0cada540b6c1210389fd Mon Sep 17 00:00:00 2001 From: GriffinR Date: Fri, 20 Jun 2025 12:59:09 -0400 Subject: [PATCH 3/7] Better pan control --- src/editor.cpp | 40 ++++++++++++++++++--------------- src/mainwindow.cpp | 15 ++++--------- src/ui/connectionpixmapitem.cpp | 6 ++++- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/src/editor.cpp b/src/editor.cpp index 0d4f7482..150b21bc 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -210,10 +210,10 @@ void Editor::setEditAction(EditAction editAction) { // Update cursor static const QMap cursors = { {EditAction::Paint, QCursor(QPixmap(":/icons/pencil_cursor.ico"), 10, 10)}, - {EditAction::Select, QCursor()}, + {EditAction::Select, QCursor(Qt::ArrowCursor)}, {EditAction::Fill, QCursor(QPixmap(":/icons/fill_color_cursor.ico"), 10, 10)}, {EditAction::Pick, QCursor(QPixmap(":/icons/pipette_cursor.ico"), 10, 10)}, - {EditAction::Move, QCursor(QPixmap(":/icons/move.ico"), 7, 7)}, + {EditAction::Move, QCursor(Qt::OpenHandCursor)}, {EditAction::Shift, QCursor(QPixmap(":/icons/shift_cursor.ico"), 10, 10)}, }; this->settings->mapCursor = cursors.value(editAction); @@ -1354,7 +1354,7 @@ void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem * } QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - if (event->buttons() & Qt::RightButton && (mapEditAction == EditAction::Paint || mapEditAction == EditAction::Fill)) { + if (event->buttons() & Qt::RightButton && (this->mapEditAction == EditAction::Paint || this->mapEditAction == EditAction::Fill)) { this->cursorMapTileRect->initRightClickSelectionAnchor(pos.x(), pos.y()); } else { this->cursorMapTileRect->initAnchor(pos.x(), pos.y()); @@ -1395,14 +1395,16 @@ void Editor::adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmap } void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item) { - if (!item->getEditsEnabled()) { + auto editAction = getEditAction(); + if (!item->getEditsEnabled() || editAction == EditAction::Move) { + event->ignore(); return; } QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); if (this->getEditingLayout()) { - if (mapEditAction == EditAction::Paint) { + if (editAction == EditAction::Paint) { if (event->buttons() & Qt::RightButton) { item->updateMetatileSelection(event); } else if (event->buttons() & Qt::MiddleButton) { @@ -1420,9 +1422,9 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i adjustStraightPathPos(event, item, &pos); item->paint(event); } - } else if (mapEditAction == EditAction::Select) { + } else if (editAction == EditAction::Select) { item->select(event); - } else if (mapEditAction == EditAction::Fill) { + } else if (editAction == EditAction::Fill) { if (event->buttons() & Qt::RightButton) { item->updateMetatileSelection(event); } else if (event->modifiers() & Qt::ControlModifier) { @@ -1430,18 +1432,18 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i } else { item->floodFill(event); } - } else if (mapEditAction == EditAction::Pick) { + } else if (editAction == EditAction::Pick) { if (event->buttons() & Qt::RightButton) { item->updateMetatileSelection(event); } else if (event->type() != QEvent::GraphicsSceneMouseRelease) { item->pick(event); } - } else if (mapEditAction == EditAction::Shift) { + } else if (editAction == EditAction::Shift) { adjustStraightPathPos(event, item, &pos); item->shift(event); } } else if (this->editMode == EditMode::Events) { - if (eventEditAction == EditAction::Paint && event->type() == QEvent::GraphicsSceneMousePress) { + if (editAction == EditAction::Paint && event->type() == QEvent::GraphicsSceneMousePress) { // Right-clicking while in paint mode will change mode to select. if (event->buttons() & Qt::RightButton) { setEditAction(EditAction::Select); @@ -1456,12 +1458,12 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i if (event && event->getPixmapItem()) event->getPixmapItem()->moveTo(pos); } - } else if (eventEditAction == EditAction::Select && event->type() == QEvent::GraphicsSceneMousePress) { + } else if (editAction == 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) { + } else if (editAction == EditAction::Shift) { static QPoint selection_origin; if (event->type() == QEvent::GraphicsSceneMouseRelease) { @@ -1484,13 +1486,15 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i } void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item) { - if (!item->getEditsEnabled()) { + auto editAction = getEditAction(); + if (!item->getEditsEnabled() || editAction == EditAction::Move) { + event->ignore(); return; } QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - if (mapEditAction == EditAction::Paint) { + if (editAction == EditAction::Paint) { if (event->buttons() & Qt::RightButton) { item->updateMovementPermissionSelection(event); } else if (event->buttons() & Qt::MiddleButton) { @@ -1503,9 +1507,9 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm adjustStraightPathPos(event, item, &pos); item->paint(event); } - } else if (mapEditAction == EditAction::Select) { + } else if (editAction == EditAction::Select) { item->select(event); - } else if (mapEditAction == EditAction::Fill) { + } else if (editAction == EditAction::Fill) { if (event->buttons() & Qt::RightButton) { item->pick(event); } else if (event->modifiers() & Qt::ControlModifier) { @@ -1513,9 +1517,9 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm } else { item->floodFill(event); } - } else if (mapEditAction == EditAction::Pick) { + } else if (editAction == EditAction::Pick) { item->pick(event); - } else if (mapEditAction == EditAction::Shift) { + } else if (editAction == EditAction::Shift) { adjustStraightPathPos(event, item, &pos); item->shift(event); } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index a7b7d165..2f56efdc 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2579,17 +2579,10 @@ void MainWindow::on_toolButton_Move_clicked() { editor->setEditAction(Editor: void MainWindow::on_toolButton_Shift_clicked() { editor->setEditAction(Editor::EditAction::Shift); } void MainWindow::setEditActionUi(Editor::EditAction editAction) { - if (editAction == Editor::EditAction::Move) { - ui->graphicsView_Map->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - ui->graphicsView_Map->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - QScroller::grabGesture(ui->graphicsView_Map, QScroller::LeftMouseButtonGesture); - ui->graphicsView_Map->setViewportUpdateMode(QGraphicsView::ViewportUpdateMode::FullViewportUpdate); - } else { - ui->graphicsView_Map->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); - ui->graphicsView_Map->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); - QScroller::ungrabGesture(ui->graphicsView_Map); - ui->graphicsView_Map->setViewportUpdateMode(QGraphicsView::ViewportUpdateMode::MinimalViewportUpdate); - } + // TODO: Viewport's hand cursor is not reliably cleared when changing to QGraphicsView::NoDrag. + auto dragMode = (editAction == Editor::EditAction::Move) ? QGraphicsView::ScrollHandDrag : QGraphicsView::NoDrag; + ui->graphicsView_Connections->setDragMode(dragMode); + ui->graphicsView_Map->setDragMode(dragMode); ui->graphicsView_Map->setFocus(); ui->toolButton_Paint->setChecked(editAction == Editor::EditAction::Paint); diff --git a/src/ui/connectionpixmapitem.cpp b/src/ui/connectionpixmapitem.cpp index c6e606b0..b4fbfa12 100644 --- a/src/ui/connectionpixmapitem.cpp +++ b/src/ui/connectionpixmapitem.cpp @@ -126,7 +126,11 @@ void ConnectionPixmapItem::setSelected(bool selected) { emit selectionChanged(selected); } -void ConnectionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *) { +void ConnectionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { + if (!this->getEditable()) { + event->ignore(); + return; + } this->setSelected(true); } From 1ab07cf3c76dd86a9a2adf74cdd14cbf7733af59 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 21 Jun 2025 21:33:52 -0400 Subject: [PATCH 4/7] Fix drag mode cursor icon not updating properly --- include/settings.h | 1 - include/ui/layoutpixmapitem.h | 5 ---- src/editor.cpp | 44 ++++++++++++++++++++++++---------- src/mainwindow.cpp | 6 ----- src/ui/collisionpixmapitem.cpp | 6 ----- src/ui/layoutpixmapitem.cpp | 8 +------ 6 files changed, 32 insertions(+), 38 deletions(-) diff --git a/include/settings.h b/include/settings.h index d37283cd..6e64fd2a 100644 --- a/include/settings.h +++ b/include/settings.h @@ -10,7 +10,6 @@ public: Settings(); bool smartPathsEnabled; bool betterCursors; - QCursor mapCursor; bool playerViewRectEnabled; bool cursorTileRectEnabled; }; diff --git a/include/ui/layoutpixmapitem.h b/include/ui/layoutpixmapitem.h index bed0ce8b..51f850d9 100644 --- a/include/ui/layoutpixmapitem.h +++ b/include/ui/layoutpixmapitem.h @@ -86,9 +86,6 @@ public: void lockNondominantAxis(QGraphicsSceneMouseEvent *event); QPoint adjustCoords(QPoint pos); - void setEditsEnabled(bool enabled) { this->editsEnabled = enabled; } - bool getEditsEnabled() { return this->editsEnabled; } - private: void paintSmartPath(int x, int y, bool fromScriptCall = false); static QList smartPathTable; @@ -96,8 +93,6 @@ private: unsigned actionId_ = 0; - bool editsEnabled = true; - signals: void startPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); void endPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); diff --git a/src/editor.cpp b/src/editor.cpp index 150b21bc..b7e73b09 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -155,7 +155,6 @@ void Editor::setEditMode(EditMode editMode) { break; } - map_item->setEditsEnabled(this->editMode != EditMode::Connections); map_item->draw(); collision_item->draw(); @@ -207,16 +206,35 @@ void Editor::setEditAction(EditAction editAction) { // The tile cursor can only grow while painting metatiles this->cursorMapTileRect->setSingleTileMode(!(editAction == EditAction::Paint && this->editMode == EditMode::Metatiles)); + auto dragMode = (editAction == EditAction::Move) ? QGraphicsView::ScrollHandDrag : QGraphicsView::NoDrag; + ui->graphicsView_Map->setDragMode(dragMode); + ui->graphicsView_Connections->setDragMode(dragMode); + // Update cursor - static const QMap cursors = { - {EditAction::Paint, QCursor(QPixmap(":/icons/pencil_cursor.ico"), 10, 10)}, - {EditAction::Select, QCursor(Qt::ArrowCursor)}, - {EditAction::Fill, QCursor(QPixmap(":/icons/fill_color_cursor.ico"), 10, 10)}, - {EditAction::Pick, QCursor(QPixmap(":/icons/pipette_cursor.ico"), 10, 10)}, - {EditAction::Move, QCursor(Qt::OpenHandCursor)}, - {EditAction::Shift, QCursor(QPixmap(":/icons/shift_cursor.ico"), 10, 10)}, - }; - this->settings->mapCursor = cursors.value(editAction); + if (this->settings->betterCursors) { + static const QMap cursors = { + {EditAction::Paint, QCursor(QPixmap(":/icons/pencil_cursor.ico"), 10, 10)}, + {EditAction::Fill, QCursor(QPixmap(":/icons/fill_color_cursor.ico"), 10, 10)}, + {EditAction::Pick, QCursor(QPixmap(":/icons/pipette_cursor.ico"), 10, 10)}, + {EditAction::Shift, QCursor(QPixmap(":/icons/shift_cursor.ico"), 10, 10)}, + }; + + // Paint tools don't apply on the Connections tab, so don't show the cursor. + // We specifically unset the cursor for Move rather than explicitly set Qt::OpenHandCursor + // because otherwise the cursor may persist outside the map after the tool changes. + if (this->editMode == EditMode::Connections || editAction == EditAction::Move) { + if (this->map_item) + this->map_item->unsetCursor(); + if (this->collision_item) + this->collision_item->unsetCursor(); + } else { + auto cursor = cursors.value(editAction); + if (this->map_item) + this->map_item->setCursor(cursor); + if (this->collision_item) + this->collision_item->setCursor(cursor); + } + } emit editActionSet(editAction); } @@ -1396,14 +1414,14 @@ void Editor::adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmap void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item) { auto editAction = getEditAction(); - if (!item->getEditsEnabled() || editAction == EditAction::Move) { + if (editAction == EditAction::Move) { event->ignore(); return; } QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); - if (this->getEditingLayout()) { + if (this->editMode == EditMode::Metatiles) { if (editAction == EditAction::Paint) { if (event->buttons() & Qt::RightButton) { item->updateMetatileSelection(event); @@ -1487,7 +1505,7 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item) { auto editAction = getEditAction(); - if (!item->getEditsEnabled() || editAction == EditAction::Move) { + if (this->editMode != EditMode::Collision || editAction == EditAction::Move) { event->ignore(); return; } diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 2f56efdc..7622b8b2 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -2579,12 +2579,6 @@ void MainWindow::on_toolButton_Move_clicked() { editor->setEditAction(Editor: void MainWindow::on_toolButton_Shift_clicked() { editor->setEditAction(Editor::EditAction::Shift); } void MainWindow::setEditActionUi(Editor::EditAction editAction) { - // TODO: Viewport's hand cursor is not reliably cleared when changing to QGraphicsView::NoDrag. - auto dragMode = (editAction == Editor::EditAction::Move) ? QGraphicsView::ScrollHandDrag : QGraphicsView::NoDrag; - ui->graphicsView_Connections->setDragMode(dragMode); - ui->graphicsView_Map->setDragMode(dragMode); - ui->graphicsView_Map->setFocus(); - ui->toolButton_Paint->setChecked(editAction == Editor::EditAction::Paint); ui->toolButton_Select->setChecked(editAction == Editor::EditAction::Select); ui->toolButton_Fill->setChecked(editAction == Editor::EditAction::Fill); diff --git a/src/ui/collisionpixmapitem.cpp b/src/ui/collisionpixmapitem.cpp index 7774ee16..9fcfb7de 100644 --- a/src/ui/collisionpixmapitem.cpp +++ b/src/ui/collisionpixmapitem.cpp @@ -8,9 +8,6 @@ void CollisionPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { this->previousPos = pos; emit this->hoverChanged(pos); } - if (this->settings->betterCursors && this->getEditsEnabled()) { - setCursor(this->settings->mapCursor); - } } void CollisionPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { @@ -20,9 +17,6 @@ void CollisionPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { } void CollisionPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { - if (this->settings->betterCursors && this->getEditsEnabled()){ - unsetCursor(); - } this->has_mouse = false; emit this->hoverCleared(); } diff --git a/src/ui/layoutpixmapitem.cpp b/src/ui/layoutpixmapitem.cpp index 915cfad7..9f8a8c04 100644 --- a/src/ui/layoutpixmapitem.cpp +++ b/src/ui/layoutpixmapitem.cpp @@ -697,21 +697,15 @@ void LayoutPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { this->metatilePos = pos; emit this->hoverChanged(pos); } - if (this->settings->betterCursors && this->editsEnabled) { - setCursor(this->settings->mapCursor); - } } -void LayoutPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { +void LayoutPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) { this->has_mouse = true; this->metatilePos = Metatile::coordFromPixmapCoord(event->pos()); emit this->hoverEntered(this->metatilePos); } void LayoutPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { - if (this->settings->betterCursors && this->editsEnabled) { - unsetCursor(); - } this->has_mouse = false; emit this->hoverCleared(); } From f42e9ed3cf06d015bc959845c94cced9b7a338f1 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 21 Jun 2025 23:26:35 -0400 Subject: [PATCH 5/7] Fix Move tool affecting cursor anchor --- include/editor.h | 7 ++++--- src/editor.cpp | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/editor.h b/include/editor.h index 10891e4c..414356d1 100644 --- a/include/editor.h +++ b/include/editor.h @@ -172,7 +172,7 @@ public: void setEditMode(EditMode editMode); EditMode getEditMode() const { return this->editMode; } - bool getEditingLayout(); + bool getEditingLayout() const; void setMapEditingButtonsEnabled(bool enabled); @@ -256,10 +256,11 @@ private: static bool startDetachedProcess(const QString &command, const QString &workingDirectory = QString(), qint64 *pid = nullptr); - -private slots: + bool canPaintMetatiles() const; void onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item); void onMapEndPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item); + +private slots: void setSmartPathCursorMode(QGraphicsSceneMouseEvent *event); void mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item); void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item); diff --git a/src/editor.cpp b/src/editor.cpp index b7e73b09..f64c4b40 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -125,7 +125,7 @@ void Editor::closeProject() { delete this->project; } -bool Editor::getEditingLayout() { +bool Editor::getEditingLayout() const { return this->editMode == EditMode::Metatiles || this->editMode == EditMode::Collision; } @@ -1366,8 +1366,12 @@ bool Editor::setLayout(QString layoutId) { return true; } +bool Editor::canPaintMetatiles() const { + return this->editMode == EditMode::Metatiles && this->mapEditAction != EditAction::Select && this->mapEditAction != EditAction::Move; +} + void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *) { - if (!this->getEditingLayout()) { + if (!canPaintMetatiles()) { return; } @@ -1380,7 +1384,7 @@ void Editor::onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem * } void Editor::onMapEndPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *) { - if (!this->getEditingLayout()) { + if (!canPaintMetatiles()) { return; } this->cursorMapTileRect->stopRightClickSelectionAnchor(); From 37ccc82bf4dbb6c94546216c4c7775c6b7d7d7d8 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sat, 21 Jun 2025 23:51:37 -0400 Subject: [PATCH 6/7] Fix incorrect EditMode limits --- src/editor.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/editor.cpp b/src/editor.cpp index f64c4b40..4f41cddb 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -1196,7 +1196,6 @@ void Editor::updateCursorRectVisibility() { auto editAction = getEditAction(); bool visible = this->settings->cursorTileRectEnabled && mouseInMap - && getEditingLayout() // Only show the tile cursor for tools that apply at a specific tile && editAction != EditAction::Select && editAction != EditAction::Move; @@ -2224,7 +2223,7 @@ bool Editor::canAddEvents(const QList &events) { } void Editor::duplicateSelectedEvents() { - if (this->selectedEvents.isEmpty() || !project || !map || !current_view || this->getEditingLayout()) + if (this->selectedEvents.isEmpty() || !project || !map || !current_view || this->editMode != EditMode::Events) return; QList duplicatedEvents; From 0da6ae9b375f5a6598c95b55f9334b43ce6dab70 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Sun, 22 Jun 2025 00:20:16 -0400 Subject: [PATCH 7/7] Fix dragging events to negative coordinates --- src/core/metatile.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/metatile.cpp b/src/core/metatile.cpp index 073fd867..73ff9c86 100644 --- a/src/core/metatile.cpp +++ b/src/core/metatile.cpp @@ -38,6 +38,8 @@ int Metatile::getIndexInTileset(int metatileId) { QPoint Metatile::coordFromPixmapCoord(const QPointF &pixelCoord) { int x = static_cast(pixelCoord.x()) / 16; int y = static_cast(pixelCoord.y()) / 16; + if (pixelCoord.x() < 0) x--; + if (pixelCoord.y() < 0) y--; return QPoint(x, y); }