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
|
||||
|
||||
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;
|
||||
QPainterPath shape() const override;
|
||||
|
@ -45,23 +46,23 @@ signals:
|
|||
void statusChanged(const QString &statusMessage);
|
||||
|
||||
private:
|
||||
QColor innerColor;
|
||||
QColor borderColor;
|
||||
const int thickness;
|
||||
const qreal half_thickness;
|
||||
const QColor innerColor;
|
||||
const QColor borderColor;
|
||||
QSize mapSize;
|
||||
QString statusMessage;
|
||||
QRect xRuler;
|
||||
QRect yRuler;
|
||||
QRectF xRuler;
|
||||
QRectF yRuler;
|
||||
QLineF cornerTick;
|
||||
bool anchored;
|
||||
bool locked;
|
||||
|
||||
static int thickness;
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void setAnchor(const QPointF &scenePos);
|
||||
void setEndPos(const QPointF &scenePos);
|
||||
QPoint snapToWithinBounds(QPoint pos) const;
|
||||
void updateGeometry();
|
||||
void updateStatus(Qt::Corner corner);
|
||||
int pixWidth() const { return width() * 16; }
|
||||
int pixHeight() const { return height() * 16; }
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ Editor::Editor(Ui::MainWindow* ui)
|
|||
this->settings = new Settings();
|
||||
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();
|
||||
this->map_ruler = new MapRuler(4);
|
||||
connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged);
|
||||
|
||||
/// Instead of updating the selected events after every single undo action
|
||||
|
|
|
@ -4,29 +4,31 @@
|
|||
#include <QGraphicsSceneEvent>
|
||||
#include <QPainter>
|
||||
#include <QColor>
|
||||
|
||||
int MapRuler::thickness = 3;
|
||||
#include <QVector>
|
||||
|
||||
|
||||
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),
|
||||
borderColor(borderColor),
|
||||
mapSize(QSize()),
|
||||
statusMessage(QString()),
|
||||
xRuler(QRect()),
|
||||
yRuler(QRect()),
|
||||
cornerTick(QLine()),
|
||||
xRuler(QRectF()),
|
||||
yRuler(QRectF()),
|
||||
cornerTick(QLineF()),
|
||||
anchored(false),
|
||||
locked(false)
|
||||
{
|
||||
connect(this, &QGraphicsObject::enabledChanged, [this]() {
|
||||
if (!isEnabled() && anchored)
|
||||
init();
|
||||
reset();
|
||||
});
|
||||
}
|
||||
|
||||
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 {
|
||||
|
@ -35,10 +37,12 @@ QPainterPath MapRuler::shape() const {
|
|||
ruler.addRect(xRuler);
|
||||
ruler.addRect(yRuler);
|
||||
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);
|
||||
for (int y = 17; y < pixHeight(); y += 16)
|
||||
for (int y = 16; y < pixHeight(); y += 16)
|
||||
ruler.addRect(yRuler.x(), y, thickness, 0);
|
||||
if (deltaX() && deltaY())
|
||||
ruler.addPolygon(QVector<QPointF>({ cornerTick.p1(), cornerTick.p2() }));
|
||||
return ruler;
|
||||
}
|
||||
|
||||
|
@ -46,16 +50,14 @@ void MapRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidge
|
|||
painter->setPen(QPen(borderColor));
|
||||
painter->setBrush(QBrush(innerColor));
|
||||
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())
|
||||
return false;
|
||||
|
||||
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) {
|
||||
mouseEvent(mouse_event);
|
||||
}
|
||||
|
@ -71,7 +73,7 @@ void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) {
|
|||
if (event->button() == Qt::LeftButton)
|
||||
locked = !locked;
|
||||
if (event->button() == Qt::RightButton)
|
||||
init();
|
||||
reset();
|
||||
else
|
||||
setEndPos(event->scenePos());
|
||||
}
|
||||
|
@ -79,20 +81,19 @@ void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) {
|
|||
|
||||
void MapRuler::setMapDimensions(const QSize &size) {
|
||||
mapSize = size;
|
||||
init();
|
||||
reset();
|
||||
}
|
||||
|
||||
void MapRuler::init() {
|
||||
void MapRuler::reset() {
|
||||
prepareGeometryChange();
|
||||
hide();
|
||||
setPoints(QPoint(), QPoint());
|
||||
statusMessage = QString();
|
||||
xRuler = QRect();
|
||||
yRuler = QRect();
|
||||
cornerTick = QLine();
|
||||
xRuler = QRectF();
|
||||
yRuler = QRectF();
|
||||
cornerTick = QLineF();
|
||||
anchored = false;
|
||||
locked = false;
|
||||
emit statusChanged(statusMessage);
|
||||
emit statusChanged(QString());
|
||||
}
|
||||
|
||||
void MapRuler::setAnchor(const QPointF &scenePos) {
|
||||
|
@ -130,42 +131,60 @@ QPoint MapRuler::snapToWithinBounds(QPoint pos) const {
|
|||
|
||||
void MapRuler::updateGeometry() {
|
||||
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
|
||||
* 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. */
|
||||
if (deltaX() < 0 && deltaY() < 0) {
|
||||
// Top-left
|
||||
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness);
|
||||
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
||||
xRuler = QRectF(-half_thickness, pixHeight() - half_thickness, pixWidth() + thickness, 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());
|
||||
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());
|
||||
updateStatus(Qt::TopLeftCorner);
|
||||
} else if (deltaX() < 0) {
|
||||
// Bottom-left
|
||||
xRuler = QRect(0, 0, pixWidth() + thickness, thickness);
|
||||
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
||||
xRuler = QRectF(-half_thickness, -half_thickness, pixWidth() + thickness, 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);
|
||||
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());
|
||||
if (deltaY())
|
||||
statusMessage += QString(", Down %1").arg(height());
|
||||
statusMessage += QString("\nStart(%1, %2), End(%3, %4)")
|
||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||
} 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);
|
||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||
break;
|
||||
case Qt::TopRightCorner:
|
||||
statusMessage = QString("Ruler: ");
|
||||
if (deltaX())
|
||||
statusMessage += QString("Right %1, ").arg(width());
|
||||
statusMessage += QString("Up %1\nStart(%2, %3), End(%4, %5)").arg(height())
|
||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||
} 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);
|
||||
.arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
|
||||
break;
|
||||
case Qt::BottomRightCorner:
|
||||
statusMessage = QString("Ruler: ");
|
||||
if (deltaX() || deltaY()) {
|
||||
if (deltaX())
|
||||
|
@ -176,10 +195,12 @@ void MapRuler::updateGeometry() {
|
|||
statusMessage += QString("Down: %1").arg(height());
|
||||
}
|
||||
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 {
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue