From d1142d244e6bdd11647578f37c6c3de1a7bedd54 Mon Sep 17 00:00:00 2001 From: GriffinR Date: Mon, 16 Jun 2025 14:36:18 -0400 Subject: [PATCH] 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){