From 649490f359bc7308a0e21f0b38cf9b8a01e7b619 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Tue, 18 Oct 2016 16:35:16 +0300 Subject: Add itemAlignment property to QListView This property allows to change the default behavior in which list items occupy the entire width of their column. Setting it to Qt::{AlignLeft,AlignRight,AlignHCenter} will reduce their widths to the minimum values, thus allowing to have intermediate free space. Then the user will be able to begin selections by mouse from this space. [ChangeLog][QtWidgets][QListView] Added itemAlignment property. Task-number: QTBUG-56606 Change-Id: Iae55c251379be4e45d0c0d69175ff4388b5785b4 Reviewed-by: Christian Ehrlicher Reviewed-by: Richard Moe Gustavsen --- src/widgets/itemviews/qlistview.cpp | 58 +++++++++++++++++++++++++++++++++---- src/widgets/itemviews/qlistview.h | 4 +++ src/widgets/itemviews/qlistview_p.h | 2 ++ 3 files changed, 59 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/widgets/itemviews/qlistview.cpp b/src/widgets/itemviews/qlistview.cpp index 05e3ebf664..7fbbf39309 100644 --- a/src/widgets/itemviews/qlistview.cpp +++ b/src/widgets/itemviews/qlistview.cpp @@ -1630,6 +1630,32 @@ bool QListView::isSelectionRectVisible() const return d->isSelectionRectVisible(); } +/*! + \property QListView::itemAlignment + \brief the alignment of each item in its cell + \since 5.12 + + This is only supported in ListMode with TopToBottom flow + and with wrapping enabled. + The default alignment is 0, which means that an item fills + its cell entirely. +*/ +void QListView::setItemAlignment(Qt::Alignment alignment) +{ + Q_D(QListView); + if (d->itemAlignment == alignment) + return; + d->itemAlignment = alignment; + if (viewMode() == ListMode && flow() == QListView::TopToBottom && isWrapping()) + d->doDelayedItemsLayout(); +} + +Qt::Alignment QListView::itemAlignment() const +{ + Q_D(const QListView); + return d->itemAlignment; +} + /*! \reimp */ @@ -1656,7 +1682,8 @@ QListViewPrivate::QListViewPrivate() column(0), uniformItemSizes(false), batchSize(100), - showElasticBand(false) + showElasticBand(false), + itemAlignment(Qt::Alignment()) { } @@ -2366,6 +2393,7 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c options.rect.setSize(contentsSize); QSize size = (uniformItemSizes() && cachedItemSize().isValid()) ? cachedItemSize() : itemSize(options, index); + QSize cellSize = size; QPoint pos; if (flow() == QListView::LeftToRight) { @@ -2378,12 +2406,22 @@ QListViewItem QListModeViewBase::indexToListViewItem(const QModelIndex &index) c int right = (segment + 1 >= segmentPositions.count() ? contentsSize.width() : segmentPositions.at(segment + 1)); - size.setWidth(right - pos.x()); + cellSize.setWidth(right - pos.x()); } else { // make the items as wide as the viewport - size.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing())); + cellSize.setWidth(qMax(size.width(), viewport()->width() - 2 * spacing())); } } + if (dd->itemAlignment & Qt::AlignHorizontal_Mask) { + size.setWidth(qMin(size.width(), cellSize.width())); + if (dd->itemAlignment & Qt::AlignRight) + pos.setX(pos.x() + cellSize.width() - size.width()); + if (dd->itemAlignment & Qt::AlignHCenter) + pos.setX(pos.x() + (cellSize.width() - size.width()) / 2); + } else { + size.setWidth(cellSize.width()); + } + return QListViewItem(QRect(pos, size), index.row()); } @@ -2562,8 +2600,18 @@ QVector QListModeViewBase::intersectingSet(const QRect &area) const if (isHidden(row)) continue; QModelIndex index = modelIndex(row); - if (index.isValid()) - ret += index; + if (index.isValid()) { + if (flow() == QListView::LeftToRight || dd->itemAlignment == Qt::Alignment()) { + ret += index; + } else { + const auto viewItem = indexToListViewItem(index); + const int iw = viewItem.width(); + const int startPos = qMax(segStartPosition, segmentPositions.at(seg)); + const int endPos = qMin(segmentPositions.at(seg + 1), segEndPosition); + if (endPos >= viewItem.x && startPos < viewItem.x + iw) + ret += index; + } + } #if 0 // for debugging else qWarning("intersectingSet: row %d was invalid", row); diff --git a/src/widgets/itemviews/qlistview.h b/src/widgets/itemviews/qlistview.h index 9fc4035999..8a5d5e02ae 100644 --- a/src/widgets/itemviews/qlistview.h +++ b/src/widgets/itemviews/qlistview.h @@ -65,6 +65,7 @@ class Q_WIDGETS_EXPORT QListView : public QAbstractItemView Q_PROPERTY(int batchSize READ batchSize WRITE setBatchSize) Q_PROPERTY(bool wordWrap READ wordWrap WRITE setWordWrap) Q_PROPERTY(bool selectionRectVisible READ isSelectionRectVisible WRITE setSelectionRectVisible) + Q_PROPERTY(Qt::Alignment itemAlignment READ itemAlignment WRITE setItemAlignment) public: enum Movement { Static, Free, Snap }; @@ -125,6 +126,9 @@ public: void setSelectionRectVisible(bool show); bool isSelectionRectVisible() const; + void setItemAlignment(Qt::Alignment alignment); + Qt::Alignment itemAlignment() const; + QRect visualRect(const QModelIndex &index) const override; void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override; QModelIndex indexAt(const QPoint &p) const override; diff --git a/src/widgets/itemviews/qlistview_p.h b/src/widgets/itemviews/qlistview_p.h index ca947292e3..181386d4d0 100644 --- a/src/widgets/itemviews/qlistview_p.h +++ b/src/widgets/itemviews/qlistview_p.h @@ -431,6 +431,8 @@ public: QRect elasticBand; bool showElasticBand; + + Qt::Alignment itemAlignment; }; // inline implementations -- cgit v1.2.3