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