// Copyright (C) 2017 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qquickfusionbusyindicator_p.h" #include QT_BEGIN_NAMESPACE QQuickFusionBusyIndicator::QQuickFusionBusyIndicator(QQuickItem *parent) : QQuickPaintedItem(parent) { } QColor QQuickFusionBusyIndicator::color() const { return m_color; } void QQuickFusionBusyIndicator::setColor(const QColor &color) { if (color == m_color) return; m_color = color; update(); } bool QQuickFusionBusyIndicator::isRunning() const { return isVisible(); } void QQuickFusionBusyIndicator::setRunning(bool running) { m_running = running; if (m_running) { setVisible(true); update(); } // Don't set visible to false if not running, because we use an opacity animation (in QML) to hide ourselves. } void QQuickFusionBusyIndicator::paint(QPainter *painter) { const qreal w = width(); const qreal h = height(); if (w <= 0 || h <= 0 || !isRunning()) return; const qreal sz = qMin(w, h); const qreal dx = (w - sz) / 2; const qreal dy = (h - sz) / 2; const int hpw = qRound(qMax(qreal(1), sz / 14)) & -1; const int pw = 2 * hpw; const QRectF bounds(dx + hpw, dy + hpw, sz - pw - 1, sz - pw - 1); QConicalGradient gradient; gradient.setCenter(QPointF(dx + sz / 2, dy + sz / 2)); gradient.setColorAt(0, m_color); gradient.setColorAt(0.1, m_color); gradient.setColorAt(1, Qt::transparent); painter->translate(0.5, 0.5); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(QPen(gradient, pw, Qt::SolidLine)); painter->drawArc(bounds, 0, 360 * 16); painter->setPen(QPen(m_color, pw, Qt::SolidLine, Qt::RoundCap)); painter->drawArc(bounds, 0, 20 * 16); } void QQuickFusionBusyIndicator::itemChange(ItemChange change, const ItemChangeData &data) { QQuickPaintedItem::itemChange(change, data); switch (change) { case ItemOpacityHasChanged: // If running is set to false and then true within a short period (QTBUG-85860), our // OpacityAnimator cancels the 1 => 0 animation (which was for running being set to false), // setting opacity to 0 and hence visible to false. This happens _after_ setRunning(true) // was called, because the properties were set synchronously but the animation is // asynchronous. To account for this situation, we only hide ourselves if we're not running. if (qFuzzyIsNull(data.realValue) && !m_running) setVisible(false); break; case ItemVisibleHasChanged: update(); break; default: break; } } QT_END_NAMESPACE #include "moc_qquickfusionbusyindicator_p.cpp"