diff --git a/include/core/map.h b/include/core/map.h index 867b5bc8..4d34a071 100644 --- a/include/core/map.h +++ b/include/core/map.h @@ -113,6 +113,7 @@ private: signals: void mapChanged(Map *map); + void mapDimensionsChanged(const QSize &size); void mapNeedsRedrawing(); }; diff --git a/include/editor.h b/include/editor.h index 62b3d339..fc8cfe26 100644 --- a/include/editor.h +++ b/include/editor.h @@ -198,12 +198,13 @@ private slots: void onHoveredMovementPermissionCleared(); void onHoveredMetatileSelectionChanged(uint16_t); void onHoveredMetatileSelectionCleared(); - void onHoveredMapMetatileChanged(const QPointF &scenePos, const QPoint &screenPos); + void onHoveredMapMetatileChanged(const QPoint &pos); void onHoveredMapMetatileCleared(); void onHoveredMapMovementPermissionChanged(int, int); void onHoveredMapMovementPermissionCleared(); void onSelectedMetatilesChanged(); void onWheelZoom(int); + void onMapRulerLengthChanged(); signals: void objectsChanged(); diff --git a/include/ui/mappixmapitem.h b/include/ui/mappixmapitem.h index deed73d8..e9d999b4 100644 --- a/include/ui/mappixmapitem.h +++ b/include/ui/mappixmapitem.h @@ -89,7 +89,7 @@ signals: void startPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *); void endPaint(QGraphicsSceneMouseEvent *, MapPixmapItem *); void mouseEvent(QGraphicsSceneMouseEvent *, MapPixmapItem *); - void hoveredMapMetatileChanged(const QPointF &scenePos, const QPoint &screenPos); + void hoveredMapMetatileChanged(const QPoint &pos); void hoveredMapMetatileCleared(); protected: diff --git a/include/ui/mapruler.h b/include/ui/mapruler.h index 7d0be579..0ee6e698 100644 --- a/include/ui/mapruler.h +++ b/include/ui/mapruler.h @@ -1,40 +1,40 @@ #ifndef MAPRULER_H #define MAPRULER_H -#include +#include #include #include -class MapRuler : public QGraphicsItem, private QLine +class MapRuler : public QGraphicsObject, private QLine { + Q_OBJECT + public: MapRuler(QColor innerColor = Qt::yellow, QColor borderColor = Qt::black) : innerColor(innerColor), - borderColor(borderColor) + borderColor(borderColor), + mapSize(QSize()) { init(); - setAcceptedMouseButtons(Qt::RightButton); } void init(); QRectF boundingRect() const override; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override; QPainterPath shape() const override; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override; + bool eventFilter(QObject *, QEvent *event) override; - // Anchor the ruler and make it visible - void setAnchor(const QPointF &scenePos, const QPoint &screenPos); - // Release the anchor and hide the ruler - void endAnchor(); - // Set the end point and repaint - void setEndPos(const QPointF &scenePos, const QPoint &screenPos); + void setEnabled(bool enabled); + bool isAnchored() const { return anchored; } + bool isLocked() const { return locked; } // Ruler start point in metatiles QPoint anchor() const { return QLine::p1(); } // Ruler end point in metatiles QPoint endPos() const { return QLine::p2(); } - // X-coordinate of the ruler left edge in metatiles + // X-coordinate of the ruler's left edge in metatiles int left() const { return qMin(anchor().x(), endPos().x()); } - // Y-coordinate of the ruler top edge in metatiles + // Y-coordinate of the ruler's top edge in metatiles int top() const { return qMin(anchor().y(), endPos().y()); } // Horizontal component of the ruler in metatiles int deltaX() const { return QLine::dx(); } @@ -44,30 +44,38 @@ public: int width() const { return qAbs(deltaX()); } // Ruler height in metatiles int height() const { return qAbs(deltaY()); } - // Ruler width in map pixels - int pixWidth() const { return width() * 16; } - // Ruler height in map pixels - int pixHeight() const { return height() * 16; } - bool isMousePressed(QGraphicsSceneMouseEvent *event) const; - bool isAnchored() const { return anchored; } - - bool locked; QString statusMessage; +public slots: + void mouseEvent(QGraphicsSceneMouseEvent *event); + void setMapDimensions(const QSize &size); + private: QColor innerColor; QColor borderColor; + QSize mapSize; QRect xRuler; QRect yRuler; QLineF cornerTick; bool anchored; + bool locked; static int thickness; - - void showDimensions(const QPoint &screenPos); + + QPoint snapToWithinBounds(QPoint pos) const; + void setAnchor(const QPointF &scenePos, const QPoint &screenPos); + void endAnchor(); + void setEndPos(const QPointF &scenePos, const QPoint &screenPos); + void showDimensions(const QPoint &screenPos) const; void hideDimensions() const; void updateGeometry(); + int pixWidth() const { return width() * 16; } + int pixHeight() const { return height() * 16; } + +signals: + void lengthChanged(); + void deactivated(const QPoint &endPos); }; #endif // MAPRULER_H diff --git a/src/core/map.cpp b/src/core/map.cpp index 3db6daeb..02cd15f8 100644 --- a/src/core/map.cpp +++ b/src/core/map.cpp @@ -353,6 +353,7 @@ void Map::setDimensions(int newWidth, int newHeight, bool setNewBlockdata) { layout->height = QString::number(newHeight); emit mapChanged(this); + emit mapDimensionsChanged(QSize(getWidth(), getHeight())); } void Map::setBorderDimensions(int newWidth, int newHeight, bool setNewBlockdata) { diff --git a/src/editor.cpp b/src/editor.cpp index 759df8f2..619abe3a 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -25,6 +25,8 @@ Editor::Editor(Ui::MainWindow* ui) this->playerViewRect = new MovableRect(&this->settings->playerViewRectEnabled, 30 * 8, 20 * 8, qRgb(255, 255, 255)); this->cursorMapTileRect = new CursorTileRect(&this->settings->cursorTileRectEnabled, qRgb(255, 255, 255)); this->map_ruler = new MapRuler(); + connect(this->map_ruler, &MapRuler::lengthChanged, this, &Editor::onMapRulerLengthChanged); + connect(this->map_ruler, &MapRuler::deactivated, this, &Editor::onHoveredMapMetatileChanged); /// Instead of updating the selected events after every single undo action /// (eg when the user rolls back several at once), only reselect events when @@ -913,8 +915,7 @@ void Editor::scaleMapView(int s) { } } -void Editor::onHoveredMapMetatileChanged(const QPointF &scenePos, const QPoint &screenPos) { - QPoint pos = Metatile::coordFromPixmapCoord(scenePos); +void Editor::onHoveredMapMetatileChanged(const QPoint &pos) { this->playerViewRect->updateLocation(pos.x(), pos.y()); this->cursorMapTileRect->updateLocation(pos.x(), pos.y()); if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles @@ -928,18 +929,22 @@ void Editor::onHoveredMapMetatileChanged(const QPointF &scenePos, const QPoint & .arg(QString::number(pow(scale_base, scale_exp), 'g', 2))); } else if (map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects && pos.x() >= 0 && pos.x() < map->getWidth() && pos.y() >= 0 && pos.y() < map->getHeight()) { - this->ui->statusBar->showMessage(QString("X: %1, Y: %2") + this->ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x") .arg(pos.x()) - .arg(pos.y())); - if (this->map_ruler->isAnchored()) { - this->map_ruler->setEndPos(scenePos, screenPos); - this->ui->statusBar->showMessage( - this->ui->statusBar->currentMessage() + "; " + this->map_ruler->statusMessage - ); - } + .arg(pos.y()) + .arg(QString::number(pow(scale_base, scale_exp), 'g', 2))); } } +void Editor::onMapRulerLengthChanged() { + const QPoint pos = map_ruler->endPos(); + ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x; %4") + .arg(pos.x()) + .arg(pos.y()) + .arg(QString::number(pow(scale_base, scale_exp), 'g', 2)) + .arg(map_ruler->statusMessage)); +} + void Editor::onHoveredMapMetatileCleared() { this->playerViewRect->setVisible(false); this->cursorMapTileRect->setVisible(false); @@ -1018,6 +1023,8 @@ bool Editor::setMap(QString map_name) { if (!displayMap()) { return false; } + map_ruler->setMapDimensions(QSize(map->getWidth(), map->getHeight())); + connect(map, &Map::mapDimensionsChanged, map_ruler, &MapRuler::setMapDimensions); updateSelectedEvents(); } @@ -1149,16 +1156,7 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item } } } else if (obj_edit_mode == "select") { - if (!this->map_ruler->isAnchored() && this->map_ruler->isMousePressed(event)) { - this->map_ruler->setAnchor(event->scenePos(), event->screenPos()); - } else if (this->map_ruler->isAnchored()) { - if (event->buttons() & Qt::LeftButton) - this->map_ruler->locked = !this->map_ruler->locked; - if (this->map_ruler->isMousePressed(event)) - this->map_ruler->endAnchor(); - else - this->map_ruler->setEndPos(event->scenePos(), event->screenPos()); - } + // do nothing here, at least for now } else if (obj_edit_mode == "shift" && item->map) { static QPoint selection_origin; static unsigned actionId = 0; @@ -1245,6 +1243,7 @@ bool Editor::displayMap() { MapSceneEventFilter *filter = new MapSceneEventFilter(); scene->installEventFilter(filter); connect(filter, &MapSceneEventFilter::wheelZoom, this, &Editor::onWheelZoom); + scene->installEventFilter(this->map_ruler); } if (map_item && scene) { @@ -1318,8 +1317,8 @@ void Editor::displayMapMetatiles() { this, SLOT(onMapStartPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*))); connect(map_item, SIGNAL(endPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*)), this, SLOT(onMapEndPaint(QGraphicsSceneMouseEvent*,MapPixmapItem*))); - connect(map_item, SIGNAL(hoveredMapMetatileChanged(const QPointF&, const QPoint&)), - this, SLOT(onHoveredMapMetatileChanged(const QPointF&, const QPoint&))); + connect(map_item, SIGNAL(hoveredMapMetatileChanged(const QPoint&)), + this, SLOT(onHoveredMapMetatileChanged(const QPoint&))); connect(map_item, SIGNAL(hoveredMapMetatileCleared()), this, SLOT(onHoveredMapMetatileCleared())); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index b599705e..45037f10 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1357,7 +1357,7 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index) editor->saveEncounterTabData(); } if (index != 1) { - editor->map_ruler->endAnchor(); + editor->map_ruler->setEnabled(false); } } @@ -2215,13 +2215,15 @@ void MainWindow::on_toolButton_Shift_clicked() void MainWindow::checkToolButtons() { QString edit_mode; - if (ui->mainTabBar->currentIndex() == 0) + if (ui->mainTabBar->currentIndex() == 0) { edit_mode = editor->map_edit_mode; - else + } else { edit_mode = editor->obj_edit_mode; - - if (edit_mode != "select" && editor->map_ruler) - editor->map_ruler->endAnchor(); + if (edit_mode == "select" && editor->map_ruler) + editor->map_ruler->setEnabled(true); + else if (editor->map_ruler) + editor->map_ruler->setEnabled(false); + } ui->toolButton_Paint->setChecked(edit_mode == "paint"); ui->toolButton_Select->setChecked(edit_mode == "select"); diff --git a/src/ui/draggablepixmapitem.cpp b/src/ui/draggablepixmapitem.cpp index d920662d..cde101b1 100644 --- a/src/ui/draggablepixmapitem.cpp +++ b/src/ui/draggablepixmapitem.cpp @@ -63,16 +63,6 @@ void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { last_y = pos.y(); this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier); this->editor->selectingEvent = true; - if (this->editor->obj_edit_mode == "select") { - if (!this->editor->map_ruler->isAnchored() && this->editor->map_ruler->isMousePressed(mouse)) { - this->editor->map_ruler->setAnchor(mouse->scenePos(), mouse->screenPos()); - } else if (this->editor->map_ruler->isAnchored()) { - if (mouse->buttons() & Qt::LeftButton) - this->editor->map_ruler->locked = !this->editor->map_ruler->locked; - if (this->editor->map_ruler->isMousePressed(mouse)) - this->editor->map_ruler->endAnchor(); - } - } } void DraggablePixmapItem::move(int x, int y) { @@ -85,10 +75,8 @@ void DraggablePixmapItem::move(int x, int y) { void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { if (active) { QPoint pos = Metatile::coordFromPixmapCoord(mouse->scenePos()); - emit this->editor->map_item->hoveredMapMetatileChanged(mouse->scenePos(), mouse->screenPos()); - if (this->editor->map_ruler->isAnchored()) { - this->editor->map_ruler->setEndPos(mouse->scenePos(), mouse->screenPos()); - } else if (pos.x() != last_x || pos.y() != last_y) { + emit this->editor->map_item->hoveredMapMetatileChanged(pos); + if (pos.x() != last_x || pos.y() != last_y) { QList selectedEvents; if (editor->selected_events->contains(this)) { for (DraggablePixmapItem *item : *editor->selected_events) { diff --git a/src/ui/mappixmapitem.cpp b/src/ui/mappixmapitem.cpp index ce4611af..0e02545d 100644 --- a/src/ui/mappixmapitem.cpp +++ b/src/ui/mappixmapitem.cpp @@ -723,7 +723,8 @@ void MapPixmapItem::draw(bool ignoreCache) { } void MapPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { - emit this->hoveredMapMetatileChanged(event->scenePos(), event->screenPos()); + QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); + emit this->hoveredMapMetatileChanged(pos); if (this->settings->betterCursors && this->paintingMode != MapPixmapItem::PaintMode::Disabled) { setCursor(this->settings->mapCursor); } @@ -746,7 +747,8 @@ void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { emit mouseEvent(event, this); } void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { - emit this->hoveredMapMetatileChanged(event->scenePos(), event->screenPos()); + QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); + emit this->hoveredMapMetatileChanged(pos); emit mouseEvent(event, this); } void MapPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { diff --git a/src/ui/mapruler.cpp b/src/ui/mapruler.cpp index b3c8cd3d..ed404176 100644 --- a/src/ui/mapruler.cpp +++ b/src/ui/mapruler.cpp @@ -1,8 +1,8 @@ #include "mapruler.h" #include "metatile.h" -#include -#include +#include +#include #include #include #include @@ -46,17 +46,71 @@ void MapRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge painter->drawLine(cornerTick); } +bool MapRuler::eventFilter(QObject*, QEvent *event) { + if (!isEnabled() || mapSize.isEmpty()) + return false; + + if (event->type() == QEvent::GraphicsSceneMousePress || event->type() == QEvent::GraphicsSceneMouseMove) { + auto mouse_event = static_cast(event); + if (mouse_event->button() == Qt::RightButton || anchored) { + mouseEvent(mouse_event); + event->accept(); + return true; + } + } + + return false; +} + +void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) { + if (!anchored && event->button() == Qt::RightButton) { + setAnchor(event->scenePos(), event->screenPos()); + } else if (anchored) { + if (event->button() == Qt::LeftButton) + locked = !locked; + if (event->button() == Qt::RightButton) + endAnchor(); + else + setEndPos(event->scenePos(), event->screenPos()); + } +} + +void MapRuler::setMapDimensions(const QSize &size) { + mapSize = size; + init(); +} + +void MapRuler::setEnabled(bool enabled) { + QGraphicsItem::setEnabled(enabled); + if (!enabled && anchored) + endAnchor(); +} + +QPoint MapRuler::snapToWithinBounds(QPoint pos) const { + if (pos.x() < 0) + pos.setX(0); + if (pos.y() < 0) + pos.setY(0); + if (pos.x() >= mapSize.width()) + pos.setX(mapSize.width() - 1); + if (pos.y() >= mapSize.height()) + pos.setY(mapSize.height() - 1); + return pos; +} + void MapRuler::setAnchor(const QPointF &scenePos, const QPoint &screenPos) { + QPoint pos = Metatile::coordFromPixmapCoord(scenePos); + pos = snapToWithinBounds(pos); anchored = true; locked = false; - QPoint tilePos = Metatile::coordFromPixmapCoord(scenePos); - setPoints(tilePos, tilePos); + setPoints(pos, pos); updateGeometry(); setVisible(true); showDimensions(screenPos); } void MapRuler::endAnchor() { + emit deactivated(endPos()); hideDimensions(); prepareGeometryChange(); init(); @@ -66,18 +120,15 @@ void MapRuler::setEndPos(const QPointF &scenePos, const QPoint &screenPos) { if (locked) return; QPoint pos = Metatile::coordFromPixmapCoord(scenePos); - QPoint lastEndPos = endPos(); + pos = snapToWithinBounds(pos); + const QPoint lastEndPos = endPos(); setP2(pos); if (pos != lastEndPos) updateGeometry(); showDimensions(screenPos); } -bool MapRuler::isMousePressed(QGraphicsSceneMouseEvent *event) const { - return event->buttons() & acceptedMouseButtons() && event->type() == QEvent::GraphicsSceneMousePress; -} - -void MapRuler::showDimensions(const QPoint &screenPos) { +void MapRuler::showDimensions(const QPoint &screenPos) const { // This is a hack to make the tool tip follow the cursor since it won't change position if the text is the same. QToolTip::showText(screenPos + QPoint(16, -8), statusMessage + ' '); QToolTip::showText(screenPos + QPoint(16, -8), statusMessage); @@ -134,4 +185,5 @@ void MapRuler::updateGeometry() { statusMessage += QString("0"); } } + emit lengthChanged(); }