diff --git a/include/editor.h b/include/editor.h index 72b94f89..d562f20f 100644 --- a/include/editor.h +++ b/include/editor.h @@ -195,7 +195,7 @@ private slots: void onHoveredMovementPermissionCleared(); void onHoveredMetatileSelectionChanged(uint16_t); void onHoveredMetatileSelectionCleared(); - void onHoveredMapMetatileChanged(int, int); + void onHoveredMapMetatileChanged(const QPointF &scenePos, const QPoint &screenPos); void onHoveredMapMetatileCleared(); void onHoveredMapMovementPermissionChanged(int, int); void onHoveredMapMovementPermissionCleared(); diff --git a/include/ui/mappixmapitem.h b/include/ui/mappixmapitem.h index e8a1cd1c..a6ed0ab9 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(int x, int y); + void hoveredMapMetatileChanged(const QPointF &scenePos, const QPoint &screenPos); void hoveredMapMetatileCleared(); protected: diff --git a/include/ui/mapruler.h b/include/ui/mapruler.h index 1fd97d84..7d0be579 100644 --- a/include/ui/mapruler.h +++ b/include/ui/mapruler.h @@ -9,8 +9,9 @@ class MapRuler : public QGraphicsItem, private QLine { public: - MapRuler(QColor interior = Qt::yellow, QColor exterior = Qt::black) - : interiorColor(interior), exteriorColor(exterior) + MapRuler(QColor innerColor = Qt::yellow, QColor borderColor = Qt::black) : + innerColor(innerColor), + borderColor(borderColor) { init(); setAcceptedMouseButtons(Qt::RightButton); @@ -20,17 +21,13 @@ public: void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override; QPainterPath shape() const override; - // Anchor the ruler on metatile 'tilePos' and show the ruler - void setAnchor(const QPoint &tilePos); - // Anchor the ruler on metatile (tileX,tileY) and show the ruler - void setAnchor(int tileX, int tileY) { setAnchor(QPoint(tileX, tileY)); } - // Release the ruler anchor and hide the ruler + // 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 ruler end point to metatile 'tilePos' and repaint - void setEndPos(const QPoint &tilePos); - // Set the ruler end point to metatile (tileX, tileY) and repaint - void setEndPos(int tileX, int tileY) { setEndPos(QPoint(tileX, tileY)); } - + // Set the end point and repaint + void setEndPos(const QPointF &scenePos, const QPoint &screenPos); + // Ruler start point in metatiles QPoint anchor() const { return QLine::p1(); } // Ruler end point in metatiles @@ -52,21 +49,25 @@ public: // Ruler height in map pixels int pixHeight() const { return height() * 16; } - bool mousePressed(Qt::MouseButtons buttons) { return buttons & acceptedMouseButtons(); } + bool isMousePressed(QGraphicsSceneMouseEvent *event) const; + bool isAnchored() const { return anchored; } + + bool locked; + QString statusMessage; private: + QColor innerColor; + QColor borderColor; QRect xRuler; QRect yRuler; QLineF cornerTick; - QRect widthTextBox; - QRect heightTextBox; - QColor interiorColor; - QColor exteriorColor; + bool anchored; - static int padding; static int thickness; - void updateShape(); + void showDimensions(const QPoint &screenPos); + void hideDimensions() const; + void updateGeometry(); }; #endif // MAPRULER_H diff --git a/src/editor.cpp b/src/editor.cpp index 00f562fc..368dd753 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -889,23 +889,31 @@ void Editor::onSelectedMetatilesChanged() { this->redrawCurrentMetatilesSelection(); } -void Editor::onHoveredMapMetatileChanged(int x, int y) { - this->playerViewRect->updateLocation(x, y); - this->cursorMapTileRect->updateLocation(x, y); +void Editor::onHoveredMapMetatileChanged(const QPointF &scenePos, const QPoint &screenPos) { + QPoint pos = Metatile::coordFromPixmapCoord(scenePos); + this->playerViewRect->updateLocation(pos.x(), pos.y()); + this->cursorMapTileRect->updateLocation(pos.x(), pos.y()); + if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles - && x >= 0 && x < map->getWidth() && y >= 0 && y < map->getHeight()) { - int blockIndex = y * map->getWidth() + x; + && pos.x() >= 0 && pos.x() < map->getWidth() && pos.y() >= 0 && pos.y() < map->getHeight()) { + int blockIndex = pos.y() * map->getWidth() + pos.x(); int metatileId = map->layout->blockdata->blocks->at(blockIndex).tile; this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x") - .arg(x) - .arg(y) + .arg(pos.x()) + .arg(pos.y()) .arg(getMetatileDisplayMessage(metatileId)) .arg(QString::number(pow(scale_base, scale_exp), 'g', 2))); } else if (map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects - && x >= 0 && x < map->getWidth() && y >= 0 && y < map->getHeight()) { + && pos.x() >= 0 && pos.x() < map->getWidth() && pos.y() >= 0 && pos.y() < map->getHeight()) { this->ui->statusBar->showMessage(QString("X: %1, Y: %2") - .arg(x) - .arg(y)); + .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 + ); + } } } @@ -915,6 +923,9 @@ void Editor::onHoveredMapMetatileCleared() { if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles || map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects) { this->ui->statusBar->clearMessage(); + if (this->map_ruler->isAnchored()) { + this->ui->statusBar->showMessage(this->map_ruler->statusMessage); + } } } @@ -1121,13 +1132,15 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item } } } else if (obj_edit_mode == "select") { - if (!this->map_ruler->isEnabled() && this->map_ruler->mousePressed(event->buttons())) { - this->map_ruler->setAnchor(x, y); - } else if (event->type() == QEvent::GraphicsSceneMouseRelease - && !this->map_ruler->mousePressed(event->buttons())) { - this->map_ruler->endAnchor(); - } else if (this->map_ruler->isEnabled()) { - this->map_ruler->setEndPos(x, y); + 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()); } } else if (obj_edit_mode == "shift" && item->map) { static QPoint selection_origin; @@ -1292,8 +1305,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(int, int)), - this, SLOT(onHoveredMapMetatileChanged(int, int))); + connect(map_item, SIGNAL(hoveredMapMetatileChanged(const QPointF&, const QPoint&)), + this, SLOT(onHoveredMapMetatileChanged(const QPointF&, const QPoint&))); connect(map_item, SIGNAL(hoveredMapMetatileCleared()), this, SLOT(onHoveredMapMetatileCleared())); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index ee1bd97e..e44753f7 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1346,6 +1346,9 @@ void MainWindow::on_mainTabBar_tabBarClicked(int index) if (projectConfig.getEncounterJsonActive()) editor->saveEncounterTabData(); } + if (index != 1) { + editor->map_ruler->endAnchor(); + } } void MainWindow::on_actionZoom_In_triggered() { diff --git a/src/ui/draggablepixmapitem.cpp b/src/ui/draggablepixmapitem.cpp index 3ae3cca4..a293aba6 100644 --- a/src/ui/draggablepixmapitem.cpp +++ b/src/ui/draggablepixmapitem.cpp @@ -2,6 +2,7 @@ #include "editor.h" #include "editcommands.h" #include "mapruler.h" +#include "metatile.h" static unsigned currentActionId = 0; @@ -56,17 +57,20 @@ void DraggablePixmapItem::bindToUserData(QComboBox *combo, QString key) { } void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) { - int x = static_cast(mouse->pos().x() + this->pos().x()) / 16; - int y = static_cast(mouse->pos().y() + this->pos().y()) / 16; - if (mouse->buttons() & this->editor->map_ruler->acceptedMouseButtons()) { - this->editor->map_ruler->setAnchor(x, y); - return; - } active = true; - last_x = x; - last_y = y; + QPoint pos = Metatile::coordFromPixmapCoord(mouse->scenePos()); + last_x = pos.x(); + last_y = pos.y(); this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier); this->editor->selectingEvent = true; + 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) { @@ -78,12 +82,11 @@ void DraggablePixmapItem::move(int x, int y) { void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { if (active) { - int x = static_cast(mouse->pos().x() + this->pos().x()) / 16; - int y = static_cast(mouse->pos().y() + this->pos().y()) / 16; - emit this->editor->map_item->hoveredMapMetatileChanged(x, y); - if (this->editor->map_ruler->isEnabled()) { - this->editor->map_ruler->setEndPos(x, y); - } else if (x != last_x || y != last_y) { + 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) { QList selectedEvents; if (editor->selected_events->contains(this)) { for (DraggablePixmapItem *item : *editor->selected_events) { @@ -92,21 +95,16 @@ void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) { } else { selectedEvents.append(this->event); } - editor->map->editHistory.push(new EventMove(selectedEvents, x - last_x, y - last_y, currentActionId)); - last_x = x; - last_y = y; + editor->map->editHistory.push(new EventMove(selectedEvents, pos.x() - last_x, pos.y() - last_y, currentActionId)); + last_x = pos.x(); + last_y = pos.y(); } } } -void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouse) { - if (!(mouse->buttons() & this->editor->map_ruler->acceptedMouseButtons())) { - this->editor->map_ruler->endAnchor(); - } - if (!this->editor->map_ruler->isEnabled()) { - active = false; - currentActionId++; - } +void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) { + active = false; + currentActionId++; } void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) { diff --git a/src/ui/mappixmapitem.cpp b/src/ui/mappixmapitem.cpp index 60555d84..537a5ddf 100644 --- a/src/ui/mappixmapitem.cpp +++ b/src/ui/mappixmapitem.cpp @@ -742,7 +742,7 @@ void MapPixmapItem::draw(bool ignoreCache) { void MapPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) { int x = static_cast(event->pos().x()) / 16; int y = static_cast(event->pos().y()) / 16; - emit this->hoveredMapMetatileChanged(x, y); + emit this->hoveredMapMetatileChanged(event->scenePos(), event->screenPos()); if (this->settings->betterCursors && this->paintingMode != MapPixmapItem::PaintMode::Disabled) { setCursor(this->settings->mapCursor); } @@ -769,7 +769,7 @@ void MapPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { void MapPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { int x = static_cast(event->pos().x()) / 16; int y = static_cast(event->pos().y()) / 16; - emit this->hoveredMapMetatileChanged(x, y); + emit this->hoveredMapMetatileChanged(event->scenePos(), event->screenPos()); emit mouseEvent(event, this); } void MapPixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { diff --git a/src/ui/mapruler.cpp b/src/ui/mapruler.cpp index f60f992b..b3c8cd3d 100644 --- a/src/ui/mapruler.cpp +++ b/src/ui/mapruler.cpp @@ -1,25 +1,28 @@ #include "mapruler.h" +#include "metatile.h" #include +#include #include #include +#include -int MapRuler::padding = 24; int MapRuler::thickness = 3; void MapRuler::init() { setVisible(false); - setEnabled(false); setPoints(QPoint(), QPoint()); + anchored = false; + locked = false; + statusMessage = QString("Ruler: 0"); xRuler = QRect(); yRuler = QRect(); - widthTextBox = QRect(); - heightTextBox = QRect(); + cornerTick = QLine(); } QRectF MapRuler::boundingRect() const { - return QRectF(-padding, -padding, pixWidth() + padding * 2, pixHeight() + padding * 2); + return QRectF(-thickness, -thickness, pixWidth() + thickness * 2, pixHeight() + thickness * 2); } QPainterPath MapRuler::shape() const { @@ -36,69 +39,99 @@ QPainterPath MapRuler::shape() const { } void MapRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { - painter->setPen(exteriorColor); - painter->setBrush(QBrush(interiorColor)); + painter->setPen(QPen(borderColor)); + painter->setBrush(QBrush(innerColor)); painter->drawPath(shape()); - if (width() && height()) + if (deltaX() && deltaY()) painter->drawLine(cornerTick); - painter->drawText(widthTextBox, Qt::AlignCenter, QString("%1").arg(width())); - painter->drawText(heightTextBox, Qt::AlignCenter, QString("%1").arg(height())); } -void MapRuler::setAnchor(const QPoint &tilePos) { - setEnabled(true); +void MapRuler::setAnchor(const QPointF &scenePos, const QPoint &screenPos) { + anchored = true; + locked = false; + QPoint tilePos = Metatile::coordFromPixmapCoord(scenePos); setPoints(tilePos, tilePos); - updateShape(); + updateGeometry(); setVisible(true); + showDimensions(screenPos); } void MapRuler::endAnchor() { - setVisible(false); - setEnabled(false); + hideDimensions(); prepareGeometryChange(); init(); } -void MapRuler::setEndPos(const QPoint &tilePos) { - if (!isEnabled() || (tilePos == endPos() && tilePos != anchor())) +void MapRuler::setEndPos(const QPointF &scenePos, const QPoint &screenPos) { + if (locked) return; - prepareGeometryChange(); - setP2(tilePos); - updateShape(); + QPoint pos = Metatile::coordFromPixmapCoord(scenePos); + QPoint lastEndPos = endPos(); + setP2(pos); + if (pos != lastEndPos) + updateGeometry(); + showDimensions(screenPos); } -void MapRuler::updateShape() { +bool MapRuler::isMousePressed(QGraphicsSceneMouseEvent *event) const { + return event->buttons() & acceptedMouseButtons() && event->type() == QEvent::GraphicsSceneMousePress; +} + +void MapRuler::showDimensions(const QPoint &screenPos) { + // 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); +} + +void MapRuler::hideDimensions() const { + QToolTip::hideText(); +} + +void MapRuler::updateGeometry() { + prepareGeometryChange(); setPos(QPoint(left() * 16 + 7, top() * 16 + 7)); - /* Determines what quadrant the ruler exists in, relative to the anchor point. The anchor point - * is the top-left corner of the metatile the ruler starts in, so a zero-length(s) ruler is - * treated as being in the bottom-right quadrant from the anchor point. */ + /* Determine what quadrant the end point is in relative to the anchor point. The anchor + * point is the top-left corner of the metatile the ruler starts in, so a zero-length(s) + * ruler is considered to be in the bottom-right quadrant from the anchor point. */ if (deltaX() < 0 && deltaY() < 0) { // Top-left xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness); yRuler = QRect(0, 0, thickness, pixHeight() + thickness); cornerTick = QLineF(yRuler.x() + 0.5, xRuler.y() + thickness - 0.5, yRuler.x() + thickness, xRuler.y()); - widthTextBox = QRect(0, pixHeight(), pixWidth(), padding); - heightTextBox = QRect(-padding, 0, padding, pixHeight()); + statusMessage = QString("Ruler: Left %1, Up %2").arg(width()).arg(height()); } else if (deltaX() < 0) { // Bottom-left xRuler = QRect(0, 0, pixWidth() + thickness, thickness); yRuler = QRect(0, 0, thickness, pixHeight() + thickness); cornerTick = QLineF(xRuler.x() + 0.5, xRuler.y() + 0.5, xRuler.x() + thickness, xRuler.y() + thickness); - widthTextBox = QRect(0, -padding, pixWidth(), padding); - heightTextBox = QRect(-padding, 0, padding, pixHeight()); + statusMessage = QString("Ruler: Left %1").arg(width()); + if (deltaY()) + statusMessage += QString(", Down %1").arg(height()); } else if (deltaY() < 0) { // Top-right xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness); yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness); cornerTick = QLineF(yRuler.x(), xRuler.y(), yRuler.x() + thickness - 0.5, xRuler.y() + thickness - 0.5); - widthTextBox = QRect(0, pixHeight(), pixWidth(), padding); - heightTextBox = QRect(pixWidth(), 0, padding, pixHeight()); + statusMessage = QString("Ruler: "); + if (deltaX()) + statusMessage += QString("Right %1, ").arg(width()); + statusMessage += QString("Up %1").arg(height()); } else { // Bottom-right xRuler = QRect(0, 0, pixWidth() + thickness, thickness); yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness); cornerTick = QLineF(yRuler.x(), yRuler.y() + thickness, yRuler.x() + thickness - 0.5, yRuler.y() + 0.5); - widthTextBox = QRect(0, -padding, pixWidth(), padding); - heightTextBox = QRect(pixWidth(), 0, padding, pixHeight()); + statusMessage = QString("Ruler: "); + if (deltaX() || deltaY()) { + if (deltaX()) + statusMessage += QString("Right %1").arg(width()); + if (deltaY()) { + if (deltaX()) + statusMessage += ", "; + statusMessage += QString("Down: %1").arg(height()); + } + } else { + statusMessage += QString("0"); + } } }