Merge remote-tracking branch 'origin/master' into script-editing

This commit is contained in:
BigBahss 2020-12-01 16:43:53 -05:00
commit 789fe7d00c
12 changed files with 232 additions and 135 deletions

View file

@ -17,6 +17,7 @@ The **"Breaking Changes"** listed below are changes that have been made in the d
- All plain text boxes now have a clear button to delete the text. - All plain text boxes now have a clear button to delete the text.
- The window sizes and positions of the tileset editor, palette editor, and region map editor are now stored in `porymap.cfg`. - The window sizes and positions of the tileset editor, palette editor, and region map editor are now stored in `porymap.cfg`.
- Add ruler tool for measuring metatile distance in events tab (Right-click to turn on/off, left-click to lock in place). - Add ruler tool for measuring metatile distance in events tab (Right-click to turn on/off, left-click to lock in place).
- Add delete button to wild pokemon encounters tab.
### Changed ### Changed
- Holding `shift` now toggles "Smart Path" drawing; when the "Smart Paths" checkbox is checked, holding `shift` will temporarily disable it. - Holding `shift` now toggles "Smart Path" drawing; when the "Smart Paths" checkbox is checked, holding `shift` will temporarily disable it.

View file

@ -260,7 +260,7 @@ Shift
Ruler Tool Ruler Tool
---------- ----------
The Ruler Tool provides a convenient way to measure distance on the map. This is particularly useful for scripting object movement. With the Pointer Tool selected you can activate the ruler with a Right-click. With the ruler active you can drag the mouse around to extend the ruler. The ruler can be deactivated with another Right-click, or locked in place with a Left-click (Left-click again to unlock the ruler). The dimensions of the ruler are displayed in a tool-tip and in the status bar in the bottom left corner of the widnow. The Ruler Tool provides a convenient way to measure distance on the map. This is particularly useful for scripting object movement. With the Pointer Tool selected you can activate the ruler with a Right-click. With the ruler active you can move the mouse around to extend the ruler. The ruler can be deactivated with another Right-click, or locked in place with a Left-click (Left-click again to unlock the ruler).
.. figure:: images/editing-map-events/event-tool-ruler.gif .. figure:: images/editing-map-events/event-tool-ruler.gif
:alt: Measuring metatile distance with the Ruler Tool :alt: Measuring metatile distance with the Ruler Tool

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 KiB

After

Width:  |  Height:  |  Size: 206 KiB

View file

@ -2527,6 +2527,23 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QPushButton" name="pushButton_DeleteWildMonGroup">
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Delete a group of wild pokemon data on this map.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../resources/images.qrc">
<normaloff>:/icons/delete.ico</normaloff>:/icons/delete.ico</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item> <item>
<spacer name="horizontalSpacer_9"> <spacer name="horizontalSpacer_9">
<property name="orientation"> <property name="orientation">

View file

@ -83,6 +83,7 @@ public:
void addNewConnection(); void addNewConnection();
void removeCurrentConnection(); void removeCurrentConnection();
void addNewWildMonGroup(QWidget *window); void addNewWildMonGroup(QWidget *window);
void deleteWildMonGroup();
void updateDiveMap(QString mapName); void updateDiveMap(QString mapName);
void updateEmergeMap(QString mapName); void updateEmergeMap(QString mapName);
void setSelectedConnectionFromMap(QString mapName); void setSelectedConnectionFromMap(QString mapName);
@ -211,7 +212,6 @@ private slots:
void onHoveredMapMovementPermissionCleared(); void onHoveredMapMovementPermissionCleared();
void onSelectedMetatilesChanged(); void onSelectedMetatilesChanged();
void onWheelZoom(int); void onWheelZoom(int);
void onMapRulerLengthChanged();
signals: signals:
void objectsChanged(); void objectsChanged();
@ -220,6 +220,7 @@ signals:
void wildMonDataChanged(); void wildMonDataChanged();
void warpEventDoubleClicked(QString mapName, QString warpNum); void warpEventDoubleClicked(QString mapName, QString warpNum);
void currentMetatilesSelectionChanged(); void currentMetatilesSelectionChanged();
void mapRulerStatusChanged(const QString &);
}; };
#endif // EDITOR_H #endif // EDITOR_H

View file

@ -127,6 +127,7 @@ private slots:
void openNewMapPopupWindow(int, QVariant); void openNewMapPopupWindow(int, QVariant);
void onNewMapCreated(); void onNewMapCreated();
void onMapCacheCleared(); void onMapCacheCleared();
void onMapRulerStatusChanged(const QString &);
void on_action_NewMap_triggered(); void on_action_NewMap_triggered();
void on_actionNew_Tileset_triggered(); void on_actionNew_Tileset_triggered();
@ -205,6 +206,7 @@ private slots:
void on_lineEdit_filterBox_textChanged(const QString &arg1); void on_lineEdit_filterBox_textChanged(const QString &arg1);
void moveEvent(QMoveEvent *event);
void closeEvent(QCloseEvent *); void closeEvent(QCloseEvent *);
void eventTabChanged(int index); void eventTabChanged(int index);
@ -220,6 +222,7 @@ private slots:
void on_tableWidget_CustomHeaderFields_cellChanged(int row, int column); void on_tableWidget_CustomHeaderFields_cellChanged(int row, int column);
void on_horizontalSlider_MetatileZoom_valueChanged(int value); void on_horizontalSlider_MetatileZoom_valueChanged(int value);
void on_pushButton_NewWildMonGroup_clicked(); void on_pushButton_NewWildMonGroup_clicked();
void on_pushButton_DeleteWildMonGroup_clicked();
void on_pushButton_ConfigureEncountersJSON_clicked(); void on_pushButton_ConfigureEncountersJSON_clicked();
void on_actionRegion_Map_Editor_triggered(); void on_actionRegion_Map_Editor_triggered();
@ -228,6 +231,7 @@ private slots:
private: private:
Ui::MainWindow *ui; Ui::MainWindow *ui;
QLabel *label_MapRulerStatus;
TilesetEditor *tilesetEditor = nullptr; TilesetEditor *tilesetEditor = nullptr;
RegionMapEditor *regionMapEditor = nullptr; RegionMapEditor *regionMapEditor = nullptr;
MapImageExporter *mapImageExporter = nullptr; MapImageExporter *mapImageExporter = nullptr;

View file

@ -22,6 +22,7 @@ protected:
void mouseMoveEvent(QMouseEvent *event); void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event);
void drawForeground(QPainter *painter, const QRectF &rect); void drawForeground(QPainter *painter, const QRectF &rect);
void moveEvent(QMoveEvent *event);
}; };
//Q_DECLARE_METATYPE(GraphicsView) //Q_DECLARE_METATYPE(GraphicsView)

View file

@ -2,8 +2,7 @@
#define MAPRULER_H #define MAPRULER_H
#include <QGraphicsObject> #include <QGraphicsObject>
#include <QPainter> #include <QLine>
#include <QColor>
class MapRuler : public QGraphicsObject, private QLine class MapRuler : public QGraphicsObject, private QLine
@ -11,20 +10,14 @@ 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
innerColor(innerColor), MapRuler(int thickness, QColor innerColor = Qt::yellow, QColor borderColor = Qt::black);
borderColor(borderColor),
mapSize(QSize())
{
init();
}
void init();
QRectF boundingRect() const override; QRectF boundingRect() const override;
QPainterPath shape() const override; QPainterPath shape() const override;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override; void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override;
bool eventFilter(QObject *, QEvent *event) override; bool eventFilter(QObject *, QEvent *event) override;
void setEnabled(bool enabled);
bool isAnchored() const { return anchored; } bool isAnchored() const { return anchored; }
bool isLocked() const { return locked; } bool isLocked() const { return locked; }
@ -45,37 +38,33 @@ public:
// Ruler height in metatiles // Ruler height in metatiles
int height() const { return qAbs(deltaY()); } int height() const { return qAbs(deltaY()); }
QString statusMessage;
public slots: public slots:
void mouseEvent(QGraphicsSceneMouseEvent *event); void mouseEvent(QGraphicsSceneMouseEvent *event);
void setMapDimensions(const QSize &size); void setMapDimensions(const QSize &size);
signals:
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;
QRect xRuler; QRectF xRuler;
QRect yRuler; QRectF yRuler;
QLineF cornerTick; QLineF cornerTick;
bool anchored; bool anchored;
bool locked; bool locked;
static int thickness; void reset();
void setAnchor(const QPointF &scenePos);
void setEndPos(const QPointF &scenePos);
QPoint snapToWithinBounds(QPoint pos) const; QPoint snapToWithinBounds(QPoint pos) const;
void setAnchor(const QPointF &scenePos, const QPoint &screenPos);
void endAnchor();
void setEndPos(const QPointF &scenePos, const QPoint &screenPos);
void showDimensions(const QPoint &screenPos) const;
void hideDimensions() 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; }
signals:
void lengthChanged();
void deactivated(const QPoint &endPos);
}; };
#endif // MAPRULER_H #endif // MAPRULER_H

View file

@ -26,9 +26,8 @@ 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::lengthChanged, this, &Editor::onMapRulerLengthChanged); connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged);
connect(this->map_ruler, &MapRuler::deactivated, this, &Editor::onHoveredMapMetatileChanged);
/// 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
@ -359,6 +358,44 @@ void Editor::addNewWildMonGroup(QWidget *window) {
} }
} }
void Editor::deleteWildMonGroup() {
QComboBox *labelCombo = ui->comboBox_EncounterGroupLabel;
if (labelCombo->count() < 1) {
return;
}
QMessageBox msgBox;
msgBox.setText("Confirm Delete");
msgBox.setInformativeText("Are you sure you want to delete " + labelCombo->currentText() + "?");
QPushButton *deleteButton = msgBox.addButton("Delete", QMessageBox::DestructiveRole);
msgBox.addButton(QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Cancel);
msgBox.exec();
if (msgBox.clickedButton() == deleteButton) {
auto it = project->wildMonData.find(map->constantName);
if (it == project->wildMonData.end()) {
logError(QString("Failed to find data for map %1. Unable to delete").arg(map->constantName));
return;
}
int i = project->encounterGroupLabels.indexOf(labelCombo->currentText());
if (i < 0) {
logError(QString("Failed to find selected wild mon group: %1. Unable to delete")
.arg(labelCombo->currentText()));
return;
}
it.value().erase(labelCombo->currentText());
project->encounterGroupLabels.remove(i);
displayWildMonTables();
emit wildMonDataChanged();
}
}
void Editor::configureEncounterJSON(QWidget *window) { void Editor::configureEncounterJSON(QWidget *window) {
QVector<QWidget *> fieldSlots; QVector<QWidget *> fieldSlots;
@ -937,24 +974,12 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
} }
} }
void Editor::onMapRulerLengthChanged() {
const QPoint pos = map_ruler->endPos();
ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x; %4")
.arg(pos.x())
.arg(pos.y())
.arg(QString::number(pow(scale_base, scale_exp), 'g', 2))
.arg(map_ruler->statusMessage));
}
void Editor::onHoveredMapMetatileCleared() { void Editor::onHoveredMapMetatileCleared() {
this->playerViewRect->setVisible(false); this->playerViewRect->setVisible(false);
this->cursorMapTileRect->setVisible(false); this->cursorMapTileRect->setVisible(false);
if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles if (map_item->paintingMode == MapPixmapItem::PaintMode::Metatiles
|| map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects) { || map_item->paintingMode == MapPixmapItem::PaintMode::EventObjects) {
this->ui->statusBar->clearMessage(); this->ui->statusBar->clearMessage();
if (this->map_ruler->isAnchored()) {
this->ui->statusBar->showMessage(this->map_ruler->statusMessage);
}
} }
} }

View file

@ -40,6 +40,7 @@
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow), ui(new Ui::MainWindow),
label_MapRulerStatus(nullptr),
selectedObject(nullptr), selectedObject(nullptr),
selectedWarp(nullptr), selectedWarp(nullptr),
selectedTrigger(nullptr), selectedTrigger(nullptr),
@ -65,6 +66,7 @@ MainWindow::MainWindow(QWidget *parent) :
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
delete label_MapRulerStatus;
delete ui; delete ui;
} }
@ -140,6 +142,17 @@ void MainWindow::initCustomUI() {
} }
delete ui->frame_mapTools->layout(); delete ui->frame_mapTools->layout();
ui->frame_mapTools->setLayout(flowLayout); ui->frame_mapTools->setLayout(flowLayout);
// Floating QLabel tool-window that displays over the map when the ruler is active
label_MapRulerStatus = new QLabel(ui->graphicsView_Map);
label_MapRulerStatus->setObjectName("label_MapRulerStatus");
label_MapRulerStatus->setWindowFlags(Qt::Tool | Qt::CustomizeWindowHint | Qt::FramelessWindowHint);
label_MapRulerStatus->setFrameShape(QFrame::Box);
label_MapRulerStatus->setMargin(3);
label_MapRulerStatus->setPalette(palette());
label_MapRulerStatus->setAlignment(Qt::AlignCenter);
label_MapRulerStatus->setTextFormat(Qt::PlainText);
label_MapRulerStatus->setTextInteractionFlags(Qt::TextSelectableByMouse);
} }
void MainWindow::initExtraSignals() { void MainWindow::initExtraSignals() {
@ -155,6 +168,7 @@ void MainWindow::initEditor() {
connect(this->editor, SIGNAL(warpEventDoubleClicked(QString,QString)), this, SLOT(openWarpMap(QString,QString))); connect(this->editor, SIGNAL(warpEventDoubleClicked(QString,QString)), this, SLOT(openWarpMap(QString,QString)));
connect(this->editor, SIGNAL(currentMetatilesSelectionChanged()), this, SLOT(currentMetatilesSelectionChanged())); connect(this->editor, SIGNAL(currentMetatilesSelectionChanged()), this, SLOT(currentMetatilesSelectionChanged()));
connect(this->editor, SIGNAL(wildMonDataChanged()), this, SLOT(onWildMonDataChanged())); connect(this->editor, SIGNAL(wildMonDataChanged()), this, SLOT(onWildMonDataChanged()));
connect(this->editor, &Editor::mapRulerStatusChanged, this, &MainWindow::onMapRulerStatusChanged);
connect(ui->toolButton_Open_Scripts, &QToolButton::clicked, this->editor, &Editor::openMapScripts); connect(ui->toolButton_Open_Scripts, &QToolButton::clicked, this->editor, &Editor::openMapScripts);
connect(ui->actionOpen_Project_in_Text_Editor, &QAction::triggered, this->editor, &Editor::openProjectInTextEditor); connect(ui->actionOpen_Project_in_Text_Editor, &QAction::triggered, this->editor, &Editor::openProjectInTextEditor);
@ -2277,6 +2291,23 @@ void MainWindow::onWildMonDataChanged() {
projectHasUnsavedChanges = true; projectHasUnsavedChanges = true;
} }
void MainWindow::onMapRulerStatusChanged(const QString &status) {
if (status.isEmpty()) {
label_MapRulerStatus->hide();
} else if (label_MapRulerStatus->parentWidget()) {
label_MapRulerStatus->setText(status);
label_MapRulerStatus->adjustSize();
label_MapRulerStatus->show();
label_MapRulerStatus->move(label_MapRulerStatus->parentWidget()->mapToGlobal(QPoint(6, 6)));
}
}
void MainWindow::moveEvent(QMoveEvent *event) {
QMainWindow::moveEvent(event);
if (label_MapRulerStatus->isVisible() && label_MapRulerStatus->parentWidget())
label_MapRulerStatus->move(label_MapRulerStatus->parentWidget()->mapToGlobal(QPoint(6, 6)));
}
void MainWindow::on_action_Export_Map_Image_triggered() { void MainWindow::on_action_Export_Map_Image_triggered() {
showExportMapImageWindow(false); showExportMapImageWindow(false);
} }
@ -2334,6 +2365,10 @@ void MainWindow::on_pushButton_NewWildMonGroup_clicked() {
editor->addNewWildMonGroup(this); editor->addNewWildMonGroup(this);
} }
void MainWindow::on_pushButton_DeleteWildMonGroup_clicked() {
editor->deleteWildMonGroup();
}
void MainWindow::on_pushButton_ConfigureEncountersJSON_clicked() { void MainWindow::on_pushButton_ConfigureEncountersJSON_clicked() {
editor->configureEncounterJSON(this); editor->configureEncounterJSON(this);
} }

View file

@ -21,3 +21,10 @@ void GraphicsView::drawForeground(QPainter *painter, const QRectF&) {
item->render(painter); item->render(painter);
} }
} }
void GraphicsView::moveEvent(QMoveEvent *event) {
QGraphicsView::moveEvent(event);
QLabel *label_MapRulerStatus = findChild<QLabel *>("label_MapRulerStatus", Qt::FindDirectChildrenOnly);
if (label_MapRulerStatus && label_MapRulerStatus->isVisible())
label_MapRulerStatus->move(mapToGlobal(QPoint(6, 6)));
}

View file

@ -1,28 +1,34 @@
#include "mapruler.h" #include "mapruler.h"
#include "metatile.h" #include "metatile.h"
#include <QGraphicsObject>
#include <QGraphicsSceneEvent> #include <QGraphicsSceneEvent>
#include <QPainter> #include <QPainter>
#include <QColor> #include <QColor>
#include <QToolTip> #include <QVector>
int MapRuler::thickness = 3;
void MapRuler::init() { MapRuler::MapRuler(int thickness, QColor innerColor, QColor borderColor) :
setVisible(false); /* The logical representation of rectangles are always one less than
setPoints(QPoint(), QPoint()); * the rendered shape, so we subtract 1 from thickness. */
anchored = false; thickness(thickness - 1),
locked = false; half_thickness(qreal(thickness - 1) / 2.0),
statusMessage = QString("Ruler: 0"); innerColor(innerColor),
xRuler = QRect(); borderColor(borderColor),
yRuler = QRect(); mapSize(QSize()),
cornerTick = QLine(); xRuler(QRectF()),
yRuler(QRectF()),
cornerTick(QLineF()),
anchored(false),
locked(false)
{
connect(this, &QGraphicsObject::enabledChanged, [this]() {
if (!isEnabled() && anchored)
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 {
@ -31,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.5; 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.5; 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;
} }
@ -42,20 +50,16 @@ 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);
event->accept();
return true;
} }
} }
@ -64,26 +68,53 @@ bool MapRuler::eventFilter(QObject*, QEvent *event) {
void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) { void MapRuler::mouseEvent(QGraphicsSceneMouseEvent *event) {
if (!anchored && event->button() == Qt::RightButton) { if (!anchored && event->button() == Qt::RightButton) {
setAnchor(event->scenePos(), event->screenPos()); setAnchor(event->scenePos());
} else if (anchored) { } else if (anchored) {
if (event->button() == Qt::LeftButton) if (event->button() == Qt::LeftButton)
locked = !locked; locked = !locked;
if (event->button() == Qt::RightButton) if (event->button() == Qt::RightButton)
endAnchor(); reset();
else else
setEndPos(event->scenePos(), event->screenPos()); setEndPos(event->scenePos());
} }
} }
void MapRuler::setMapDimensions(const QSize &size) { void MapRuler::setMapDimensions(const QSize &size) {
mapSize = size; mapSize = size;
init(); reset();
} }
void MapRuler::setEnabled(bool enabled) { void MapRuler::reset() {
QGraphicsItem::setEnabled(enabled); prepareGeometryChange();
if (!enabled && anchored) hide();
endAnchor(); setPoints(QPoint(), QPoint());
xRuler = QRectF();
yRuler = QRectF();
cornerTick = QLineF();
anchored = false;
locked = false;
emit statusChanged(QString());
}
void MapRuler::setAnchor(const QPointF &scenePos) {
QPoint pos = Metatile::coordFromPixmapCoord(scenePos);
pos = snapToWithinBounds(pos);
anchored = true;
locked = false;
setPoints(pos, pos);
updateGeometry();
show();
}
void MapRuler::setEndPos(const QPointF &scenePos) {
if (locked)
return;
QPoint pos = Metatile::coordFromPixmapCoord(scenePos);
pos = snapToWithinBounds(pos);
const QPoint lastEndPos = endPos();
setP2(pos);
if (pos != lastEndPos)
updateGeometry();
} }
QPoint MapRuler::snapToWithinBounds(QPoint pos) const { QPoint MapRuler::snapToWithinBounds(QPoint pos) const {
@ -98,80 +129,62 @@ QPoint MapRuler::snapToWithinBounds(QPoint pos) const {
return pos; return pos;
} }
void MapRuler::setAnchor(const QPointF &scenePos, const QPoint &screenPos) {
QPoint pos = Metatile::coordFromPixmapCoord(scenePos);
pos = snapToWithinBounds(pos);
anchored = true;
locked = false;
setPoints(pos, pos);
updateGeometry();
setVisible(true);
showDimensions(screenPos);
}
void MapRuler::endAnchor() {
emit deactivated(endPos());
hideDimensions();
prepareGeometryChange();
init();
}
void MapRuler::setEndPos(const QPointF &scenePos, const QPoint &screenPos) {
if (locked)
return;
QPoint pos = Metatile::coordFromPixmapCoord(scenePos);
pos = snapToWithinBounds(pos);
const QPoint lastEndPos = endPos();
setP2(pos);
if (pos != lastEndPos)
updateGeometry();
showDimensions(screenPos);
}
void MapRuler::showDimensions(const QPoint &screenPos) const {
// 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() { 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").arg(width()).arg(height()); updateStatus(Qt::TopLeftCorner);
} 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());
} else if (deltaY() < 0) { statusMessage += QString("\nStart(%1, %2), End(%3, %4)")
// Top-right .arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
xRuler = QRect(0, pixHeight(), pixWidth() + thickness, thickness); break;
yRuler = QRect(pixWidth(), 0, thickness, pixHeight() + thickness); case Qt::TopRightCorner:
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").arg(height()); statusMessage += QString("Up %1\nStart(%2, %3), End(%4, %5)").arg(height())
} else { .arg(anchor().x()).arg(anchor().y()).arg(endPos().x()).arg(endPos().y());
// Bottom-right break;
xRuler = QRect(0, 0, pixWidth() + thickness, thickness); case Qt::BottomRightCorner:
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())
@ -181,9 +194,13 @@ void MapRuler::updateGeometry() {
statusMessage += ", "; statusMessage += ", ";
statusMessage += QString("Down: %1").arg(height()); 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 { } else {
statusMessage += QString("0"); statusMessage += QString("0\nStart(%1, %2)")
.arg(anchor().x()).arg(anchor().y());
} }
break;
} }
emit lengthChanged(); emit statusChanged(statusMessage);
} }