m_itemSize.height());
m_layouter->setItemSize(dynamicItemSize);
}
-
- // Triggering a synchronous layout is fine from a performance point of view,
- // as with dynamic item sizes no moving animation must be done.
- m_layouter->setSize(newSize);
- doLayout(NoAnimation);
- } else {
- const bool animate = !changesItemGridLayout(newSize,
- m_layouter->itemSize(),
- m_layouter->itemMargin());
- m_layouter->setSize(newSize);
-
- if (animate) {
- // Trigger an asynchronous relayout with m_layoutTimer to prevent
- // performance bottlenecks. If the timer is exceeded, an animated layout
- // will be triggered.
- if (!m_layoutTimer->isActive()) {
- m_layoutTimer->start();
- }
- } else {
- m_layoutTimer->stop();
- doLayout(NoAnimation);
- }
}
+
+ m_layouter->setSize(newSize);
+ // We don't animate the moving of the items here because
+ // it would look like the items are slow to find their position.
+ doLayout(NoAnimation);
}
qreal KItemListView::verticalPageStep() const
return size().height() - headerHeight;
}
-int KItemListView::itemAt(const QPointF& pos) const
+std::optional<int> KItemListView::itemAt(const QPointF& pos) const
{
QHashIterator<int, KItemListWidget*> it(m_visibleItems);
while (it.hasNext()) {
const KItemListWidget* widget = it.value();
const QPointF mappedPos = widget->mapFromItem(this, pos);
- if (widget->contains(mappedPos)) {
+ if (widget->contains(mappedPos) || widget->selectionRect().contains(mappedPos)) {
return it.key();
}
}
- return -1;
+ return std::nullopt;
}
bool KItemListView::isAboveSelectionToggle(int index, const QPointF& pos) const
return m_layouter->lastVisibleIndex();
}
-void KItemListView::calculateItemSizeHints(QVector<qreal>& logicalHeightHints, qreal& logicalWidthHint) const
+void KItemListView::calculateItemSizeHints(QVector<std::pair<qreal, bool>>& logicalHeightHints, qreal& logicalWidthHint) const
{
widgetCreator()->calculateItemSizeHints(logicalHeightHints, logicalWidthHint, this);
}
return m_supportsItemExpanding;
}
+void KItemListView::setHighlightEntireRow(bool highlightEntireRow)
+{
+ if (m_highlightEntireRow != highlightEntireRow) {
+ m_highlightEntireRow = highlightEntireRow;
+ onHighlightEntireRowChanged(highlightEntireRow);
+ }
+}
+
+bool KItemListView::highlightEntireRow() const
+{
+ return m_highlightEntireRow;
+}
+
+void KItemListView::setAlternateBackgrounds(bool alternate)
+{
+ if (m_alternateBackgrounds != alternate) {
+ m_alternateBackgrounds = alternate;
+ updateAlternateBackgrounds();
+ }
+}
+
+bool KItemListView::alternateBackgrounds() const
+{
+ return m_alternateBackgrounds;
+}
+
QRectF KItemListView::itemRect(int index) const
{
return m_layouter->itemRect(index);
return contextRect;
}
+bool KItemListView::isElided(int index) const
+{
+ return m_sizeHintResolver->isElided(index);
+}
+
void KItemListView::scrollToItem(int index)
{
QRectF viewGeometry = geometry();
if (newOffset != scrollOffset()) {
Q_EMIT scrollTo(newOffset);
+ return;
}
}
+
+ Q_EMIT scrollingStopped();
}
void KItemListView::beginTransaction()
connect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged,
this, &KItemListView::slotHeaderColumnWidthChanged);
+ connect(m_headerWidget, &KItemListHeaderWidget::leadingPaddingChanged,
+ this, &KItemListView::slotLeadingPaddingChanged);
connect(m_headerWidget, &KItemListHeaderWidget::columnMoved,
this, &KItemListView::slotHeaderColumnMoved);
connect(m_headerWidget, &KItemListHeaderWidget::sortOrderChanged,
} else if (!visible && m_headerWidget->isVisible()) {
disconnect(m_headerWidget, &KItemListHeaderWidget::columnWidthChanged,
this, &KItemListView::slotHeaderColumnWidthChanged);
+ disconnect(m_headerWidget, &KItemListHeaderWidget::leadingPaddingChanged,
+ this, &KItemListView::slotLeadingPaddingChanged);
disconnect(m_headerWidget, &KItemListHeaderWidget::columnMoved,
this, &KItemListView::slotHeaderColumnMoved);
disconnect(m_headerWidget, &KItemListHeaderWidget::sortOrderChanged,
size,
m_layouter->itemMargin());
- const bool alternateBackgroundsChanged = (m_visibleRoles.count() > 1) &&
+ const bool alternateBackgroundsChanged = m_alternateBackgrounds &&
(( m_itemSize.isEmpty() && !size.isEmpty()) ||
(!m_itemSize.isEmpty() && size.isEmpty()));
Q_UNUSED(previous)
}
+void KItemListView::onHighlightEntireRowChanged(bool highlightEntireRow)
+{
+ Q_UNUSED(highlightEntireRow)
+}
+
void KItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
{
Q_UNUSED(supportsExpanding)
doLayout(NoAnimation);
}
+void KItemListView::slotLeadingPaddingChanged(qreal width)
+{
+ Q_UNUSED(width)
+ if (m_headerWidget->automaticColumnResizing()) {
+ applyAutomaticColumnWidths();
+ }
+ applyColumnWidthsFromHeader();
+ doLayout(NoAnimation);
+}
+
void KItemListView::slotHeaderColumnMoved(const QByteArray& role,
int currentIndex,
int previousIndex)
{
disconnectRoleEditingSignals(index);
- Q_EMIT roleEditingCanceled(index, role, value);
m_editingRole = false;
+ Q_EMIT roleEditingCanceled(index, role, value);
}
void KItemListView::slotRoleEditingFinished(int index, const QByteArray& role, const QVariant& value)
{
disconnectRoleEditingSignals(index);
- Q_EMIT roleEditingFinished(index, role, value);
m_editingRole = false;
+ Q_EMIT roleEditingFinished(index, role, value);
}
void KItemListView::setController(KItemListController* controller)
const bool animate = (hint == Animation);
for (int i = firstVisibleIndex; i <= lastVisibleIndex; ++i) {
bool applyNewPos = true;
- bool wasHidden = false;
const QRectF itemBounds = m_layouter->itemRect(i);
const QPointF newPos = itemBounds.topLeft();
KItemListWidget* widget = m_visibleItems.value(i);
if (!widget) {
- wasHidden = true;
if (!reusableItems.isEmpty()) {
// Reuse a KItemListWidget instance from an invisible item
const int oldIndex = reusableItems.takeLast();
// prevents a "move animation mess" when inserting several ranges in parallel.
applyNewPos = !moveWidget(widget, newPos);
}
- } else if (!itemsRemoved && !itemsInserted && !wasHidden) {
- // The size of the view might have been changed. Animate the moving of the position.
- applyNewPos = !moveWidget(widget, newPos);
}
} else {
m_animation->stop(widget);
bool KItemListView::useAlternateBackgrounds() const
{
- return m_itemSize.isEmpty() && m_visibleRoles.count() > 1;
+ return m_alternateBackgrounds && m_itemSize.isEmpty();
}
QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeList& itemRanges) const
const int headerMargin = m_headerWidget->style()->pixelMetric(QStyle::PM_HeaderMargin);
for (const QByteArray& visibleRole : qAsConst(m_visibleRoles)) {
const QString headerText = m_model->roleDescription(visibleRole);
- const qreal headerWidth = fontMetrics.width(headerText) + gripMargin + headerMargin * 2;
+ const qreal headerWidth = fontMetrics.horizontalAdvance(headerText) + gripMargin + headerMargin * 2;
widths.insert(visibleRole, headerWidth);
}
- // Calculate the preferred column withs for each item and ignore values
+ // Calculate the preferred column widths for each item and ignore values
// smaller than the width for showing the headline unclipped.
const KItemListWidgetCreatorBase* creator = widgetCreator();
int calculatedItemCount = 0;
void KItemListView::applyColumnWidthsFromHeader()
{
// Apply the new size to the layouter
- const qreal requiredWidth = columnWidthsSum();
+ const qreal requiredWidth = columnWidthsSum() + m_headerWidget->leadingPadding();
const QSizeF dynamicItemSize(qMax(size().width(), requiredWidth),
m_itemSize.height());
m_layouter->setItemSize(dynamicItemSize);
for (const QByteArray& role : qAsConst(m_visibleRoles)) {
widget->setColumnWidth(role, m_headerWidget->columnWidth(role));
}
+ widget->setLeadingPadding(m_headerWidget->leadingPadding());
}
void KItemListView::updatePreferredColumnWidths(const KItemRangeList& itemRanges)
qreal firstColumnWidth = m_headerWidget->columnWidth(firstRole);
QSizeF dynamicItemSize = m_itemSize;
- qreal requiredWidth = columnWidthsSum();
+ qreal requiredWidth = columnWidthsSum() + m_headerWidget->leadingPadding();
const qreal availableWidth = size().width();
if (requiredWidth < availableWidth) {
// Stretch the first column to use the whole remaining width
groupHeaderHeight += 2 * m_styleOption.horizontalMargin;
groupHeaderMargin = m_styleOption.horizontalMargin;
} else if (m_itemSize.isEmpty()){
- groupHeaderHeight += 2 * m_styleOption.padding;
+ groupHeaderHeight += 4 * m_styleOption.padding;
groupHeaderMargin = m_styleOption.iconSize / 2;
} else {
groupHeaderHeight += 2 * m_styleOption.padding + m_styleOption.verticalMargin;