From 8cfd0881ac3fcbb45fd42dedcb1caf0be38eacaf Mon Sep 17 00:00:00 2001 From: Jan Dalheimer Date: Mon, 30 Dec 2013 23:39:10 +0100 Subject: [PATCH] Progress indicators --- CMakeLists.txt | 1 + CategorizedProxyModel.cpp | 4 +-- CategorizedView.cpp | 10 ++++---- CategorizedView.h | 15 +++++++---- InstanceDelegate.cpp | 25 ++++++++++++++++++ main.cpp | 19 +++++++++++--- main.h | 53 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 111 insertions(+), 16 deletions(-) create mode 100644 main.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b94cf53e..029c90b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,7 @@ include_directories(${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_ set(SOURCES main.cpp + main.h CategorizedView.h CategorizedView.cpp diff --git a/CategorizedProxyModel.cpp b/CategorizedProxyModel.cpp index e4a7563a..efcf13c8 100644 --- a/CategorizedProxyModel.cpp +++ b/CategorizedProxyModel.cpp @@ -8,8 +8,8 @@ CategorizedProxyModel::CategorizedProxyModel(QObject *parent) } bool CategorizedProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { - const QString leftCategory = left.data(CategorizedView::CategoryRole).toString(); - const QString rightCategory = right.data(CategorizedView::CategoryRole).toString(); + const QString leftCategory = left.data(CategorizedViewRoles::CategoryRole).toString(); + const QString rightCategory = right.data(CategorizedViewRoles::CategoryRole).toString(); if (leftCategory == rightCategory) { return left.row() < right.row(); diff --git a/CategorizedView.cpp b/CategorizedView.cpp index 27575b59..6bf18cbc 100644 --- a/CategorizedView.cpp +++ b/CategorizedView.cpp @@ -135,7 +135,7 @@ void CategorizedView::dataChanged(const QModelIndex &topLeft, const QModelIndex QListView::dataChanged(topLeft, bottomRight, roles); - if (roles.contains(CategoryRole)) + if (roles.contains(CategorizedViewRoles::CategoryRole) || roles.contains(Qt::DisplayRole)) { updateGeometries(); update(); @@ -178,7 +178,7 @@ void CategorizedView::updateGeometries() for (int i = 0; i < model()->rowCount(); ++i) { - const QString category = model()->index(i, 0).data(CategoryRole).toString(); + const QString category = model()->index(i, 0).data(CategorizedViewRoles::CategoryRole).toString(); if (!cats.contains(category)) { Category *old = this->category(category); @@ -238,7 +238,7 @@ bool CategorizedView::isIndexHidden(const QModelIndex &index) const CategorizedView::Category *CategorizedView::category(const QModelIndex &index) const { - return category(index.data(CategoryRole).toString()); + return category(index.data(CategorizedViewRoles::CategoryRole).toString()); } CategorizedView::Category *CategorizedView::category(const QString &cat) const { @@ -274,7 +274,7 @@ QList CategorizedView::itemsForCategory(const CategorizedView::Cate QList *indices = new QList(); for (int i = 0; i < model()->rowCount(); ++i) { - if (model()->index(i, 0).data(CategoryRole).toString() == category->text) + if (model()->index(i, 0).data(CategorizedViewRoles::CategoryRole).toString() == category->text) { indices->append(model()->index(i, 0)); } @@ -713,7 +713,7 @@ void CategorizedView::dropEvent(QDropEvent *event) const QString categoryText = category->text; if (model()->dropMimeData(event->mimeData(), Qt::MoveAction, row, 0, QModelIndex())) { - model()->setData(model()->index(row, 0), categoryText, CategoryRole); + model()->setData(model()->index(row, 0), categoryText, CategorizedViewRoles::CategoryRole); event->setDropAction(Qt::MoveAction); event->accept(); } diff --git a/CategorizedView.h b/CategorizedView.h index 8ab9ce87..08d43be8 100644 --- a/CategorizedView.h +++ b/CategorizedView.h @@ -5,6 +5,16 @@ #include #include +struct CategorizedViewRoles +{ + enum + { + CategoryRole = Qt::UserRole, + ProgressValueRole, + ProgressMaximumRole + }; +}; + class CategorizedView : public QListView { Q_OBJECT @@ -13,11 +23,6 @@ public: CategorizedView(QWidget *parent = 0); ~CategorizedView(); - enum - { - CategoryRole = Qt::UserRole - }; - virtual QRect visualRect(const QModelIndex &index) const; QModelIndex indexAt(const QPoint &point) const; void setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) override; diff --git a/InstanceDelegate.cpp b/InstanceDelegate.cpp index 5020b8b6..50cead55 100644 --- a/InstanceDelegate.cpp +++ b/InstanceDelegate.cpp @@ -20,6 +20,8 @@ #include #include +#include "CategorizedView.h" + // Origin: Qt static void viewItemTextLayout(QTextLayout &textLayout, int lineWidth, qreal &height, qreal &widthUsed) @@ -85,6 +87,26 @@ void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, cons painter->setRenderHint(QPainter::Antialiasing); } +// TODO this can be made a lot prettier +void drawProgressOverlay(QPainter *painter, const QStyleOptionViewItemV4 &option, const int value, const int maximum) +{ + if (maximum == 0 || value == maximum) + { + return; + } + + painter->save(); + + qreal percent = (qreal)value / (qreal)maximum; + QColor color = option.palette.color(QPalette::Dark); + color.setAlphaF(0.70f); + painter->setBrush(color); + painter->setPen(QPen(QBrush(), 0)); + painter->drawPie(option.rect, 90 * 16, -percent * 360 * 60); + + painter->restore(); +} + static QSize viewItemTextSize(const QStyleOptionViewItemV4 *option) { QStyle *style = option->widget ? option->widget->style() : QApplication::style(); @@ -229,6 +251,9 @@ void ListViewDelegate::paint(QPainter *painter, const QStyleOptionViewItem &opti line.draw(painter, position); } + drawProgressOverlay(painter, opt, index.data(CategorizedViewRoles::ProgressValueRole).toInt(), + index.data(CategorizedViewRoles::ProgressMaximumRole).toInt()); + painter->restore(); } diff --git a/main.cpp b/main.cpp index 58d1c9ba..bd6a44f9 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,16 @@ -#include "CategorizedView.h" +#include "main.h" + #include #include #include +#include +#include "CategorizedView.h" #include "CategorizedProxyModel.h" #include "InstanceDelegate.h" +Progresser *progresser; + QPixmap icon(const Qt::GlobalColor color) { QPixmap p = QPixmap(32, 32); @@ -29,8 +34,9 @@ QStandardItem *createItem(const Qt::GlobalColor color, const QString &text, cons QStandardItem *item = new QStandardItem; item->setText(text); item->setData(icon(color), Qt::DecorationRole); - item->setData(category, CategorizedView::CategoryRole); + item->setData(category, CategorizedViewRoles::CategoryRole); item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + //progresser->addTrackedIndex(item); return item; } QStandardItem *createItem(const int index, const QString &category) @@ -38,8 +44,9 @@ QStandardItem *createItem(const int index, const QString &category) QStandardItem *item = new QStandardItem; item->setText(QString("Item #%1").arg(index)); item->setData(icon(index), Qt::DecorationRole); - item->setData(category, CategorizedView::CategoryRole); + item->setData(category, CategorizedViewRoles::CategoryRole); item->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); + //progresser->addTrackedIndex(item); return item; } @@ -47,6 +54,10 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); + qsrand(QTime::currentTime().msec()); + + progresser = new Progresser(); + QStandardItemModel model; model.setRowCount(10); model.setColumnCount(1); @@ -62,7 +73,7 @@ int main(int argc, char *argv[]) model.setItem(7, createItem(Qt::white, "White", "Not Colorful")); model.setItem(8, createItem(Qt::darkGreen, "Dark Green", "")); - model.setItem(9, createItem(Qt::green, "Green", "")); + model.setItem(9, progresser->addTrackedIndex(createItem(Qt::green, "Green", ""))); for (int i = 0; i < 20; ++i) { diff --git a/main.h b/main.h new file mode 100644 index 00000000..f4c7a3f8 --- /dev/null +++ b/main.h @@ -0,0 +1,53 @@ +#ifndef MAIN_H +#define MAIN_H + +#include +#include +#include +#include +#include + +#include "CategorizedView.h" + +class Progresser : public QObject +{ + Q_OBJECT +public: + explicit Progresser(QObject *parent = 0) : QObject(parent) + { + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(timeout())); + timer->start(50); + } + + QStandardItem *addTrackedIndex(QStandardItem *item) + { + item->setData(1000, CategorizedViewRoles::ProgressMaximumRole); + m_items.append(item); + return item; + } + +public slots: + void timeout() + { + foreach (QStandardItem *item, m_items) + { + int value = item->data(CategorizedViewRoles::ProgressValueRole).toInt(); + value += qrand() % 3; + if (value >= item->data(CategorizedViewRoles::ProgressMaximumRole).toInt()) + { + item->setData(item->data(CategorizedViewRoles::ProgressMaximumRole).toInt(), + CategorizedViewRoles::ProgressValueRole); + } + else + { + item->setData(value, CategorizedViewRoles::ProgressValueRole); + } + } + } + +private: + QList m_items; +}; + +#endif // MAIN_H