From 2307c61c95c09f435f7d0525104ad6fe2042ca68 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 12 Mar 2020 15:26:33 +0100 Subject: [PATCH] Factor an overlay widget out of progress indicator The principle of having a widget on top of all other children of the same parent, for the purpose of painting an overlay, is generic. Change-Id: I6d3ee89cc51354988fedcc40340bb45a065db607 Reviewed-by: David Schulz --- src/libs/utils/CMakeLists.txt | 1 + src/libs/utils/overlaywidget.cpp | 76 ++++++++++++++++++++++++++++ src/libs/utils/overlaywidget.h | 55 ++++++++++++++++++++ src/libs/utils/progressindicator.cpp | 49 ++---------------- src/libs/utils/progressindicator.h | 9 +--- src/libs/utils/utils-lib.pri | 6 ++- src/libs/utils/utils.qbs | 2 + 7 files changed, 144 insertions(+), 54 deletions(-) create mode 100644 src/libs/utils/overlaywidget.cpp create mode 100644 src/libs/utils/overlaywidget.h diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index ff7bbe62862..87929671188 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -96,6 +96,7 @@ add_qtc_library(Utils osspecificaspects.h outputformat.h outputformatter.cpp outputformatter.h + overlaywidget.cpp overlaywidget.h overridecursor.cpp overridecursor.h parameteraction.cpp parameteraction.h pathchooser.cpp pathchooser.h diff --git a/src/libs/utils/overlaywidget.cpp b/src/libs/utils/overlaywidget.cpp new file mode 100644 index 00000000000..d1a5f6e3d3f --- /dev/null +++ b/src/libs/utils/overlaywidget.cpp @@ -0,0 +1,76 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "overlaywidget.h" + +#include "qtcassert.h" + +#include +#include + +Utils::OverlayWidget::OverlayWidget(QWidget *parent) +{ + setAttribute(Qt::WA_TransparentForMouseEvents); + if (parent) + attachToWidget(parent); +} + +void Utils::OverlayWidget::setPaintFunction(const Utils::OverlayWidget::PaintFunction &paint) +{ + m_paint = paint; +} + +bool Utils::OverlayWidget::eventFilter(QObject *obj, QEvent *ev) +{ + if (obj == parent() && ev->type() == QEvent::Resize) + resizeToParent(); + return QWidget::eventFilter(obj, ev); +} + +void Utils::OverlayWidget::paintEvent(QPaintEvent *ev) +{ + if (m_paint) { + QPainter p(this); + m_paint(this, p, ev); + } +} + +void Utils::OverlayWidget::attachToWidget(QWidget *parent) +{ + if (parentWidget()) + parentWidget()->removeEventFilter(this); + setParent(parent); + if (parent) { + parent->installEventFilter(this); + resizeToParent(); + raise(); + } +} + +void Utils::OverlayWidget::resizeToParent() +{ + QTC_ASSERT(parentWidget(), return ); + setGeometry(QRect(QPoint(0, 0), parentWidget()->size())); +} diff --git a/src/libs/utils/overlaywidget.h b/src/libs/utils/overlaywidget.h new file mode 100644 index 00000000000..354d5354b00 --- /dev/null +++ b/src/libs/utils/overlaywidget.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include "utils_global.h" + +#include + +namespace Utils { + +class QTCREATOR_UTILS_EXPORT OverlayWidget : public QWidget +{ + Q_OBJECT +public: + using PaintFunction = std::function; + + explicit OverlayWidget(QWidget *parent = nullptr); + + void attachToWidget(QWidget *parent); + void setPaintFunction(const PaintFunction &paint); + +protected: + bool eventFilter(QObject *obj, QEvent *ev) override; + void paintEvent(QPaintEvent *ev) override; + +private: + void resizeToParent(); + + PaintFunction m_paint; +}; + +} // namespace Utils diff --git a/src/libs/utils/progressindicator.cpp b/src/libs/utils/progressindicator.cpp index dc2d8bb6268..7bc016f8ee6 100644 --- a/src/libs/utils/progressindicator.cpp +++ b/src/libs/utils/progressindicator.cpp @@ -220,9 +220,11 @@ void ProgressIndicatorPainter::nextAnimationStep() \sa setIndicatorSize */ ProgressIndicator::ProgressIndicator(ProgressIndicatorSize size, QWidget *parent) - : QWidget(parent), m_paint(size) + : OverlayWidget(parent) + , m_paint(size) { - setAttribute(Qt::WA_TransparentForMouseEvents); + setPaintFunction( + [this](QWidget *w, QPainter &p, QPaintEvent *) { m_paint.paint(p, w->rect()); }); m_paint.setUpdateCallback([this]() { update(); }); updateGeometry(); } @@ -248,29 +250,6 @@ QSize ProgressIndicator::sizeHint() const return m_paint.size(); } -/*! - Makes the indicator a child of \a parent, automatically centering on it, - and adapting to size changes. -*/ -void ProgressIndicator::attachToWidget(QWidget *parent) -{ - if (parentWidget()) - parentWidget()->removeEventFilter(this); - setParent(parent); - parent->installEventFilter(this); - resizeToParent(); - raise(); -} - -/*! - \internal -*/ -void ProgressIndicator::paintEvent(QPaintEvent *) -{ - QPainter p(this); - m_paint.paint(p, rect()); -} - /*! \internal */ @@ -287,24 +266,4 @@ void ProgressIndicator::hideEvent(QHideEvent *) m_paint.stopAnimation(); } -/*! - \internal -*/ -bool ProgressIndicator::eventFilter(QObject *obj, QEvent *ev) -{ - if (obj == parent() && ev->type() == QEvent::Resize) { - resizeToParent(); - } - return QWidget::eventFilter(obj, ev); -} - -/*! - \internal -*/ -void ProgressIndicator::resizeToParent() -{ - QTC_ASSERT(parentWidget(), return); - setGeometry(QRect(QPoint(0, 0), parentWidget()->size())); -} - } // namespace Utils diff --git a/src/libs/utils/progressindicator.h b/src/libs/utils/progressindicator.h index 6713709c1b0..0d13cf89524 100644 --- a/src/libs/utils/progressindicator.h +++ b/src/libs/utils/progressindicator.h @@ -25,6 +25,7 @@ #pragma once +#include "overlaywidget.h" #include "utils_global.h" #include @@ -76,7 +77,7 @@ private: UpdateCallback m_callback; }; -class QTCREATOR_UTILS_EXPORT ProgressIndicator : public QWidget +class QTCREATOR_UTILS_EXPORT ProgressIndicator : public OverlayWidget { Q_OBJECT public: @@ -86,17 +87,11 @@ public: QSize sizeHint() const final; - void attachToWidget(QWidget *parent); - protected: - void paintEvent(QPaintEvent *) final; void showEvent(QShowEvent *) final; void hideEvent(QHideEvent *) final; - bool eventFilter(QObject *obj, QEvent *ev) final; private: - void resizeToParent(); - ProgressIndicatorPainter m_paint; }; diff --git a/src/libs/utils/utils-lib.pri b/src/libs/utils/utils-lib.pri index 55dd718a728..69db3b63a00 100644 --- a/src/libs/utils/utils-lib.pri +++ b/src/libs/utils/utils-lib.pri @@ -132,7 +132,8 @@ SOURCES += \ $$PWD/jsontreeitem.cpp \ $$PWD/namevaluevalidator.cpp \ $$PWD/camelcasecursor.cpp \ - $$PWD/infolabel.cpp + $$PWD/infolabel.cpp \ + $$PWD/overlaywidget.cpp HEADERS += \ $$PWD/environmentfwd.h \ @@ -279,7 +280,8 @@ HEADERS += \ $$PWD/listmodel.h \ $$PWD/namevaluevalidator.h \ $$PWD/camelcasecursor.h \ - $$PWD/infolabel.h + $$PWD/infolabel.h \ + $$PWD/overlaywidget.h FORMS += $$PWD/filewizardpage.ui \ $$PWD/projectintropage.ui \ diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index ed15c78d8e6..2c1b098c9e5 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -176,6 +176,8 @@ Project { "outputformat.h", "outputformatter.cpp", "outputformatter.h", + "overlaywidget.cpp", + "overlaywidget.h", "overridecursor.cpp", "overridecursor.h", "parameteraction.cpp",