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
KItemListWidget* itemListWidget = qobject_cast<KItemListWidget*>(widget);
Q_ASSERT(itemListWidget);
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.
// 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.
// been finished.
recycleGroupHeaderForWidget(itemListWidget);
widgetCreator()->recycle(itemListWidget);
// been finished.
recycleGroupHeaderForWidget(itemListWidget);
widgetCreator()->recycle(itemListWidget);
- break;
- }
-
- case KItemListViewAnimation::CreateAnimation:
- case KItemListViewAnimation::MovingAnimation:
- case KItemListViewAnimation::ResizeAnimation: {
const int index = itemListWidget->index();
const bool invisible = (index < m_layouter->firstVisibleIndex()) ||
(index > m_layouter->lastVisibleIndex());
if (invisible && !m_animation->isStarted(itemListWidget)) {
recycleWidget(itemListWidget);
}
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;
+ 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));
// 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));
m_hoverAnimation(nullptr),
m_hoverSequenceIndex(0),
m_selectionToggle(nullptr),
m_hoverAnimation(nullptr),
m_hoverSequenceIndex(0),
m_selectionToggle(nullptr),
+ m_editedRole(),
+ m_iconSize(-1)
{
connect(&m_hoverSequenceTimer, &QTimer::timeout, this, &KItemListWidget::slotHoverSequenceTimerTimeout);
}
{
connect(&m_hoverSequenceTimer, &QTimer::timeout, this, &KItemListWidget::slotHoverSequenceTimerTimeout);
}
+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)) {
bool KItemListWidget::contains(const QPointF& point) const
{
if (!QGraphicsWidget::contains(point)) {
void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
const KItemListStyleOption& previous)
{
void KItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
const KItemListStyleOption& previous)
{
+
+ // set the initial value of m_iconSize if not set
+ if (m_iconSize == -1) {
+ m_iconSize = current.iconSize;
+ }
}
void KItemListWidget::currentChanged(bool current)
}
void KItemListWidget::currentChanged(bool current)
+void KItemListWidget::iconSizeChanged(int current, int previous)
+{
+ Q_UNUSED(current)
+ Q_UNUSED(previous)
+}
+
void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
{
QGraphicsWidget::resizeEvent(event);
void KItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
{
QGraphicsWidget::resizeEvent(event);
+ Q_PROPERTY(int iconSize READ iconSize WRITE setIconSize)
+
public:
KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
~KItemListWidget() override;
public:
KItemListWidget(KItemListWidgetInformant* informant, QGraphicsItem* parent);
~KItemListWidget() override;
void setEditedRole(const QByteArray& role);
QByteArray editedRole() const;
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()
/**
* @return True if \a point is inside KItemListWidget::hoverRect(),
* KItemListWidget::textRect(), KItemListWidget::selectionToggleRect()
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 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();
void resizeEvent(QGraphicsSceneResizeEvent* event) override;
void clearHoverCache();
KItemListSelectionToggle* m_selectionToggle;
QByteArray m_editedRole;
KItemListSelectionToggle* m_selectionToggle;
QByteArray m_editedRole;
};
inline const KItemListWidgetInformant* KItemListWidget::informant() const
};
inline const KItemListWidgetInformant* KItemListWidget::informant() const
{
const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
{
const_cast<KStandardItemListWidget*>(this)->triggerCacheRefreshing();
- const int iconHeight = styleOption().iconSize;
-
+ const int widgetIconSize = iconSize();
int toggleSize = KIconLoader::SizeSmall;
int toggleSize = KIconLoader::SizeSmall;
- if (iconHeight >= KIconLoader::SizeEnormous) {
+ if (widgetIconSize >= KIconLoader::SizeEnormous) {
toggleSize = KIconLoader::SizeMedium;
toggleSize = KIconLoader::SizeMedium;
- } else if (iconHeight >= KIconLoader::SizeLarge) {
+ } else if (widgetIconSize >= KIconLoader::SizeLarge) {
toggleSize = KIconLoader::SizeSmallMedium;
}
toggleSize = KIconLoader::SizeSmallMedium;
}
void KStandardItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
const KItemListStyleOption& previous)
{
void KStandardItemListWidget::styleOptionChanged(const KItemListStyleOption& current,
const KItemListStyleOption& previous)
{
- Q_UNUSED(current)
- Q_UNUSED(previous)
+ KItemListWidget::styleOptionChanged(current, previous);
+
updateAdditionalInfoTextColor();
m_dirtyLayout = true;
}
updateAdditionalInfoTextColor();
m_dirtyLayout = true;
}
m_roleEditor->setFocus();
}
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) {
void KStandardItemListWidget::resizeEvent(QGraphicsSceneResizeEvent* event)
{
if (m_roleEditor) {
const QHash<QByteArray, QVariant> values = data();
const int expandedParentsCount = values.value("expandedParentsCount", 0).toInt();
if (expandedParentsCount >= 0) {
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 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;
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);
const KItemListStyleOption& option = styleOption();
const qreal padding = option.padding;
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();
const QHash<QByteArray, QVariant> values = data();
const KItemListStyleOption& option = styleOption();
const qreal padding = option.padding;
const qreal maxWidth = size().width() - 2 * padding;
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
const qreal lineSpacing = m_customizedFontMetrics.lineSpacing();
// Initialize properties for the "text" role. It will be used as anchor
layout.endLayout();
// Use one line for each additional information
layout.endLayout();
// Use one line for each additional information
- const int additionalRolesCount = qMax(visibleRoles().count() - 1, 0);
nameTextInfo->staticText.setTextWidth(maxWidth);
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,
m_textRect = QRectF(padding + (maxWidth - nameWidth) / 2,
nameTextInfo->pos.y(),
nameWidth,
const qreal widgetHeight = size().height();
const qreal lineSpacing = m_customizedFontMetrics.lineSpacing();
const qreal textLinesHeight = qMax(visibleRoles().count(), 1) * lineSpacing;
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;
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)) {
qreal y = qRound((widgetHeight - textLinesHeight) / 2);
const qreal maxWidth = size().width() - x - option.padding;
for (const QByteArray& role : qAsConst(m_sortedVisibleRoles)) {
const QHash<QByteArray, QVariant> values = data();
const qreal widgetHeight = size().height();
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);
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 {
if (m_supportsItemExpanding) {
firstColumnInc += (m_expansionArea.left() + m_expansionArea.right() + widgetHeight) / 2;
} else {
void selectedChanged(bool selected) override;
void siblingsInformationChanged(const QBitArray& current, const QBitArray& previous) override;
void editedRoleChanged(const QByteArray& current, const QByteArray& previous) override;
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;
void resizeEvent(QGraphicsSceneResizeEvent* event) override;
void showEvent(QShowEvent* event) override;
void hideEvent(QHideEvent* event) override;
+ case IconResizeAnimation: {
+ propertyAnim = new QPropertyAnimation(widget, QByteArrayLiteral("iconSize"));
+ propertyAnim->setDuration(animationDuration);
+ propertyAnim->setEndValue(endValue);
+ break;
+ }
+
MovingAnimation,
CreateAnimation,
DeleteAnimation,
MovingAnimation,
CreateAnimation,
DeleteAnimation,
+ ResizeAnimation,
+ IconResizeAnimation,
+ AnimationTypeCount
};
explicit KItemListViewAnimation(QObject* parent = nullptr);
};
explicit KItemListViewAnimation(QObject* parent = nullptr);
void slotFinished();
private:
void slotFinished();
private:
- enum { AnimationTypeCount = 4 };
-
Qt::Orientation m_scrollOrientation;
qreal m_scrollOffset;
QHash<QGraphicsWidget*, QPropertyAnimation*> m_animation[AnimationTypeCount];
Qt::Orientation m_scrollOrientation;
qreal m_scrollOffset;
QHash<QGraphicsWidget*, QPropertyAnimation*> m_animation[AnimationTypeCount];