From 5fa01e7dbc632f8fc073e96b99fdf33a1d230995 Mon Sep 17 00:00:00 2001 From: szeli1 <143485814+szeli1@users.noreply.github.com> Date: Mon, 3 Mar 2025 00:03:37 +0100 Subject: [PATCH] Navigate workspace in the main window by dragging the mouse (#7595) The scroll bars shown in the main window were removed in favor of a new navigation feature that utilizes dragging the mouse instead. Users can now hold the mouse down on an empty part of the workspace and drag the mouse around to navigate where necessary. --- include/MainWindow.h | 21 ++++++++++-- src/gui/MainWindow.cpp | 74 +++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/include/MainWindow.h b/include/MainWindow.h index 6c140a1e6..1330de8c5 100644 --- a/include/MainWindow.h +++ b/include/MainWindow.h @@ -29,6 +29,7 @@ #include #include #include +#include #include "ConfigManager.h" @@ -57,7 +58,7 @@ class MainWindow : public QMainWindow public: QMdiArea* workspace() { - return m_workspace; + return static_cast(m_workspace); } QWidget* toolBar() @@ -203,7 +204,22 @@ private: bool guiSaveProject(); bool guiSaveProjectAs( const QString & filename ); - QMdiArea * m_workspace; + class MovableQMdiArea : public QMdiArea + { + public: + MovableQMdiArea(QWidget* parent = nullptr); + ~MovableQMdiArea() {} + protected: + void mousePressEvent(QMouseEvent* event) override; + void mouseMoveEvent(QMouseEvent* event) override; + void mouseReleaseEvent(QMouseEvent* event) override; + private: + bool m_isBeingMoved; + int m_lastX; + int m_lastY; + }; + + MovableQMdiArea * m_workspace; QWidget * m_toolBar; QGridLayout * m_toolBarLayout; @@ -258,7 +274,6 @@ signals: } ; - } // namespace gui } // namespace lmms diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 225a3f0e9..275ef4d29 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -159,7 +159,7 @@ MainWindow::MainWindow() : sideBar->appendTab(new FileBrowser(root_paths.join("*"), FileItem::defaultFilters(), title, embed::getIconPixmap("computer").transformed(QTransform().rotate(90)), splitter, dirs_as_items)); - m_workspace = new QMdiArea(splitter); + m_workspace = new MovableQMdiArea(splitter); // Load background emit initProgress(tr("Loading background picture")); @@ -179,8 +179,8 @@ MainWindow::MainWindow() : } m_workspace->setOption( QMdiArea::DontMaximizeSubWindowOnActivation ); - m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); - m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded ); + m_workspace->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_workspace->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); hbox->addWidget(sideBar); hbox->addWidget(splitter); @@ -531,8 +531,6 @@ void MainWindow::finalize() } - - int MainWindow::addWidgetToToolBar( QWidget * _w, int _row, int _col ) { int col = ( _col == -1 ) ? m_toolBarLayout->columnCount() + 7 : _col; @@ -944,12 +942,6 @@ void MainWindow::toggleWindow( QWidget *window, bool forceShow ) parent->hide(); refocus(); } - - // Workaround for Qt Bug #260116 - m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); - m_workspace->setHorizontalScrollBarPolicy( Qt::ScrollBarAsNeeded ); - m_workspace->setVerticalScrollBarPolicy( Qt::ScrollBarAsNeeded ); } @@ -1601,4 +1593,64 @@ void MainWindow::onProjectFileNameChanged() } +MainWindow::MovableQMdiArea::MovableQMdiArea(QWidget* parent) : + QMdiArea(parent), + m_isBeingMoved(false), + m_lastX(0), + m_lastY(0) +{} + +void MainWindow::MovableQMdiArea::mousePressEvent(QMouseEvent* event) +{ + m_lastX = event->x(); + m_lastY = event->y(); + m_isBeingMoved = true; + setCursor(Qt::ClosedHandCursor); +} + +void MainWindow::MovableQMdiArea::mouseMoveEvent(QMouseEvent* event) +{ + if (m_isBeingMoved == false) { return; } + + int minXBoundary = window()->width() - 100; + int maxXBoundary = 100; + int minYBoundary = window()->height() - 100; + int maxYBoundary = 100; + + int minX = minXBoundary; + int maxX = maxXBoundary; + int minY = minYBoundary; + int maxY = maxYBoundary; + + auto subWindows = subWindowList(); + for (auto* curWindow : subWindows) + { + if (curWindow->isVisible()) + { + minX = std::min(minX, curWindow->x()); + maxX = std::max(maxX, curWindow->x() + curWindow->width()); + minY = std::min(minY, curWindow->y()); + maxY = std::max(maxY, curWindow->y() + curWindow->height()); + } + } + + int scrollX = m_lastX - event->x(); + int scrollY = m_lastY - event->y(); + + scrollX = scrollX < 0 && minX >= minXBoundary ? 0 : scrollX; + scrollX = scrollX > 0 && maxX <= maxXBoundary ? 0 : scrollX; + scrollY = scrollY < 0 && minY >= minYBoundary ? 0 : scrollY; + scrollY = scrollY > 0 && maxY <= maxYBoundary ? 0 : scrollY; + + scrollContentsBy(-scrollX, -scrollY); + m_lastX = event->x(); + m_lastY = event->y(); +} + +void MainWindow::MovableQMdiArea::mouseReleaseEvent(QMouseEvent* event) +{ + setCursor(Qt::ArrowCursor); + m_isBeingMoved = false; +} + } // namespace lmms::gui