bucket fill shortcut is now Alt key
Some checks failed
Build Porymap / build-linux (5.14.2) (push) Has been cancelled
Build Porymap / build-linux (6.8.2) (push) Has been cancelled
Build Porymap / build-macos (macos-15-intel) (push) Has been cancelled
Build Porymap / build-macos (macos-latest) (push) Has been cancelled
Build Porymap / build-static-windows (push) Has been cancelled

This commit is contained in:
Marcus Huderle 2025-10-26 17:56:42 -05:00
parent 1987fe64e8
commit 66f26ab057
5 changed files with 74 additions and 7 deletions

View File

@ -12,6 +12,8 @@ and this project somewhat adheres to [Semantic Versioning](https://semver.org/sp
### Changed
- Separate `File > Duplicate Current Map/Layout` into two options to allow duplicating the current layout when a map is open.
- The name field now receives focus immediately for the new map/layout dialogs.
- The middle mouse button can now be used to pan around the map views, rather than needing to select the Map Tool. This is a very convenient shortcut that matches popular image-editing programs.
- Previously, the middle mouse button could be used as a shortcut with the pencil tool to switch to bucket-fill mode. This is now achieved using the `Alt` key.
### Fixed
- Fix rare crash while quitting Porymap.

View File

@ -82,6 +82,8 @@ Pencil Tool
The Pencil Tool |pencil-tool| (``Tools > Pencil``, or ``N``) is your bread and butter when editing maps. Simply left-click to paint your current metatile selection onto the map. You can click and drag to paint a bigger portion of the map. When clicking and dragging, the metatiles will be painted as if they are snapping to a grid. This simplifies things like painting large areas of trees.
While using the Pencil Tool (or really, viewing any map view in Porymap), the middle mouse button can be pressed as a hotkey to pan around the map. This is a convenient shortcut as an alternative to selecting the Move Tool.
.. figure:: images/editing-map-tiles/snapping-painting.gif
:alt: Painting a Large Metatile Selection
:align: center

View File

@ -4,12 +4,15 @@
#include <QGraphicsView>
#include <QMouseEvent>
// For general utility features that we add to QGraphicsView
class GraphicsView : public QGraphicsView
{
Q_OBJECT
public:
GraphicsView(QWidget *parent = nullptr) : QGraphicsView(parent) {}
GraphicsView(QWidget *parent = nullptr) : QGraphicsView(parent) {
viewport()->installEventFilter(this);
}
void centerOn(const QGraphicsView *other) {
if (other && other->viewport()) {
@ -17,6 +20,64 @@ public:
QGraphicsView::centerOn(other->mapToScene(center));
}
}
bool eventFilter(QObject *obj, QEvent *event) {
// The goal here is to enable pressing the middle mouse button to pan around the graphics view.
// In Qt, the normal way to do this is via setDragMode(). However, that dragging mechanism only
// works via the LEFT mouse button. To support middle mouse button, we have to hijack the middle
// mouse button press event and simulate a fake left button press event. We're not done there,
// though. The children pixmap items will also be receiving that fake button press along with their
// own copy of the original middle-mouse press event because of how QGraphicsScene event handling
// works. So, we maintain a this->isMiddleButtonScrollInProgress boolean which the Editor can query
// to determine if it should ignore mouse events on the pixmap items (e.g. painting, bucket fill).
if (obj == viewport()) {
if (enableMiddleMouseButtonScroll) {
if (event->type() == QEvent::MouseButtonPress) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
if (mouseEvent->button() == Qt::MiddleButton) {
this->setDragMode(QGraphicsView::DragMode::ScrollHandDrag);
QMouseEvent* pressEvent = new QMouseEvent(
QEvent::GraphicsSceneMousePress,
mouseEvent->pos(), Qt::MouseButton::LeftButton,
Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
this->isMiddleButtonScrollInProgress = true;
this->mousePressEvent(pressEvent);
}
return false;
}
else if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
QMouseEvent* releaseEvent = new QMouseEvent(
QEvent::GraphicsSceneMouseRelease,
mouseEvent->pos(), Qt::MouseButton::LeftButton,
Qt::MouseButton::LeftButton, Qt::KeyboardModifier::NoModifier);
this->mouseReleaseEvent(releaseEvent);
this->setDragMode(desiredDragMode);
this->isMiddleButtonScrollInProgress = false;
}
}
}
return QGraphicsView::eventFilter(obj, event);
}
bool getIsMiddleButtonScrollInProgress() {
return this->isMiddleButtonScrollInProgress;
}
void setDesiredDragMode(DragMode mode) {
this->setDragMode(mode);
this->desiredDragMode = mode;
}
protected:
bool enableMiddleMouseButtonScroll;
private:
bool isMiddleButtonScrollInProgress;
DragMode desiredDragMode;
};
class NoScrollGraphicsView : public GraphicsView

View File

@ -16,8 +16,10 @@ class MapView : public GraphicsView
Q_OBJECT
public:
MapView() : GraphicsView() {}
MapView(QWidget *parent) : GraphicsView(parent) {}
MapView() : MapView(nullptr) {}
MapView(QWidget *parent) : GraphicsView(parent) {
this->enableMiddleMouseButtonScroll = true;
}
Editor *editor;

View File

@ -217,8 +217,8 @@ void Editor::setEditAction(EditAction editAction) {
this->cursorMapTileRect->setSingleTileMode(!(editAction == EditAction::Paint && this->editMode == EditMode::Metatiles));
auto dragMode = (editAction == EditAction::Move) ? QGraphicsView::ScrollHandDrag : QGraphicsView::NoDrag;
ui->graphicsView_Map->setDragMode(dragMode);
ui->graphicsView_Connections->setDragMode(dragMode);
ui->graphicsView_Map->setDesiredDragMode(dragMode);
ui->graphicsView_Connections->setDesiredDragMode(dragMode);
// Update cursor
if (this->settings->betterCursors) {
@ -1434,7 +1434,7 @@ void Editor::adjustStraightPathPos(QGraphicsSceneMouseEvent *event, LayoutPixmap
void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *item) {
auto editAction = getEditAction();
if (editAction == EditAction::Move) {
if (editAction == EditAction::Move || ui->graphicsView_Map->getIsMiddleButtonScrollInProgress()) {
event->ignore();
return;
}
@ -1450,7 +1450,7 @@ void Editor::mouseEvent_map(QGraphicsSceneMouseEvent *event, LayoutPixmapItem *i
} else {
item->updateMetatileSelection(event);
}
} else if (event->buttons() & Qt::MiddleButton) {
} else if (event->modifiers() & Qt::AltModifier) {
if (event->modifiers() & Qt::ControlModifier) {
item->magicFill(event);
} else {