┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Popov <[email protected]>2022-02-13 12:16:34 +0000
committerFelix Ernst <[email protected]>2022-02-13 12:16:34 +0000
commita05343530d0f43434715888902067512309098ce (patch)
tree18876595d04599620acc96684f314a21119b6ed0
parente9bd295b3cce63048b141d1fdba844091419a973 (diff)
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
-rw-r--r--src/kitemviews/kitemlistview.cpp23
-rw-r--r--src/kitemviews/kitemlistwidget.cpp29
-rw-r--r--src/kitemviews/kitemlistwidget.h11
-rw-r--r--src/kitemviews/kstandarditemlistwidget.cpp44
-rw-r--r--src/kitemviews/kstandarditemlistwidget.h1
-rw-r--r--src/kitemviews/private/kitemlistviewanimation.cpp8
-rw-r--r--src/kitemviews/private/kitemlistviewanimation.h6
7 files changed, 84 insertions, 38 deletions
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<KItemListWidget*>(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;
@@ -129,6 +131,13 @@ public:
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()
* or KItemListWidget::expansionToggleRect().
@@ -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<KStandardItemListWidget*>(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<QByteArray, QVariant> 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<QByteArray, QVariant> 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<QByteArray, QVariant> 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<QGraphicsWidget*, QPropertyAnimation*> m_animation[AnimationTypeCount];