diff options
Diffstat (limited to 'src/extras/Private/qquickflatprogressbar.cpp')
| -rw-r--r-- | src/extras/Private/qquickflatprogressbar.cpp | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/src/extras/Private/qquickflatprogressbar.cpp b/src/extras/Private/qquickflatprogressbar.cpp new file mode 100644 index 000000000..f45a708af --- /dev/null +++ b/src/extras/Private/qquickflatprogressbar.cpp @@ -0,0 +1,202 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Quick Extras module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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.LGPLv3 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.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 later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickflatprogressbar_p.h" + +#include <QtCore/QtMath> +#include <QtGui/QPainter> + +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); +} |
