Turn MapRuler dimensions into a mouse-tracking tooltip, and show in status bar

This commit is contained in:
BigBahss 2020-10-02 12:12:19 -04:00
parent 84f920bb03
commit 39aa420265
8 changed files with 147 additions and 99 deletions

View file

@ -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();

View file

@ -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:

View file

@ -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,16 +21,12 @@ 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(); }
@ -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

View file

@ -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()));

View file

@ -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() {

View file

@ -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<int>(mouse->pos().x() + this->pos().x()) / 16;
int y = static_cast<int>(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<int>(mouse->pos().x() + this->pos().x()) / 16;
int y = static_cast<int>(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 <Event *> 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 *) {

View file

@ -742,7 +742,7 @@ void MapPixmapItem::draw(bool ignoreCache) {
void MapPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
int x = static_cast<int>(event->pos().x()) / 16;
int y = static_cast<int>(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<int>(event->pos().x()) / 16;
int y = static_cast<int>(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) {

View file

@ -1,25 +1,28 @@
#include "mapruler.h"
#include "metatile.h"
#include <QGraphicsItem>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QColor>
#include <QToolTip>
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");
}
}
}