2020-09-25 16:53:07 +01:00
|
|
|
#include "mapruler.h"
|
2020-10-02 17:12:19 +01:00
|
|
|
#include "metatile.h"
|
2020-09-25 16:53:07 +01:00
|
|
|
|
|
|
|
#include <QGraphicsItem>
|
2020-10-02 17:12:19 +01:00
|
|
|
#include <QGraphicsSceneMouseEvent>
|
2020-09-25 16:53:07 +01:00
|
|
|
#include <QPainter>
|
|
|
|
#include <QColor>
|
2020-10-02 17:12:19 +01:00
|
|
|
#include <QToolTip>
|
2020-09-25 16:53:07 +01:00
|
|
|
|
|
|
|
int MapRuler::thickness = 3;
|
|
|
|
|
|
|
|
|
|
|
|
void MapRuler::init() {
|
|
|
|
setVisible(false);
|
|
|
|
setPoints(QPoint(), QPoint());
|
2020-10-02 17:12:19 +01:00
|
|
|
anchored = false;
|
|
|
|
locked = false;
|
|
|
|
statusMessage = QString("Ruler: 0");
|
2020-09-25 16:53:07 +01:00
|
|
|
xRuler = QRect();
|
|
|
|
yRuler = QRect();
|
2020-10-02 17:12:19 +01:00
|
|
|
cornerTick = QLine();
|
2020-09-25 16:53:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QRectF MapRuler::boundingRect() const {
|
2020-10-02 17:12:19 +01:00
|
|
|
return QRectF(-thickness, -thickness, pixWidth() + thickness * 2, pixHeight() + thickness * 2);
|
2020-09-25 16:53:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QPainterPath MapRuler::shape() const {
|
|
|
|
QPainterPath ruler;
|
|
|
|
ruler.setFillRule(Qt::WindingFill);
|
|
|
|
ruler.addRect(xRuler);
|
|
|
|
ruler.addRect(yRuler);
|
|
|
|
ruler = ruler.simplified();
|
2020-09-25 16:56:02 +01:00
|
|
|
for (int x = 17.5; x < pixWidth(); x += 16)
|
|
|
|
ruler.addRect(x, xRuler.y(), 0, thickness);
|
|
|
|
for (int y = 17.5; y < pixHeight(); y += 16)
|
|
|
|
ruler.addRect(yRuler.x(), y, thickness, 0);
|
2020-09-25 16:53:07 +01:00
|
|
|
return ruler;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MapRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
|
2020-10-02 17:12:19 +01:00
|
|
|
painter->setPen(QPen(borderColor));
|
|
|
|
painter->setBrush(QBrush(innerColor));
|
2020-09-25 16:53:07 +01:00
|
|
|
painter->drawPath(shape());
|
2020-10-02 17:12:19 +01:00
|
|
|
if (deltaX() && deltaY())
|
2020-09-25 16:56:02 +01:00
|
|
|
painter->drawLine(cornerTick);
|
2020-09-25 16:53:07 +01:00
|
|
|
}
|
|
|
|
|
2020-10-02 17:12:19 +01:00
|
|
|
void MapRuler::setAnchor(const QPointF &scenePos, const QPoint &screenPos) {
|
|
|
|
anchored = true;
|
|
|
|
locked = false;
|
|
|
|
QPoint tilePos = Metatile::coordFromPixmapCoord(scenePos);
|
2020-09-25 16:53:07 +01:00
|
|
|
setPoints(tilePos, tilePos);
|
2020-10-02 17:12:19 +01:00
|
|
|
updateGeometry();
|
2020-09-25 16:53:07 +01:00
|
|
|
setVisible(true);
|
2020-10-02 17:12:19 +01:00
|
|
|
showDimensions(screenPos);
|
2020-09-25 16:53:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void MapRuler::endAnchor() {
|
2020-10-02 17:12:19 +01:00
|
|
|
hideDimensions();
|
2020-09-25 16:53:07 +01:00
|
|
|
prepareGeometryChange();
|
|
|
|
init();
|
|
|
|
}
|
|
|
|
|
2020-10-02 17:12:19 +01:00
|
|
|
void MapRuler::setEndPos(const QPointF &scenePos, const QPoint &screenPos) {
|
|
|
|
if (locked)
|
2020-09-25 16:53:07 +01:00
|
|
|
return;
|
2020-10-02 17:12:19 +01:00
|
|
|
QPoint pos = Metatile::coordFromPixmapCoord(scenePos);
|
|
|
|
QPoint lastEndPos = endPos();
|
|
|
|
setP2(pos);
|
|
|
|
if (pos != lastEndPos)
|
|
|
|
updateGeometry();
|
|
|
|
showDimensions(screenPos);
|
2020-09-25 16:53:07 +01:00
|
|
|
}
|
|
|
|
|
2020-10-02 17:12:19 +01:00
|
|
|
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();
|
2020-09-25 16:53:07 +01:00
|
|
|
setPos(QPoint(left() * 16 + 7, top() * 16 + 7));
|
2020-10-02 17:12:19 +01:00
|
|
|
/* 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. */
|
2020-09-25 16:53:07 +01:00
|
|
|
if (deltaX() < 0 && deltaY() < 0) {
|
|
|
|
// Top-left
|
|
|
|
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness);
|
|
|
|
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
2020-09-25 16:56:02 +01:00
|
|
|
cornerTick = QLineF(yRuler.x() + 0.5, xRuler.y() + thickness - 0.5, yRuler.x() + thickness, xRuler.y());
|
2020-10-02 17:12:19 +01:00
|
|
|
statusMessage = QString("Ruler: Left %1, Up %2").arg(width()).arg(height());
|
2020-09-25 16:53:07 +01:00
|
|
|
} else if (deltaX() < 0) {
|
|
|
|
// Bottom-left
|
|
|
|
xRuler = QRect(0, 0, pixWidth() + thickness, thickness);
|
|
|
|
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
2020-09-25 16:56:02 +01:00
|
|
|
cornerTick = QLineF(xRuler.x() + 0.5, xRuler.y() + 0.5, xRuler.x() + thickness, xRuler.y() + thickness);
|
2020-10-02 17:12:19 +01:00
|
|
|
statusMessage = QString("Ruler: Left %1").arg(width());
|
|
|
|
if (deltaY())
|
|
|
|
statusMessage += QString(", Down %1").arg(height());
|
2020-09-25 16:53:07 +01:00
|
|
|
} else if (deltaY() < 0) {
|
|
|
|
// Top-right
|
|
|
|
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness);
|
|
|
|
yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness);
|
2020-09-25 16:56:02 +01:00
|
|
|
cornerTick = QLineF(yRuler.x(), xRuler.y(), yRuler.x() + thickness - 0.5, xRuler.y() + thickness - 0.5);
|
2020-10-02 17:12:19 +01:00
|
|
|
statusMessage = QString("Ruler: ");
|
|
|
|
if (deltaX())
|
|
|
|
statusMessage += QString("Right %1, ").arg(width());
|
|
|
|
statusMessage += QString("Up %1").arg(height());
|
2020-09-25 16:53:07 +01:00
|
|
|
} else {
|
|
|
|
// Bottom-right
|
|
|
|
xRuler = QRect(0, 0, pixWidth() + thickness, thickness);
|
|
|
|
yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness);
|
2020-09-25 16:56:02 +01:00
|
|
|
cornerTick = QLineF(yRuler.x(), yRuler.y() + thickness, yRuler.x() + thickness - 0.5, yRuler.y() + 0.5);
|
2020-10-02 17:12:19 +01:00
|
|
|
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");
|
|
|
|
}
|
2020-09-25 16:53:07 +01:00
|
|
|
}
|
|
|
|
}
|