1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-07-02 16:31:23 +00:00

Add drag-open animation

This commit adds an animation for folders that makes clear that
they will open or expand soon. This is the case when the option to
open folders during drag operations is enabled and a user drags an
item on top of a folder.

The animation goes like this:
- Replace the folder's icon with the "folder-open" icon
- Go back to the folder's original icon
- Replace the folder's icon with the "folder-open" icon once more
This commit is contained in:
Felix Ernst 2024-02-18 13:15:18 +01:00 committed by Felix Ernst
parent 796332d63a
commit 94828aa307
5 changed files with 66 additions and 1 deletions

View File

@ -830,6 +830,7 @@ bool KItemListController::dragMoveEvent(QGraphicsSceneDragDropEvent *event, cons
if (!m_autoActivationTimer->isActive() && m_autoActivationTimer->interval() >= 0) {
m_autoActivationTimer->setProperty("index", index);
m_autoActivationTimer->start();
newHoveredWidget->startActivateSoonAnimation(m_autoActivationTimer->remainingTime());
}
} else {
m_autoActivationTimer->stop();

View File

@ -438,6 +438,11 @@ QPixmap KItemListWidget::createDragPixmap(const QStyleOptionGraphicsItem *option
return pixmap;
}
void KItemListWidget::startActivateSoonAnimation(int timeUntilActivation)
{
Q_UNUSED(timeUntilActivation)
}
void KItemListWidget::dataChanged(const QHash<QByteArray, QVariant> &current, const QSet<QByteArray> &roles)
{
Q_UNUSED(current)

View File

@ -188,6 +188,12 @@ public:
*/
virtual QPixmap createDragPixmap(const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr);
/**
* Starts an animation that makes clear that the item will be activated soon.
* @param timeUntilActivation time in milliseconds until the item will activate
*/
virtual void startActivateSoonAnimation(int timeUntilActivation);
Q_SIGNALS:
void roleEditingCanceled(int index, const QByteArray &role, const QVariant &value);
void roleEditingFinished(int index, const QByteArray &role, const QVariant &value);

View File

@ -24,6 +24,7 @@
#include <QGraphicsView>
#include <QPixmapCache>
#include <QStyleOption>
#include <QVariantAnimation>
// #define KSTANDARDITEMLISTWIDGET_DEBUG
@ -589,6 +590,50 @@ QPixmap KStandardItemListWidget::createDragPixmap(const QStyleOptionGraphicsItem
return clippedPixmap;
}
void KStandardItemListWidget::startActivateSoonAnimation(int timeUntilActivation)
{
if (m_activateSoonAnimation) {
m_activateSoonAnimation->stop(); // automatically DeleteWhenStopped
}
m_activateSoonAnimation = new QVariantAnimation{this};
m_activateSoonAnimation->setStartValue(0.0);
m_activateSoonAnimation->setEndValue(1.0);
m_activateSoonAnimation->setDuration(timeUntilActivation);
const QVariant originalIconName{data()["iconName"]};
connect(m_activateSoonAnimation, &QVariantAnimation::valueChanged, this, [originalIconName, this](const QVariant &value) {
auto progress = value.toFloat();
QVariant wantedIconName;
if (progress < 0.333) {
wantedIconName = "folder-open";
} else if (progress < 0.666) {
wantedIconName = originalIconName;
} else {
wantedIconName = "folder-open";
}
QHash<QByteArray, QVariant> itemData{data()};
if (itemData["iconName"] != wantedIconName) {
itemData.insert("iconName", wantedIconName);
setData(itemData);
invalidateIconCache();
}
});
connect(m_activateSoonAnimation, &QObject::destroyed, this, [originalIconName, this]() {
QHash<QByteArray, QVariant> itemData{data()};
if (itemData["iconName"] == "folder-open") {
itemData.insert("iconName", originalIconName);
setData(itemData);
invalidateIconCache();
}
});
m_activateSoonAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
KItemListWidgetInformant *KStandardItemListWidget::createInformant()
{
return new KStandardItemListWidgetInformant();
@ -736,7 +781,9 @@ void KStandardItemListWidget::styleOptionChanged(const KItemListStyleOption &cur
void KStandardItemListWidget::hoveredChanged(bool hovered)
{
Q_UNUSED(hovered)
if (!hovered && m_activateSoonAnimation) {
m_activateSoonAnimation->stop(); // automatically DeleteWhenStopped
}
m_dirtyLayout = true;
}

View File

@ -17,6 +17,7 @@
class KItemListRoleEditor;
class KItemListStyleOption;
class KItemListView;
class QVariantAnimation;
/**
* @brief standard implementation of the ItemList widget informant for use with KStandardItemListView and KStandardItemModel.
@ -103,6 +104,8 @@ public:
QRectF expansionToggleRect() const override;
QRectF selectionToggleRect() const override;
QPixmap createDragPixmap(const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;
/** @see KItemListWidget::startActivateSoonAnimation() */
void startActivateSoonAnimation(int timeUntilActivation) override;
static KItemListWidgetInformant *createInformant();
@ -282,6 +285,9 @@ private:
KItemListRoleEditor *m_roleEditor;
KItemListRoleEditor *m_oldRoleEditor;
/** @see startActivateSoonAnimation() */
QPointer<QVariantAnimation> m_activateSoonAnimation;
friend class KStandardItemListWidgetInformant; // Accesses private static methods to be able to
// share a common layout calculation
};