From 7fb6e882be32e39be5b2be98f54867aded64d198 Mon Sep 17 00:00:00 2001 From: johanneshilden Date: Fri, 29 Sep 2017 16:33:26 +0300 Subject: [PATCH] Add Progress component --- components/components.pro | 9 +- components/qtmaterialprogress.cpp | 168 +++++++++++++++++++++ components/qtmaterialprogress.h | 42 ++++++ components/qtmaterialprogress_internal.cpp | 18 +++ components/qtmaterialprogress_internal.h | 38 +++++ components/qtmaterialprogress_p.h | 30 ++++ examples/examples.pro | 9 +- examples/progresssettingseditor.cpp | 99 ++++++++++++ examples/progresssettingseditor.h | 27 ++++ examples/progresssettingsform.ui | 128 ++++++++++++++++ 10 files changed, 563 insertions(+), 5 deletions(-) create mode 100644 components/qtmaterialprogress.cpp create mode 100644 components/qtmaterialprogress.h create mode 100644 components/qtmaterialprogress_internal.cpp create mode 100644 components/qtmaterialprogress_internal.h create mode 100644 components/qtmaterialprogress_p.h create mode 100644 examples/progresssettingseditor.cpp create mode 100644 examples/progresssettingseditor.h create mode 100644 examples/progresssettingsform.ui diff --git a/components/components.pro b/components/components.pro index bed915c..fb84846 100644 --- a/components/components.pro +++ b/components/components.pro @@ -16,7 +16,9 @@ SOURCES = \ qtmaterialflatbutton_internal.cpp \ qtmaterialflatbutton.cpp \ lib/qtmaterialstatetransition.cpp \ - qtmaterialiconbutton.cpp + qtmaterialiconbutton.cpp \ + qtmaterialprogress_internal.cpp \ + qtmaterialprogress.cpp HEADERS = \ qtmaterialavatar_p.h \ qtmaterialavatar.h \ @@ -44,6 +46,9 @@ HEADERS = \ lib/qtmaterialstatetransition.h \ lib/qtmaterialstatetransitionevent.h \ qtmaterialiconbutton_p.h \ - qtmaterialiconbutton.h + qtmaterialiconbutton.h \ + qtmaterialprogress_internal.h \ + qtmaterialprogress_p.h \ + qtmaterialprogress.h RESOURCES += \ resources.qrc diff --git a/components/qtmaterialprogress.cpp b/components/qtmaterialprogress.cpp new file mode 100644 index 0000000..cdbcfdd --- /dev/null +++ b/components/qtmaterialprogress.cpp @@ -0,0 +1,168 @@ +#include "qtmaterialprogress.h" +#include "qtmaterialprogress_p.h" +#include +#include +#include "qtmaterialprogress_internal.h" +#include "lib/qtmaterialstyle.h" + +/*! + * \class QtMaterialProgressPrivate + * \internal + */ + +QtMaterialProgressPrivate::QtMaterialProgressPrivate(QtMaterialProgress *q) + : q_ptr(q) +{ +} + +QtMaterialProgressPrivate::~QtMaterialProgressPrivate() +{ +} + +void QtMaterialProgressPrivate::init() +{ + Q_Q(QtMaterialProgress); + + delegate = new QtMaterialProgressDelegate(q); + progressType = Material::IndeterminateProgress; + useThemeColors = true; + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(q); + animation->setPropertyName("offset"); + animation->setTargetObject(delegate); + animation->setStartValue(0); + animation->setEndValue(1); + animation->setDuration(1000); + + animation->setLoopCount(-1); + + animation->start(); +} + +/*! + * \class QtMaterialProgress + */ + +QtMaterialProgress::QtMaterialProgress(QWidget *parent) + : QProgressBar(parent), + d_ptr(new QtMaterialProgressPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialProgress::~QtMaterialProgress() +{ +} + +void QtMaterialProgress::setProgressType(Material::ProgressType type) +{ + Q_D(QtMaterialProgress); + + d->progressType = type; + update(); +} + +Material::ProgressType QtMaterialProgress::progressType() const +{ + Q_D(const QtMaterialProgress); + + return d->progressType; +} + +void QtMaterialProgress::setUseThemeColors(bool state) +{ + Q_D(QtMaterialProgress); + + if (d->useThemeColors == state) { + return; + } + + d->useThemeColors = state; + update(); +} + +bool QtMaterialProgress::useThemeColors() const +{ + Q_D(const QtMaterialProgress); + + return d->useThemeColors; +} + +void QtMaterialProgress::setProgressColor(const QColor &color) +{ + Q_D(QtMaterialProgress); + + d->progressColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialProgress::progressColor() const +{ + Q_D(const QtMaterialProgress); + + if (d->useThemeColors || !d->progressColor.isValid()) { + return QtMaterialStyle::instance().themeColor("primary1"); + } else { + return d->progressColor; + } +} + +void QtMaterialProgress::setBackgroundColor(const QColor &color) +{ + Q_D(QtMaterialProgress); + + d->backgroundColor = color; + setUseThemeColors(false); +} + +QColor QtMaterialProgress::backgroundColor() const +{ + Q_D(const QtMaterialProgress); + + if (d->useThemeColors || !d->backgroundColor.isValid()) { + return QtMaterialStyle::instance().themeColor("border"); + } else { + return d->backgroundColor; + } +} + +/*! + * \reimp + */ +void QtMaterialProgress::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + Q_D(QtMaterialProgress); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(isEnabled() ? backgroundColor() + : QtMaterialStyle::instance().themeColor("disabled")); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + + QPainterPath path; + path.addRoundedRect(0, height()/2-3, width(), 6, 3, 3); + painter.setClipPath(path); + + painter.drawRect(0, 0, width(), height()); + + if (isEnabled()) + { + brush.setColor(progressColor()); + painter.setBrush(brush); + + if (Material::IndeterminateProgress == d->progressType) { + painter.drawRect(d->delegate->offset()*width()*2-width(), 0, width(), height()); + } else { + qreal p = static_cast(width())*(value()-minimum())/(maximum()-minimum()); + painter.drawRect(0, 0, p, height()); + } + } +} diff --git a/components/qtmaterialprogress.h b/components/qtmaterialprogress.h new file mode 100644 index 0000000..0e69b1d --- /dev/null +++ b/components/qtmaterialprogress.h @@ -0,0 +1,42 @@ +#ifndef QTMATERIALPROGRESS_H +#define QTMATERIALPROGRESS_H + +#include +#include "lib/qtmaterialtheme.h" + +class QtMaterialProgressPrivate; + +class QtMaterialProgress : public QProgressBar +{ + Q_OBJECT + + Q_PROPERTY(QColor progressColor WRITE setProgressColor READ progressColor) + Q_PROPERTY(QColor backgroundColor WRITE setProgressColor READ backgroundColor) + +public: + explicit QtMaterialProgress(QWidget *parent = 0); + ~QtMaterialProgress(); + + void setProgressType(Material::ProgressType type); + Material::ProgressType progressType() const; + + void setUseThemeColors(bool state); + bool useThemeColors() const; + + void setProgressColor(const QColor &color); + QColor progressColor() const; + + void setBackgroundColor(const QColor &color); + QColor backgroundColor() const; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialProgress) + Q_DECLARE_PRIVATE(QtMaterialProgress) +}; + +#endif // QTMATERIALPROGRESS_H diff --git a/components/qtmaterialprogress_internal.cpp b/components/qtmaterialprogress_internal.cpp new file mode 100644 index 0000000..0544bae --- /dev/null +++ b/components/qtmaterialprogress_internal.cpp @@ -0,0 +1,18 @@ +#include "qtmaterialprogress_internal.h" + +/*! + * \class QtMaterialProgressDelegate + * \internal + */ + +QtMaterialProgressDelegate::QtMaterialProgressDelegate(QtMaterialProgress *parent) + : QObject(parent), + m_progress(parent), + m_offset(0) +{ + Q_ASSERT(parent); +} + +QtMaterialProgressDelegate::~QtMaterialProgressDelegate() +{ +} diff --git a/components/qtmaterialprogress_internal.h b/components/qtmaterialprogress_internal.h new file mode 100644 index 0000000..811e3d6 --- /dev/null +++ b/components/qtmaterialprogress_internal.h @@ -0,0 +1,38 @@ +#ifndef QTMATERIALPROGRESS_INTERNAL_H +#define QTMATERIALPROGRESS_INTERNAL_H + +#include +#include "qtmaterialprogress.h" + +class QtMaterialProgressDelegate : public QObject +{ + Q_OBJECT + + Q_PROPERTY(qreal offset WRITE setOffset READ offset) + +public: + QtMaterialProgressDelegate(QtMaterialProgress *parent); + ~QtMaterialProgressDelegate(); + + inline void setOffset(qreal offset); + inline qreal offset() const; + +private: + Q_DISABLE_COPY(QtMaterialProgressDelegate) + + QtMaterialProgress *const m_progress; + qreal m_offset; +}; + +inline void QtMaterialProgressDelegate::setOffset(qreal offset) +{ + m_offset = offset; + m_progress->update(); +} + +inline qreal QtMaterialProgressDelegate::offset() const +{ + return m_offset; +} + +#endif // QTMATERIALPROGRESS_INTERNAL_H diff --git a/components/qtmaterialprogress_p.h b/components/qtmaterialprogress_p.h new file mode 100644 index 0000000..b55fb02 --- /dev/null +++ b/components/qtmaterialprogress_p.h @@ -0,0 +1,30 @@ +#ifndef QTMATERIALPROGRESS_P_H +#define QTMATERIALPROGRESS_P_H + +#include +#include +#include "lib/qtmaterialtheme.h" + +class QtMaterialProgress; +class QtMaterialProgressDelegate; + +class QtMaterialProgressPrivate +{ + Q_DISABLE_COPY(QtMaterialProgressPrivate) + Q_DECLARE_PUBLIC(QtMaterialProgress) + +public: + QtMaterialProgressPrivate(QtMaterialProgress *q); + ~QtMaterialProgressPrivate(); + + void init(); + + QtMaterialProgress *const q_ptr; + QtMaterialProgressDelegate *delegate; + Material::ProgressType progressType; + QColor progressColor; + QColor backgroundColor; + bool useThemeColors; +}; + +#endif // QTMATERIALPROGRESS_P_H diff --git a/examples/examples.pro b/examples/examples.pro index e6d8989..9f92148 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -8,7 +8,8 @@ SOURCES = mainwindow.cpp \ fabsettingseditor.cpp \ raisedbuttonsettingseditor.cpp \ flatbuttonsettingseditor.cpp \ - iconbuttonsettingseditor.cpp + iconbuttonsettingseditor.cpp \ + progresssettingseditor.cpp HEADERS = mainwindow.h \ avatarsettingseditor.h \ badgesettingseditor.h \ @@ -16,7 +17,8 @@ HEADERS = mainwindow.h \ fabsettingseditor.h \ raisedbuttonsettingseditor.h \ flatbuttonsettingseditor.h \ - iconbuttonsettingseditor.h + iconbuttonsettingseditor.h \ + progresssettingseditor.h LIBS += ../components/libcomponents.a INCLUDEPATH += ../components/ TARGET = ../examples-exe @@ -30,4 +32,5 @@ FORMS += \ checkboxsettingsform.ui \ fabsettingsform.ui \ flatbuttonsettingsform.ui \ - iconbuttonsettingsform.ui + iconbuttonsettingsform.ui \ + progresssettingsform.ui diff --git a/examples/progresssettingseditor.cpp b/examples/progresssettingseditor.cpp new file mode 100644 index 0000000..83ac4e7 --- /dev/null +++ b/examples/progresssettingseditor.cpp @@ -0,0 +1,99 @@ +#include "progresssettingseditor.h" +#include +#include "qtmaterialprogress.h" +#include "lib/qtmaterialtheme.h" + +ProgressSettingsEditor::ProgressSettingsEditor(QWidget *parent) + : QWidget(parent), + ui(new Ui::ProgressSettingsForm), + m_progress(new QtMaterialProgress) +{ + QVBoxLayout *layout = new QVBoxLayout; + setLayout(layout); + + QWidget *widget = new QWidget; + layout->addWidget(widget); + + QWidget *canvas = new QWidget; + canvas->setStyleSheet("QWidget { background: white; }"); + layout->addWidget(canvas); + + ui->setupUi(widget); + layout->setContentsMargins(20, 20, 20, 20); + + layout = new QVBoxLayout; + canvas->setLayout(layout); + layout->addWidget(m_progress); + layout->setAlignment(m_progress, Qt::AlignCenter); + + setupForm(); + + connect(ui->disabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->progressTypeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateWidget())); + connect(ui->progressSlider, SIGNAL(valueChanged(int)), this, SLOT(updateWidget())); + connect(ui->useThemeColorsCheckBox, SIGNAL(toggled(bool)), this, SLOT(updateWidget())); + connect(ui->progressColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + connect(ui->backgroundColorToolButton, SIGNAL(pressed()), this, SLOT(selectColor())); + + ui->progressSlider->setRange(0, 100); +} + +ProgressSettingsEditor::~ProgressSettingsEditor() +{ + delete ui; +} + +void ProgressSettingsEditor::setupForm() +{ + switch (m_progress->progressType()) + { + case Material::DeterminateProgress: + ui->progressTypeComboBox->setCurrentIndex(0); + break; + case Material::IndeterminateProgress: + ui->progressTypeComboBox->setCurrentIndex(1); + break; + default: + break; + } + + ui->disabledCheckBox->setChecked(!m_progress->isEnabled()); + ui->progressSlider->setValue(m_progress->value()); + ui->useThemeColorsCheckBox->setChecked(m_progress->useThemeColors()); +} + +void ProgressSettingsEditor::updateWidget() +{ + switch (ui->progressTypeComboBox->currentIndex()) + { + case 0: + m_progress->setProgressType(Material::DeterminateProgress); + break; + case 1: + m_progress->setProgressType(Material::IndeterminateProgress); + break; + default: + break; + } + + m_progress->setDisabled(ui->disabledCheckBox->isChecked()); + m_progress->setValue(ui->progressSlider->value()); + m_progress->setUseThemeColors(ui->useThemeColorsCheckBox->isChecked()); +} + +void ProgressSettingsEditor::selectColor() +{ + QColorDialog dialog; + if (dialog.exec()) { + QColor color = dialog.selectedColor(); + QString senderName = sender()->objectName(); + if ("progressColorToolButton" == senderName) { + m_progress->setProgressColor(color); + ui->progressColorLineEdit->setText(color.name(QColor::HexRgb)); + } else if ("backgroundColorToolButton" == senderName) { + m_progress->setBackgroundColor(color); + ui->backgroundColorLineEdit->setText(color.name(QColor::HexRgb)); + } + } + setupForm(); +} diff --git a/examples/progresssettingseditor.h b/examples/progresssettingseditor.h new file mode 100644 index 0000000..bc5bbaa --- /dev/null +++ b/examples/progresssettingseditor.h @@ -0,0 +1,27 @@ +#ifndef PROGRESSSETTINGSEDITOR_H +#define PROGRESSSETTINGSEDITOR_H + +#include +#include "ui_progresssettingsform.h" + +class QtMaterialProgress; + +class ProgressSettingsEditor : public QWidget +{ + Q_OBJECT + +public: + explicit ProgressSettingsEditor(QWidget *parent = 0); + ~ProgressSettingsEditor(); + +protected slots: + void setupForm(); + void updateWidget(); + void selectColor(); + +private: + Ui::ProgressSettingsForm *const ui; + QtMaterialProgress *const m_progress; +}; + +#endif // PROGRESSSETTINGSEDITOR_H diff --git a/examples/progresssettingsform.ui b/examples/progresssettingsform.ui new file mode 100644 index 0000000..b7e004b --- /dev/null +++ b/examples/progresssettingsform.ui @@ -0,0 +1,128 @@ + + + ProgressSettingsForm + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 0 + 0 + 240 + 197 + + + + + + + Disabled + + + + + + + + + + Progress type + + + + + + + + Determinate + + + + + Indeterminate + + + + + + + + Progress + + + + + + + Qt::Horizontal + + + + + + + Use theme colors + + + + + + + + + + Progress color + + + + + + + + + + + + ... + + + + + + + + + Background color + + + + + + + + + + + + ... + + + + + + + + + + +