Skip to content

Commit

Permalink
Make panning with Space require pressing a mouse button as well (#3637)
Browse files Browse the repository at this point in the history
At the same time, you can now also use Space panning with the tileset
view. Code refactored to share panning code between map and tileset
views.

An open hand cursor is used when Space is pressed and a closed hand
cursor while actually panning.

Space still triggers panning immediately, when mouse is already pressed.

The "auto scrolling" mode is still not supported in the tileset view,
since this complicates things a little and I'm not sure if supporting
this in the tileset view is meaningful.

Closes #3626
  • Loading branch information
bjorn authored Mar 31, 2023
1 parent 6ebbedd commit e09849e
Show file tree
Hide file tree
Showing 13 changed files with 388 additions and 172 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
### Unreleased

* Make panning with Space require pressing a mouse button as well (#3626)
* Scripting: Added read-only access to Project properties (by dogboydog, #3622)
* Scripting: Fixed behavior of Dialog.SameWidgetRows (#3607)
* Fixed object labels to adjust to application font changes
Expand Down
2 changes: 2 additions & 0 deletions src/tiled/libtilededitor.qbs
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,8 @@ DynamicLibrary {
"offsetmapdialog.ui",
"painttilelayer.cpp",
"painttilelayer.h",
"pannableviewhelper.cpp",
"pannableviewhelper.h",
"pluginlistmodel.cpp",
"pluginlistmodel.h",
"pointhandle.cpp",
Expand Down
29 changes: 0 additions & 29 deletions src/tiled/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@
#include "resizedialog.h"
#include "scriptmanager.h"
#include "sentryhelper.h"
#include "stylehelper.h"
#include "templatesdock.h"
#include "tileset.h"
#include "tilesetdock.h"
Expand Down Expand Up @@ -940,34 +939,6 @@ void MainWindow::changeEvent(QEvent *event)
}
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->isAutoRepeat())
return;

if (MapView *mapView = mDocumentManager->currentMapView()) {
switch (event->key()) {
case Qt::Key_Space:
mapView->setScrollingMode(MapView::DragScrolling);
break;
}
}
}

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
if (event->isAutoRepeat())
return;

if (MapView *mapView = mDocumentManager->currentMapView()) {
switch (event->key()) {
case Qt::Key_Space:
mapView->setScrollingMode(MapView::NoScrolling);
break;
}
}
}

void MainWindow::dragEnterEvent(QDragEnterEvent *e)
{
const QList<QUrl> urls = e->mimeData()->urls();
Expand Down
3 changes: 0 additions & 3 deletions src/tiled/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,6 @@ class TILED_EDITOR_EXPORT MainWindow : public QMainWindow
void closeEvent(QCloseEvent *event) override;
void changeEvent(QEvent *event) override;

void keyPressEvent(QKeyEvent *) override;
void keyReleaseEvent(QKeyEvent *) override;

void dragEnterEvent(QDragEnterEvent *) override;
void dropEvent(QDropEvent *) override;

Expand Down
10 changes: 5 additions & 5 deletions src/tiled/mapeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,9 +443,9 @@ void MapEditor::setCurrentDocument(Document *document)
mapScene->setSelectedTool(mSelectedTool);

if (mSelectedTool)
mapView->viewport()->setCursor(mSelectedTool->cursor());
mapView->setToolCursor(mSelectedTool->cursor());
else
mapView->viewport()->unsetCursor();
mapView->unsetToolCursor();

mViewWithTool = mapView;
}
Expand Down Expand Up @@ -662,9 +662,9 @@ void MapEditor::setSelectedTool(AbstractTool *tool)
mapScene->setSelectedTool(tool);

if (tool)
mViewWithTool->viewport()->setCursor(tool->cursor());
mViewWithTool->setToolCursor(tool->cursor());
else
mViewWithTool->viewport()->unsetCursor();
mViewWithTool->unsetToolCursor();
}

if (tool) {
Expand Down Expand Up @@ -806,7 +806,7 @@ void MapEditor::currentWidgetChanged()
void MapEditor::cursorChanged(const QCursor &cursor)
{
if (mViewWithTool)
mViewWithTool->viewport()->setCursor(cursor);
mViewWithTool->setToolCursor(cursor);
}

void MapEditor::updateStatusInfoLabel(const QString &statusInfo)
Expand Down
116 changes: 39 additions & 77 deletions src/tiled/mapview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "maprenderer.h"
#include "mapscene.h"
#include "objectgroup.h"
#include "pannableviewhelper.h"
#include "preferences.h"
#include "tileanimationdriver.h"
#include "utils.h"
Expand Down Expand Up @@ -102,11 +103,25 @@ MapView::MapView(QWidget *parent)
connect(mZoomable, &Zoomable::scaleChanged, this, &MapView::adjustScale);

connect(mPanningDriver, &TileAnimationDriver::update, this, &MapView::updatePanning);

mPannableViewHelper = new PannableViewHelper(this);
mPannableViewHelper->setAutoPanningEnabled(true);

connect(mPannableViewHelper, &PannableViewHelper::cursorChanged,
this, &MapView::updateCursor);
connect(mPannableViewHelper, &PannableViewHelper::modeChanged,
this, [this] (PannableViewHelper::PanningMode mode) {

if (mode == PannableViewHelper::AutoPanning)
mScrollStartPos = mLastMousePos;

setInteractive(mode == PannableViewHelper::NoPanning);
updatePanningDriverState();
});
}

MapView::~MapView()
{
setScrollingMode(NoScrolling); // Just in case we didn't get a hide event
}

void MapView::setScene(MapScene *scene)
Expand Down Expand Up @@ -254,6 +269,16 @@ void MapView::focusMapObject(MapObject *mapObject)
forceCenterOn(screenCoords, *mapObject->objectGroup());
}

void MapView::updateCursor()
{
if (const auto cursor = mPannableViewHelper->cursor())
viewport()->setCursor(*cursor);
else if (mToolCursor)
viewport()->setCursor(*mToolCursor);
else
viewport()->unsetCursor();
}

void MapView::setPanDirections(PanDirections directions)
{
if (mPanDirections == directions)
Expand All @@ -265,7 +290,7 @@ void MapView::setPanDirections(PanDirections directions)

void MapView::updatePanningDriverState()
{
const bool run = (mPanDirections && ourSmoothScrollingEnabled) || mScrollingMode == AutoScrolling;
const bool run = (mPanDirections && ourSmoothScrollingEnabled) || mPannableViewHelper->mode() == PannableViewHelper::AutoPanning;
if (run && mPanningDriver->state() != QAbstractAnimation::Running)
mPanningDriver->start();
else if (!run && mPanningDriver->state() == QAbstractAnimation::Running)
Expand All @@ -276,7 +301,7 @@ void MapView::updatePanning(int deltaTime)
{
QPoint distance;

if (mScrollingMode == AutoScrolling) {
if (mPannableViewHelper->mode() == PannableViewHelper::AutoPanning) {
distance = (mLastMousePos - mScrollStartPos) * deltaTime / 100;
} else if (mPanDirections && ourSmoothScrollingEnabled) {
if (mPanDirections & Left)
Expand Down Expand Up @@ -333,29 +358,16 @@ void MapView::setMapDocument(MapDocument *mapDocument)
}
}

void MapView::setScrollingMode(ScrollingMode mode)
void MapView::setToolCursor(const QCursor &cursor)
{
if (mScrollingMode == mode)
return;

mScrollingMode = mode;
setInteractive(mode == NoScrolling);
mToolCursor = std::make_unique<QCursor>(cursor);
updateCursor();
}

switch (mScrollingMode) {
case DragScrolling:
case AutoScrolling:
mLastMousePos = QCursor::pos();
mScrollStartPos = mLastMousePos;
QApplication::setOverrideCursor(mScrollingMode == DragScrolling ? Qt::ClosedHandCursor : Qt::SizeAllCursor);
viewport()->grabMouse();
updatePanningDriverState();
break;
case NoScrolling:
viewport()->releaseMouse();
QApplication::restoreOverrideCursor();
updatePanningDriverState();
break;
}
void MapView::unsetToolCursor()
{
mToolCursor.reset();
updateCursor();
}

/**
Expand Down Expand Up @@ -425,7 +437,7 @@ void MapView::forceCenterOn(QPointF position, const Layer &layer)

bool MapView::event(QEvent *e)
{
// Ignore space bar events since they're handled by the MainWindow
// Ignore space bar events since they're handled by the SpaceBarEventFilter
if (e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease) {
if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Space) {
e->ignore();
Expand Down Expand Up @@ -470,8 +482,8 @@ void MapView::paintEvent(QPaintEvent *event)

void MapView::hideEvent(QHideEvent *event)
{
// Disable hand scrolling when the view gets hidden in any way
setScrollingMode(NoScrolling);
// Disable panning when the view gets hidden in any way
mPannableViewHelper->setMode(PannableViewHelper::NoPanning);
QGraphicsView::hideEvent(event);
}

Expand Down Expand Up @@ -599,64 +611,14 @@ void MapView::wheelEvent(QWheelEvent *event)
scrollBy(-pixels);
}

/**
* Activates hand scrolling when the middle mouse button is pressed.
*/
void MapView::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::MiddleButton && isActiveWindow()) {
setScrollingMode(ourAutoScrollingEnabled ? AutoScrolling : DragScrolling);
return;
}

QGraphicsView::mousePressEvent(event);
}

/**
* Deactivates hand scrolling when the middle mouse button is released.
*/
void MapView::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::MiddleButton) {
setScrollingMode(NoScrolling);
return;
}

QGraphicsView::mouseReleaseEvent(event);
}

void MapView::focusInEvent(QFocusEvent *event)
{
Q_UNUSED(event)
emit focused();
}

/**
* Moves the view with the mouse while hand scrolling.
*/
void MapView::mouseMoveEvent(QMouseEvent *event)
{
switch (mScrollingMode) {
case DragScrolling: {
auto *hBar = static_cast<FlexibleScrollBar*>(horizontalScrollBar());
auto *vBar = static_cast<FlexibleScrollBar*>(verticalScrollBar());
const QPoint d = event->globalPos() - mLastMousePos;

int horizontalValue = hBar->value() + (isRightToLeft() ? d.x() : -d.x());
int verticalValue = vBar->value() - d.y();

// Panning can freely move the map without restriction on boundaries
hBar->forceSetValue(horizontalValue);
vBar->forceSetValue(verticalValue);

mLastMousePos = event->globalPos();
return;
}
case AutoScrolling:
case NoScrolling:
break;
}

QGraphicsView::mouseMoveEvent(event);
mLastMousePos = event->globalPos();
mLastMouseScenePos = mapToScene(viewport()->mapFromGlobal(mLastMousePos));
Expand Down
16 changes: 6 additions & 10 deletions src/tiled/mapview.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class MapObject;

class MapDocument;
class MapScene;
class PannableViewHelper;
class TileAnimationDriver;
class Zoomable;

Expand Down Expand Up @@ -69,13 +70,8 @@ class MapView : public QGraphicsView

void fitMapInView();

enum ScrollingMode {
NoScrolling,
DragScrolling,
AutoScrolling
};
ScrollingMode scrollingMode() const { return mScrollingMode; }
void setScrollingMode(ScrollingMode mode);
void setToolCursor(const QCursor &cursor);
void unsetToolCursor();

using QGraphicsView::centerOn;
Q_INVOKABLE void centerOn(qreal x, qreal y) { forceCenterOn(QPointF(x, y)); }
Expand All @@ -97,8 +93,6 @@ class MapView : public QGraphicsView

void wheelEvent(QWheelEvent *event) override;

void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;

void focusInEvent(QFocusEvent *event) override;
Expand All @@ -117,6 +111,7 @@ class MapView : public QGraphicsView
void updateSceneRect(const QRectF &sceneRect, const QTransform &transform);
void updateViewRect();
void focusMapObject(MapObject *mapObject);
void updateCursor();

enum PanDirectionFlag {
Left = 0x1,
Expand All @@ -138,7 +133,8 @@ class MapView : public QGraphicsView
QPoint mLastMousePos;
QPoint mScrollStartPos;
QPointF mLastMouseScenePos;
ScrollingMode mScrollingMode = NoScrolling;
PannableViewHelper *mPannableViewHelper;
std::unique_ptr<QCursor> mToolCursor;
bool mViewInitialized = false;
bool mHasInitialCenterPos = false;
QPointF mInitialCenterPos;
Expand Down
Loading

0 comments on commit e09849e

Please sign in to comment.