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 "settings.h"
|
||||||
#include "movablerect.h"
|
#include "movablerect.h"
|
||||||
#include "cursortilerect.h"
|
#include "cursortilerect.h"
|
||||||
|
#include "mapruler.h"
|
||||||
|
|
||||||
class DraggablePixmapItem;
|
class DraggablePixmapItem;
|
||||||
class MetatilesPixmapItem;
|
class MetatilesPixmapItem;
|
||||||
|
@ -115,6 +116,7 @@ public:
|
||||||
QList<QGraphicsLineItem*> gridLines;
|
QList<QGraphicsLineItem*> gridLines;
|
||||||
MovableRect *playerViewRect = nullptr;
|
MovableRect *playerViewRect = nullptr;
|
||||||
CursorTileRect *cursorMapTileRect = nullptr;
|
CursorTileRect *cursorMapTileRect = nullptr;
|
||||||
|
MapRuler *map_ruler = nullptr;
|
||||||
|
|
||||||
QGraphicsScene *scene_metatiles = nullptr;
|
QGraphicsScene *scene_metatiles = nullptr;
|
||||||
QGraphicsScene *scene_current_metatile_selection = 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/regionmapeditor.cpp \
|
||||||
src/ui/newmappopup.cpp \
|
src/ui/newmappopup.cpp \
|
||||||
src/ui/mapimageexporter.cpp \
|
src/ui/mapimageexporter.cpp \
|
||||||
|
src/ui/newtilesetdialog.cpp \
|
||||||
|
src/ui/mapruler.cpp \
|
||||||
src/config.cpp \
|
src/config.cpp \
|
||||||
src/editor.cpp \
|
src/editor.cpp \
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
|
@ -75,8 +77,7 @@ SOURCES += src/core/block.cpp \
|
||||||
src/project.cpp \
|
src/project.cpp \
|
||||||
src/scripting.cpp \
|
src/scripting.cpp \
|
||||||
src/settings.cpp \
|
src/settings.cpp \
|
||||||
src/log.cpp \
|
src/log.cpp
|
||||||
src/ui/newtilesetdialog.cpp
|
|
||||||
|
|
||||||
HEADERS += include/core/block.h \
|
HEADERS += include/core/block.h \
|
||||||
include/core/blockdata.h \
|
include/core/blockdata.h \
|
||||||
|
@ -134,15 +135,16 @@ HEADERS += include/core/block.h \
|
||||||
include/ui/regionmapeditor.h \
|
include/ui/regionmapeditor.h \
|
||||||
include/ui/newmappopup.h \
|
include/ui/newmappopup.h \
|
||||||
include/ui/mapimageexporter.h \
|
include/ui/mapimageexporter.h \
|
||||||
|
include/ui/newtilesetdialog.h \
|
||||||
|
include/ui/overlay.h \
|
||||||
|
include/ui/mapruler.h \
|
||||||
include/config.h \
|
include/config.h \
|
||||||
include/editor.h \
|
include/editor.h \
|
||||||
include/mainwindow.h \
|
include/mainwindow.h \
|
||||||
include/project.h \
|
include/project.h \
|
||||||
include/scripting.h \
|
include/scripting.h \
|
||||||
include/settings.h \
|
include/settings.h \
|
||||||
include/log.h \
|
include/log.h
|
||||||
include/ui/newtilesetdialog.h \
|
|
||||||
include/ui/overlay.h
|
|
||||||
|
|
||||||
FORMS += forms/mainwindow.ui \
|
FORMS += forms/mainwindow.ui \
|
||||||
forms/eventpropertiesframe.ui \
|
forms/eventpropertiesframe.ui \
|
||||||
|
|
|
@ -23,6 +23,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();
|
||||||
|
|
||||||
/// Instead of updating the selected events after every single undo action
|
/// Instead of updating the selected events after every single undo action
|
||||||
/// (eg when the user rolls back several at once), only reselect events when
|
/// (eg when the user rolls back several at once), only reselect events when
|
||||||
|
@ -41,6 +42,7 @@ Editor::~Editor()
|
||||||
delete this->settings;
|
delete this->settings;
|
||||||
delete this->playerViewRect;
|
delete this->playerViewRect;
|
||||||
delete this->cursorMapTileRect;
|
delete this->cursorMapTileRect;
|
||||||
|
delete this->map_ruler;
|
||||||
|
|
||||||
closeProject();
|
closeProject();
|
||||||
}
|
}
|
||||||
|
@ -1119,7 +1121,14 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, MapPixmapItem *item
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (obj_edit_mode == "select") {
|
} 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) {
|
} else if (obj_edit_mode == "shift" && item->map) {
|
||||||
static QPoint selection_origin;
|
static QPoint selection_origin;
|
||||||
static unsigned actionId = 0;
|
static unsigned actionId = 0;
|
||||||
|
@ -1217,6 +1226,7 @@ bool Editor::displayMap() {
|
||||||
delete map_item;
|
delete map_item;
|
||||||
scene->removeItem(this->playerViewRect);
|
scene->removeItem(this->playerViewRect);
|
||||||
scene->removeItem(this->cursorMapTileRect);
|
scene->removeItem(this->cursorMapTileRect);
|
||||||
|
scene->removeItem(this->map_ruler);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayMetatileSelector();
|
displayMetatileSelector();
|
||||||
|
@ -1233,8 +1243,10 @@ bool Editor::displayMap() {
|
||||||
|
|
||||||
this->playerViewRect->setZValue(1000);
|
this->playerViewRect->setZValue(1000);
|
||||||
this->cursorMapTileRect->setZValue(1001);
|
this->cursorMapTileRect->setZValue(1001);
|
||||||
|
this->map_ruler->setZValue(1002);
|
||||||
scene->addItem(this->playerViewRect);
|
scene->addItem(this->playerViewRect);
|
||||||
scene->addItem(this->cursorMapTileRect);
|
scene->addItem(this->cursorMapTileRect);
|
||||||
|
scene->addItem(this->map_ruler);
|
||||||
|
|
||||||
if (map_item) {
|
if (map_item) {
|
||||||
map_item->setVisible(false);
|
map_item->setVisible(false);
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
#include "draggablepixmapitem.h"
|
#include "draggablepixmapitem.h"
|
||||||
|
|
||||||
#include "editor.h"
|
#include "editor.h"
|
||||||
|
|
||||||
#include "editcommands.h"
|
#include "editcommands.h"
|
||||||
|
#include "mapruler.h"
|
||||||
|
|
||||||
static unsigned currentActionId = 0;
|
static unsigned currentActionId = 0;
|
||||||
|
|
||||||
|
@ -57,9 +56,15 @@ void DraggablePixmapItem::bindToUserData(QComboBox *combo, QString key) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DraggablePixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *mouse) {
|
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;
|
active = true;
|
||||||
last_x = static_cast<int>(mouse->pos().x() + this->pos().x()) / 16;
|
last_x = x;
|
||||||
last_y = static_cast<int>(mouse->pos().y() + this->pos().y()) / 16;
|
last_y = y;
|
||||||
this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier);
|
this->editor->selectMapEvent(this, mouse->modifiers() & Qt::ControlModifier);
|
||||||
this->editor->selectingEvent = true;
|
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 x = static_cast<int>(mouse->pos().x() + this->pos().x()) / 16;
|
||||||
int y = static_cast<int>(mouse->pos().y() + this->pos().y()) / 16;
|
int y = static_cast<int>(mouse->pos().y() + this->pos().y()) / 16;
|
||||||
emit this->editor->map_item->hoveredMapMetatileChanged(x, y);
|
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;
|
QList <Event *> selectedEvents;
|
||||||
if (editor->selected_events->contains(this)) {
|
if (editor->selected_events->contains(this)) {
|
||||||
for (DraggablePixmapItem *item : *editor->selected_events) {
|
for (DraggablePixmapItem *item : *editor->selected_events) {
|
||||||
|
@ -92,10 +99,15 @@ void DraggablePixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *mouse) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DraggablePixmapItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *) {
|
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;
|
active = false;
|
||||||
currentActionId++;
|
currentActionId++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
|
void DraggablePixmapItem::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *) {
|
||||||
if (this->event->get("event_type") == EventType::Warp) {
|
if (this->event->get("event_type") == EventType::Warp) {
|
||||||
|
|
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