2015-01-12 15:44:53 +01:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2015-01-12 15:44:53 +01:00
|
|
|
**
|
|
|
|
|
** 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
|
2016-01-15 14:58:39 +01:00
|
|
|
** 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.
|
2015-01-12 15:44:53 +01:00
|
|
|
**
|
2016-01-15 14:58:39 +01:00
|
|
|
** 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.
|
2015-01-12 15:44:53 +01:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "progressindicator.h"
|
2015-01-16 11:59:54 +01:00
|
|
|
|
2017-06-06 18:01:39 +02:00
|
|
|
#include "icon.h"
|
2015-01-16 11:59:54 +01:00
|
|
|
#include "qtcassert.h"
|
2015-01-12 15:44:53 +01:00
|
|
|
#include "stylehelper.h"
|
|
|
|
|
|
2015-01-16 11:59:54 +01:00
|
|
|
#include <QEvent>
|
2015-01-12 15:44:53 +01:00
|
|
|
#include <QPainter>
|
|
|
|
|
#include <QPixmap>
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
\class Utils::ProgressIndicator
|
|
|
|
|
\brief The ProgressIndicator class shows an circular, endlessly animated progress indicator.
|
|
|
|
|
|
|
|
|
|
Use it if you want to indicate that some work is being done, but you do not have the detailed
|
|
|
|
|
progress information needed for a progress bar. You can either create the widget on demand,
|
|
|
|
|
or create the widget once and only show it on demand. The animation only runs while the widget
|
|
|
|
|
is visible.
|
|
|
|
|
|
|
|
|
|
\inmodule Qt Creator
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\class Utils::ProgressIndicatorPainter
|
|
|
|
|
\brief The ProgressIndicatorPainter class is the painting backend for the ProgressIndicator
|
|
|
|
|
class.
|
|
|
|
|
|
|
|
|
|
You can use it to paint a circular, endlessly animated progress indicator directly onto a
|
|
|
|
|
QPaintDevice, for example, if you want to show a progress indicator where you cannot use
|
|
|
|
|
a QWidget.
|
|
|
|
|
|
|
|
|
|
\inmodule Qt Creator
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/*!
|
|
|
|
|
\enum Utils::ProgressIndicatorSize
|
|
|
|
|
|
|
|
|
|
Size of a progress indicator.
|
|
|
|
|
\sa Utils::ProgressIndicator
|
|
|
|
|
\sa Utils::ProgressIndicatorPainter
|
|
|
|
|
|
|
|
|
|
\value Small
|
|
|
|
|
Small icon size. Useful for tool bars, status bars, rows in tree views,
|
|
|
|
|
and so on.
|
|
|
|
|
\value Medium
|
|
|
|
|
Larger progress indicator useful for covering whole medium sized widgets.
|
|
|
|
|
\value Large
|
|
|
|
|
Very large progress indicator that can be used to cover large parts of a UI.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-07-25 13:51:36 +02:00
|
|
|
namespace {
|
2015-01-12 15:44:53 +01:00
|
|
|
|
2017-07-25 13:51:36 +02:00
|
|
|
static QString imageFileNameForIndicatorSize(Utils::ProgressIndicatorSize size)
|
2015-01-16 18:10:09 +01:00
|
|
|
{
|
|
|
|
|
switch (size) {
|
2017-07-25 13:51:36 +02:00
|
|
|
case Utils::ProgressIndicatorSize::Large:
|
|
|
|
|
return QLatin1String(":/utils/images/progressindicator_big.png");
|
|
|
|
|
case Utils::ProgressIndicatorSize::Medium:
|
|
|
|
|
return QLatin1String(":/utils/images/progressindicator_medium.png");
|
|
|
|
|
case Utils::ProgressIndicatorSize::Small:
|
|
|
|
|
default:
|
2015-01-16 18:10:09 +01:00
|
|
|
return QLatin1String(":/utils/images/progressindicator_small.png");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-25 13:51:36 +02:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
namespace Utils {
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Constructs a progress indicator painter for the indicator \a size.
|
|
|
|
|
|
|
|
|
|
\sa setUpdateCallback
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
ProgressIndicatorPainter::ProgressIndicatorPainter(ProgressIndicatorSize size)
|
|
|
|
|
{
|
|
|
|
|
m_timer.setSingleShot(false);
|
|
|
|
|
QObject::connect(&m_timer, &QTimer::timeout, [this]() {
|
|
|
|
|
nextAnimationStep();
|
|
|
|
|
if (m_callback)
|
|
|
|
|
m_callback();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
setIndicatorSize(size);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Changes the size of the progress indicator to \a size. Users of the class need
|
|
|
|
|
to adapt their painting or layouting code to the change in resulting pixel size.
|
|
|
|
|
|
|
|
|
|
\sa indicatorSize
|
|
|
|
|
\sa size
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
void ProgressIndicatorPainter::setIndicatorSize(ProgressIndicatorSize size)
|
2015-01-16 11:59:54 +01:00
|
|
|
{
|
2015-01-12 15:44:53 +01:00
|
|
|
m_size = size;
|
2017-07-25 13:51:36 +02:00
|
|
|
m_rotationStep = size == ProgressIndicatorSize::Small ? 45 : 30;
|
|
|
|
|
m_timer.setInterval(size == ProgressIndicatorSize::Small ? 100 : 80);
|
2017-06-06 18:01:39 +02:00
|
|
|
m_pixmap = Icon({{imageFileNameForIndicatorSize(size),
|
|
|
|
|
Theme::PanelTextColorMid}}, Icon::Tint).pixmap();
|
2015-01-16 11:59:54 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the current indicator size. Use \l size to get the resulting
|
|
|
|
|
pixel size.
|
|
|
|
|
|
|
|
|
|
\sa setIndicatorSize
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
ProgressIndicatorSize ProgressIndicatorPainter::indicatorSize() const
|
2015-01-16 11:59:54 +01:00
|
|
|
{
|
|
|
|
|
return m_size;
|
2015-01-12 15:44:53 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Sets the callback \a cb that is called whenever the progress indicator needs a repaint, because
|
|
|
|
|
its animation progressed. The callback is a void function taking no parameters, and should
|
|
|
|
|
usually trigger a QWidget::update on the widget that does the actual painting.
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
void ProgressIndicatorPainter::setUpdateCallback(const UpdateCallback &cb)
|
|
|
|
|
{
|
|
|
|
|
m_callback = cb;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the size of the progress indicator in device independent pixels.
|
|
|
|
|
|
|
|
|
|
\sa setIndicatorSize
|
|
|
|
|
\sa paint
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
QSize ProgressIndicatorPainter::size() const
|
2015-01-12 15:44:53 +01:00
|
|
|
{
|
|
|
|
|
return m_pixmap.size() / m_pixmap.devicePixelRatio();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Paints the progress indicator centered in the \a rect on the given \a painter.
|
|
|
|
|
|
|
|
|
|
\sa size
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
void ProgressIndicatorPainter::paint(QPainter &painter, const QRect &rect) const
|
|
|
|
|
{
|
|
|
|
|
painter.save();
|
|
|
|
|
painter.setRenderHint(QPainter::SmoothPixmapTransform);
|
|
|
|
|
QPoint translate(rect.x() + rect.width() / 2, rect.y() + rect.height() / 2);
|
|
|
|
|
QTransform t;
|
|
|
|
|
t.translate(translate.x(), translate.y());
|
|
|
|
|
t.rotate(m_rotation);
|
|
|
|
|
t.translate(-translate.x(), -translate.y());
|
|
|
|
|
painter.setTransform(t);
|
|
|
|
|
QSize pixmapUserSize(m_pixmap.size() / m_pixmap.devicePixelRatio());
|
|
|
|
|
painter.drawPixmap(QPoint(rect.x() + ((rect.width() - pixmapUserSize.width()) / 2),
|
|
|
|
|
rect.y() + ((rect.height() - pixmapUserSize.height()) / 2)),
|
|
|
|
|
m_pixmap);
|
|
|
|
|
painter.restore();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Starts the progress indicator animation.
|
|
|
|
|
|
|
|
|
|
\sa setUpdateCallback
|
|
|
|
|
\sa stopAnimation
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
void ProgressIndicatorPainter::startAnimation()
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(m_callback, return);
|
|
|
|
|
m_timer.start();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Stops the progress indicator animation.
|
|
|
|
|
|
|
|
|
|
\sa setUpdateCallback
|
|
|
|
|
\sa startAnimation
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
void ProgressIndicatorPainter::stopAnimation()
|
|
|
|
|
{
|
|
|
|
|
m_timer.stop();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2018-07-17 23:21:05 +03:00
|
|
|
void ProgressIndicatorPainter::nextAnimationStep()
|
2017-07-25 13:51:36 +02:00
|
|
|
{
|
|
|
|
|
m_rotation = (m_rotation + m_rotationStep + 360) % 360;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Constructs a ProgressIndicator of the size \a size and with the parent \a parent.
|
|
|
|
|
|
|
|
|
|
Use \l attachToWidget to make the progress indicator automatically resize and center on the
|
|
|
|
|
parent widget.
|
|
|
|
|
|
|
|
|
|
\sa attachToWidget
|
|
|
|
|
\sa setIndicatorSize
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
ProgressIndicator::ProgressIndicator(ProgressIndicatorSize size, QWidget *parent)
|
2020-03-12 15:26:33 +01:00
|
|
|
: OverlayWidget(parent)
|
|
|
|
|
, m_paint(size)
|
2017-07-25 13:51:36 +02:00
|
|
|
{
|
2020-03-12 15:26:33 +01:00
|
|
|
setPaintFunction(
|
|
|
|
|
[this](QWidget *w, QPainter &p, QPaintEvent *) { m_paint.paint(p, w->rect()); });
|
2017-07-25 13:51:36 +02:00
|
|
|
m_paint.setUpdateCallback([this]() { update(); });
|
|
|
|
|
updateGeometry();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Changes the size of the progress indicator to \a size.
|
|
|
|
|
|
|
|
|
|
\sa indicatorSize
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
void ProgressIndicator::setIndicatorSize(ProgressIndicatorSize size)
|
|
|
|
|
{
|
|
|
|
|
m_paint.setIndicatorSize(size);
|
|
|
|
|
updateGeometry();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
Returns the size of the indicator in device independent pixels.
|
|
|
|
|
|
|
|
|
|
\sa indicatorSize
|
|
|
|
|
*/
|
2017-07-25 13:51:36 +02:00
|
|
|
QSize ProgressIndicator::sizeHint() const
|
|
|
|
|
{
|
|
|
|
|
return m_paint.size();
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2015-01-12 15:44:53 +01:00
|
|
|
void ProgressIndicator::showEvent(QShowEvent *)
|
|
|
|
|
{
|
2017-07-25 13:51:36 +02:00
|
|
|
m_paint.startAnimation();
|
2015-01-12 15:44:53 +01:00
|
|
|
}
|
|
|
|
|
|
2017-11-03 10:50:40 +01:00
|
|
|
/*!
|
|
|
|
|
\internal
|
|
|
|
|
*/
|
2015-01-12 15:44:53 +01:00
|
|
|
void ProgressIndicator::hideEvent(QHideEvent *)
|
|
|
|
|
{
|
2017-07-25 13:51:36 +02:00
|
|
|
m_paint.stopAnimation();
|
2015-01-12 15:44:53 +01:00
|
|
|
}
|
|
|
|
|
|
2017-07-25 13:51:36 +02:00
|
|
|
} // namespace Utils
|