Add MapRuler (right-click & drag in events view)
This commit is contained in:
parent
457cd1bb85
commit
ca6969564f
6 changed files with 207 additions and 14 deletions
|
@ -23,6 +23,7 @@
|
|||
#include "settings.h"
|
||||
#include "movablerect.h"
|
||||
#include "cursortilerect.h"
|
||||
#include "mapruler.h"
|
||||
|
||||
class DraggablePixmapItem;
|
||||
class MetatilesPixmapItem;
|
||||
|
@ -115,6 +116,7 @@ public:
|
|||
QList<QGraphicsLineItem*> gridLines;
|
||||
MovableRect *playerViewRect = nullptr;
|
||||
CursorTileRect *cursorMapTileRect = nullptr;
|
||||
MapRuler *map_ruler = nullptr;
|
||||
|
||||
QGraphicsScene *scene_metatiles = nullptr;
|
||||
QGraphicsScene *scene_current_metatile_selection = nullptr;
|
||||
|
|
71
include/ui/mapruler.h
Normal file
71
include/ui/mapruler.h
Normal file
|
@ -0,0 +1,71 @@
|
|||
#ifndef MAPRULER_H
|
||||
#define MAPRULER_H
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
#include <QColor>
|
||||
|
||||
|
||||
class MapRuler : public QGraphicsItem, private QLine
|
||||
{
|
||||
public:
|
||||
MapRuler(QColor interior = Qt::yellow, QColor exterior = Qt::black)
|
||||
: interiorColor(interior), exteriorColor(exterior)
|
||||
{
|
||||
init();
|
||||
setAcceptedMouseButtons(Qt::RightButton);
|
||||
}
|
||||
void init();
|
||||
QRectF boundingRect() const override;
|
||||
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
|
||||
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)); }
|
||||
|
||||
// Ruler start point in metatiles
|
||||
QPoint anchor() const { return QLine::p1(); }
|
||||
// Ruler end point in metatiles
|
||||
QPoint endPos() const { return QLine::p2(); }
|
||||
// X-coordinate of the ruler left edge in metatiles
|
||||
int left() const { return qMin(anchor().x(), endPos().x()); }
|
||||
// Y-coordinate of the ruler top edge in metatiles
|
||||
int top() const { return qMin(anchor().y(), endPos().y()); }
|
||||
// Horizontal component of the ruler in metatiles
|
||||
int deltaX() const { return QLine::dx(); }
|
||||
// Vertical component of the ruler in metatiles
|
||||
int deltaY() const { return QLine::dy(); }
|
||||
// Ruler width in metatiles
|
||||
int width() const { return qAbs(deltaX()); }
|
||||
// Ruler height in metatiles
|
||||
int height() const { return qAbs(deltaY()); }
|
||||
// Ruler width in map pixels
|
||||
int pixWidth() const { return width() * 16; }
|
||||
// Ruler height in map pixels
|
||||
int pixHeight() const { return height() * 16; }
|
||||
|
||||
bool mousePressed(Qt::MouseButtons buttons) { return buttons & acceptedMouseButtons(); }
|
||||
|
||||
private:
|
||||
QRect xRuler;
|
||||
QRect yRuler;
|
||||
QRect widthTextBox;
|
||||
QRect heightTextBox;
|
||||
QColor interiorColor;
|
||||
QColor exteriorColor;
|
||||
|
||||
static int padding;
|
||||
static int thickness;
|
||||
|
||||
void updateShape();
|
||||
};
|
||||
|
||||
#endif // MAPRULER_H
|
12
porymap.pro
12
porymap.pro
|
@ -68,6 +68,8 @@ SOURCES += src/core/block.cpp \
|
|||
src/ui/regionmapeditor.cpp \
|
||||
src/ui/newmappopup.cpp \
|
||||
src/ui/mapimageexporter.cpp \
|
||||
src/ui/newtilesetdialog.cpp \
|
||||
src/ui/mapruler.cpp \
|
||||
src/config.cpp \
|
||||
src/editor.cpp \
|
||||
src/main.cpp \
|
||||
|
@ -75,8 +77,7 @@ SOURCES += src/core/block.cpp \
|
|||
src/project.cpp \
|
||||
src/scripting.cpp \
|
||||
src/settings.cpp \
|
||||
src/log.cpp \
|
||||
src/ui/newtilesetdialog.cpp
|
||||
src/log.cpp
|
||||
|
||||
HEADERS += include/core/block.h \
|
||||
include/core/blockdata.h \
|
||||
|
@ -134,15 +135,16 @@ HEADERS += include/core/block.h \
|
|||
include/ui/regionmapeditor.h \
|
||||
include/ui/newmappopup.h \
|
||||
include/ui/mapimageexporter.h \
|
||||
include/ui/newtilesetdialog.h \
|
||||
include/ui/overlay.h \
|
||||
include/ui/mapruler.h \
|
||||
include/config.h \
|
||||
include/editor.h \
|
||||
include/mainwindow.h \
|
||||
include/project.h \
|
||||
include/scripting.h \
|
||||
include/settings.h \
|
||||
include/log.h \
|
||||
include/ui/newtilesetdialog.h \
|
||||
include/ui/overlay.h
|
||||
include/log.h
|
||||
|
||||
FORMS += forms/mainwindow.ui \
|
||||
forms/eventpropertiesframe.ui \
|
||||
|
|
|
@ -23,6 +23,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();
|
||||
|
||||
/// Instead of updating the selected events after every single undo action
|
||||
/// (eg when the user rolls back several at once), only reselect events when
|
||||
|
@ -41,6 +42,7 @@ Editor::~Editor()
|
|||
delete this->settings;
|
||||
delete this->playerViewRect;
|
||||
delete this->cursorMapTileRect;
|
||||
delete this->map_ruler;
|
||||
|
||||
closeProject();
|
||||
}
|
||||
|
@ -1119,7 +1121,14 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
|||
}
|
||||
}
|
||||
} else if (obj_edit_mode == "select") {
|
||||
// do nothing here, at least for now
|
||||
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);
|
||||
}
|
||||
} else if (obj_edit_mode == "shift" && item->map) {
|
||||
static QPoint selection_origin;
|
||||
static unsigned actionId = 0;
|
||||
|
@ -1217,6 +1226,7 @@ bool Editor::displayMap() {
|
|||
delete map_item;
|
||||
scene->removeItem(this->playerViewRect);
|
||||
scene->removeItem(this->cursorMapTileRect);
|
||||
scene->removeItem(this->map_ruler);
|
||||
}
|
||||
|
||||
displayMetatileSelector();
|
||||
|
@ -1233,8 +1243,10 @@ bool Editor::displayMap() {
|
|||
|
||||
this->playerViewRect->setZValue(1000);
|
||||
this->cursorMapTileRect->setZValue(1001);
|
||||
this->map_ruler->setZValue(1002);
|
||||
scene->addItem(this->playerViewRect);
|
||||
scene->addItem(this->cursorMapTileRect);
|
||||
scene->addItem(this->map_ruler);
|
||||
|
||||
if (map_item) {
|
||||
map_item->setVisible(false);
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#include "draggablepixmapitem.h"
|
||||
|
||||
#include "editor.h"
|
||||
|
||||
#include "editcommands.h"
|
||||
#include "mapruler.h"
|
||||
|
||||
static unsigned currentActionId = 0;
|
||||
|
||||
|
@ -57,9 +56,15 @@ 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 = static_cast<int>(mouse->pos().x() + this->pos().x()) / 16;
|
||||
last_y = static_cast<int>(mouse->pos().y() + this->pos().y()) / 16;
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier);
|
||||
this->editor->selectingEvent = true;
|
||||
}
|
||||
|
@ -76,7 +81,9 @@ void DraggablePixmapItem::mouseMoveEvent(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;
|
||||
emit this->editor->map_item->hoveredMapMetatileChanged(x, y);
|
||||
if (x != last_x || y != last_y) {
|
||||
if (this->editor->map_ruler->isEnabled()) {
|
||||
this->editor->map_ruler->setEndPos(x, y);
|
||||
} else if (x != last_x || y != last_y) {
|
||||
QList <Event *> selectedEvents;
|
||||
if (editor->selected_events->contains(this)) {
|
||||
for (DraggablePixmapItem *item : *editor->selected_events) {
|
||||
|
@ -92,9 +99,14 @@ void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) {
|
|||
}
|
||||
}
|
||||
|
||||
void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) {
|
||||
active = false;
|
||||
currentActionId++;
|
||||
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::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
|
||||
|
|
94
src/ui/mapruler.cpp
Normal file
94
src/ui/mapruler.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
#include "mapruler.h"
|
||||
|
||||
#include <QGraphicsItem>
|
||||
#include <QPainter>
|
||||
#include <QColor>
|
||||
|
||||
int MapRuler::padding = 24;
|
||||
int MapRuler::thickness = 3;
|
||||
|
||||
|
||||
void MapRuler::init() {
|
||||
setVisible(false);
|
||||
setEnabled(false);
|
||||
setPoints(QPoint(), QPoint());
|
||||
xRuler = QRect();
|
||||
yRuler = QRect();
|
||||
widthTextBox = QRect();
|
||||
heightTextBox = QRect();
|
||||
}
|
||||
|
||||
QRectF MapRuler::boundingRect() const {
|
||||
return QRectF(-padding, -padding, pixWidth() + padding * 2, pixHeight() + padding * 2);
|
||||
}
|
||||
|
||||
QPainterPath MapRuler::shape() const {
|
||||
QPainterPath ruler;
|
||||
ruler.setFillRule(Qt::WindingFill);
|
||||
ruler.addRect(xRuler);
|
||||
ruler.addRect(yRuler);
|
||||
ruler = ruler.simplified();
|
||||
return ruler;
|
||||
}
|
||||
|
||||
void MapRuler::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) {
|
||||
painter->setPen(exteriorColor);
|
||||
painter->setBrush(QBrush(interiorColor));
|
||||
painter->drawPath(shape());
|
||||
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);
|
||||
setPoints(tilePos, tilePos);
|
||||
updateShape();
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
void MapRuler::endAnchor() {
|
||||
setVisible(false);
|
||||
setEnabled(false);
|
||||
prepareGeometryChange();
|
||||
init();
|
||||
}
|
||||
|
||||
void MapRuler::setEndPos(const QPoint &tilePos) {
|
||||
if (!isEnabled() || (tilePos == endPos() && tilePos != anchor()))
|
||||
return;
|
||||
prepareGeometryChange();
|
||||
setP2(tilePos);
|
||||
updateShape();
|
||||
}
|
||||
|
||||
void MapRuler::updateShape() {
|
||||
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. */
|
||||
if (deltaX() < 0 && deltaY() < 0) {
|
||||
// Top-left
|
||||
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness);
|
||||
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
||||
widthTextBox = QRect(0, pixHeight(), pixWidth(), padding);
|
||||
heightTextBox = QRect(-padding, 0, padding, pixHeight());
|
||||
} else if (deltaX() < 0) {
|
||||
// Bottom-left
|
||||
xRuler = QRect(0, 0, pixWidth() + thickness, thickness);
|
||||
yRuler = QRect(0, 0, thickness, pixHeight() + thickness);
|
||||
widthTextBox = QRect(0, -padding, pixWidth(), padding);
|
||||
heightTextBox = QRect(-padding, 0, padding, pixHeight());
|
||||
} else if (deltaY() < 0) {
|
||||
// Top-right
|
||||
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness);
|
||||
yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness);
|
||||
widthTextBox = QRect(0, pixHeight(), pixWidth(), padding);
|
||||
heightTextBox = QRect(pixWidth(), 0, padding, pixHeight());
|
||||
} else {
|
||||
// Bottom-right
|
||||
xRuler = QRect(0, 0, pixWidth() + thickness, thickness);
|
||||
yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness);
|
||||
widthTextBox = QRect(0, -padding, pixWidth(), padding);
|
||||
heightTextBox = QRect(pixWidth(), 0, padding, pixHeight());
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue