From a2ef115c66ad757ea4140239767d75f14313d95f Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Wed, 10 Mar 2021 15:52:30 +0800 Subject: [PATCH] Simplify progress bar painting --- src/gui/CMakeLists.txt | 4 +- src/gui/gui.pri | 4 +- src/gui/previewlistdelegate.cpp | 30 ++------- src/gui/previewlistdelegate.h | 6 +- ...bardelegate.cpp => progressbarpainter.cpp} | 51 +++++++-------- ...ressbardelegate.h => progressbarpainter.h} | 14 ++-- src/gui/properties/proplistdelegate.cpp | 65 +++++++------------ src/gui/properties/proplistdelegate.h | 16 +++-- src/gui/transferlistdelegate.cpp | 19 +++++- src/gui/transferlistdelegate.h | 10 ++- src/gui/transferlistwidget.cpp | 19 ++---- src/gui/transferlistwidget.h | 2 - 12 files changed, 109 insertions(+), 131 deletions(-) rename src/gui/{progressbardelegate.cpp => progressbarpainter.cpp} (56%) rename src/gui/{progressbardelegate.h => progressbarpainter.h} (79%) diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index bafec9458..507e0acd7 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -26,7 +26,7 @@ add_library(qbt_gui STATIC powermanagement/powermanagement.h previewlistdelegate.h previewselectdialog.h - progressbardelegate.h + progressbarpainter.h properties/downloadedpiecesbar.h properties/peerlistsortmodel.h properties/peerlistwidget.h @@ -106,7 +106,7 @@ add_library(qbt_gui STATIC powermanagement/powermanagement.cpp previewlistdelegate.cpp previewselectdialog.cpp - progressbardelegate.cpp + progressbarpainter.cpp properties/downloadedpiecesbar.cpp properties/peerlistsortmodel.cpp properties/peerlistwidget.cpp diff --git a/src/gui/gui.pri b/src/gui/gui.pri index 5f2ecec09..f49e5e70f 100644 --- a/src/gui/gui.pri +++ b/src/gui/gui.pri @@ -27,7 +27,7 @@ HEADERS += \ $$PWD/powermanagement/powermanagement.h \ $$PWD/previewlistdelegate.h \ $$PWD/previewselectdialog.h \ - $$PWD/progressbardelegate.h \ + $$PWD/progressbarpainter.h \ $$PWD/properties/downloadedpiecesbar.h \ $$PWD/properties/peerlistsortmodel.h \ $$PWD/properties/peerlistwidget.h \ @@ -107,7 +107,7 @@ SOURCES += \ $$PWD/powermanagement/powermanagement.cpp \ $$PWD/previewlistdelegate.cpp \ $$PWD/previewselectdialog.cpp \ - $$PWD/progressbardelegate.cpp \ + $$PWD/progressbarpainter.cpp \ $$PWD/properties/downloadedpiecesbar.cpp \ $$PWD/properties/peerlistsortmodel.cpp \ $$PWD/properties/peerlistwidget.cpp \ diff --git a/src/gui/previewlistdelegate.cpp b/src/gui/previewlistdelegate.cpp index 3137432e8..8a17ad715 100644 --- a/src/gui/previewlistdelegate.cpp +++ b/src/gui/previewlistdelegate.cpp @@ -28,18 +28,11 @@ #include "previewlistdelegate.h" -#include #include #include -#include #include -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) -#include -#endif - #include "base/utils/misc.h" -#include "base/utils/string.h" #include "previewselectdialog.h" PreviewListDelegate::PreviewListDelegate(QObject *parent) @@ -61,30 +54,19 @@ void PreviewListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &o break; case PreviewSelectDialog::PROGRESS: - { + { const qreal progress = (index.data().toReal() * 100); + const QString text = (progress >= 100) + ? QString::fromLatin1("100%") + : (Utils::String::fromDouble(progress, 1) + '%'); - QStyleOptionProgressBar newopt; - newopt.rect = opt.rect; - newopt.text = ((progress == 100) ? QString("100%") : (Utils::String::fromDouble(progress, 1) + '%')); - newopt.progress = static_cast(progress); - newopt.maximum = 100; - newopt.minimum = 0; - newopt.state |= QStyle::State_Enabled; - newopt.textVisible = true; - -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) - // XXX: To avoid having the progress text on the right of the bar - QProxyStyle st("fusion"); - st.drawControl(QStyle::CE_ProgressBar, &newopt, painter, 0); -#else - QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); -#endif + m_progressBarPainter.paint(painter, option, text, static_cast(progress)); } break; default: QItemDelegate::paint(painter, option, index); + break; } painter->restore(); diff --git a/src/gui/previewlistdelegate.h b/src/gui/previewlistdelegate.h index e98d40a90..7591d94a5 100644 --- a/src/gui/previewlistdelegate.h +++ b/src/gui/previewlistdelegate.h @@ -30,6 +30,8 @@ #include +#include "progressbarpainter.h" + class PreviewListDelegate final : public QItemDelegate { Q_OBJECT @@ -38,7 +40,9 @@ class PreviewListDelegate final : public QItemDelegate public: explicit PreviewListDelegate(QObject *parent = nullptr); -private: void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; QWidget *createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const override; + +private: + ProgressBarPainter m_progressBarPainter; }; diff --git a/src/gui/progressbardelegate.cpp b/src/gui/progressbarpainter.cpp similarity index 56% rename from src/gui/progressbardelegate.cpp rename to src/gui/progressbarpainter.cpp index 0666142c2..30de4b327 100644 --- a/src/gui/progressbardelegate.cpp +++ b/src/gui/progressbarpainter.cpp @@ -26,49 +26,46 @@ * exception statement from your version. */ -#include "progressbardelegate.h" +#include "progressbarpainter.h" -#include -#include #include +#include +#include #include #if (defined(Q_OS_WIN) || defined(Q_OS_MACOS)) #include #endif -ProgressBarDelegate::ProgressBarDelegate(const int progressColumn, const int dataRole, QObject *parent) - : QStyledItemDelegate {parent} - , m_progressColumn {progressColumn} - , m_dataRole {dataRole} +ProgressBarPainter::ProgressBarPainter() { #if (defined(Q_OS_WIN) || defined(Q_OS_MACOS)) - m_dummyProgressBar.setStyle(new QProxyStyle {"fusion"}); + auto *fusionStyle = new QProxyStyle {"fusion"}; + fusionStyle->setParent(&m_dummyProgressBar); + m_dummyProgressBar.setStyle(fusionStyle); #endif } -void ProgressBarDelegate::initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const +void ProgressBarPainter::paint(QPainter *painter, const QStyleOptionViewItem &option, const QString &text, const int progress) const { - option.text = index.data().toString(); - option.progress = static_cast(index.data(m_dataRole).toReal()); - option.maximum = 100; - option.minimum = 0; - option.textVisible = true; -} + QStyleOptionProgressBar styleOption; + styleOption.initFrom(&m_dummyProgressBar); + // QStyleOptionProgressBar fields + styleOption.maximum = 100; + styleOption.minimum = 0; + styleOption.progress = progress; + styleOption.text = text; + styleOption.textVisible = true; + // QStyleOption fields + styleOption.rect = option.rect; + styleOption.state = option.state; -void ProgressBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - if (index.column() != m_progressColumn) - return QStyledItemDelegate::paint(painter, option, index); - - QStyleOptionProgressBar newopt; - newopt.initFrom(&m_dummyProgressBar); - newopt.rect = option.rect; - newopt.state = option.state; - initProgressStyleOption(newopt, index); + const bool isEnabled = option.state.testFlag(QStyle::State_Enabled); + styleOption.palette.setCurrentColorGroup(isEnabled ? QPalette::Active : QPalette::Disabled); painter->save(); - m_dummyProgressBar.style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); - m_dummyProgressBar.style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter, &m_dummyProgressBar); + const QStyle *style = m_dummyProgressBar.style(); + style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); + style->drawControl(QStyle::CE_ProgressBar, &styleOption, painter, &m_dummyProgressBar); painter->restore(); } diff --git a/src/gui/progressbardelegate.h b/src/gui/progressbarpainter.h similarity index 79% rename from src/gui/progressbardelegate.h rename to src/gui/progressbarpainter.h index 5432f17d7..b6ecac377 100644 --- a/src/gui/progressbardelegate.h +++ b/src/gui/progressbarpainter.h @@ -29,23 +29,17 @@ #pragma once #include -#include -class QStyleOptionProgressBar; +class QStyleOptionViewItem; -class ProgressBarDelegate : public QStyledItemDelegate +class ProgressBarPainter { public: - ProgressBarDelegate(int progressColumn, int dataRole, QObject *parent = nullptr); + ProgressBarPainter(); -protected: - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; - virtual void initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QString &text, int progress) const; private: - const int m_progressColumn; - const int m_dataRole; - // for painting progressbar with stylesheet option, a dummy progress bar is required QProgressBar m_dummyProgressBar; }; diff --git a/src/gui/properties/proplistdelegate.cpp b/src/gui/properties/proplistdelegate.cpp index 5e10dd6d5..ef288ceb2 100644 --- a/src/gui/properties/proplistdelegate.cpp +++ b/src/gui/properties/proplistdelegate.cpp @@ -28,61 +28,22 @@ #include "proplistdelegate.h" -#include #include #include #include -#include #include -#include - -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) -#include -#endif #include "base/bittorrent/downloadpriority.h" #include "base/bittorrent/torrent.h" #include "gui/torrentcontentmodel.h" #include "propertieswidget.h" -namespace -{ - QPalette progressBarDisabledPalette() - { - static const QPalette palette = []() - { - QProgressBar bar; - bar.setEnabled(false); - QStyleOptionProgressBar opt; - opt.initFrom(&bar); - return opt.palette; - }(); - return palette; - } -} - PropListDelegate::PropListDelegate(PropertiesWidget *properties) - : ProgressBarDelegate {PROGRESS, TorrentContentModel::UnderlyingDataRole, properties} - , m_properties(properties) + : QStyledItemDelegate {properties} + , m_properties {properties} { } -void PropListDelegate::initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const -{ - ProgressBarDelegate::initProgressStyleOption(option, index); - const int priority - = index.sibling(index.row(), PRIORITY).data(TorrentContentModel::UnderlyingDataRole).toInt(); - if (static_cast(priority) == BitTorrent::DownloadPriority::Ignored) - { - option.state &= ~QStyle::State_Enabled; - option.palette = progressBarDisabledPalette(); - } - else - { - option.state |= QStyle::State_Enabled; - } -} - void PropListDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { auto *combobox = static_cast(editor); @@ -156,3 +117,25 @@ void PropListDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionV { editor->setGeometry(option.rect); } + +void PropListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + switch (index.column()) + { + case PropColumn::PROGRESS: + { + const int progress = static_cast(index.data(TorrentContentModel::UnderlyingDataRole).toReal()); + const int priority = index.sibling(index.row(), PropColumn::PRIORITY).data(TorrentContentModel::UnderlyingDataRole).toInt(); + const bool isEnabled = static_cast(priority) != BitTorrent::DownloadPriority::Ignored; + + QStyleOptionViewItem customOption {option}; + customOption.state.setFlag(QStyle::State_Enabled, isEnabled); + + m_progressBarPainter.paint(painter, customOption, index.data().toString(), progress); + } + break; + default: + QStyledItemDelegate::paint(painter, option, index); + break; + } +} diff --git a/src/gui/properties/proplistdelegate.h b/src/gui/properties/proplistdelegate.h index 815582bbe..7c44dc249 100644 --- a/src/gui/properties/proplistdelegate.h +++ b/src/gui/properties/proplistdelegate.h @@ -28,11 +28,12 @@ #pragma once -#include "gui/progressbardelegate.h" +#include + +#include "gui/progressbarpainter.h" class QAbstractItemModel; class QModelIndex; -class QPainter; class QStyleOptionViewItem; class PropertiesWidget; @@ -48,25 +49,26 @@ enum PropColumn AVAILABILITY }; -class PropListDelegate final : public ProgressBarDelegate +class PropListDelegate final : public QStyledItemDelegate { Q_OBJECT + Q_DISABLE_COPY(PropListDelegate) public: explicit PropListDelegate(PropertiesWidget *properties); void setEditorData(QWidget *editor, const QModelIndex &index) const override; - QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem & /* option */, const QModelIndex &index) const override; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; public slots: void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override; - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex & /* index */) const override; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override; signals: void filteredFilesChanged() const; private: - void initProgressStyleOption(QStyleOptionProgressBar &option, const QModelIndex &index) const override; - PropertiesWidget *m_properties; + ProgressBarPainter m_progressBarPainter; }; diff --git a/src/gui/transferlistdelegate.cpp b/src/gui/transferlistdelegate.cpp index 318ef6f11..f80b485df 100644 --- a/src/gui/transferlistdelegate.cpp +++ b/src/gui/transferlistdelegate.cpp @@ -33,7 +33,7 @@ #include "transferlistmodel.h" TransferListDelegate::TransferListDelegate(QObject *parent) - : ProgressBarDelegate {TransferListModel::TR_PROGRESS, TransferListModel::UnderlyingDataRole, parent} + : QStyledItemDelegate {parent} { } @@ -61,3 +61,20 @@ QSize TransferListDelegate::sizeHint(const QStyleOptionViewItem &option, const Q size.setHeight(std::max(nameColHeight, size.height())); return size; } + +void TransferListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + switch (index.column()) + { + case TransferListModel::TR_PROGRESS: + { + const int progress = static_cast(index.data(TransferListModel::UnderlyingDataRole).toReal()); + + m_progressBarPainter.paint(painter, option, index.data().toString(), progress); + } + break; + default: + QStyledItemDelegate::paint(painter, option, index); + break; + } +} diff --git a/src/gui/transferlistdelegate.h b/src/gui/transferlistdelegate.h index 7be78cc39..c361ff546 100644 --- a/src/gui/transferlistdelegate.h +++ b/src/gui/transferlistdelegate.h @@ -28,9 +28,11 @@ #pragma once -#include "progressbardelegate.h" +#include -class TransferListDelegate final : public ProgressBarDelegate +#include "progressbarpainter.h" + +class TransferListDelegate final : public QStyledItemDelegate { Q_OBJECT Q_DISABLE_COPY(TransferListDelegate) @@ -40,4 +42,8 @@ public: QWidget *createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const override; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override; + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + +private: + ProgressBarPainter m_progressBarPainter; }; diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index 9fce01fc5..ca1abb8f6 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -126,32 +126,27 @@ namespace } TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *mainWindow) - : QTreeView(parent) - , m_mainWindow(mainWindow) + : QTreeView {parent} + , m_listModel {new TransferListModel {this}} + , m_sortFilterModel {new TransferListSortModel {this}} + , m_mainWindow {mainWindow} { - - setUniformRowHeights(true); // Load settings - bool columnLoaded = loadSettings(); + const bool columnLoaded = loadSettings(); // Create and apply delegate - m_listDelegate = new TransferListDelegate(this); - setItemDelegate(m_listDelegate); + setItemDelegate(new TransferListDelegate {this}); - // Create transfer list model - m_listModel = new TransferListModel(this); - - m_sortFilterModel = new TransferListSortModel(this); m_sortFilterModel->setDynamicSortFilter(true); m_sortFilterModel->setSourceModel(m_listModel); m_sortFilterModel->setFilterKeyColumn(TransferListModel::TR_NAME); m_sortFilterModel->setFilterRole(Qt::DisplayRole); m_sortFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); m_sortFilterModel->setSortRole(TransferListModel::UnderlyingDataRole); - setModel(m_sortFilterModel); // Visual settings + setUniformRowHeights(true); setRootIsDecorated(false); setAllColumnsShowFocus(true); setSortingEnabled(true); diff --git a/src/gui/transferlistwidget.h b/src/gui/transferlistwidget.h index d1604b2bb..dc5a888bd 100644 --- a/src/gui/transferlistwidget.h +++ b/src/gui/transferlistwidget.h @@ -33,7 +33,6 @@ #include class MainWindow; -class TransferListDelegate; class TransferListModel; class TransferListSortModel; @@ -121,7 +120,6 @@ private: void applyToSelectedTorrents(const std::function &fn); QVector getVisibleTorrents() const; - TransferListDelegate *m_listDelegate; TransferListModel *m_listModel; TransferListSortModel *m_sortFilterModel; MainWindow *m_mainWindow;