MapRuler: Fix artifacting, fix centering for other thickness values
This commit is contained in:
parent
6ca4802948
commit
b9aaef24c6
3 changed files with 77 additions and 55 deletions
|
@ -10,7 +10,8 @@ class MapRuler : public QGraphicsObject, private QLine
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MapRuler(QColor innerColor = Qt::yellow, QColor borderColor = Qt::black);
|
// thickness is given in scene pixels
|
||||||
|
MapRuler(int thickness, QColor innerColor = Qt::yellow, QColor borderColor = Qt::black);
|
||||||
|
|
||||||
QRectF boundingRect() const override;
|
QRectF boundingRect() const override;
|
||||||
QPainterPath shape() const override;
|
QPainterPath shape() const override;
|
||||||
|
@ -45,23 +46,23 @@ signals:
|
||||||
void statusChanged(const QString &statusMessage);
|
void statusChanged(const QString &statusMessage);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QColor innerColor;
|
const int thickness;
|
||||||
QColor borderColor;
|
const qreal half_thickness;
|
||||||
|
const QColor innerColor;
|
||||||
|
const QColor borderColor;
|
||||||
QSize mapSize;
|
QSize mapSize;
|
||||||
QString statusMessage;
|
QRectF xRuler;
|
||||||
QRect xRuler;
|
QRectF yRuler;
|
||||||
QRect yRuler;
|
|
||||||
QLineF cornerTick;
|
QLineF cornerTick;
|
||||||
bool anchored;
|
bool anchored;
|
||||||
bool locked;
|
bool locked;
|
||||||
|
|
||||||
static int thickness;
|
void reset();
|
||||||
|
|
||||||
void init();
|
|
||||||
void setAnchor(const QPointF &scenePos);
|
void setAnchor(const QPointF &scenePos);
|
||||||
void setEndPos(const QPointF &scenePos);
|
void setEndPos(const QPointF &scenePos);
|
||||||
QPoint snapToWithinBounds(QPoint pos) const;
|
QPoint snapToWithinBounds(QPoint pos) const;
|
||||||
void updateGeometry();
|
void updateGeometry();
|
||||||
|
void updateStatus(Qt::Corner corner);
|
||||||
int pixWidth() const { return width() * 16; }
|
int pixWidth() const { return width() * 16; }
|
||||||
int pixHeight() const { return height() * 16; }
|
int pixHeight() const { return height() * 16; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,7 +24,7 @@ Editor::Editor(Ui::MainWindow* ui)
|
||||||
this->settings = new Settings();
|
this->settings = new Settings();
|
||||||
this->playerViewRect = new MovableRect(&this->settings->playerViewRectEnabled, 30 * 8, 20 * 8, qRgb(255, 255, 255));
|
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->cursorMapTileRect = new CursorTileRect(&this->settings->cursorTileRectEnabled, qRgb(255, 255, 255));
|
||||||
this->map_ruler = new MapRuler();
|
this->map_ruler = new MapRuler(4);
|
||||||
connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged);
|
connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged);
|
||||||
|
|
||||||
/// Instead of updating the selected events after every single undo action
|
/// Instead of updating the selected events after every single undo action
|
||||||
|
|
|
@ -4,29 +4,31 @@
|
||||||
#include <QGraphicsSceneEvent>
|
#include <QGraphicsSceneEvent>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QVector>
|
||||||
int MapRuler::thickness = 3;
|
|
||||||
|
|
||||||
|
|
||||||
MapRuler::MapRuler(QColor innerColor, QColor borderColor) :
|
MapRuler::MapRuler(int thickness, QColor innerColor, QColor borderColor) :
|
||||||
|
/* The logical representation of rectangles are always one less than
|
||||||
|
* the rendered shape, so we subtract 1 from thickness. */
|
||||||
|
thickness(thickness - 1),
|
||||||
|
half_thickness(qreal(thickness - 1) / 2.0),
|
||||||
innerColor(innerColor),
|
innerColor(innerColor),
|
||||||
borderColor(borderColor),
|
borderColor(borderColor),
|
||||||
mapSize(QSize()),
|
mapSize(QSize()),
|
||||||
statusMessage(QString()),
|
xRuler(QRectF()),
|
||||||
xRuler(QRect()),
|
yRuler(QRectF()),
|
||||||
yRuler(QRect()),
|
cornerTick(QLineF()),
|
||||||
cornerTick(QLine()),
|
|
||||||
anchored(false),
|
anchored(false),
|
||||||
locked(false)
|
locked(false)
|
||||||
{
|
{
|
||||||
connect(this, &QGraphicsObject::enabledChanged, [this]() {
|
connect(this, &QGraphicsObject::enabledChanged, [this]() {
|
||||||
if (!isEnabled() && anchored)
|
if (!isEnabled() && anchored)
|
||||||
init();
|
reset();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF MapRuler::boundingRect() const {
|
QRectF MapRuler::boundingRect() const {
|
||||||
return QRectF(-thickness, -thickness, pixWidth() + thickness * 2, pixHeight() + thickness * 2);
|
return QRectF(-(half_thickness + 1), -(half_thickness + 1), pixWidth() + thickness + 2, pixHeight() + thickness + 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainterPath MapRuler::shape() const {
|
QPainterPath MapRuler::shape() const {
|
||||||
|
@ -35,10 +37,12 @@ QPainterPath MapRuler::shape() const {
|
||||||
ruler.addRect(xRuler);
|
ruler.addRect(xRuler);
|
||||||
ruler.addRect(yRuler);
|
ruler.addRect(yRuler);
|
||||||
ruler = ruler.simplified();
|
ruler = ruler.simplified();
|
||||||
for (int x = 17; x < pixWidth(); x += 16)
|
for (int x = 16; x < pixWidth(); x += 16)
|
||||||
ruler.addRect(x, xRuler.y(), 0, thickness);
|
ruler.addRect(x, xRuler.y(), 0, thickness);
|
||||||
for (int y = 17; y < pixHeight(); y += 16)
|
for (int y = 16; y < pixHeight(); y += 16)
|
||||||
ruler.addRect(yRuler.x(), y, thickness, 0);
|
ruler.addRect(yRuler.x(), y, thickness, 0);
|
||||||
|
if (deltaX() && deltaY())
|
||||||
|
ruler.addPolygon(QVector<QPointF>({ cornerTick.p1(), cornerTick.p2() }));
|
||||||
return ruler;
|
return ruler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,16 +50,14 @@ void MapRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge
|
||||||
painter->setPen(QPen(borderColor));
|
painter->setPen(QPen(borderColor));
|
||||||
painter->setBrush(QBrush(innerColor));
|
painter->setBrush(QBrush(innerColor));
|
||||||
painter->drawPath(shape());
|
painter->drawPath(shape());
|
||||||
if (deltaX() && deltaY())
|
|
||||||
painter->drawLine(cornerTick);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MapRuler::eventFilter(QObject*, QEvent *event) {
|
bool MapRuler::eventFilter(QObject *, QEvent *event) {
|
||||||
if (!isEnabled() || mapSize.isEmpty())
|
if (!isEnabled() || mapSize.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (event->type() == QEvent::GraphicsSceneMousePress || event->type() == QEvent::GraphicsSceneMouseMove) {
|
if (event->type() == QEvent::GraphicsSceneMousePress || event->type() == QEvent::GraphicsSceneMouseMove) {
|
||||||
auto mouse_event = static_cast<QGraphicsSceneMouseEvent *>(event);
|
auto *mouse_event = static_cast<QGraphicsSceneMouseEvent *>(event);
|
||||||
if (mouse_event->button() == Qt::RightButton || anchored) {
|
if (mouse_event->button() == Qt::RightButton || anchored) {
|
||||||
mouseEvent(mouse_event);
|
mouseEvent(mouse_event);
|
||||||
}
|
}
|
||||||
|
@ -71,7 +73,7 @@ void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
if (event->button() == Qt::LeftButton)
|
if (event->button() == Qt::LeftButton)
|
||||||
locked = !locked;
|
locked = !locked;
|
||||||
if (event->button() == Qt::RightButton)
|
if (event->button() == Qt::RightButton)
|
||||||
init();
|
reset();
|
||||||
else
|
else
|
||||||
setEndPos(event->scenePos());
|
setEndPos(event->scenePos());
|
||||||
}
|
}
|
||||||
|
@ -79,20 +81,19 @@ void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) {
|
||||||
|
|
||||||
void MapRuler::setMapDimensions(const QSize &size) {
|
void MapRuler::setMapDimensions(const QSize &size) {
|
||||||
mapSize = size;
|
mapSize = size;
|
||||||
init();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRuler::init() {
|
void MapRuler::reset() {
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
hide();
|
hide();
|
||||||
setPoints(QPoint(), QPoint());
|
setPoints(QPoint(), QPoint());
|
||||||
statusMessage = QString();
|
xRuler = QRectF();
|
||||||
xRuler = QRect();
|
yRuler = QRectF();
|
||||||
yRuler = QRect();
|
cornerTick = QLineF();
|
||||||
cornerTick = QLine();
|
|
||||||
anchored = false;
|
anchored = false;
|
||||||
locked = false;
|
locked = false;
|
||||||
emit statusChanged(statusMessage);
|
emit statusChanged(QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MapRuler::setAnchor(const QPointF &scenePos) {
|
void MapRuler::setAnchor(const QPointF &scenePos) {
|
||||||
|
@ -130,42 +131,60 @@ QPoint MapRuler::snapToWithinBounds(QPoint pos) const {
|
||||||
|
|
||||||
void MapRuler::updateGeometry() {
|
void MapRuler::updateGeometry() {
|
||||||
prepareGeometryChange();
|
prepareGeometryChange();
|
||||||
setPos(QPoint(left() * 16 + 7, top() * 16 + 7));
|
setPos(QPoint(left() * 16 + 8, top() * 16 + 8));
|
||||||
/* Determine what quadrant the end point is in relative to the anchor point. The anchor
|
/* 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)
|
* point is the top-left corner of the metatile the ruler starts in, so a zero-length
|
||||||
* ruler is considered to be in the bottom-right quadrant from the anchor point. */
|
* ruler is considered to be in the bottom-right quadrant from the anchor point. */
|
||||||
if (deltaX() < 0 && deltaY() < 0) {
|
if (deltaX() < 0 && deltaY() < 0) {
|
||||||
// Top-left
|
// Top-left
|
||||||
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness);
|
xRuler = QRectF(-half_thickness, pixHeight() - half_thickness, pixWidth() + thickness, thickness);
|
||||||
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
yRuler = QRectF(-half_thickness, -half_thickness, thickness, pixHeight() + thickness);
|
||||||
cornerTick = QLineF(yRuler.x() + 0.5, xRuler.y() + thickness - 0.5, yRuler.x() + thickness, xRuler.y());
|
cornerTick = QLineF(yRuler.x() + 0.5, xRuler.y() + thickness - 0.5, yRuler.x() + thickness, xRuler.y());
|
||||||
statusMessage = QString("Ruler: Left %1, Up %2\nStart(%3, %4), End(%5, %6)").arg(width()).arg(height())
|
updateStatus(Qt::TopLeftCorner);
|
||||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
|
||||||
} else if (deltaX() < 0) {
|
} else if (deltaX() < 0) {
|
||||||
// Bottom-left
|
// Bottom-left
|
||||||
xRuler = QRect(0, 0, pixWidth() + thickness, thickness);
|
xRuler = QRectF(-half_thickness, -half_thickness, pixWidth() + thickness, thickness);
|
||||||
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
yRuler = QRectF(-half_thickness, -half_thickness, thickness, pixHeight() + thickness);
|
||||||
cornerTick = QLineF(xRuler.x() + 0.5, xRuler.y() + 0.5, xRuler.x() + thickness, xRuler.y() + thickness);
|
cornerTick = QLineF(xRuler.x() + 0.5, xRuler.y() + 0.5, xRuler.x() + thickness, xRuler.y() + thickness);
|
||||||
|
updateStatus(Qt::BottomLeftCorner);
|
||||||
|
} else if (deltaY() < 0) {
|
||||||
|
// Top-right
|
||||||
|
xRuler = QRectF(-half_thickness, pixHeight() - half_thickness, pixWidth() + thickness, thickness);
|
||||||
|
yRuler = QRectF(pixWidth() - half_thickness, -half_thickness, thickness, pixHeight() + thickness);
|
||||||
|
cornerTick = QLineF(yRuler.x(), xRuler.y(), yRuler.x() + thickness - 0.5, xRuler.y() + thickness - 0.5);
|
||||||
|
updateStatus(Qt::TopRightCorner);
|
||||||
|
} else {
|
||||||
|
// Bottom-right
|
||||||
|
xRuler = QRectF(-half_thickness, -half_thickness, pixWidth() + thickness, thickness);
|
||||||
|
yRuler = QRectF(pixWidth() - half_thickness, -half_thickness, thickness, pixHeight() + thickness);
|
||||||
|
cornerTick = QLineF(yRuler.x(), yRuler.y() + thickness, yRuler.x() + thickness - 0.5, yRuler.y() + 0.5);
|
||||||
|
updateStatus(Qt::BottomRightCorner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapRuler::updateStatus(Qt::Corner corner) {
|
||||||
|
QString statusMessage;
|
||||||
|
switch (corner)
|
||||||
|
{
|
||||||
|
case Qt::TopLeftCorner:
|
||||||
|
statusMessage = QString("Ruler: Left %1, Up %2\nStart(%3, %4), End(%5, %6)").arg(width()).arg(height())
|
||||||
|
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||||
|
break;
|
||||||
|
case Qt::BottomLeftCorner:
|
||||||
statusMessage = QString("Ruler: Left %1").arg(width());
|
statusMessage = QString("Ruler: Left %1").arg(width());
|
||||||
if (deltaY())
|
if (deltaY())
|
||||||
statusMessage += QString(", Down %1").arg(height());
|
statusMessage += QString(", Down %1").arg(height());
|
||||||
statusMessage += QString("\nStart(%1, %2), End(%3, %4)")
|
statusMessage += QString("\nStart(%1, %2), End(%3, %4)")
|
||||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||||
} else if (deltaY() < 0) {
|
break;
|
||||||
// Top-right
|
case Qt::TopRightCorner:
|
||||||
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);
|
|
||||||
statusMessage = QString("Ruler: ");
|
statusMessage = QString("Ruler: ");
|
||||||
if (deltaX())
|
if (deltaX())
|
||||||
statusMessage += QString("Right %1, ").arg(width());
|
statusMessage += QString("Right %1, ").arg(width());
|
||||||
statusMessage += QString("Up %1\nStart(%2, %3), End(%4, %5)").arg(height())
|
statusMessage += QString("Up %1\nStart(%2, %3), End(%4, %5)").arg(height())
|
||||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||||
} else {
|
break;
|
||||||
// Bottom-right
|
case Qt::BottomRightCorner:
|
||||||
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);
|
|
||||||
statusMessage = QString("Ruler: ");
|
statusMessage = QString("Ruler: ");
|
||||||
if (deltaX() || deltaY()) {
|
if (deltaX() || deltaY()) {
|
||||||
if (deltaX())
|
if (deltaX())
|
||||||
|
@ -176,10 +195,12 @@ void MapRuler::updateGeometry() {
|
||||||
statusMessage += QString("Down: %1").arg(height());
|
statusMessage += QString("Down: %1").arg(height());
|
||||||
}
|
}
|
||||||
statusMessage += QString("\nStart(%1, %2), End(%3, %4)")
|
statusMessage += QString("\nStart(%1, %2), End(%3, %4)")
|
||||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||||
} else {
|
} else {
|
||||||
statusMessage += QString("0\nStart(%1, %2)").arg(anchor().x()).arg(anchor().y());
|
statusMessage += QString("0\nStart(%1, %2)")
|
||||||
|
.arg(anchor().x()).arg(anchor().y());
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
emit statusChanged(statusMessage);
|
emit statusChanged(statusMessage);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue