/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Extras module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** 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 Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** 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-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include "qquickflatprogressbar_p.h" #include #include QQuickFlatProgressBar::QQuickFlatProgressBar(QQuickItem *parent) : QQuickPaintedItem(parent), mStripeOffset(0), mRadius(0), mIndeterminate(false) { mAnimation.setTargetObject(this); mAnimation.setPropertyName("stripeOffset"); mAnimation.setEndValue(0); mAnimation.setDuration(800); mAnimation.setLoopCount(-1); connect(this, SIGNAL(stripeOffsetChanged(qreal)), this, SLOT(repaint())); connect(this, SIGNAL(progressChanged(qreal)), this, SLOT(repaint())); connect(this, SIGNAL(enabledChanged()), this, SLOT(repaint())); connect(this, SIGNAL(indeterminateChanged(bool)), this, SLOT(repaint())); connect(this, SIGNAL(widthChanged()), this, SLOT(onWidthChanged())); connect(this, SIGNAL(heightChanged()), this, SLOT(onHeightChanged())); connect(this, SIGNAL(visibleChanged()), this, SLOT(onVisibleChanged())); } int QQuickFlatProgressBar::barWidth() { // 14 is the design height of stripes on the bar, 10 is design width of stripe return int(height() * 10 / 14); } void QQuickFlatProgressBar::paint(QPainter *painter) { // This item should always be rounded to an integer size, so it is safe to use int here. const int w = width(); const int h = height(); painter->setRenderHint(QPainter::Antialiasing, true); painter->setPen(Qt::transparent); // Draw the background. painter->setBrush(isIndeterminate() && mProgress > 0 ? QColor(92, 170, 21) : QColor(0, 0, 0, 255 * 0.15)); painter->drawRoundedRect(0, 0, w, h, mRadius, mRadius); // Draw progress, or indeterminate stripes. painter->setClipPath(mClipPath); if (!mIndeterminate) { painter->setBrush(isEnabled() ? QColor(92, 170, 21) : QColor(179, 179, 179)); painter->drawRect(0, 0, int(w * mProgress), h); } else { QPainterPath innerClipPath; // 1 is the design margin thickness. const int margin = qMax(1, int(height() * (1.0 / 16.0))); // We take the margin from the radius so that the inner and outer radii match each other visually. innerClipPath.addRoundedRect(margin, margin, width() - margin * 2, height() - margin * 2, mRadius - margin, mRadius - margin); painter->setClipPath(innerClipPath); painter->translate(mStripeOffset, 0); const qreal stripeWidth = barWidth(); // The horizontal distance created by the slant of the stripe. const qreal stripeSlantDistance = h; // One stripe width is equal to the height of the bar. QPainterPath stripe; stripe.moveTo(0, h); stripe.lineTo(stripeSlantDistance, 0); stripe.lineTo(stripeSlantDistance + stripeWidth, 0); stripe.lineTo(stripeWidth, h); stripe.closeSubpath(); painter->setBrush(QBrush(mProgress > 0 ? QColor(255, 255, 255, 77) : Qt::white)); for (int i = -stripeWidth * 2; i < w + stripeWidth * 2; i += stripeWidth * 2) { painter->translate(i, 0); painter->drawPath(stripe); painter->translate(-i, 0); } painter->translate(-mStripeOffset, 0); } } qreal QQuickFlatProgressBar::stripeOffset() const { return mStripeOffset; } void QQuickFlatProgressBar::setStripeOffset(qreal pos) { if (pos != mStripeOffset) { mStripeOffset = pos; emit stripeOffsetChanged(pos); } } qreal QQuickFlatProgressBar::progress() const { return mProgress; } void QQuickFlatProgressBar::setProgress(qreal progress) { if (progress != mProgress) { mProgress = progress; emit progressChanged(mProgress); } } bool QQuickFlatProgressBar::isIndeterminate() { return mIndeterminate; } void QQuickFlatProgressBar::setIndeterminate(bool indeterminate) { if (indeterminate != mIndeterminate) { mIndeterminate = indeterminate; emit indeterminateChanged(mIndeterminate); } } void QQuickFlatProgressBar::repaint() { QQuickPaintedItem::update(QRect(0, 0, width(), height())); } void QQuickFlatProgressBar::restartAnimation() { mAnimation.stop(); mAnimation.setStartValue(-barWidth() * 2); mAnimation.start(); } void QQuickFlatProgressBar::onVisibleChanged() { if (isVisible()) { restartAnimation(); } else { mAnimation.stop(); } } void QQuickFlatProgressBar::onWidthChanged() { restartAnimation(); mClipPath = QPainterPath(); mClipPath.addRoundedRect(0, 0, width(), height(), mRadius, mRadius); } void QQuickFlatProgressBar::onHeightChanged() { restartAnimation(); // 3 is the design radius, 16 is the design height of the bar const qreal radius = height() * 3 / 16; if (radius != mRadius) { mRadius = radius; } mClipPath = QPainterPath(); mClipPath.addRoundedRect(0, 0, width(), height(), mRadius, mRadius); }