diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/icondelegate.cpp | 9 | ||||
| -rw-r--r-- | src/modelutils.cpp | 58 | ||||
| -rw-r--r-- | src/modelutils.h | 12 | ||||
| -rw-r--r-- | src/modlistbypriorityproxy.cpp | 46 | ||||
| -rw-r--r-- | src/modlistbypriorityproxy.h | 1 | ||||
| -rw-r--r-- | src/modlistview.cpp | 17 | ||||
| -rw-r--r-- | src/modlistview.h | 1 | ||||
| -rw-r--r-- | src/pluginlistview.cpp | 16 | ||||
| -rw-r--r-- | src/pluginlistview.h | 1 | ||||
| -rw-r--r-- | src/settings.cpp | 1 | ||||
| -rw-r--r-- | src/viewmarkingscrollbar.cpp | 30 | ||||
| -rw-r--r-- | src/viewmarkingscrollbar.h | 6 |
12 files changed, 163 insertions, 35 deletions
diff --git a/src/icondelegate.cpp b/src/icondelegate.cpp index 03964263..901b5731 100644 --- a/src/icondelegate.cpp +++ b/src/icondelegate.cpp @@ -27,7 +27,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. using namespace MOBase;
-IconDelegate::IconDelegate(QObject *parent)
+IconDelegate::IconDelegate(QObject* parent)
: QStyledItemDelegate(parent)
{
}
@@ -66,7 +66,12 @@ void IconDelegate::paintIcons( void IconDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
- QStyledItemDelegate::paint(painter, option, index);
+ if (auto* w = qobject_cast<QAbstractItemView*>(parent())) {
+ w->itemDelegate()->paint(painter, option, index);
+ }
+ else {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
paintIcons(painter, option, index, getIcons(index));
}
diff --git a/src/modelutils.cpp b/src/modelutils.cpp index d464bb91..7b54d258 100644 --- a/src/modelutils.cpp +++ b/src/modelutils.cpp @@ -2,6 +2,8 @@ #include <QAbstractProxyModel> +namespace MOShared { + QModelIndexList flatIndex( const QAbstractItemModel* model, int column, const QModelIndex& parent) { @@ -13,6 +15,26 @@ QModelIndexList flatIndex( return index; } +static QModelIndexList visibleIndexImpl(QTreeView* view, int column, const QModelIndex& parent) +{ + if (parent.isValid() && !view->isExpanded(parent)) { + return {}; + } + + auto* model = view->model(); + QModelIndexList index; + for (std::size_t i = 0; i < model->rowCount(parent); ++i) { + index.append(model->index(i, column, parent)); + index.append(visibleIndexImpl(view, column, index.back())); + } + return index; +} + +QModelIndexList visibleIndex(QTreeView* view, int column) +{ + return visibleIndexImpl(view, column, QModelIndex()); +} + QModelIndex indexModelToView(const QModelIndex& index, const QAbstractItemView* view) { // we need to stack the proxy @@ -67,3 +89,39 @@ QModelIndexList indexViewToModel(const QModelIndexList& index, const QAbstractIt } return result; } + +QColor childrenColor(const QModelIndex& index, QTreeView* view, int role) +{ + auto* model = view->model(); + auto rowIndex = index.sibling(index.row(), 0); + + if (model->hasChildren(rowIndex) && !view->isExpanded(rowIndex)) { + + // this is a non-expanded item + std::vector<QColor> colors; + for (int i = 0; i < model->rowCount(rowIndex); ++i) { + auto childData = model->data(model->index(i, index.column(), rowIndex), role); + if (childData.isValid() && childData.canConvert<QColor>()) { + colors.push_back(childData.value<QColor>()); + } + } + + if (colors.empty()) { + return QColor(); + } + + int r = 0, g = 0, b = 0, a = 0; + for (auto& color : colors) { + r += color.red(); + g += color.green(); + b += color.blue(); + a += color.alpha(); + } + + return QColor(r / colors.size(), g / colors.size(), b / colors.size(), a / colors.size()); + } + + return QColor(); +} + +} diff --git a/src/modelutils.h b/src/modelutils.h index b5becb6c..cb7c9394 100644 --- a/src/modelutils.h +++ b/src/modelutils.h @@ -3,16 +3,28 @@ #include <QAbstractItemView> #include <QAbstractItemModel> +#include <QColor> + +namespace MOShared { // retrieve all the row index under the given parent QModelIndexList flatIndex( const QAbstractItemModel* model, int column = 0, const QModelIndex& parent = QModelIndex()); +// retrieve all the visible index in the given view +QModelIndexList visibleIndex(QTreeView* view, int column = 0); + // convert back-and-forth through model proxies QModelIndex indexModelToView(const QModelIndex& index, const QAbstractItemView* view); QModelIndexList indexModelToView(const QModelIndexList& index, const QAbstractItemView* view); QModelIndex indexViewToModel(const QModelIndex& index, const QAbstractItemModel* model); QModelIndexList indexViewToModel(const QModelIndexList& index, const QAbstractItemModel* model); +// retrieve the color of the children of the given index for the given, or an invalid +// color if the item is expanded or the children do not have colors for the given role +// +QColor childrenColor(const QModelIndex& index, QTreeView* view, int role); + +} #endif diff --git a/src/modlistbypriorityproxy.cpp b/src/modlistbypriorityproxy.cpp index 749991d0..7ef540b0 100644 --- a/src/modlistbypriorityproxy.cpp +++ b/src/modlistbypriorityproxy.cpp @@ -181,6 +181,52 @@ bool ModListByPriorityProxy::hasChildren(const QModelIndex& parent) const return item->children.size() > 0; } +QVariant ModListByPriorityProxy::data(const QModelIndex& index, int role) const +{ + auto sourceIndex = mapToSource(index); + if (!sourceIndex.isValid()) { + return QVariant(); + } + + auto sourceData = sourceModel()->data(sourceIndex, role); + if (role != Qt::BackgroundRole && role != ModList::ScrollMarkRole) { + return sourceData; + } + + if (!hasChildren(index)) { + return sourceData; + } + + bool expanded = !m_CollapsedItems.contains(index.sibling(index.row(), 0).data(Qt::DisplayRole).toString()); + + if (expanded) { + return sourceData; + } + + // this is a non-expanded item + std::vector<QColor> colors; + for (int i = 0; i < rowCount(index); ++i) { + auto childData = sourceModel()->data(mapToSource(this->index(i, index.column(), index)), role); + if (childData.isValid() && childData.canConvert<QColor>()) { + colors.push_back(childData.value<QColor>()); + } + } + + if (true || colors.empty()) { + return sourceData; + } + + int r = 0, g = 0, b = 0, a = 0; + for (auto& color : colors) { + r += color.red(); + g += color.green(); + b += color.blue(); + a += color.alpha(); + } + + return QColor(r / colors.size(), g / colors.size(), b / colors.size(), a / colors.size()); +} + bool ModListByPriorityProxy::setData(const QModelIndex& index, const QVariant& value, int role) { // only care about the "name" column diff --git a/src/modlistbypriorityproxy.h b/src/modlistbypriorityproxy.h index e5a8adff..5149b7a2 100644 --- a/src/modlistbypriorityproxy.h +++ b/src/modlistbypriorityproxy.h @@ -37,6 +37,7 @@ public: int columnCount(const QModelIndex& index) const override; bool hasChildren(const QModelIndex& parent) const override; + QVariant data(const QModelIndex& index, int role) const override; bool setData(const QModelIndex& index, const QVariant& value, int role) override; bool canDropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) const override; bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override; diff --git a/src/modlistview.cpp b/src/modlistview.cpp index 80aa6495..da4d79cf 100644 --- a/src/modlistview.cpp +++ b/src/modlistview.cpp @@ -28,6 +28,7 @@ #include "modelutils.h"
using namespace MOBase;
+using namespace MOShared;
// delegate to remove indentation for mods when using collapsible
// separator
@@ -57,6 +58,13 @@ public: }
}
QStyledItemDelegate::paint(painter, opt, index);
+
+ auto color = childrenColor(index, m_view, Qt::BackgroundRole);
+ if (color.isValid()) {
+ // int shift = 3 * opt.rect.height() / 4;
+ // opt.rect.adjust(0, shift, 0, 0);
+ painter->fillRect(opt.rect, color);
+ }
}
};
@@ -67,7 +75,7 @@ ModListView::ModListView(QWidget* parent) , m_byPriorityProxy(nullptr)
, m_byCategoryProxy(nullptr)
, m_byNexusIdProxy(nullptr)
- , m_scrollbar(new ViewMarkingScrollBar(this->model(), ModList::ScrollMarkRole, this))
+ , m_scrollbar(new ViewMarkingScrollBar(this, ModList::ScrollMarkRole))
{
setVerticalScrollBar(m_scrollbar);
MOBase::setCustomizableColumns(this);
@@ -79,13 +87,6 @@ ModListView::ModListView(QWidget* parent) connect(this, &ModListView::customContextMenuRequested, this, &ModListView::onCustomContextMenuRequested);
}
-void ModListView::setModel(QAbstractItemModel* model)
-{
- QTreeView::setModel(model);
- setVerticalScrollBar(new ViewMarkingScrollBar(model, ModList::ScrollMarkRole, this));
-}
-
-
void ModListView::refresh()
{
updateGroupByProxy(-1);
diff --git a/src/modlistview.h b/src/modlistview.h index c0d96f3f..dac96822 100644 --- a/src/modlistview.h +++ b/src/modlistview.h @@ -38,7 +38,6 @@ public: public:
explicit ModListView(QWidget* parent = 0);
- void setModel(QAbstractItemModel* model) override;
void setup(OrganizerCore& core, CategoryFactory& factory, MainWindow* mw, Ui::MainWindow* mwui);
diff --git a/src/pluginlistview.cpp b/src/pluginlistview.cpp index 589c5737..d17b4a2f 100644 --- a/src/pluginlistview.cpp +++ b/src/pluginlistview.cpp @@ -21,19 +21,13 @@ using namespace MOBase; PluginListView::PluginListView(QWidget *parent) : QTreeView(parent) , m_sortProxy(nullptr) - , m_Scrollbar(new ViewMarkingScrollBar(this->model(), Qt::BackgroundRole, this)) + , m_Scrollbar(new ViewMarkingScrollBar(this, Qt::BackgroundRole)) , m_didUpdateMasterList(false) { setVerticalScrollBar(m_Scrollbar); MOBase::setCustomizableColumns(this); } -void PluginListView::setModel(QAbstractItemModel *model) -{ - QTreeView::setModel(model); - setVerticalScrollBar(new ViewMarkingScrollBar(model, Qt::BackgroundRole, this)); -} - int PluginListView::sortColumn() const { return m_sortProxy ? m_sortProxy->sortColumn() : -1; @@ -41,22 +35,22 @@ int PluginListView::sortColumn() const QModelIndex PluginListView::indexModelToView(const QModelIndex& index) const { - return ::indexModelToView(index, this); + return MOShared::indexModelToView(index, this); } QModelIndexList PluginListView::indexModelToView(const QModelIndexList& index) const { - return ::indexModelToView(index, this); + return MOShared::indexModelToView(index, this); } QModelIndex PluginListView::indexViewToModel(const QModelIndex& index) const { - return ::indexViewToModel(index, m_core->pluginList()); + return MOShared::indexViewToModel(index, m_core->pluginList()); } QModelIndexList PluginListView::indexViewToModel(const QModelIndexList& index) const { - return ::indexViewToModel(index, m_core->pluginList()); + return MOShared::indexViewToModel(index, m_core->pluginList()); } void PluginListView::updatePluginCount() diff --git a/src/pluginlistview.h b/src/pluginlistview.h index e5dc15e7..6470ced9 100644 --- a/src/pluginlistview.h +++ b/src/pluginlistview.h @@ -19,7 +19,6 @@ class PluginListView : public QTreeView Q_OBJECT public: explicit PluginListView(QWidget* parent = nullptr); - void setModel(QAbstractItemModel* model) override; void setup(OrganizerCore& core, MainWindow* mw, Ui::MainWindow* mwui); diff --git a/src/settings.cpp b/src/settings.cpp index 0e2de9d7..e379a819 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -31,6 +31,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <iplugingame.h> using namespace MOBase; +using namespace MOShared; EndorsementState endorsementStateFromString(const QString& s) diff --git a/src/viewmarkingscrollbar.cpp b/src/viewmarkingscrollbar.cpp index 0991f171..fb165922 100644 --- a/src/viewmarkingscrollbar.cpp +++ b/src/viewmarkingscrollbar.cpp @@ -4,9 +4,11 @@ #include <QStyleOptionSlider>
#include <QPainter>
-ViewMarkingScrollBar::ViewMarkingScrollBar(QAbstractItemModel* model, int role, QWidget *parent)
- : QScrollBar(parent)
- , m_model(model)
+using namespace MOShared;
+
+ViewMarkingScrollBar::ViewMarkingScrollBar(QTreeView* view, int role)
+ : QScrollBar(view)
+ , m_view(view)
, m_role(role)
{
// not implemented for horizontal sliders
@@ -15,7 +17,7 @@ ViewMarkingScrollBar::ViewMarkingScrollBar(QAbstractItemModel* model, int role, void ViewMarkingScrollBar::paintEvent(QPaintEvent* event)
{
- if (m_model == nullptr) {
+ if (m_view->model() == nullptr) {
return;
}
QScrollBar::paintEvent(event);
@@ -28,17 +30,27 @@ void ViewMarkingScrollBar::paintEvent(QPaintEvent* event) QRect handleRect = style()->subControlRect(QStyle::CC_ScrollBar, &styleOption, QStyle::SC_ScrollBarSlider, this);
QRect innerRect = style()->subControlRect(QStyle::CC_ScrollBar, &styleOption, QStyle::SC_ScrollBarGroove, this);
- auto indices = flatIndex(m_model, 0, QModelIndex());
+ auto indices = visibleIndex(m_view, 0);
painter.translate(innerRect.topLeft() + QPoint(0, 3));
qreal scale = static_cast<qreal>(innerRect.height() - 3) / static_cast<qreal>(indices.size());
for (int i = 0; i < indices.size(); ++i) {
QVariant data = indices[i].data(m_role);
- if (data.isValid()) {
- QColor col = data.value<QColor>();
- painter.setPen(col);
- painter.setBrush(col);
+ QColor color;
+
+ if (data.canConvert<QColor>()) {
+ color = data.value<QColor>();
+ }
+
+ auto childrenColor = MOShared::childrenColor(indices[i], m_view, m_role);
+ if (childrenColor.isValid()) {
+ color = childrenColor;
+ }
+
+ if (color.isValid()) {
+ painter.setPen(color);
+ painter.setBrush(color);
painter.drawRect(QRect(2, i * scale - 2, handleRect.width() - 5, 3));
}
}
diff --git a/src/viewmarkingscrollbar.h b/src/viewmarkingscrollbar.h index 88d77039..6947a018 100644 --- a/src/viewmarkingscrollbar.h +++ b/src/viewmarkingscrollbar.h @@ -1,20 +1,20 @@ #ifndef VIEWMARKINGSCROLLBAR_H
#define VIEWMARKINGSCROLLBAR_H
-#include <QAbstractItemModel>
+#include <QTreeView>
#include <QScrollBar>
class ViewMarkingScrollBar : public QScrollBar
{
public:
- ViewMarkingScrollBar(QAbstractItemModel *model, int role, QWidget* parent = nullptr);
+ ViewMarkingScrollBar(QTreeView* view, int role);
protected:
void paintEvent(QPaintEvent *event) override;
private:
- QAbstractItemModel* m_model;
+ QTreeView* m_view;
int m_role;
};
|
