]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/kitemviews/kitemlistview.cpp
Full row highlight implementation
[dolphin.git] / src / kitemviews / kitemlistview.cpp
index 96c337de39b02c873e9ed5335f396e5ec88d8367..86583db1ec958a25ed5b3fa7e1ea3febec725f76 100644 (file)
@@ -372,29 +372,12 @@ void KItemListView::setGeometry(const QRectF& rect)
                                          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
@@ -406,7 +389,7 @@ 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()) {
@@ -414,12 +397,12 @@ int KItemListView::itemAt(const QPointF& pos) const
 
         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
@@ -475,7 +458,7 @@ int KItemListView::lastVisibleIndex() 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);
 }
@@ -494,6 +477,32 @@ bool KItemListView::supportsItemExpanding() const
     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);
@@ -512,6 +521,11 @@ QRectF KItemListView::itemContextRect(int index) const
     return contextRect;
 }
 
+bool KItemListView::isElided(int index) const
+{
+    return m_sizeHintResolver->isElided(index);
+}
+
 void KItemListView::scrollToItem(int index)
 {
     QRectF viewGeometry = geometry();
@@ -543,8 +557,11 @@ void KItemListView::scrollToItem(int index)
 
         if (newOffset != scrollOffset()) {
             Q_EMIT scrollTo(newOffset);
+            return;
         }
     }
+
+    Q_EMIT scrollingStopped();
 }
 
 void KItemListView::beginTransaction()
@@ -590,6 +607,8 @@ void KItemListView::setHeaderVisible(bool visible)
 
         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,
@@ -602,6 +621,8 @@ void KItemListView::setHeaderVisible(bool visible)
     } 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,
@@ -762,7 +783,7 @@ void KItemListView::setItemSize(const QSizeF& size)
                                                 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()));
 
@@ -938,6 +959,11 @@ void KItemListView::onStyleOptionChanged(const KItemListStyleOption& current, co
     Q_UNUSED(previous)
 }
 
+void KItemListView::onHighlightEntireRowChanged(bool highlightEntireRow)
+{
+    Q_UNUSED(highlightEntireRow)
+}
+
 void KItemListView::onSupportsItemExpandingChanged(bool supportsExpanding)
 {
     Q_UNUSED(supportsExpanding)
@@ -1530,6 +1556,16 @@ void KItemListView::slotHeaderColumnWidthChanged(const QByteArray& role,
     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)
@@ -1619,16 +1655,16 @@ void KItemListView::slotRoleEditingCanceled(int index, const QByteArray& role, c
 {
     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)
@@ -1767,13 +1803,11 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha
     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();
@@ -1840,9 +1874,6 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha
                     // 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);
@@ -2239,7 +2270,7 @@ void KItemListView::updateAlternateBackgroundForWidget(KItemListWidget* 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
@@ -2256,11 +2287,11 @@ QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi
     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;
@@ -2297,7 +2328,7 @@ QHash<QByteArray, qreal> KItemListView::preferredColumnWidths(const KItemRangeLi
 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);
@@ -2315,6 +2346,7 @@ void KItemListView::updateWidgetColumnWidths(KItemListWidget* widget)
     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)
@@ -2392,7 +2424,7 @@ void KItemListView::applyAutomaticColumnWidths()
     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
@@ -2571,7 +2603,7 @@ void KItemListView::updateGroupHeaderHeight()
         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;