Refactor cursor rectangles

This commit is contained in:
GriffinR 2025-06-16 14:36:18 -04:00
parent 513ba15838
commit d1142d244e
14 changed files with 221 additions and 290 deletions

View File

@ -100,6 +100,7 @@ public:
QRect getVisibleRect() const; QRect getVisibleRect() const;
bool isWithinBounds(int x, int y) const; bool isWithinBounds(int x, int y) const;
bool isWithinBounds(const QPoint &pos) const;
bool isWithinBounds(const QRect &rect) const; bool isWithinBounds(const QRect &rect) const;
bool isWithinBorderBounds(int x, int y) const; bool isWithinBorderBounds(int x, int y) const;

View File

@ -122,9 +122,10 @@ public:
void updateEventPixmapItemZValue(EventPixmapItem *item); void updateEventPixmapItemZValue(EventPixmapItem *item);
qreal getEventOpacity(const Event *event) const; qreal getEventOpacity(const Event *event) const;
bool isMouseInMap() const;
void setPlayerViewRect(const QRectF &rect); void setPlayerViewRect(const QRectF &rect);
void updateCursorRectPos(int x, int y); void setCursorRectPos(const QPoint &pos);
void setCursorRectVisible(bool visible); void updateCursorRectVisibility();
void onEventDragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition); void onEventDragged(Event *event, const QPoint &oldPosition, const QPoint &newPosition);
void onEventReleased(Event *event, const QPoint &position); void onEventReleased(Event *event, const QPoint &position);
@ -251,6 +252,7 @@ private:
QString getMovementPermissionText(uint16_t collision, uint16_t elevation); QString getMovementPermissionText(uint16_t collision, uint16_t elevation);
QString getMetatileDisplayMessage(uint16_t metatileId); QString getMetatileDisplayMessage(uint16_t metatileId);
void setCollisionTabSpinBoxes(uint16_t collision, uint16_t elevation); void setCollisionTabSpinBoxes(uint16_t collision, uint16_t elevation);
void adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item, QPoint *pos) const;
static bool startDetachedProcess(const QString &command, static bool startDetachedProcess(const QString &command,
const QString &workingDirectory = QString(), const QString &workingDirectory = QString(),
qint64 *pid = nullptr); qint64 *pid = nullptr);
@ -259,7 +261,6 @@ private slots:
void onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item); void onMapStartPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
void onMapEndPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item); void onMapEndPaint(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
void setSmartPathCursorMode(QGraphicsSceneMouseEvent *event); void setSmartPathCursorMode(QGraphicsSceneMouseEvent *event);
void setStraightPathCursorMode(QGraphicsSceneMouseEvent *event);
void mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item); void mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item);
void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item); void mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixmapItem *item);
void setSelectedConnectionItem(ConnectionPixmapItem *connectionItem); void setSelectedConnectionItem(ConnectionPixmapItem *connectionItem);
@ -267,10 +268,9 @@ private slots:
void onHoveredMovementPermissionCleared(); void onHoveredMovementPermissionCleared();
void onHoveredMetatileSelectionChanged(uint16_t); void onHoveredMetatileSelectionChanged(uint16_t);
void onHoveredMetatileSelectionCleared(); void onHoveredMetatileSelectionCleared();
void onHoveredMapMetatileChanged(const QPoint &pos); void onMapHoverEntered(const QPoint &pos);
void onHoveredMapMetatileCleared(); void onMapHoverChanged(const QPoint &pos);
void onHoveredMapMovementPermissionChanged(int, int); void onMapHoverCleared();
void onHoveredMapMovementPermissionCleared();
void onSelectedMetatilesChanged(); void onSelectedMetatilesChanged();
void onWheelZoom(int); void onWheelZoom(int);

View File

@ -23,11 +23,11 @@ public:
QSpinBox * selectedElevation; QSpinBox * selectedElevation;
qreal *opacity; qreal *opacity;
void updateMovementPermissionSelection(QGraphicsSceneMouseEvent *event); void updateMovementPermissionSelection(QGraphicsSceneMouseEvent *event);
virtual void paint(QGraphicsSceneMouseEvent*); virtual void paint(QGraphicsSceneMouseEvent*) override;
virtual void floodFill(QGraphicsSceneMouseEvent*); virtual void floodFill(QGraphicsSceneMouseEvent*) override;
virtual void magicFill(QGraphicsSceneMouseEvent*); virtual void magicFill(QGraphicsSceneMouseEvent*) override;
virtual void pick(QGraphicsSceneMouseEvent*); virtual void pick(QGraphicsSceneMouseEvent*) override;
void draw(bool ignoreCache = false); void draw(bool ignoreCache = false) override;
private: private:
unsigned actionId_ = 0; unsigned actionId_ = 0;
@ -36,16 +36,17 @@ private:
signals: signals:
void mouseEvent(QGraphicsSceneMouseEvent *, CollisionPixmapItem *); void mouseEvent(QGraphicsSceneMouseEvent *, CollisionPixmapItem *);
void hoveredMapMovementPermissionChanged(int, int); void hoverEntered(const QPoint &pos);
void hoveredMapMovementPermissionCleared(); void hoverChanged(const QPoint &pos);
void hoverCleared();
protected: protected:
void hoverMoveEvent(QGraphicsSceneHoverEvent*); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*) override;
void hoverEnterEvent(QGraphicsSceneHoverEvent*); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent*); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override;
void mousePressEvent(QGraphicsSceneMouseEvent*); virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent*); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent*); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
}; };
#endif // COLLISIONPIXMAPITEM_H #endif // COLLISIONPIXMAPITEM_H

View File

@ -8,78 +8,55 @@
class CursorTileRect : public QGraphicsItem class CursorTileRect : public QGraphicsItem
{ {
public: public:
CursorTileRect(bool *enabled, QRgb color); CursorTileRect(const QSize &tileSize, const QRgb &color, QGraphicsItem *parent = nullptr);
QRectF boundingRect() const override
{ QSize size() const;
int width = this->width;
int height = this->height; QRectF boundingRect() const override {
if (this->singleTileMode) { auto s = size();
width = 16;
height = 16;
} else if (!this->rightClickSelectionAnchored && this->smartPathMode && this->selectionHeight == 3 && this->selectionWidth == 3) {
width = 32;
height = 32;
}
qreal penWidth = 4; qreal penWidth = 4;
return QRectF(-penWidth, return QRectF(-penWidth,
-penWidth, -penWidth,
width + penWidth * 2, s.width() + penWidth * 2,
height + penWidth * 2); s.height() + penWidth * 2);
} }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) override {
{ if (!isVisible()) return;
if (!(*enabled)) return; auto rect = QRectF(pos(), size());
int width = this->width; painter->setPen(m_color);
int height = this->height; painter->drawRect(rect + QMargins(1,1,1,1)); // Fill
if (this->singleTileMode) {
width = 16;
height = 16;
} else if (this->smartPathInEffect()) {
width = 32;
height = 32;
}
painter->setPen(this->color);
painter->drawRect(x() - 1, y() - 1, width + 2, height + 2);
painter->setPen(QColor(0, 0, 0)); painter->setPen(QColor(0, 0, 0));
painter->drawRect(x() - 2, y() - 2, width + 4, height + 4); painter->drawRect(rect + QMargins(2,2,2,2)); // Outer border
painter->drawRect(x(), y(), width, height); painter->drawRect(rect); // Inner border
} }
void initAnchor(int coordX, int coordY); void initAnchor(int coordX, int coordY);
void stopAnchor(); void stopAnchor();
void initRightClickSelectionAnchor(int coordX, int coordY); void initRightClickSelectionAnchor(int coordX, int coordY);
void stopRightClickSelectionAnchor(); void stopRightClickSelectionAnchor();
void setSmartPathMode(bool enable) { this->smartPathMode = enable; } void setSmartPathMode(bool enable) { m_smartPathMode = enable; }
bool getSmartPathMode() const { return this->smartPathMode; } bool getSmartPathMode() const { return m_smartPathMode; }
void setStraightPathMode(bool enable) { this->straightPathMode = enable; } void setSingleTileMode(bool enable) { m_singleTileMode = enable; }
bool getStraightPathMode() const { return this->straightPathMode; } bool getSingleTileMode() const { return m_singleTileMode; }
void setSingleTileMode(bool enable) { this->singleTileMode = enable; }
bool getSingleTileMode() const { return this->singleTileMode; }
void updateLocation(int x, int y); void updateLocation(int x, int y);
void updateSelectionSize(int width, int height); void updateSelectionSize(int width, int height);
void setActive(bool active);
bool getActive();
bool *enabled;
private: private:
bool active; const QSize m_tileSize;
int width; QSize m_selectionSize;
int height; QPoint m_anchorCoord;
bool anchored; QRgb m_color;
bool rightClickSelectionAnchored;
bool smartPathMode; bool m_anchored = false;
bool straightPathMode; bool m_rightClickSelectionAnchored = false;
bool singleTileMode; bool m_smartPathMode = false;
int anchorCoordX; bool m_singleTileMode = false;
int anchorCoordY;
int selectionWidth; bool smartPathInEffect() const;
int selectionHeight;
QRgb color;
bool smartPathInEffect();
}; };

View File

@ -102,16 +102,17 @@ signals:
void startPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); void startPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
void endPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); void endPaint(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
void mouseEvent(QGraphicsSceneMouseEvent *, LayoutPixmapItem *); void mouseEvent(QGraphicsSceneMouseEvent *, LayoutPixmapItem *);
void hoveredMapMetatileChanged(const QPoint &pos); void hoverEntered(const QPoint &pos);
void hoveredMapMetatileCleared(); void hoverChanged(const QPoint &pos);
void hoverCleared();
protected: protected:
void hoverMoveEvent(QGraphicsSceneHoverEvent*); virtual void hoverMoveEvent(QGraphicsSceneHoverEvent*) override;
void hoverEnterEvent(QGraphicsSceneHoverEvent*); virtual void hoverEnterEvent(QGraphicsSceneHoverEvent*) override;
void hoverLeaveEvent(QGraphicsSceneHoverEvent*); virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent*) override;
void mousePressEvent(QGraphicsSceneMouseEvent*); virtual void mousePressEvent(QGraphicsSceneMouseEvent*) override;
void mouseMoveEvent(QGraphicsSceneMouseEvent*); virtual void mouseMoveEvent(QGraphicsSceneMouseEvent*) override;
void mouseReleaseEvent(QGraphicsSceneMouseEvent*); virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent*) override;
}; };
#endif // MAPPIXMAPITEM_H #endif // MAPPIXMAPITEM_H

View File

@ -10,7 +10,7 @@
class MovableRect : public QGraphicsRectItem class MovableRect : public QGraphicsRectItem
{ {
public: public:
MovableRect(bool *enabled, const QRectF &rect, const QRgb &color); MovableRect(const QRectF &rect, const QRgb &color);
QRectF boundingRect() const override { QRectF boundingRect() const override {
qreal penWidth = 4; qreal penWidth = 4;
return QRectF(-penWidth, return QRectF(-penWidth,
@ -29,12 +29,7 @@ public:
} }
void updateLocation(int x, int y); void updateLocation(int x, int y);
void setActive(bool active);
bool getActive() const { return this->active; }
protected: protected:
bool *enabled = nullptr;
bool active = true;
QRectF baseRect; QRectF baseRect;
QRgb color; QRgb color;
@ -48,7 +43,7 @@ class ResizableRect : public QObject, public MovableRect
{ {
Q_OBJECT Q_OBJECT
public: public:
ResizableRect(QObject *parent, bool *enabled, int width, int height, QRgb color); ResizableRect(QObject *parent, int width, int height, QRgb color);
QRectF boundingRect() const override { QRectF boundingRect() const override {
return QRectF(this->rect() + QMargins(lineWidth, lineWidth, lineWidth, lineWidth)); return QRectF(this->rect() + QMargins(lineWidth, lineWidth, lineWidth, lineWidth));

View File

@ -55,6 +55,10 @@ bool Layout::isWithinBounds(int x, int y) const {
return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight()); return (x >= 0 && x < this->getWidth() && y >= 0 && y < this->getHeight());
} }
bool Layout::isWithinBounds(const QPoint &pos) const {
return isWithinBounds(pos.x(), pos.y());
}
bool Layout::isWithinBounds(const QRect &rect) const { bool Layout::isWithinBounds(const QRect &rect) const {
return rect.left() >= 0 && rect.right() < this->getWidth() && rect.top() >= 0 && rect.bottom() < this->getHeight(); return rect.left() >= 0 && rect.right() < this->getWidth() && rect.top() >= 0 && rect.bottom() < this->getHeight();
} }

View File

@ -30,7 +30,7 @@ Editor::Editor(Ui::MainWindow* ui)
{ {
this->ui = ui; this->ui = ui;
this->settings = new Settings(); this->settings = new Settings();
this->cursorMapTileRect = new CursorTileRect(&this->settings->cursorTileRectEnabled, qRgb(255, 255, 255)); this->cursorMapTileRect = new CursorTileRect(QSize(16,16), qRgb(255, 255, 255));
this->map_ruler = new MapRuler(4); this->map_ruler = new MapRuler(4);
connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged); connect(this->map_ruler, &MapRuler::statusChanged, this, &Editor::mapRulerStatusChanged);
@ -169,7 +169,6 @@ void Editor::setEditMode(EditMode editMode) {
editStack = &this->layout->editHistory; editStack = &this->layout->editHistory;
} }
this->playerViewRect->setActive(editingLayout);
this->editGroup.setActiveStack(editStack); this->editGroup.setActiveStack(editStack);
this->ui->toolButton_Fill->setEnabled(editingLayout); this->ui->toolButton_Fill->setEnabled(editingLayout);
this->ui->toolButton_Dropper->setEnabled(editingLayout); this->ui->toolButton_Dropper->setEnabled(editingLayout);
@ -203,8 +202,7 @@ void Editor::setEditAction(EditAction editAction) {
this->map_ruler->setEnabled(false); this->map_ruler->setEnabled(false);
} }
// Only show the tile cursor for tools that apply at a specific tile updateCursorRectVisibility();
this->cursorMapTileRect->setActive(getEditingLayout() && editAction != EditAction::Select && editAction != EditAction::Move);
// The tile cursor can only grow while painting metatiles // The tile cursor can only grow while painting metatiles
this->cursorMapTileRect->setSingleTileMode(!(editAction == EditAction::Paint && this->editMode == EditMode::Metatiles)); this->cursorMapTileRect->setSingleTileMode(!(editAction == EditAction::Paint && this->editMode == EditMode::Metatiles));
@ -1139,15 +1137,20 @@ void Editor::scaleMapView(int s) {
ui->graphicsView_Connections->setTransform(transform); ui->graphicsView_Connections->setTransform(transform);
} }
void Editor::setPlayerViewRect(const QRectF &rect) { bool Editor::isMouseInMap() const {
delete this->playerViewRect; return (this->map_item && this->map_item->has_mouse) || (this->collision_item && this->collision_item->has_mouse);
this->playerViewRect = new MovableRect(&this->settings->playerViewRectEnabled, rect, qRgb(255, 255, 255));
this->playerViewRect->setActive(getEditingLayout());
if (ui->graphicsView_Map->scene())
ui->graphicsView_Map->scene()->update();
} }
void Editor::updateCursorRectPos(int x, int y) { void Editor::setPlayerViewRect(const QRectF &rect) {
delete this->playerViewRect;
this->playerViewRect = new MovableRect(rect, qRgb(255, 255, 255));
updateCursorRectVisibility();
}
void Editor::setCursorRectPos(const QPoint &pos) {
int x = qMax(0, qMin(pos.x(), this->layout ? this->layout->getWidth() - 1 : 0));
int y = qMax(0, qMin(pos.y(), this->layout ? this->layout->getHeight() - 1 : 0));
if (this->playerViewRect) if (this->playerViewRect)
this->playerViewRect->updateLocation(x, y); this->playerViewRect->updateLocation(x, y);
if (this->cursorMapTileRect) if (this->cursorMapTileRect)
@ -1156,23 +1159,55 @@ void Editor::updateCursorRectPos(int x, int y) {
ui->graphicsView_Map->scene()->update(); ui->graphicsView_Map->scene()->update();
} }
void Editor::setCursorRectVisible(bool visible) { void Editor::updateCursorRectVisibility() {
if (this->playerViewRect) bool mouseInMap = isMouseInMap();
this->playerViewRect->setVisible(visible); bool changed = false;
if (this->cursorMapTileRect)
this->cursorMapTileRect->setVisible(visible); if (this->playerViewRect) {
if (ui->graphicsView_Map->scene()) bool visible = this->settings->playerViewRectEnabled
&& mouseInMap
&& this->editMode != EditMode::Connections;
if (visible != this->playerViewRect->isVisible()) {
this->playerViewRect->setVisible(visible);
changed = true;
}
}
if (this->cursorMapTileRect) {
auto editAction = getEditAction();
bool visible = this->settings->cursorTileRectEnabled
&& mouseInMap
&& getEditingLayout()
// Only show the tile cursor for tools that apply at a specific tile
&& editAction != EditAction::Select
&& editAction != EditAction::Move;
if (visible != this->cursorMapTileRect->isVisible()) {
this->cursorMapTileRect->setVisible(visible);
changed = true;
}
}
// TODO: Investigate whether it'd be worth limiting the scene update to the old and new areas of the cursor rectangles.
if (ui->graphicsView_Map->scene() && changed) {
ui->graphicsView_Map->scene()->update(); ui->graphicsView_Map->scene()->update();
}
} }
void Editor::onHoveredMapMetatileChanged(const QPoint &pos) { void Editor::onMapHoverEntered(const QPoint &pos) {
int x = pos.x(); updateCursorRectVisibility();
int y = pos.y(); onMapHoverChanged(pos);
if (!layout || !layout->isWithinBounds(x, y)) }
void Editor::onMapHoverChanged(const QPoint &pos) {
this->setCursorRectPos(pos);
if (!layout || !layout->isWithinBounds(pos))
return; return;
this->updateCursorRectPos(x, y); int x = pos.x();
if (this->getEditingLayout()) { int y = pos.y();
if (this->editMode == EditMode::Metatiles) {
int blockIndex = y * layout->getWidth() + x; int blockIndex = y * layout->getWidth() + x;
int metatileId = layout->blockdata.at(blockIndex).metatileId(); int metatileId = layout->blockdata.at(blockIndex).metatileId();
this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x") this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3, Scale = %4x")
@ -1180,8 +1215,15 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
.arg(y) .arg(y)
.arg(getMetatileDisplayMessage(metatileId)) .arg(getMetatileDisplayMessage(metatileId))
.arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2))); .arg(QString::number(zoomLevels[this->scaleIndex], 'g', 2)));
} } else if (this->editMode == EditMode::Collision) {
else if (this->editMode == EditMode::Events) { int blockIndex = y * layout->getWidth() + x;
uint16_t collision = layout->blockdata.at(blockIndex).collision();
uint16_t elevation = layout->blockdata.at(blockIndex).elevation();
this->ui->statusBar->showMessage(QString("X: %1, Y: %2, %3")
.arg(x)
.arg(y)
.arg(this->getMovementPermissionText(collision, elevation)));
} else if (this->editMode == EditMode::Events) {
this->ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x") this->ui->statusBar->showMessage(QString("X: %1, Y: %2, Scale = %3x")
.arg(x) .arg(x)
.arg(y) .arg(y)
@ -1191,36 +1233,10 @@ void Editor::onHoveredMapMetatileChanged(const QPoint &pos) {
Scripting::cb_BlockHoverChanged(x, y); Scripting::cb_BlockHoverChanged(x, y);
} }
void Editor::onHoveredMapMetatileCleared() { void Editor::onMapHoverCleared() {
this->setCursorRectVisible(false); updateCursorRectVisibility();
if (map_item->getEditsEnabled()) { if (getEditingLayout()) {
this->ui->statusBar->clearMessage(); ui->statusBar->clearMessage();
}
Scripting::cb_BlockHoverCleared();
}
void Editor::onHoveredMapMovementPermissionChanged(int x, int y) {
if (!layout || !layout->isWithinBounds(x, y))
return;
this->updateCursorRectPos(x, y);
if (this->getEditingLayout()) {
int blockIndex = y * layout->getWidth() + x;
uint16_t collision = layout->blockdata.at(blockIndex).collision();
uint16_t elevation = layout->blockdata.at(blockIndex).elevation();
QString message = QString("X: %1, Y: %2, %3")
.arg(x)
.arg(y)
.arg(this->getMovementPermissionText(collision, elevation));
this->ui->statusBar->showMessage(message);
}
Scripting::cb_BlockHoverChanged(x, y);
}
void Editor::onHoveredMapMovementPermissionCleared() {
this->setCursorRectVisible(false);
if (this->getEditingLayout()) {
this->ui->statusBar->clearMessage();
} }
Scripting::cb_BlockHoverCleared(); Scripting::cb_BlockHoverCleared();
} }
@ -1371,11 +1387,10 @@ void Editor::setSmartPathCursorMode(QGraphicsSceneMouseEvent *event)
} }
} }
void Editor::setStraightPathCursorMode(QGraphicsSceneMouseEvent *event) { void Editor::adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item, QPoint *pos) const {
if (event->modifiers() & Qt::ControlModifier) { if (event->modifiers() & Qt::ControlModifier) {
this->cursorMapTileRect->setStraightPathMode(true); item->lockNondominantAxis(event);
} else { *pos = item->adjustCoords(*pos);
this->cursorMapTileRect->setStraightPathMode(false);
} }
} }
@ -1399,14 +1414,10 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i
} else { } else {
if (event->type() == QEvent::GraphicsSceneMouseRelease) { if (event->type() == QEvent::GraphicsSceneMouseRelease) {
// Update the tile rectangle at the end of a click-drag selection // Update the tile rectangle at the end of a click-drag selection
this->updateCursorRectPos(pos.x(), pos.y()); setCursorRectPos(pos);
}
this->setSmartPathCursorMode(event);
this->setStraightPathCursorMode(event);
if (this->cursorMapTileRect->getStraightPathMode()) {
item->lockNondominantAxis(event);
pos = item->adjustCoords(pos);
} }
setSmartPathCursorMode(event);
adjustStraightPathPos(event, item, &pos);
item->paint(event); item->paint(event);
} }
} else if (mapEditAction == EditAction::Select) { } else if (mapEditAction == EditAction::Select) {
@ -1426,11 +1437,7 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i
item->pick(event); item->pick(event);
} }
} else if (mapEditAction == EditAction::Shift) { } else if (mapEditAction == EditAction::Shift) {
this->setStraightPathCursorMode(event); adjustStraightPathPos(event, item, &pos);
if (this->cursorMapTileRect->getStraightPathMode()) {
item->lockNondominantAxis(event);
pos = item->adjustCoords(pos);
}
item->shift(event); item->shift(event);
} }
} else if (this->editMode == EditMode::Events) { } else if (this->editMode == EditMode::Events) {
@ -1493,11 +1500,7 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm
item->floodFill(event); item->floodFill(event);
} }
} else { } else {
this->setStraightPathCursorMode(event); adjustStraightPathPos(event, item, &pos);
if (this->cursorMapTileRect->getStraightPathMode()) {
item->lockNondominantAxis(event);
pos = item->adjustCoords(pos);
}
item->paint(event); item->paint(event);
} }
} else if (mapEditAction == EditAction::Select) { } else if (mapEditAction == EditAction::Select) {
@ -1513,11 +1516,7 @@ void Editor::mouseEvent_collision(QGraphicsSceneMouseEvent *event, CollisionPixm
} else if (mapEditAction == EditAction::Pick) { } else if (mapEditAction == EditAction::Pick) {
item->pick(event); item->pick(event);
} else if (mapEditAction == EditAction::Shift) { } else if (mapEditAction == EditAction::Shift) {
this->setStraightPathCursorMode(event); adjustStraightPathPos(event, item, &pos);
if (this->cursorMapTileRect->getStraightPathMode()) {
item->lockNondominantAxis(event);
pos = item->adjustCoords(pos);
}
item->shift(event); item->shift(event);
} }
} }
@ -1643,8 +1642,9 @@ void Editor::displayMapMetatiles() {
connect(map_item, &LayoutPixmapItem::mouseEvent, this, &Editor::mouseEvent_map); connect(map_item, &LayoutPixmapItem::mouseEvent, this, &Editor::mouseEvent_map);
connect(map_item, &LayoutPixmapItem::startPaint, this, &Editor::onMapStartPaint); connect(map_item, &LayoutPixmapItem::startPaint, this, &Editor::onMapStartPaint);
connect(map_item, &LayoutPixmapItem::endPaint, this, &Editor::onMapEndPaint); connect(map_item, &LayoutPixmapItem::endPaint, this, &Editor::onMapEndPaint);
connect(map_item, &LayoutPixmapItem::hoveredMapMetatileChanged, this, &Editor::onHoveredMapMetatileChanged); connect(map_item, &LayoutPixmapItem::hoverEntered, this, &Editor::onMapHoverEntered);
connect(map_item, &LayoutPixmapItem::hoveredMapMetatileCleared, this, &Editor::onHoveredMapMetatileCleared); connect(map_item, &LayoutPixmapItem::hoverChanged, this, &Editor::onMapHoverChanged);
connect(map_item, &LayoutPixmapItem::hoverCleared, this, &Editor::onMapHoverCleared);
map_item->draw(true); map_item->draw(true);
scene->addItem(map_item); scene->addItem(map_item);
@ -1666,10 +1666,9 @@ void Editor::displayMapMovementPermissions() {
collision_item = new CollisionPixmapItem(this->layout, ui->spinBox_SelectedCollision, ui->spinBox_SelectedElevation, collision_item = new CollisionPixmapItem(this->layout, ui->spinBox_SelectedCollision, ui->spinBox_SelectedElevation,
this->metatile_selector_item, this->settings, &this->collisionOpacity); this->metatile_selector_item, this->settings, &this->collisionOpacity);
connect(collision_item, &CollisionPixmapItem::mouseEvent, this, &Editor::mouseEvent_collision); connect(collision_item, &CollisionPixmapItem::mouseEvent, this, &Editor::mouseEvent_collision);
connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionChanged, connect(collision_item, &CollisionPixmapItem::hoverEntered, this, &Editor::onMapHoverEntered);
this, &Editor::onHoveredMapMovementPermissionChanged); connect(collision_item, &CollisionPixmapItem::hoverChanged, this, &Editor::onMapHoverChanged);
connect(collision_item, &CollisionPixmapItem::hoveredMapMovementPermissionCleared, connect(collision_item, &CollisionPixmapItem::hoverCleared, this, &Editor::onMapHoverCleared);
this, &Editor::onHoveredMapMovementPermissionCleared);
collision_item->draw(true); collision_item->draw(true);
scene->addItem(collision_item); scene->addItem(collision_item);
@ -2092,7 +2091,7 @@ void Editor::onEventDragged(Event *event, const QPoint &oldPosition, const QPoin
if (!this->map || !this->map_item) if (!this->map || !this->map_item)
return; return;
this->map_item->hoveredMapMetatileChanged(newPosition); this->map_item->hoverChanged(newPosition);
// Drag all the other selected events (if any) with it // Drag all the other selected events (if any) with it
QList<Event*> draggedEvents; QList<Event*> draggedEvents;

View File

@ -2176,7 +2176,6 @@ void MainWindow::on_mapViewTab_tabBarClicked(int index)
prefab.updatePrefabUi(this->editor->layout); prefab.updatePrefabUi(this->editor->layout);
} }
} }
editor->setCursorRectVisible(false);
} }
void MainWindow::on_mainTabBar_tabBarClicked(int index) void MainWindow::on_mainTabBar_tabBarClicked(int index)
@ -2240,11 +2239,7 @@ void MainWindow::on_actionPlayer_View_Rectangle_triggered()
bool enabled = ui->actionPlayer_View_Rectangle->isChecked(); bool enabled = ui->actionPlayer_View_Rectangle->isChecked();
porymapConfig.showPlayerView = enabled; porymapConfig.showPlayerView = enabled;
this->editor->settings->playerViewRectEnabled = enabled; this->editor->settings->playerViewRectEnabled = enabled;
if ((this->editor->map_item && this->editor->map_item->has_mouse) this->editor->updateCursorRectVisibility();
|| (this->editor->collision_item && this->editor->collision_item->has_mouse)) {
this->editor->playerViewRect->setVisible(enabled && this->editor->playerViewRect->getActive());
ui->graphicsView_Map->scene()->update();
}
} }
void MainWindow::on_actionCursor_Tile_Outline_triggered() void MainWindow::on_actionCursor_Tile_Outline_triggered()
@ -2252,11 +2247,7 @@ void MainWindow::on_actionCursor_Tile_Outline_triggered()
bool enabled = ui->actionCursor_Tile_Outline->isChecked(); bool enabled = ui->actionCursor_Tile_Outline->isChecked();
porymapConfig.showCursorTile = enabled; porymapConfig.showCursorTile = enabled;
this->editor->settings->cursorTileRectEnabled = enabled; this->editor->settings->cursorTileRectEnabled = enabled;
if ((this->editor->map_item && this->editor->map_item->has_mouse) this->editor->updateCursorRectVisibility();
|| (this->editor->collision_item && this->editor->collision_item->has_mouse)) {
this->editor->cursorMapTileRect->setVisible(enabled && this->editor->cursorMapTileRect->getActive());
ui->graphicsView_Map->scene()->update();
}
} }
void MainWindow::on_actionShow_Events_In_Map_View_triggered() { void MainWindow::on_actionShow_Events_In_Map_View_triggered() {

View File

@ -6,7 +6,7 @@ void CollisionPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
if (pos != this->previousPos) { if (pos != this->previousPos) {
this->previousPos = pos; this->previousPos = pos;
emit this->hoveredMapMovementPermissionChanged(pos.x(), pos.y()); emit this->hoverChanged(pos);
} }
if (this->settings->betterCursors && this->getEditsEnabled()) { if (this->settings->betterCursors && this->getEditsEnabled()) {
setCursor(this->settings->mapCursor); setCursor(this->settings->mapCursor);
@ -15,16 +15,16 @@ void CollisionPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
void CollisionPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { void CollisionPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) {
this->has_mouse = true; this->has_mouse = true;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); this->previousPos = Metatile::coordFromPixmapCoord(event->pos());
emit this->hoveredMapMovementPermissionChanged(pos.x(), pos.y()); emit this->hoverEntered(this->previousPos);
} }
void CollisionPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { void CollisionPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) {
emit this->hoveredMapMovementPermissionCleared();
if (this->settings->betterCursors && this->getEditsEnabled()){ if (this->settings->betterCursors && this->getEditsEnabled()){
unsetCursor(); unsetCursor();
} }
this->has_mouse = false; this->has_mouse = false;
emit this->hoverCleared();
} }
void CollisionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { void CollisionPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
@ -38,7 +38,7 @@ void CollisionPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
if (pos != this->previousPos) { if (pos != this->previousPos) {
this->previousPos = pos; this->previousPos = pos;
emit this->hoveredMapMovementPermissionChanged(pos.x(), pos.y()); emit this->hoverChanged(pos);
} }
emit mouseEvent(event, this); emit mouseEvent(event, this);
} }

View File

@ -1,94 +1,70 @@
#include "cursortilerect.h" #include "cursortilerect.h"
#include "log.h" #include "log.h"
CursorTileRect::CursorTileRect(bool *enabled, QRgb color) CursorTileRect::CursorTileRect(const QSize &tileSize, const QRgb &color, QGraphicsItem *parent)
{ : QGraphicsItem(parent),
this->enabled = enabled; m_tileSize(tileSize),
this->active = true; m_selectionSize(QSize(1,1)),
this->color = color; m_anchorCoord(QPoint(0,0)),
this->width = 16; m_color(color)
this->height = 16; { }
this->smartPathMode = false;
this->straightPathMode = false; // Size of the cursor may be explicitly enforced depending on settings.
this->singleTileMode = false; QSize CursorTileRect::size() const {
this->anchored = false; if (m_singleTileMode)
this->rightClickSelectionAnchored = false; return m_tileSize;
this->anchorCoordX = 0;
this->anchorCoordY = 0; if (smartPathInEffect())
this->selectionWidth = 1; return m_tileSize * 2;
this->selectionHeight = 1;
return QSize(m_tileSize.width() * m_selectionSize.width(),
m_tileSize.height() * m_selectionSize.height());
} }
void CursorTileRect::setActive(bool active) void CursorTileRect::initAnchor(int coordX, int coordY) {
{ m_anchorCoord = QPoint(coordX, coordY);
this->active = active; m_anchored = true;
} }
bool CursorTileRect::getActive() void CursorTileRect::stopAnchor() {
{ m_anchored = false;
return active;
} }
void CursorTileRect::initAnchor(int coordX, int coordY) void CursorTileRect::initRightClickSelectionAnchor(int coordX, int coordY) {
{ m_anchorCoord = QPoint(coordX, coordY);
this->anchorCoordX = coordX; m_rightClickSelectionAnchored = true;
this->anchorCoordY = coordY;
this->anchored = true;
} }
void CursorTileRect::stopAnchor() void CursorTileRect::stopRightClickSelectionAnchor() {
{ m_rightClickSelectionAnchored = false;
this->anchored = false;
} }
void CursorTileRect::initRightClickSelectionAnchor(int coordX, int coordY) void CursorTileRect::updateSelectionSize(int width, int height) {
{ m_selectionSize = QSize(width, height).expandedTo(QSize(1,1));
this->anchorCoordX = coordX; prepareGeometryChange();
this->anchorCoordY = coordY; update();
this->rightClickSelectionAnchored = true;
} }
void CursorTileRect::stopRightClickSelectionAnchor() bool CursorTileRect::smartPathInEffect() const {
{ return !m_rightClickSelectionAnchored && m_smartPathMode && m_selectionSize == QSize(3,3);
this->rightClickSelectionAnchored = false;
} }
void CursorTileRect::updateSelectionSize(int width, int height) void CursorTileRect::updateLocation(int coordX, int coordY) {
{ if (!m_singleTileMode) {
this->selectionWidth = width; if (m_rightClickSelectionAnchored) {
this->selectionHeight = height; coordX = qMin(coordX, m_anchorCoord.x());
this->width = width * 16; coordY = qMin(coordY, m_anchorCoord.y());
this->height = height * 16; } else if (m_anchored && !smartPathInEffect()) {
this->prepareGeometryChange(); int xDiff = coordX - m_anchorCoord.x();
this->update(); int yDiff = coordY - m_anchorCoord.y();
} if (xDiff < 0 && xDiff % m_selectionSize.width() != 0) xDiff -= m_selectionSize.width();
if (yDiff < 0 && yDiff % m_selectionSize.height() != 0) yDiff -= m_selectionSize.height();
bool CursorTileRect::smartPathInEffect() coordX = m_anchorCoord.x() + (xDiff / m_selectionSize.width()) * m_selectionSize.width();
{ coordY = m_anchorCoord.y() + (yDiff / m_selectionSize.height()) * m_selectionSize.height();
return !this->rightClickSelectionAnchored && this->smartPathMode && this->selectionHeight == 3 && this->selectionWidth == 3;
}
void CursorTileRect::updateLocation(int coordX, int coordY)
{
if (!this->singleTileMode) {
if (this->rightClickSelectionAnchored) {
coordX = qMin(coordX, this->anchorCoordX);
coordY = qMin(coordY, this->anchorCoordY);
}
else if (this->anchored && !this->smartPathInEffect()) {
int xDiff = coordX - this->anchorCoordX;
int yDiff = coordY - this->anchorCoordY;
if (xDiff < 0 && xDiff % this->selectionWidth != 0) xDiff -= this->selectionWidth;
if (yDiff < 0 && yDiff % this->selectionHeight != 0) yDiff -= this->selectionHeight;
coordX = this->anchorCoordX + (xDiff / this->selectionWidth) * this->selectionWidth;
coordY = this->anchorCoordY + (yDiff / this->selectionHeight) * this->selectionHeight;
} }
} }
coordX = qMax(coordX, 0);
coordY = qMax(coordY, 0);
this->setX(coordX * 16); this->setX(coordX * 16);
this->setY(coordY * 16); this->setY(coordY * 16);
this->setVisible(*this->enabled && this->active);
} }

View File

@ -695,7 +695,7 @@ void LayoutPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); QPoint pos = Metatile::coordFromPixmapCoord(event->pos());
if (pos != this->metatilePos) { if (pos != this->metatilePos) {
this->metatilePos = pos; this->metatilePos = pos;
emit this->hoveredMapMetatileChanged(pos); emit this->hoverChanged(pos);
} }
if (this->settings->betterCursors && this->editsEnabled) { if (this->settings->betterCursors && this->editsEnabled) {
setCursor(this->settings->mapCursor); setCursor(this->settings->mapCursor);
@ -704,16 +704,16 @@ void LayoutPixmapItem::hoverMoveEvent(QGraphicsSceneHoverEvent *event) {
void LayoutPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) { void LayoutPixmapItem::hoverEnterEvent(QGraphicsSceneHoverEvent * event) {
this->has_mouse = true; this->has_mouse = true;
QPoint pos = Metatile::coordFromPixmapCoord(event->pos()); this->metatilePos = Metatile::coordFromPixmapCoord(event->pos());
emit this->hoveredMapMetatileChanged(pos); emit this->hoverEntered(this->metatilePos);
} }
void LayoutPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) { void LayoutPixmapItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *) {
emit this->hoveredMapMetatileCleared();
if (this->settings->betterCursors && this->editsEnabled) { if (this->settings->betterCursors && this->editsEnabled) {
unsetCursor(); unsetCursor();
} }
this->has_mouse = false; this->has_mouse = false;
emit this->hoverCleared();
} }
void LayoutPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { void LayoutPixmapItem::mousePressEvent(QGraphicsSceneMouseEvent *event) {
@ -730,7 +730,7 @@ void LayoutPixmapItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
return; return;
this->metatilePos = pos; this->metatilePos = pos;
emit hoveredMapMetatileChanged(pos); emit hoverChanged(pos);
emit mouseEvent(event, this); emit mouseEvent(event, this);
} }

View File

@ -5,14 +5,11 @@
#include "movablerect.h" #include "movablerect.h"
#include "utility.h" #include "utility.h"
MovableRect::MovableRect(bool *enabled, const QRectF &rect, const QRgb &color) MovableRect::MovableRect(const QRectF &rect, const QRgb &color)
: QGraphicsRectItem(rect), : QGraphicsRectItem(rect),
enabled(enabled),
baseRect(rect), baseRect(rect),
color(color) color(color)
{ { }
updateVisibility();
}
/// Center rect on grid position (x, y) /// Center rect on grid position (x, y)
void MovableRect::updateLocation(int x, int y) { void MovableRect::updateLocation(int x, int y) {
@ -20,28 +17,19 @@ void MovableRect::updateLocation(int x, int y) {
this->baseRect.y() + (y * 16), this->baseRect.y() + (y * 16),
this->baseRect.width(), this->baseRect.width(),
this->baseRect.height()); this->baseRect.height());
updateVisibility();
} }
void MovableRect::setActive(bool active) {
this->active = active;
updateVisibility();
}
void MovableRect::updateVisibility() {
setVisible(*this->enabled && this->active);
}
/****************************************************************************** /******************************************************************************
************************************************************************ ************************************************************************
******************************************************************************/ ******************************************************************************/
ResizableRect::ResizableRect(QObject *parent, bool *enabled, int width, int height, QRgb color) ResizableRect::ResizableRect(QObject *parent, int width, int height, QRgb color)
: QObject(parent), : QObject(parent),
MovableRect(enabled, QRect(0, 0, width * 16, height * 16), color) MovableRect(QRect(0, 0, width * 16, height * 16), color)
{ {
setAcceptHoverEvents(true); setAcceptHoverEvents(true);
setFlags(this->flags() | QGraphicsItem::ItemIsMovable); setFlags(this->flags() | QGraphicsItem::ItemIsMovable);
} }
ResizableRect::Edge ResizableRect::detectEdge(int x, int y) { ResizableRect::Edge ResizableRect::detectEdge(int x, int y) {

View File

@ -136,9 +136,7 @@ void ResizeLayoutPopup::setupLayoutView() {
this->ui->spinBox_height->setMinimum(1); this->ui->spinBox_height->setMinimum(1);
this->ui->spinBox_height->setMaximum(maxHeight); this->ui->spinBox_height->setMaximum(maxHeight);
static bool layoutSizeRectVisible = true; this->outline = new ResizableRect(this, this->layout->getWidth(), this->layout->getHeight(), qRgb(255, 0, 255));
this->outline = new ResizableRect(this, &layoutSizeRectVisible, this->layout->getWidth(), this->layout->getHeight(), qRgb(255, 0, 255));
this->outline->setZValue(Editor::ZValue::ResizeLayoutPopup); // Ensure on top of view this->outline->setZValue(Editor::ZValue::ResizeLayoutPopup); // Ensure on top of view
this->outline->setLimit(cover->rect().toAlignedRect()); this->outline->setLimit(cover->rect().toAlignedRect());
connect(outline, &ResizableRect::rectUpdated, [=](QRect rect){ connect(outline, &ResizableRect::rectUpdated, [=](QRect rect){