diff options
author | Jan Dalheimer <jan@dalheimer.de> | 2013-12-31 17:26:36 +0100 |
---|---|---|
committer | Jan Dalheimer <jan@dalheimer.de> | 2013-12-31 17:26:36 +0100 |
commit | c47933d95cae407a99acfbbb941655f7cd52e1ae (patch) | |
tree | e61e312395089934affedea3916416881acfdc10 | |
parent | 8cfd0881ac3fcbb45fd42dedcb1caf0be38eacaf (diff) | |
download | MultiMC-c47933d95cae407a99acfbbb941655f7cd52e1ae.tar MultiMC-c47933d95cae407a99acfbbb941655f7cd52e1ae.tar.gz MultiMC-c47933d95cae407a99acfbbb941655f7cd52e1ae.tar.lz MultiMC-c47933d95cae407a99acfbbb941655f7cd52e1ae.tar.xz MultiMC-c47933d95cae407a99acfbbb941655f7cd52e1ae.zip |
Loads of changes and some refactorings
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | CategorizedView.cpp | 296 | ||||
-rw-r--r-- | CategorizedView.h | 56 | ||||
-rw-r--r-- | CategorizedViewCategory.cpp | 128 | ||||
-rw-r--r-- | CategorizedViewCategory.h | 39 |
5 files changed, 248 insertions, 273 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 029c90b3..44a28c57 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,8 @@ set(SOURCES CategorizedView.h CategorizedView.cpp + CategorizedViewCategory.h + CategorizedViewCategory.cpp CategorizedProxyModel.h CategorizedProxyModel.cpp InstanceDelegate.h diff --git a/CategorizedView.cpp b/CategorizedView.cpp index 6bf18cbc..60230661 100644 --- a/CategorizedView.cpp +++ b/CategorizedView.cpp @@ -11,6 +11,8 @@ #include <QMimeData> #include <QScrollBar> +#include "CategorizedViewCategory.h" + template<typename T> bool listsIntersect(const QList<T> &l1, const QList<T> t2) { @@ -24,86 +26,6 @@ bool listsIntersect(const QList<T> &l1, const QList<T> t2) return false; } -CategorizedView::Category::Category(const QString &text, CategorizedView *view) - : view(view), text(text), collapsed(false) -{ -} -CategorizedView::Category::Category(const CategorizedView::Category *other) : - view(other->view), text(other->text), collapsed(other->collapsed), iconRect(other->iconRect), textRect(other->textRect) -{ -} - -void CategorizedView::Category::drawHeader(QPainter *painter, const int y) -{ - painter->save(); - - int height = headerHeight() - 4; - int collapseSize = height; - - // the icon - iconRect = QRect(view->m_rightMargin + 2, 2 + y, collapseSize, collapseSize); - painter->setPen(QPen(Qt::black, 1)); - painter->drawRect(iconRect); - static const int margin = 2; - QRect iconSubrect = iconRect.adjusted(margin, margin, -margin, -margin); - int midX = iconSubrect.center().x(); - int midY = iconSubrect.center().y(); - if (collapsed) - { - painter->drawLine(midX, iconSubrect.top(), midX, iconSubrect.bottom()); - } - painter->drawLine(iconSubrect.left(), midY, iconSubrect.right(), midY); - - // the text - int textWidth = painter->fontMetrics().width(text); - textRect = QRect(iconRect.right() + 4, y, textWidth, headerHeight()); - view->style()->drawItemText(painter, textRect, Qt::AlignHCenter | Qt::AlignVCenter, view->palette(), true, text); - - // the line - painter->drawLine(textRect.right() + 4, y + headerHeight() / 2, view->contentWidth() - view->m_rightMargin, y + headerHeight() / 2); - - painter->restore(); -} - -int CategorizedView::Category::totalHeight() const -{ - return headerHeight() + 5 + contentHeight(); -} -int CategorizedView::Category::headerHeight() const -{ - return qApp->fontMetrics().height() + 4; -} -int CategorizedView::Category::contentHeight() const -{ - if (collapsed) - { - return 0; - } - QMap<int, int> rowToHeightMapping; - foreach (const QModelIndex &index, view->itemsForCategory(this)) - { - int row = view->categoryInternalPosition(index).second; - if (!rowToHeightMapping.contains(row)) - { - rowToHeightMapping.insert(row, view->itemSize(index).height()); - } - } - int result = 0; - if (!rowToHeightMapping.isEmpty()) - { - for (int i = 0; i < numRows(); ++i) - { - Q_ASSERT(rowToHeightMapping.contains(i)); - result += rowToHeightMapping[i]; - } - } - return result; -} -int CategorizedView::Category::numRows() const -{ - return qMax(1, qCeil((qreal)view->numItemsForCategory(this) / (qreal)view->itemsPerRow())); -} - CategorizedView::CategorizedView(QWidget *parent) : QListView(parent), m_leftMargin(5), m_rightMargin(5), m_bottomMargin(5), m_categoryMargin(5)//, m_updatesDisabled(false), m_categoryEditor(0), m_editedCategory(0) { @@ -115,9 +37,6 @@ CategorizedView::CategorizedView(QWidget *parent) setDragDropMode(QListView::InternalMove); setAcceptDrops(true); setSpacing(10); - - m_cachedCategoryToIndexMapping.setMaxCost(50); - m_cachedVisualRects.setMaxCost(50); } CategorizedView::~CategorizedView() @@ -172,23 +91,21 @@ void CategorizedView::updateGeometries() int previousScroll = verticalScrollBar()->value(); - invalidateCaches(); - - QMap<QString, Category *> cats; + QMap<QString, CategorizedViewCategory *> cats; for (int i = 0; i < model()->rowCount(); ++i) { const QString category = model()->index(i, 0).data(CategorizedViewRoles::CategoryRole).toString(); if (!cats.contains(category)) { - Category *old = this->category(category); + CategorizedViewCategory *old = this->category(category); if (old) { - cats.insert(category, new Category(old)); + cats.insert(category, new CategorizedViewCategory(old)); } else { - cats.insert(category, new Category(category, this)); + cats.insert(category, new CategorizedViewCategory(category, this)); } } } @@ -201,6 +118,11 @@ void CategorizedView::updateGeometries() qDeleteAll(m_categories); m_categories = cats.values(); + for (auto cat : m_categories) + { + cat->update(); + } + if (m_categories.isEmpty()) { verticalScrollBar()->setRange(0, 0); @@ -208,7 +130,7 @@ void CategorizedView::updateGeometries() else { int totalHeight = 0; - foreach (const Category *category, m_categories) + foreach (const CategorizedViewCategory *category, m_categories) { totalHeight += category->totalHeight() + m_categoryMargin; } @@ -225,7 +147,7 @@ void CategorizedView::updateGeometries() bool CategorizedView::isIndexHidden(const QModelIndex &index) const { - Category *cat = category(index); + CategorizedViewCategory *cat = category(index); if (cat) { return cat->collapsed; @@ -236,11 +158,11 @@ bool CategorizedView::isIndexHidden(const QModelIndex &index) const } } -CategorizedView::Category *CategorizedView::category(const QModelIndex &index) const +CategorizedViewCategory *CategorizedView::category(const QModelIndex &index) const { return category(index.data(CategorizedViewRoles::CategoryRole).toString()); } -CategorizedView::Category *CategorizedView::category(const QString &cat) const +CategorizedViewCategory *CategorizedView::category(const QString &cat) const { for (int i = 0; i < m_categories.size(); ++i) { @@ -251,7 +173,7 @@ CategorizedView::Category *CategorizedView::category(const QString &cat) const } return 0; } -CategorizedView::Category *CategorizedView::categoryAt(const QPoint &pos) const +CategorizedViewCategory *CategorizedView::categoryAt(const QPoint &pos) const { for (int i = 0; i < m_categories.size(); ++i) { @@ -263,70 +185,6 @@ CategorizedView::Category *CategorizedView::categoryAt(const QPoint &pos) const return 0; } -int CategorizedView::numItemsForCategory(const CategorizedView::Category *category) const -{ - return itemsForCategory(category).size(); -} -QList<QModelIndex> CategorizedView::itemsForCategory(const CategorizedView::Category *category) const -{ - if (!m_cachedCategoryToIndexMapping.contains(category) || true) - { - QList<QModelIndex> *indices = new QList<QModelIndex>(); - for (int i = 0; i < model()->rowCount(); ++i) - { - if (model()->index(i, 0).data(CategorizedViewRoles::CategoryRole).toString() == category->text) - { - indices->append(model()->index(i, 0)); - } - } - m_cachedCategoryToIndexMapping.insert(category, indices, indices->size()); - } - return *m_cachedCategoryToIndexMapping.object(category); -} -QModelIndex CategorizedView::firstItemForCategory(const CategorizedView::Category *category) const -{ - QList<QModelIndex> indices = itemsForCategory(category); - QModelIndex first; - foreach (const QModelIndex &index, indices) - { - if (index.row() < first.row() || !first.isValid()) - { - first = index; - } - } - - return first; -} -QModelIndex CategorizedView::lastItemForCategory(const CategorizedView::Category *category) const -{ - QList<QModelIndex> indices = itemsForCategory(category); - QModelIndex last; - foreach (const QModelIndex &index, indices) - { - if (index.row() > last.row() || !last.isValid()) - { - last = index; - } - } - - return last; -} - -int CategorizedView::categoryTop(const CategorizedView::Category *category) const -{ - int res = 0; - const QList<Category *> cats = sortedCategories(); - for (int i = 0; i < cats.size(); ++i) - { - if (cats.at(i) == category) - { - break; - } - res += cats.at(i)->totalHeight() + m_categoryMargin; - } - return res; -} - int CategorizedView::itemsPerRow() const { return qFloor((qreal)(contentWidth()) / (qreal)(itemWidth() + spacing())); @@ -336,49 +194,34 @@ int CategorizedView::contentWidth() const return width() - m_leftMargin - m_rightMargin; } -QList<CategorizedView::Category *> CategorizedView::sortedCategories() const -{ - QList<Category *> out = m_categories; - qSort(out.begin(), out.end(), [](const Category *c1, const Category *c2) { return c1->text < c2->text; }); - return out; -} - int CategorizedView::itemWidth() const { - if (m_cachedItemWidth == -1) - { - m_cachedItemWidth = itemDelegate()->sizeHint(viewOptions(), model()->index(model()->rowCount() -1, 0)).width(); - } - return m_cachedItemWidth; + return itemDelegate()->sizeHint(viewOptions(), model()->index(model()->rowCount() -1, 0)).width(); } -QSize CategorizedView::itemSize(const QModelIndex &index) const +int CategorizedView::categoryRowHeight(const QModelIndex &index) const { - if (!m_cachedItemSizes.contains(index)) + QModelIndexList indices; + int internalRow = categoryInternalPosition(index).second; + foreach (const QModelIndex &i, category(index)->items()) { - QModelIndexList indices; - int internalRow = categoryInternalPosition(index).second; - foreach (const QModelIndex &i, itemsForCategory(category(index))) + if (categoryInternalPosition(i).second == internalRow) { - if (categoryInternalPosition(i).second == internalRow) - { - indices.append(i); - } + indices.append(i); } + } - int largestHeight = 0; - foreach (const QModelIndex &i, indices) - { - largestHeight = qMax(largestHeight, itemDelegate()->sizeHint(viewOptions(), i).height()); - } - m_cachedItemSizes.insert(index, new QSize(itemWidth(), largestHeight)); + int largestHeight = 0; + foreach (const QModelIndex &i, indices) + { + largestHeight = qMax(largestHeight, itemDelegate()->sizeHint(viewOptions(), i).height()); } - return *m_cachedItemSizes.object(index); + return largestHeight; } QPair<int, int> CategorizedView::categoryInternalPosition(const QModelIndex &index) const { - QList<QModelIndex> indices = itemsForCategory(category(index)); + QList<QModelIndex> indices = category(index)->items(); int x = 0; int y = 0; const int perRow = itemsPerRow(); @@ -397,14 +240,25 @@ QPair<int, int> CategorizedView::categoryInternalPosition(const QModelIndex &ind } return qMakePair(x, y); } -int CategorizedView::itemHeightForCategoryRow(const CategorizedView::Category *category, const int internalRow) const +int CategorizedView::categoryInternalRowTop(const QModelIndex &index) const { - foreach (const QModelIndex &i, itemsForCategory(category)) + CategorizedViewCategory *cat = category(index); + int categoryInternalRow = categoryInternalPosition(index).second; + int result = 0; + for (int i = 0; i < categoryInternalRow; ++i) + { + result += cat->rowHeights.at(i); + } + return result; +} +int CategorizedView::itemHeightForCategoryRow(const CategorizedViewCategory *category, const int internalRow) const +{ + foreach (const QModelIndex &i, category->items()) { QPair<int, int> pos = categoryInternalPosition(i); if (pos.second == internalRow) { - return itemSize(i).height(); + return categoryRowHeight(i); } } return -1; @@ -586,13 +440,10 @@ void CategorizedView::paintEvent(QPaintEvent *event) QPainter painter(this->viewport()); painter.translate(-offset()); - // FIXME we shouldn't need to do this - invalidateCaches(); - int y = 0; for (int i = 0; i < m_categories.size(); ++i) { - Category *category = m_categories.at(i); + CategorizedViewCategory *category = m_categories.at(i); category->drawHeader(&painter, y); y += category->totalHeight() + m_categoryMargin; } @@ -627,16 +478,16 @@ void CategorizedView::paintEvent(QPaintEvent *event) if (!m_lastDragPosition.isNull()) { - QPair<Category *, int> pair = rowDropPos(m_lastDragPosition); - Category *category = pair.first; + QPair<CategorizedViewCategory *, int> pair = rowDropPos(m_lastDragPosition); + CategorizedViewCategory *category = pair.first; int row = pair.second; if (category) { - int internalRow = row - firstItemForCategory(category).row(); + int internalRow = row - category->firstRow; QLine line; - if (internalRow >= numItemsForCategory(category)) + if (internalRow >= category->numItems()) { - QRect toTheRightOfRect = visualRect(lastItemForCategory(category)); + QRect toTheRightOfRect = visualRect(category->lastItem()); line = QLine(toTheRightOfRect.topRight(), toTheRightOfRect.bottomRight()); } else @@ -700,8 +551,8 @@ void CategorizedView::dropEvent(QDropEvent *event) return; } - QPair<Category *, int> dropPos = rowDropPos(event->pos() + offset()); - const Category *category = dropPos.first; + QPair<CategorizedViewCategory *, int> dropPos = rowDropPos(event->pos() + offset()); + const CategorizedViewCategory *category = dropPos.first; const int row = dropPos.second; if (row == -1) @@ -772,24 +623,17 @@ QRect CategorizedView::visualRect(const QModelIndex &index) const return QRect(); } - if (!m_cachedVisualRects.contains(index)) - { - const Category *cat = category(index); - QPair<int, int> pos = categoryInternalPosition(index); - int x = pos.first; - int y = pos.second; - - QSize size = itemSize(index); + const CategorizedViewCategory *cat = category(index); + QPair<int, int> pos = categoryInternalPosition(index); + int x = pos.first; + int y = pos.second; - QRect *out = new QRect; - out->setTop(categoryTop(cat) + cat->headerHeight() + 5 + y * size.height()); - out->setLeft(spacing() + x * itemWidth() + x * spacing()); - out->setSize(size); + QRect out; + out.setTop(cat->top() + cat->headerHeight() + 5 + categoryInternalRowTop(index)); + out.setLeft(spacing() + x * itemWidth() + x * spacing()); + out.setSize(itemDelegate()->sizeHint(viewOptions(), index)); - m_cachedVisualRects.insert(index, out); - } - - return *m_cachedVisualRects.object(index); + return out; } /* void CategorizedView::startCategoryEditor(Category *category) @@ -908,13 +752,13 @@ bool CategorizedView::isDragEventAccepted(QDropEvent *event) } return true; } -QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint &pos) +QPair<CategorizedViewCategory *, int> CategorizedView::rowDropPos(const QPoint &pos) { // check that we aren't on a category header and calculate which category we're in - Category *category = 0; + CategorizedViewCategory *category = 0; { int y = 0; - foreach (Category *cat, m_categories) + foreach (CategorizedViewCategory *cat, m_categories) { if (pos.y() > y && pos.y() < (y + cat->headerHeight())) { @@ -933,7 +777,7 @@ QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint } } - QList<QModelIndex> indices = itemsForCategory(category); + QList<QModelIndex> indices = category->items(); // calculate the internal column int internalColumn = -1; @@ -967,7 +811,7 @@ QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint int internalRow = -1; { // FIXME rework the drag and drop code - const int top = categoryTop(category); + const int top = category->top(); for (int r = 0, h = top; r < category->numRows(); h += itemHeightForCategoryRow(category, r), ++r) { if (pos.y() > h && pos.y() < (h + itemHeightForCategoryRow(category, r))) @@ -1000,14 +844,6 @@ QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint return qMakePair(category, indices.at(categoryRow).row()); } -void CategorizedView::invalidateCaches() -{ - m_cachedItemWidth = -1; - m_cachedCategoryToIndexMapping.clear(); - m_cachedVisualRects.clear(); - m_cachedItemSizes.clear(); -} - QPoint CategorizedView::offset() const { return QPoint(horizontalOffset(), verticalOffset()); diff --git a/CategorizedView.h b/CategorizedView.h index 08d43be8..0550c7f8 100644 --- a/CategorizedView.h +++ b/CategorizedView.h @@ -3,7 +3,6 @@ #include <QListView> #include <QLineEdit> -#include <QCache> struct CategorizedViewRoles { @@ -15,6 +14,8 @@ struct CategorizedViewRoles }; }; +struct CategorizedViewCategory; + class CategorizedView : public QListView { Q_OBJECT @@ -28,7 +29,7 @@ public: void setSelection(const QRect &rect, const QItemSelectionModel::SelectionFlags commands) override; protected slots: - void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles); + void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles); virtual void rowsInserted(const QModelIndex &parent, int start, int end); virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); virtual void updateGeometries(); @@ -50,57 +51,27 @@ protected: void startDrag(Qt::DropActions supportedActions) override; private: - struct Category - { - Category(const QString &text, CategorizedView *view); - Category(const Category *other); - CategorizedView *view; - QString text; - bool collapsed; - QRect iconRect; - QRect textRect; - - void drawHeader(QPainter *painter, const int y); - int totalHeight() const; - int headerHeight() const; - int contentHeight() const; - int numRows() const; - }; - friend struct Category; + friend struct CategorizedViewCategory; - QList<Category *> m_categories; - mutable QCache<const Category *, QList<QModelIndex> > m_cachedCategoryToIndexMapping; - mutable QCache<const QModelIndex, QRect> m_cachedVisualRects; + QList<CategorizedViewCategory *> m_categories; int m_leftMargin; int m_rightMargin; int m_bottomMargin; int m_categoryMargin; - int m_itemSpacing; //bool m_updatesDisabled; - Category *category(const QModelIndex &index) const; - Category *category(const QString &cat) const; - Category *categoryAt(const QPoint &pos) const; - int numItemsForCategory(const Category *category) const; - QList<QModelIndex> itemsForCategory(const Category *category) const; - QModelIndex firstItemForCategory(const Category *category) const; - QModelIndex lastItemForCategory(const Category *category) const; - - int categoryTop(const Category *category) const; + CategorizedViewCategory *category(const QModelIndex &index) const; + CategorizedViewCategory *category(const QString &cat) const; + CategorizedViewCategory *categoryAt(const QPoint &pos) const; int itemsPerRow() const; int contentWidth() const; - static bool lessThanCategoryPointer(const Category *c1, const Category *c2); - QList<Category *> sortedCategories() const; - private: - mutable int m_cachedItemWidth; - mutable QCache<QModelIndex, QSize> m_cachedItemSizes; int itemWidth() const; - QSize itemSize(const QModelIndex &index) const; + int categoryRowHeight(const QModelIndex &index) const; /*QLineEdit *m_categoryEditor; Category *m_editedCategory; @@ -113,21 +84,20 @@ private: QPoint m_pressedPosition; QPersistentModelIndex m_pressedIndex; bool m_pressedAlreadySelected; - Category *m_pressedCategory; + CategorizedViewCategory *m_pressedCategory; QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag; QPoint m_lastDragPosition; QPair<int, int> categoryInternalPosition(const QModelIndex &index) const; - int itemHeightForCategoryRow(const Category *category, const int internalRow) const; + int categoryInternalRowTop(const QModelIndex &index) const; + int itemHeightForCategoryRow(const CategorizedViewCategory *category, const int internalRow) const; QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const; QList<QPair<QRect, QModelIndex> > draggablePaintPairs(const QModelIndexList &indices, QRect *r) const; bool isDragEventAccepted(QDropEvent *event); - QPair<Category *, int> rowDropPos(const QPoint &pos); - - void invalidateCaches(); + QPair<CategorizedViewCategory *, int> rowDropPos(const QPoint &pos); QPoint offset() const; }; diff --git a/CategorizedViewCategory.cpp b/CategorizedViewCategory.cpp new file mode 100644 index 00000000..b82ffc96 --- /dev/null +++ b/CategorizedViewCategory.cpp @@ -0,0 +1,128 @@ +#include "CategorizedViewCategory.h" + +#include <QModelIndex> +#include <QPainter> +#include <QtMath> + +#include "CategorizedView.h" + +CategorizedViewCategory::CategorizedViewCategory(const QString &text, CategorizedView *view) + : view(view), text(text), collapsed(false) +{ +} +CategorizedViewCategory::CategorizedViewCategory(const CategorizedViewCategory *other) : + view(other->view), text(other->text), collapsed(other->collapsed), iconRect(other->iconRect), textRect(other->textRect) +{ +} + +void CategorizedViewCategory::update() +{ + firstRow = firstItem().row(); + + rowHeights = QVector<int>(numRows()); + for (int i = 0; i < numRows(); ++i) + { + rowHeights[i] = view->categoryRowHeight(view->model()->index(i * view->itemsPerRow() + firstRow, 0)); + } +} + +void CategorizedViewCategory::drawHeader(QPainter *painter, const int y) +{ + painter->save(); + + int height = headerHeight() - 4; + int collapseSize = height; + + // the icon + iconRect = QRect(view->m_rightMargin + 2, 2 + y, collapseSize, collapseSize); + painter->setPen(QPen(Qt::black, 1)); + painter->drawRect(iconRect); + static const int margin = 2; + QRect iconSubrect = iconRect.adjusted(margin, margin, -margin, -margin); + int midX = iconSubrect.center().x(); + int midY = iconSubrect.center().y(); + if (collapsed) + { + painter->drawLine(midX, iconSubrect.top(), midX, iconSubrect.bottom()); + } + painter->drawLine(iconSubrect.left(), midY, iconSubrect.right(), midY); + + // the text + int textWidth = painter->fontMetrics().width(text); + textRect = QRect(iconRect.right() + 4, y, textWidth, headerHeight()); + painter->setBrush(view->viewOptions().palette.text()); + view->style()->drawItemText(painter, textRect, Qt::AlignHCenter | Qt::AlignVCenter, view->viewport()->palette(), true, text); + + // the line + painter->drawLine(textRect.right() + 4, y + headerHeight() / 2, view->contentWidth() - view->m_rightMargin, y + headerHeight() / 2); + + painter->restore(); +} + +int CategorizedViewCategory::totalHeight() const +{ + return headerHeight() + 5 + contentHeight(); +} +int CategorizedViewCategory::headerHeight() const +{ + return view->viewport()->fontMetrics().height() + 4; +} +int CategorizedViewCategory::contentHeight() const +{ + if (collapsed) + { + return 0; + } + int result = 0; + for (int i = 0; i < rowHeights.size(); ++i) + { + result += rowHeights[i]; + } + return result; +} +int CategorizedViewCategory::numRows() const +{ + return qMax(1, qCeil((qreal)numItems() / (qreal)view->itemsPerRow())); +} +int CategorizedViewCategory::top() const +{ + int res = 0; + const QList<CategorizedViewCategory *> cats = view->m_categories; + for (int i = 0; i < cats.size(); ++i) + { + if (cats.at(i) == this) + { + break; + } + res += cats.at(i)->totalHeight() + view->m_categoryMargin; + } + return res; +} + +QList<QModelIndex> CategorizedViewCategory::items() const +{ + QList<QModelIndex> indices; + for (int i = 0; i < view->model()->rowCount(); ++i) + { + const QModelIndex index = view->model()->index(i, 0); + if (index.data(CategorizedViewRoles::CategoryRole).toString() == text) + { + indices.append(index); + } + } + return indices; +} +int CategorizedViewCategory::numItems() const +{ + return items().size(); +} +QModelIndex CategorizedViewCategory::firstItem() const +{ + QList<QModelIndex> indices = items(); + return indices.isEmpty() ? QModelIndex() : indices.first(); +} +QModelIndex CategorizedViewCategory::lastItem() const +{ + QList<QModelIndex> indices = items(); + return indices.isEmpty() ? QModelIndex() : indices.last(); +} diff --git a/CategorizedViewCategory.h b/CategorizedViewCategory.h new file mode 100644 index 00000000..cb6ef8c5 --- /dev/null +++ b/CategorizedViewCategory.h @@ -0,0 +1,39 @@ +#ifndef CATEGORIZEDVIEWROW_H +#define CATEGORIZEDVIEWROW_H + +#include <QString> +#include <QRect> +#include <QVector> + +class CategorizedView; +class QPainter; +class QModelIndex; + +struct CategorizedViewCategory +{ + CategorizedViewCategory(const QString &text, CategorizedView *view); + CategorizedViewCategory(const CategorizedViewCategory *other); + CategorizedView *view; + QString text; + bool collapsed; + QRect iconRect; + QRect textRect; + QVector<int> rowHeights; + int firstRow; + + void update(); + + void drawHeader(QPainter *painter, const int y); + int totalHeight() const; + int headerHeight() const; + int contentHeight() const; + int numRows() const; + int top() const; + + QList<QModelIndex> items() const; + int numItems() const; + QModelIndex firstItem() const; + QModelIndex lastItem() const; +}; + +#endif // CATEGORIZEDVIEWROW_H |