aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2022-10-20 12:18:42 +0200
committerEike Ziller <eike.ziller@qt.io>2022-11-09 11:11:26 +0000
commit1beaa0771cf45abd04d62e5aa833d289fcf1019e (patch)
tree212427cdda39b9da3c8688f0b3e4d0b64727ef86
parenta8801eff5faa99104cc9016fe5d10f77ba2bc3c9 (diff)
Support temporarily dragging progress details out of the way
The progress details can cover UI that the user is interested in, and with e.g. the Clangd indexing, building and update check we have some long term progress details visible. It is already possible to hide the details by pressing the tool button, but another natural reaction is to just drag the UI out of the way. Add support to drag the progress details to a different position temporarily. The original "preferred" location is reset either when we show a new progress detail and we didn't show anything before, or when the user hides and shows the progress details via the button. Fixes: QTCREATORBUG-28078 Change-Id: Ie9cecf8b4a34385426a4de3baaf4da92e6387254 Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
-rw-r--r--src/plugins/coreplugin/progressmanager/futureprogress.cpp4
-rw-r--r--src/plugins/coreplugin/progressmanager/futureprogress.h2
-rw-r--r--src/plugins/coreplugin/progressmanager/progressbar.cpp9
-rw-r--r--src/plugins/coreplugin/progressmanager/progressbar.h2
-rw-r--r--src/plugins/coreplugin/progressmanager/progressview.cpp68
-rw-r--r--src/plugins/coreplugin/progressmanager/progressview.h17
6 files changed, 88 insertions, 14 deletions
diff --git a/src/plugins/coreplugin/progressmanager/futureprogress.cpp b/src/plugins/coreplugin/progressmanager/futureprogress.cpp
index b2ea4fdd96..1590931839 100644
--- a/src/plugins/coreplugin/progressmanager/futureprogress.cpp
+++ b/src/plugins/coreplugin/progressmanager/futureprogress.cpp
@@ -296,11 +296,11 @@ QFuture<void> FutureProgress::future() const
/*!
\internal
*/
-void FutureProgress::mousePressEvent(QMouseEvent *event)
+void FutureProgress::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
emit clicked();
- QWidget::mousePressEvent(event);
+ QWidget::mouseReleaseEvent(event);
}
void FutureProgress::paintEvent(QPaintEvent *)
diff --git a/src/plugins/coreplugin/progressmanager/futureprogress.h b/src/plugins/coreplugin/progressmanager/futureprogress.h
index 0f6630cd8c..20bdf1784d 100644
--- a/src/plugins/coreplugin/progressmanager/futureprogress.h
+++ b/src/plugins/coreplugin/progressmanager/futureprogress.h
@@ -74,7 +74,7 @@ signals:
void subtitleInStatusBarChanged();
protected:
- void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
void paintEvent(QPaintEvent *) override;
private:
diff --git a/src/plugins/coreplugin/progressmanager/progressbar.cpp b/src/plugins/coreplugin/progressmanager/progressbar.cpp
index e143b26251..c1ced8961f 100644
--- a/src/plugins/coreplugin/progressmanager/progressbar.cpp
+++ b/src/plugins/coreplugin/progressmanager/progressbar.cpp
@@ -181,17 +181,15 @@ QSize ProgressBar::sizeHint() const
namespace { const int INDENT = 6; }
-void ProgressBar::mousePressEvent(QMouseEvent *event)
+void ProgressBar::mouseReleaseEvent(QMouseEvent *event)
{
if (m_cancelEnabled) {
if (event->modifiers() == Qt::NoModifier
&& m_cancelRect.contains(event->pos())) {
- event->accept();
emit clicked();
- return;
}
}
- QWidget::mousePressEvent(event);
+ QWidget::mouseReleaseEvent(event);
}
QFont ProgressBar::titleFont() const
@@ -202,9 +200,10 @@ QFont ProgressBar::titleFont() const
return boldFont;
}
-void ProgressBar::mouseMoveEvent(QMouseEvent *)
+void ProgressBar::mouseMoveEvent(QMouseEvent *ev)
{
update();
+ QWidget::mouseMoveEvent(ev);
}
void ProgressBar::paintEvent(QPaintEvent *)
diff --git a/src/plugins/coreplugin/progressmanager/progressbar.h b/src/plugins/coreplugin/progressmanager/progressbar.h
index 060f0e947b..5c33273e8c 100644
--- a/src/plugins/coreplugin/progressmanager/progressbar.h
+++ b/src/plugins/coreplugin/progressmanager/progressbar.h
@@ -49,7 +49,7 @@ signals:
void clicked();
protected:
- void mousePressEvent(QMouseEvent *event) override;
+ void mouseReleaseEvent(QMouseEvent *event) override;
private:
QFont titleFont() const;
diff --git a/src/plugins/coreplugin/progressmanager/progressview.cpp b/src/plugins/coreplugin/progressmanager/progressview.cpp
index f145d34428..be2c113e8d 100644
--- a/src/plugins/coreplugin/progressmanager/progressview.cpp
+++ b/src/plugins/coreplugin/progressmanager/progressview.cpp
@@ -3,7 +3,9 @@
#include "progressview.h"
+#include <QApplication>
#include <QEvent>
+#include <QMouseEvent>
#include <QVBoxLayout>
using namespace Core;
@@ -24,6 +26,8 @@ ProgressView::~ProgressView() = default;
void ProgressView::addProgressWidget(QWidget *widget)
{
+ if (m_layout->count() == 0)
+ m_anchorBottomRight = {}; // reset temporarily user-moved progress details
m_layout->insertWidget(0, widget);
}
@@ -44,6 +48,7 @@ void ProgressView::setReferenceWidget(QWidget *widget)
m_referenceWidget = widget;
if (m_referenceWidget)
installEventFilter(this);
+ m_anchorBottomRight = {};
reposition();
}
@@ -61,6 +66,9 @@ bool ProgressView::event(QEvent *event)
} else if (event->type() == QEvent::Leave) {
m_hovered = false;
emit hoveredChanged(m_hovered);
+ } else if (event->type() == QEvent::Show) {
+ m_anchorBottomRight = {}; // reset temporarily user-moved progress details
+ reposition();
}
return QWidget::event(event);
}
@@ -72,11 +80,65 @@ bool ProgressView::eventFilter(QObject *obj, QEvent *event)
return false;
}
+void ProgressView::mousePressEvent(QMouseEvent *ev)
+{
+ if ((ev->buttons() & Qt::LeftButton) && parentWidget() && m_referenceWidget) {
+ m_clickPosition = ev->globalPosition();
+ m_clickPositionInWidget = ev->position();
+ } else {
+ m_clickPosition.reset();
+ }
+ QWidget::mousePressEvent(ev);
+}
+
+static QPoint boundedInParent(QWidget *widget, const QPoint &pos, QWidget *parent)
+{
+ QPoint bounded = pos;
+ bounded.setX(qBound(widget->rect().width(), bounded.x(), parent->width()));
+ bounded.setY(qBound(widget->rect().height(), bounded.y(), parent->height()));
+ return bounded;
+}
+
+void ProgressView::mouseMoveEvent(QMouseEvent *ev)
+{
+ if (m_clickPosition) {
+ const QPointF current = ev->globalPosition();
+ if (m_isDragging
+ || (current - *m_clickPosition).manhattanLength() > QApplication::startDragDistance()) {
+ m_isDragging = true;
+ const QPointF newGlobal = current - m_clickPositionInWidget;
+ const QPoint bottomRightInParent = parentWidget()->mapFromGlobal(newGlobal).toPoint()
+ + rect().bottomRight();
+ m_anchorBottomRight = boundedInParent(this, bottomRightInParent, parentWidget())
+ - topRightReferenceInParent();
+ if (m_anchorBottomRight.manhattanLength() <= QApplication::startDragDistance())
+ m_anchorBottomRight = {};
+ QMetaObject::invokeMethod(this, [this] { reposition(); });
+ }
+ }
+ QWidget::mouseMoveEvent(ev);
+}
+
+void ProgressView::mouseReleaseEvent(QMouseEvent *ev)
+{
+ if ((ev->buttons() & Qt::LeftButton)) {
+ m_clickPosition.reset();
+ m_isDragging = false;
+ }
+ QWidget::mouseReleaseEvent(ev);
+}
+
void ProgressView::reposition()
{
if (!parentWidget() || !m_referenceWidget)
return;
- QPoint topRightReferenceInParent =
- m_referenceWidget->mapTo(parentWidget(), m_referenceWidget->rect().topRight());
- move(topRightReferenceInParent - rect().bottomRight());
+ move(boundedInParent(this, topRightReferenceInParent() + m_anchorBottomRight, parentWidget())
+ - rect().bottomRight());
+}
+
+QPoint ProgressView::topRightReferenceInParent() const
+{
+ if (!parentWidget() || !m_referenceWidget)
+ return {};
+ return m_referenceWidget->mapTo(parentWidget(), m_referenceWidget->rect().topRight());
}
diff --git a/src/plugins/coreplugin/progressmanager/progressview.h b/src/plugins/coreplugin/progressmanager/progressview.h
index f9bdf5043b..60176d374a 100644
--- a/src/plugins/coreplugin/progressmanager/progressview.h
+++ b/src/plugins/coreplugin/progressmanager/progressview.h
@@ -3,10 +3,9 @@
#pragma once
-#include "progressmanager.h"
-
#include <QWidget>
+#include <optional>
QT_BEGIN_NAMESPACE
class QVBoxLayout;
@@ -34,15 +33,29 @@ public:
protected:
bool event(QEvent *event) override;
bool eventFilter(QObject *obj, QEvent *event) override;
+ void mousePressEvent(QMouseEvent *ev) override;
+ void mouseMoveEvent(QMouseEvent *ev) override;
+ void mouseReleaseEvent(QMouseEvent *ev) override;
signals:
void hoveredChanged(bool hovered);
private:
void reposition();
+ QPoint topRightReferenceInParent() const;
QVBoxLayout *m_layout;
QWidget *m_referenceWidget = nullptr;
+
+ // dragging
+ std::optional<QPointF> m_clickPosition;
+ QPointF m_clickPositionInWidget;
+ bool m_isDragging = false;
+
+ // relative to referenceWidget's topRight in parentWidget()
+ // can be changed by the user by dragging
+ QPoint m_anchorBottomRight;
+
bool m_hovered = false;
};