Loads of fixes
This commit is contained in:
parent
4662fbd298
commit
1e1b2342f4
@ -79,7 +79,6 @@ int CategorizedView::Category::contentHeight() const
|
|||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const int rows = qMax(1, qCeil((qreal)view->numItemsForCategory(this) / (qreal)view->itemsPerRow()));
|
|
||||||
QMap<int, int> rowToHeightMapping;
|
QMap<int, int> rowToHeightMapping;
|
||||||
foreach (const QModelIndex &index, view->itemsForCategory(this))
|
foreach (const QModelIndex &index, view->itemsForCategory(this))
|
||||||
{
|
{
|
||||||
@ -90,20 +89,23 @@ int CategorizedView::Category::contentHeight() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
int result = 0;
|
int result = 0;
|
||||||
for (int i = 0; i < rows; ++i)
|
if (!rowToHeightMapping.isEmpty())
|
||||||
{
|
{
|
||||||
Q_ASSERT(rowToHeightMapping.contains(i));
|
for (int i = 0; i < numRows(); ++i)
|
||||||
result += rowToHeightMapping[i];
|
{
|
||||||
|
Q_ASSERT(rowToHeightMapping.contains(i));
|
||||||
|
result += rowToHeightMapping[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
QSize CategorizedView::Category::categoryTotalSize() const
|
int CategorizedView::Category::numRows() const
|
||||||
{
|
{
|
||||||
return QSize(view->contentWidth(), contentHeight());
|
return qMax(1, qCeil((qreal)view->numItemsForCategory(this) / (qreal)view->itemsPerRow()));
|
||||||
}
|
}
|
||||||
|
|
||||||
CategorizedView::CategorizedView(QWidget *parent)
|
CategorizedView::CategorizedView(QWidget *parent)
|
||||||
: QListView(parent), m_leftMargin(5), m_rightMargin(5), m_categoryMargin(5)//, m_updatesDisabled(false), m_categoryEditor(0), m_editedCategory(0)
|
: QListView(parent), m_leftMargin(5), m_rightMargin(5), m_bottomMargin(5), m_categoryMargin(5)//, m_updatesDisabled(false), m_categoryEditor(0), m_editedCategory(0)
|
||||||
{
|
{
|
||||||
setViewMode(IconMode);
|
setViewMode(IconMode);
|
||||||
setMovement(Snap);
|
setMovement(Snap);
|
||||||
@ -168,10 +170,7 @@ void CategorizedView::updateGeometries()
|
|||||||
{
|
{
|
||||||
QListView::updateGeometries();
|
QListView::updateGeometries();
|
||||||
|
|
||||||
m_cachedItemWidth = -1;
|
invalidateCaches();
|
||||||
m_cachedCategoryToIndexMapping.clear();
|
|
||||||
m_cachedVisualRects.clear();
|
|
||||||
m_cachedItemSizes.clear();
|
|
||||||
|
|
||||||
QMap<QString, Category *> cats;
|
QMap<QString, Category *> cats;
|
||||||
|
|
||||||
@ -213,6 +212,7 @@ void CategorizedView::updateGeometries()
|
|||||||
}
|
}
|
||||||
// remove the last margin (we don't want it)
|
// remove the last margin (we don't want it)
|
||||||
totalHeight -= m_categoryMargin;
|
totalHeight -= m_categoryMargin;
|
||||||
|
totalHeight += m_bottomMargin;
|
||||||
verticalScrollBar()->setRange(0, totalHeight- height());
|
verticalScrollBar()->setRange(0, totalHeight- height());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,7 +265,7 @@ int CategorizedView::numItemsForCategory(const CategorizedView::Category *catego
|
|||||||
}
|
}
|
||||||
QList<QModelIndex> CategorizedView::itemsForCategory(const CategorizedView::Category *category) const
|
QList<QModelIndex> CategorizedView::itemsForCategory(const CategorizedView::Category *category) const
|
||||||
{
|
{
|
||||||
if (!m_cachedCategoryToIndexMapping.contains(category))
|
if (!m_cachedCategoryToIndexMapping.contains(category) || true)
|
||||||
{
|
{
|
||||||
QList<QModelIndex> *indices = new QList<QModelIndex>();
|
QList<QModelIndex> *indices = new QList<QModelIndex>();
|
||||||
for (int i = 0; i < model()->rowCount(); ++i)
|
for (int i = 0; i < model()->rowCount(); ++i)
|
||||||
@ -393,26 +393,30 @@ QPair<int, int> CategorizedView::categoryInternalPosition(const QModelIndex &ind
|
|||||||
}
|
}
|
||||||
return qMakePair(x, y);
|
return qMakePair(x, y);
|
||||||
}
|
}
|
||||||
|
int CategorizedView::itemHeightForCategoryRow(const CategorizedView::Category *category, const int internalRow) const
|
||||||
|
{
|
||||||
|
foreach (const QModelIndex &i, itemsForCategory(category))
|
||||||
|
{
|
||||||
|
QPair<int, int> pos = categoryInternalPosition(i);
|
||||||
|
if (pos.second == internalRow)
|
||||||
|
{
|
||||||
|
return itemSize(i).height();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
void CategorizedView::mousePressEvent(QMouseEvent *event)
|
void CategorizedView::mousePressEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
//endCategoryEditor();
|
//endCategoryEditor();
|
||||||
|
|
||||||
QPoint pos = event->pos();
|
QPoint pos = event->pos() + offset();
|
||||||
QPersistentModelIndex index = indexAt(pos);
|
QPersistentModelIndex index = indexAt(pos);
|
||||||
|
|
||||||
m_pressedIndex = index;
|
m_pressedIndex = index;
|
||||||
m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
|
m_pressedAlreadySelected = selectionModel()->isSelected(m_pressedIndex);
|
||||||
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
|
QItemSelectionModel::SelectionFlags command = selectionCommand(index, event);
|
||||||
QPoint offset = QPoint(horizontalOffset(), verticalOffset());
|
m_pressedPosition = pos;
|
||||||
if (!(command & QItemSelectionModel::Current))
|
|
||||||
{
|
|
||||||
m_pressedPosition = pos + offset;
|
|
||||||
}
|
|
||||||
else if (!indexAt(m_pressedPosition - offset).isValid())
|
|
||||||
{
|
|
||||||
m_pressedPosition = visualRect(currentIndex()).center() + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_pressedCategory = categoryAt(m_pressedPosition);
|
m_pressedCategory = categoryAt(m_pressedPosition);
|
||||||
if (m_pressedCategory)
|
if (m_pressedCategory)
|
||||||
@ -430,7 +434,7 @@ void CategorizedView::mousePressEvent(QMouseEvent *event)
|
|||||||
setAutoScroll(false);
|
setAutoScroll(false);
|
||||||
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
selectionModel()->setCurrentIndex(index, QItemSelectionModel::NoUpdate);
|
||||||
setAutoScroll(autoScroll);
|
setAutoScroll(autoScroll);
|
||||||
QRect rect(m_pressedPosition - offset, pos);
|
QRect rect(m_pressedPosition, pos);
|
||||||
if (command.testFlag(QItemSelectionModel::Toggle))
|
if (command.testFlag(QItemSelectionModel::Toggle))
|
||||||
{
|
{
|
||||||
command &= ~QItemSelectionModel::Toggle;
|
command &= ~QItemSelectionModel::Toggle;
|
||||||
@ -459,7 +463,7 @@ void CategorizedView::mouseMoveEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
if (state() == DraggingState)
|
if (state() == DraggingState)
|
||||||
{
|
{
|
||||||
topLeft = m_pressedPosition - QPoint(horizontalOffset(), verticalOffset());
|
topLeft = m_pressedPosition - offset();
|
||||||
if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance())
|
if ((topLeft - event->pos()).manhattanLength() > QApplication::startDragDistance())
|
||||||
{
|
{
|
||||||
m_pressedIndex = QModelIndex();
|
m_pressedIndex = QModelIndex();
|
||||||
@ -474,7 +478,7 @@ void CategorizedView::mouseMoveEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
if (selectionMode() != SingleSelection)
|
if (selectionMode() != SingleSelection)
|
||||||
{
|
{
|
||||||
topLeft = m_pressedPosition - QPoint(horizontalOffset(), verticalOffset());
|
topLeft = m_pressedPosition - offset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -515,7 +519,7 @@ void CategorizedView::mouseMoveEvent(QMouseEvent *event)
|
|||||||
}
|
}
|
||||||
void CategorizedView::mouseReleaseEvent(QMouseEvent *event)
|
void CategorizedView::mouseReleaseEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
QPoint pos = event->pos();
|
QPoint pos = event->pos() - offset();
|
||||||
QPersistentModelIndex index = indexAt(pos);
|
QPersistentModelIndex index = indexAt(pos);
|
||||||
|
|
||||||
bool click = (index == m_pressedIndex && index.isValid()) || (m_pressedCategory && m_pressedCategory == categoryAt(pos));
|
bool click = (index == m_pressedIndex && index.isValid()) || (m_pressedCategory && m_pressedCategory == categoryAt(pos));
|
||||||
@ -582,8 +586,10 @@ void CategorizedView::mouseDoubleClickEvent(QMouseEvent *event)
|
|||||||
void CategorizedView::paintEvent(QPaintEvent *event)
|
void CategorizedView::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
QPainter painter(this->viewport());
|
QPainter painter(this->viewport());
|
||||||
QPoint offset(horizontalOffset(), verticalOffset());
|
painter.translate(-offset());
|
||||||
painter.translate(-offset);
|
|
||||||
|
// FIXME we shouldn't need to do this
|
||||||
|
invalidateCaches();
|
||||||
|
|
||||||
int y = 0;
|
int y = 0;
|
||||||
for (int i = 0; i < m_categories.size(); ++i)
|
for (int i = 0; i < m_categories.size(); ++i)
|
||||||
@ -665,7 +671,7 @@ void CategorizedView::dragEnterEvent(QDragEnterEvent *event)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_lastDragPosition = event->pos();
|
m_lastDragPosition = event->pos() + offset();
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
@ -675,7 +681,7 @@ void CategorizedView::dragMoveEvent(QDragMoveEvent *event)
|
|||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_lastDragPosition = event->pos();
|
m_lastDragPosition = event->pos() + offset();
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
event->accept();
|
event->accept();
|
||||||
}
|
}
|
||||||
@ -696,7 +702,7 @@ void CategorizedView::dropEvent(QDropEvent *event)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPair<Category *, int> dropPos = rowDropPos(event->pos());
|
QPair<Category *, int> dropPos = rowDropPos(event->pos() + offset());
|
||||||
const Category *category = dropPos.first;
|
const Category *category = dropPos.first;
|
||||||
const int row = dropPos.second;
|
const int row = dropPos.second;
|
||||||
|
|
||||||
@ -729,7 +735,8 @@ void CategorizedView::startDrag(Qt::DropActions supportedActions)
|
|||||||
}
|
}
|
||||||
QRect rect;
|
QRect rect;
|
||||||
QPixmap pixmap = renderToPixmap(indexes, &rect);
|
QPixmap pixmap = renderToPixmap(indexes, &rect);
|
||||||
rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
|
rect.translate(offset());
|
||||||
|
//rect.adjust(horizontalOffset(), verticalOffset(), 0, 0);
|
||||||
QDrag *drag = new QDrag(this);
|
QDrag *drag = new QDrag(this);
|
||||||
drag->setPixmap(pixmap);
|
drag->setPixmap(pixmap);
|
||||||
drag->setMimeData(data);
|
drag->setMimeData(data);
|
||||||
@ -935,15 +942,22 @@ QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint
|
|||||||
int internalColumn = -1;
|
int internalColumn = -1;
|
||||||
{
|
{
|
||||||
const int itemWidth = this->itemWidth();
|
const int itemWidth = this->itemWidth();
|
||||||
for (int i = 0, c = 0;
|
if (pos.x() >= (itemWidth * itemsPerRow()))
|
||||||
i < contentWidth();
|
|
||||||
i += itemWidth, ++c)
|
|
||||||
{
|
{
|
||||||
if (pos.x() > (i - itemWidth / 2) &&
|
internalColumn = itemsPerRow();
|
||||||
pos.x() < (i + itemWidth / 2))
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0, c = 0;
|
||||||
|
i < contentWidth();
|
||||||
|
i += itemWidth + spacing(), ++c)
|
||||||
{
|
{
|
||||||
internalColumn = c;
|
if (pos.x() > (i - itemWidth / 2) &&
|
||||||
break;
|
pos.x() <= (i + itemWidth / 2))
|
||||||
|
{
|
||||||
|
internalColumn = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (internalColumn == -1)
|
if (internalColumn == -1)
|
||||||
@ -956,13 +970,10 @@ QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint
|
|||||||
int internalRow = -1;
|
int internalRow = -1;
|
||||||
{
|
{
|
||||||
// FIXME rework the drag and drop code
|
// FIXME rework the drag and drop code
|
||||||
const int itemHeight = 0; //itemSize().height();
|
|
||||||
const int top = categoryTop(category);
|
const int top = categoryTop(category);
|
||||||
for (int i = top + category->headerHeight(), r = 0;
|
for (int r = 0, h = top; r < category->numRows(); h += itemHeightForCategoryRow(category, r), ++r)
|
||||||
i < top + category->totalHeight();
|
|
||||||
i += itemHeight, ++r)
|
|
||||||
{
|
{
|
||||||
if (pos.y() > i && pos.y() < (i + itemHeight))
|
if (pos.y() > h && pos.y() < (h + itemHeightForCategoryRow(category, r)))
|
||||||
{
|
{
|
||||||
internalRow = r;
|
internalRow = r;
|
||||||
break;
|
break;
|
||||||
@ -984,11 +995,23 @@ QPair<CategorizedView::Category *, int> CategorizedView::rowDropPos(const QPoint
|
|||||||
int categoryRow = internalRow * itemsPerRow() + internalColumn;
|
int categoryRow = internalRow * itemsPerRow() + internalColumn;
|
||||||
|
|
||||||
// this is used if we're past the last item
|
// this is used if we're past the last item
|
||||||
int numItemsInLastRow = indices.size() % itemsPerRow();
|
if (categoryRow >= indices.size())
|
||||||
if (internalColumn >= numItemsInLastRow)
|
|
||||||
{
|
{
|
||||||
return qMakePair(category, indices.last().row() + 1);
|
return qMakePair(category, indices.last().row() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return qMakePair(category, indices.at(categoryRow).row());
|
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());
|
||||||
|
}
|
||||||
|
@ -59,7 +59,7 @@ private:
|
|||||||
int totalHeight() const;
|
int totalHeight() const;
|
||||||
int headerHeight() const;
|
int headerHeight() const;
|
||||||
int contentHeight() const;
|
int contentHeight() const;
|
||||||
QSize categoryTotalSize() const;
|
int numRows() const;
|
||||||
};
|
};
|
||||||
friend struct Category;
|
friend struct Category;
|
||||||
|
|
||||||
@ -69,6 +69,7 @@ private:
|
|||||||
|
|
||||||
int m_leftMargin;
|
int m_leftMargin;
|
||||||
int m_rightMargin;
|
int m_rightMargin;
|
||||||
|
int m_bottomMargin;
|
||||||
int m_categoryMargin;
|
int m_categoryMargin;
|
||||||
int m_itemSpacing;
|
int m_itemSpacing;
|
||||||
|
|
||||||
@ -112,6 +113,7 @@ private:
|
|||||||
QPoint m_lastDragPosition;
|
QPoint m_lastDragPosition;
|
||||||
|
|
||||||
QPair<int, int> categoryInternalPosition(const QModelIndex &index) const;
|
QPair<int, int> categoryInternalPosition(const QModelIndex &index) const;
|
||||||
|
int itemHeightForCategoryRow(const Category *category, const int internalRow) const;
|
||||||
|
|
||||||
QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const;
|
QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const;
|
||||||
QList<QPair<QRect, QModelIndex> > draggablePaintPairs(const QModelIndexList &indices, QRect *r) const;
|
QList<QPair<QRect, QModelIndex> > draggablePaintPairs(const QModelIndexList &indices, QRect *r) const;
|
||||||
@ -119,6 +121,10 @@ private:
|
|||||||
bool isDragEventAccepted(QDropEvent *event);
|
bool isDragEventAccepted(QDropEvent *event);
|
||||||
|
|
||||||
QPair<Category *, int> rowDropPos(const QPoint &pos);
|
QPair<Category *, int> rowDropPos(const QPoint &pos);
|
||||||
|
|
||||||
|
void invalidateCaches();
|
||||||
|
|
||||||
|
QPoint offset() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WIDGET_H
|
#endif // WIDGET_H
|
||||||
|
2
main.cpp
2
main.cpp
@ -64,7 +64,7 @@ int main(int argc, char *argv[])
|
|||||||
model.setItem(8, createItem(Qt::darkGreen, "Dark Green", ""));
|
model.setItem(8, createItem(Qt::darkGreen, "Dark Green", ""));
|
||||||
model.setItem(9, createItem(Qt::green, "Green", ""));
|
model.setItem(9, createItem(Qt::green, "Green", ""));
|
||||||
|
|
||||||
for (int i = 0; i < 21; ++i)
|
for (int i = 0; i < 20; ++i)
|
||||||
{
|
{
|
||||||
model.setItem(i + 10, createItem(i+1, "Items 1-20"));
|
model.setItem(i + 10, createItem(i+1, "Items 1-20"));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user