From: Eugene Popov Date: Sun, 13 Feb 2022 12:16:34 +0000 (+0000) Subject: Fix zooming animation X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/a05343530d0f43434715888902067512309098ce Fix zooming animation Current implementation of the zooming animation is a bit buggy. This MR fixes the following issues: * in the Icon view mode, the icons sometimes "jump" * in the Compact view mode, the labels sometimes are cut off BUG: 449179 --- diff --git a/src/kitemviews/kitemlistview.cpp b/src/kitemviews/kitemlistview.cpp index 86583db1e..fa76c3b00 100644 --- a/src/kitemviews/kitemlistview.cpp +++ b/src/kitemviews/kitemlistview.cpp @@ -1462,8 +1462,7 @@ void KItemListView::slotAnimationFinished(QGraphicsWidget* widget, KItemListWidget* itemListWidget = qobject_cast(widget); Q_ASSERT(itemListWidget); - switch (type) { - case KItemListViewAnimation::DeleteAnimation: { + if (type == KItemListViewAnimation::DeleteAnimation) { // As we recycle the widget in this case it is important to assure that no // other animation has been started. This is a convention in KItemListView and // not a requirement defined by KItemListViewAnimation. @@ -1474,22 +1473,13 @@ void KItemListView::slotAnimationFinished(QGraphicsWidget* widget, // been finished. recycleGroupHeaderForWidget(itemListWidget); widgetCreator()->recycle(itemListWidget); - break; - } - - case KItemListViewAnimation::CreateAnimation: - case KItemListViewAnimation::MovingAnimation: - case KItemListViewAnimation::ResizeAnimation: { + } else { const int index = itemListWidget->index(); const bool invisible = (index < m_layouter->firstVisibleIndex()) || (index > m_layouter->lastVisibleIndex()); if (invisible && !m_animation->isStarted(itemListWidget)) { recycleWidget(itemListWidget); } - break; - } - - default: break; } } @@ -1904,6 +1894,15 @@ void KItemListView::doLayout(LayoutAnimationHint hint, int changedIndex, int cha } } + const int newIconSize = widget->styleOption().iconSize; + if (widget->iconSize() != newIconSize) { + if (animate) { + m_animation->start(widget, KItemListViewAnimation::IconResizeAnimation, newIconSize); + } else { + widget->setIconSize(newIconSize); + } + } + // Updating the cell-information must be done as last step: The decision whether the // moving-animation should be started at all is based on the previous cell-information. const Cell cell(m_layouter->itemColumn(i), m_layouter->itemRow(i)); diff --git a/src/kitemviews/kitemlistwidget.cpp b/src/kitemviews/kitemlistwidget.cpp index 79ffee210..f729f0239 100644 --- a/src/kitemviews/kitemlistwidget.cpp +++ b/src/kitemviews/kitemlistwidget.cpp @@ -47,7 +47,8 @@ KItemListWidget::KItemListWidget(KItemListWidgetInformant* informant, QGraphicsI m_hoverAnimation(nullptr), m_hoverSequenceIndex(0), m_selectionToggle(nullptr), - m_editedRole() + m_editedRole(), + m_iconSize(-1) { connect(&m_hoverSequenceTimer, &QTimer::timeout, this, &KItemListWidget::slotHoverSequenceTimerTimeout); } @@ -368,6 +369,20 @@ QByteArray KItemListWidget::editedRole() const return m_editedRole; } +void KItemListWidget::setIconSize(int iconSize) +{ + if (m_iconSize != iconSize) { + const int previousIconSize = m_iconSize; + m_iconSize = iconSize; + iconSizeChanged(iconSize, previousIconSize); + } +} + +int KItemListWidget::iconSize() const +{ + return m_iconSize; +} + bool KItemListWidget::contains(const QPointF& point) const { if (!QGraphicsWidget::contains(point)) { @@ -451,8 +466,12 @@ void KItemListWidget::leadingPaddingChanged(qreal width) void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous) { - Q_UNUSED(current) Q_UNUSED(previous) + + // set the initial value of m_iconSize if not set + if (m_iconSize == -1) { + m_iconSize = current.iconSize; + } } void KItemListWidget::currentChanged(bool current) @@ -487,6 +506,12 @@ void KItemListWidget::editedRoleChanged(const QByteArray& current, const QByteAr Q_UNUSED(previous) } +void KItemListWidget::iconSizeChanged(int current, int previous) +{ + Q_UNUSED(current) + Q_UNUSED(previous) +} + void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { QGraphicsWidget::resizeEvent(event); diff --git a/src/kitemviews/kitemlistwidget.h b/src/kitemviews/kitemlistwidget.h index 0b82266c4..517f7e049 100644 --- a/src/kitemviews/kitemlistwidget.h +++ b/src/kitemviews/kitemlistwidget.h @@ -53,6 +53,8 @@ class DOLPHIN_EXPORT KItemListWidget : public QGraphicsWidget { Q_OBJECT + Q_PROPERTY(int iconSize READ iconSize WRITE setIconSize) + public: KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent); ~KItemListWidget() override; @@ -128,6 +130,13 @@ public: void setEditedRole(const QByteArray& role); QByteArray editedRole() const; + /** + * Contains the actual icon size used to draw the icon. + * Also used during icon resizing animation. + */ + void setIconSize(int iconSize); + int iconSize() const; + /** * @return True if \a point is inside KItemListWidget::hoverRect(), * KItemListWidget::textRect(), KItemListWidget::selectionToggleRect() @@ -196,6 +205,7 @@ protected: virtual void alternateBackgroundChanged(bool enabled); virtual void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous); virtual void editedRoleChanged(const QByteArray& current, const QByteArray& previous); + virtual void iconSizeChanged(int current, int previous); void resizeEvent(QGraphicsSceneResizeEvent* event) override; void clearHoverCache(); @@ -263,6 +273,7 @@ private: KItemListSelectionToggle* m_selectionToggle; QByteArray m_editedRole; + int m_iconSize; }; inline const KItemListWidgetInformant* KItemListWidget::informant() const diff --git a/src/kitemviews/kstandarditemlistwidget.cpp b/src/kitemviews/kstandarditemlistwidget.cpp index 668382cd5..585a96fbf 100644 --- a/src/kitemviews/kstandarditemlistwidget.cpp +++ b/src/kitemviews/kstandarditemlistwidget.cpp @@ -532,12 +532,11 @@ QRectF KStandardItemListWidget::selectionToggleRect() const { const_cast(this)->triggerCacheRefreshing(); - const int iconHeight = styleOption().iconSize; - + const int widgetIconSize = iconSize(); int toggleSize = KIconLoader::SizeSmall; - if (iconHeight >= KIconLoader::SizeEnormous) { + if (widgetIconSize >= KIconLoader::SizeEnormous) { toggleSize = KIconLoader::SizeMedium; - } else if (iconHeight >= KIconLoader::SizeLarge) { + } else if (widgetIconSize >= KIconLoader::SizeLarge) { toggleSize = KIconLoader::SizeSmallMedium; } @@ -736,8 +735,8 @@ void KStandardItemListWidget::leadingPaddingChanged(qreal padding) { void KStandardItemListWidget::styleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous) { - Q_UNUSED(current) - Q_UNUSED(previous) + KItemListWidget::styleOptionChanged(current, previous); + updateAdditionalInfoTextColor(); m_dirtyLayout = true; } @@ -833,6 +832,15 @@ void KStandardItemListWidget::editedRoleChanged(const QByteArray& current, const m_roleEditor->setFocus(); } +void KStandardItemListWidget::iconSizeChanged(int current, int previous) +{ + KItemListWidget::iconSizeChanged(current, previous); + + invalidateIconCache(); + triggerCacheRefreshing(); + update(); +} + void KStandardItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event) { if (m_roleEditor) { @@ -944,13 +952,13 @@ void KStandardItemListWidget::updateExpansionArea() const QHash values = data(); const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt(); if (expandedParentsCount >= 0) { - const KItemListStyleOption& option = styleOption(); + const int widgetIconSize = iconSize(); const qreal widgetHeight = size().height(); - const qreal inc = (widgetHeight - option.iconSize) / 2; + const qreal inc = (widgetHeight - widgetIconSize) / 2; const qreal x = expandedParentsCount * widgetHeight + inc; const qreal y = inc; const qreal xPadding = m_highlightEntireRow ? leadingPadding() : 0; - m_expansionArea = QRectF(xPadding + x, y, option.iconSize, option.iconSize); + m_expansionArea = QRectF(xPadding + x, y, widgetIconSize, widgetIconSize); return; } } @@ -968,8 +976,9 @@ void KStandardItemListWidget::updatePixmapCache() const KItemListStyleOption& option = styleOption(); const qreal padding = option.padding; - const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : option.iconSize; - const int maxIconHeight = option.iconSize; + const int widgetIconSize = iconSize(); + const int maxIconWidth = iconOnTop ? widgetSize.width() - 2 * padding : widgetIconSize; + const int maxIconHeight = widgetIconSize; const QHash values = data(); @@ -1212,7 +1221,6 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() const KItemListStyleOption& option = styleOption(); const qreal padding = option.padding; const qreal maxWidth = size().width() - 2 * padding; - const qreal widgetHeight = size().height(); const qreal lineSpacing = m_customizedFontMetrics.lineSpacing(); // Initialize properties for the "text" role. It will be used as anchor @@ -1266,12 +1274,8 @@ void KStandardItemListWidget::updateIconsLayoutTextCache() layout.endLayout(); // Use one line for each additional information - const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0); nameTextInfo->staticText.setTextWidth(maxWidth); - nameTextInfo->pos = QPointF(padding, widgetHeight - - nameHeight - - additionalRolesCount * lineSpacing - - padding); + nameTextInfo->pos = QPointF(padding, iconSize() + 2 * padding); m_textRect = QRectF(padding + (maxWidth - nameWidth) / 2, nameTextInfo->pos.y(), nameWidth, @@ -1336,10 +1340,9 @@ void KStandardItemListWidget::updateCompactLayoutTextCache() const qreal widgetHeight = size().height(); const qreal lineSpacing = m_customizedFontMetrics.lineSpacing(); const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * lineSpacing; - const int scaledIconSize = (textLinesHeight < option.iconSize) ? widgetHeight - 2 * option.padding : option.iconSize; qreal maximumRequiredTextWidth = 0; - const qreal x = option.padding * 3 + scaledIconSize; + const qreal x = option.padding * 3 + iconSize(); qreal y = qRound((widgetHeight - textLinesHeight) / 2); const qreal maxWidth = size().width() - x - option.padding; for (const QByteArray& role : qAsConst(m_sortedVisibleRoles)) { @@ -1379,11 +1382,10 @@ void KStandardItemListWidget::updateDetailsLayoutTextCache() const QHash values = data(); const qreal widgetHeight = size().height(); - const int scaledIconSize = widgetHeight - 2 * option.padding; const int fontHeight = m_customizedFontMetrics.height(); const qreal columnWidthInc = columnPadding(option); - qreal firstColumnInc = scaledIconSize; + qreal firstColumnInc = iconSize(); if (m_supportsItemExpanding) { firstColumnInc += (m_expansionArea.left() + m_expansionArea.right() + widgetHeight) / 2; } else { diff --git a/src/kitemviews/kstandarditemlistwidget.h b/src/kitemviews/kstandarditemlistwidget.h index 3edec0db5..060396a55 100644 --- a/src/kitemviews/kstandarditemlistwidget.h +++ b/src/kitemviews/kstandarditemlistwidget.h @@ -177,6 +177,7 @@ protected: void selectedChanged(bool selected) override; void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous) override; void editedRoleChanged(const QByteArray& current, const QByteArray& previous) override; + void iconSizeChanged(int current, int previous) override; void resizeEvent(QGraphicsSceneResizeEvent* event) override; void showEvent(QShowEvent* event) override; void hideEvent(QHideEvent* event) override; diff --git a/src/kitemviews/private/kitemlistviewanimation.cpp b/src/kitemviews/private/kitemlistviewanimation.cpp index 9dc5fbada..0c16c8b0a 100644 --- a/src/kitemviews/private/kitemlistviewanimation.cpp +++ b/src/kitemviews/private/kitemlistviewanimation.cpp @@ -146,7 +146,15 @@ void KItemListViewAnimation::start(QGraphicsWidget* widget, AnimationType type, break; } + case IconResizeAnimation: { + propertyAnim = new QPropertyAnimation(widget, QByteArrayLiteral("iconSize")); + propertyAnim->setDuration(animationDuration); + propertyAnim->setEndValue(endValue); + break; + } + default: + Q_UNREACHABLE(); break; } diff --git a/src/kitemviews/private/kitemlistviewanimation.h b/src/kitemviews/private/kitemlistviewanimation.h index 8d11dbf89..5e0ebf982 100644 --- a/src/kitemviews/private/kitemlistviewanimation.h +++ b/src/kitemviews/private/kitemlistviewanimation.h @@ -32,7 +32,9 @@ public: MovingAnimation, CreateAnimation, DeleteAnimation, - ResizeAnimation + ResizeAnimation, + IconResizeAnimation, + AnimationTypeCount }; explicit KItemListViewAnimation(QObject* parent = nullptr); @@ -79,8 +81,6 @@ private Q_SLOTS: void slotFinished(); private: - enum { AnimationTypeCount = 4 }; - Qt::Orientation m_scrollOrientation; qreal m_scrollOffset; QHash m_animation[AnimationTypeCount];