mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 17:33:05 +00:00
refactor: app item swing animation
Change-Id: Ia794194e56781c63eb7516b3c1fd389de17ccab8
This commit is contained in:
parent
052b6b29d2
commit
16f20ae454
Notes:
gerrit
2018-07-05 13:28:26 +08:00
Verified+1: <jenkins@deepin.com> Code-Review+2: hualet <mr.asianwang@gmail.com> Submitted-by: listenerri <listenerri@gmail.com> Submitted-at: Thu, 05 Jul 2018 13:28:26 +0800 Reviewed-on: https://cr.deepin.io/36366 Project: dde/dde-dock Branch: refs/heads/master
@ -24,6 +24,7 @@
|
|||||||
#include "util/themeappicon.h"
|
#include "util/themeappicon.h"
|
||||||
#include "util/imagefactory.h"
|
#include "util/imagefactory.h"
|
||||||
#include "xcb/xcb_misc.h"
|
#include "xcb/xcb_misc.h"
|
||||||
|
#include "components/appswingeffectbuilder.h"
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
@ -39,67 +40,6 @@
|
|||||||
|
|
||||||
#define APP_DRAG_THRESHOLD 20
|
#define APP_DRAG_THRESHOLD 20
|
||||||
|
|
||||||
const static qreal Frames[] = { 0,
|
|
||||||
0.327013,
|
|
||||||
0.987033,
|
|
||||||
1.77584,
|
|
||||||
2.61157,
|
|
||||||
3.45043,
|
|
||||||
4.26461,
|
|
||||||
5.03411,
|
|
||||||
5.74306,
|
|
||||||
6.37782,
|
|
||||||
6.92583,
|
|
||||||
7.37484,
|
|
||||||
7.71245,
|
|
||||||
7.92557,
|
|
||||||
8, 7.86164,
|
|
||||||
7.43184,
|
|
||||||
6.69344,
|
|
||||||
5.64142,
|
|
||||||
4.2916,
|
|
||||||
2.68986,
|
|
||||||
0.91694,
|
|
||||||
-0.91694,
|
|
||||||
-2.68986,
|
|
||||||
-4.2916,
|
|
||||||
-5.64142,
|
|
||||||
-6.69344,
|
|
||||||
-7.43184,
|
|
||||||
-7.86164,
|
|
||||||
-8,
|
|
||||||
-7.86164,
|
|
||||||
-7.43184,
|
|
||||||
-6.69344,
|
|
||||||
-5.64142,
|
|
||||||
-4.2916,
|
|
||||||
-2.68986,
|
|
||||||
-0.91694,
|
|
||||||
0.91694,
|
|
||||||
2.68986,
|
|
||||||
4.2916,
|
|
||||||
5.64142,
|
|
||||||
6.69344,
|
|
||||||
7.43184,
|
|
||||||
7.86164,
|
|
||||||
8,
|
|
||||||
7.93082,
|
|
||||||
7.71592,
|
|
||||||
7.34672,
|
|
||||||
6.82071,
|
|
||||||
6.1458,
|
|
||||||
5.34493,
|
|
||||||
4.45847,
|
|
||||||
3.54153,
|
|
||||||
2.65507,
|
|
||||||
1.8542,
|
|
||||||
1.17929,
|
|
||||||
0.653279,
|
|
||||||
0.28408,
|
|
||||||
0.0691776,
|
|
||||||
0,
|
|
||||||
};
|
|
||||||
|
|
||||||
int AppItem::IconBaseSize;
|
int AppItem::IconBaseSize;
|
||||||
QPoint AppItem::MousePressPos;
|
QPoint AppItem::MousePressPos;
|
||||||
|
|
||||||
@ -109,8 +49,8 @@ AppItem::AppItem(const QDBusObjectPath &entry, QWidget *parent)
|
|||||||
m_appPreviewTips(new PreviewContainer(this)),
|
m_appPreviewTips(new PreviewContainer(this)),
|
||||||
m_itemEntryInter(new DockEntryInter("com.deepin.dde.daemon.Dock", entry.path(), QDBusConnection::sessionBus(), this)),
|
m_itemEntryInter(new DockEntryInter("com.deepin.dde.daemon.Dock", entry.path(), QDBusConnection::sessionBus(), this)),
|
||||||
|
|
||||||
m_swingEffectView(new QGraphicsView(this)),
|
m_swingEffectView(nullptr),
|
||||||
m_itemScene(new QGraphicsScene(this)),
|
m_itemAnimation(nullptr),
|
||||||
|
|
||||||
m_dragging(false),
|
m_dragging(false),
|
||||||
|
|
||||||
@ -125,10 +65,7 @@ AppItem::AppItem(const QDBusObjectPath &entry, QWidget *parent)
|
|||||||
m_smallWatcher(new QFutureWatcher<QPixmap>(this)),
|
m_smallWatcher(new QFutureWatcher<QPixmap>(this)),
|
||||||
m_largeWatcher(new QFutureWatcher<QPixmap>(this))
|
m_largeWatcher(new QFutureWatcher<QPixmap>(this))
|
||||||
{
|
{
|
||||||
m_swingEffectView->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
|
|
||||||
QHBoxLayout *centralLayout = new QHBoxLayout;
|
QHBoxLayout *centralLayout = new QHBoxLayout;
|
||||||
centralLayout->addWidget(m_swingEffectView);
|
|
||||||
centralLayout->setMargin(0);
|
centralLayout->setMargin(0);
|
||||||
centralLayout->setSpacing(0);
|
centralLayout->setSpacing(0);
|
||||||
|
|
||||||
@ -136,16 +73,6 @@ AppItem::AppItem(const QDBusObjectPath &entry, QWidget *parent)
|
|||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
setLayout(centralLayout);
|
setLayout(centralLayout);
|
||||||
|
|
||||||
m_swingEffectView->setScene(m_itemScene);
|
|
||||||
m_swingEffectView->setAlignment(Qt::AlignCenter);
|
|
||||||
m_swingEffectView->setVisible(false);
|
|
||||||
m_swingEffectView->setFrameStyle(QFrame::NoFrame);
|
|
||||||
m_swingEffectView->setContentsMargins(0, 0, 0, 0);
|
|
||||||
m_swingEffectView->setRenderHints(QPainter::SmoothPixmapTransform);
|
|
||||||
m_swingEffectView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
|
|
||||||
m_swingEffectView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
m_swingEffectView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
|
||||||
|
|
||||||
m_id = m_itemEntryInter->id();
|
m_id = m_itemEntryInter->id();
|
||||||
m_active = m_itemEntryInter->isActive();
|
m_active = m_itemEntryInter->isActive();
|
||||||
|
|
||||||
@ -238,7 +165,7 @@ void AppItem::paintEvent(QPaintEvent *e)
|
|||||||
{
|
{
|
||||||
DockItem::paintEvent(e);
|
DockItem::paintEvent(e);
|
||||||
|
|
||||||
if (m_dragging || (m_swingEffectView->isVisible() && DockDisplayMode != Fashion))
|
if (m_dragging || (m_swingEffectView != nullptr && DockDisplayMode != Fashion))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
@ -322,7 +249,7 @@ void AppItem::paintEvent(QPaintEvent *e)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_swingEffectView->isVisible())
|
if (m_swingEffectView != nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// icon
|
// icon
|
||||||
@ -602,62 +529,42 @@ void AppItem::cancelAndHidePreview()
|
|||||||
void AppItem::playSwingEffect()
|
void AppItem::playSwingEffect()
|
||||||
{
|
{
|
||||||
// NOTE(sbw): return if animation view already playing
|
// NOTE(sbw): return if animation view already playing
|
||||||
if (m_swingEffectView->isVisible())
|
if (m_swingEffectView != nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stopSwingEffect();
|
stopSwingEffect();
|
||||||
if (!m_itemAnimation.timeLine())
|
|
||||||
{
|
|
||||||
QTimeLine *tl = new QTimeLine(1200, this);
|
|
||||||
tl->setFrameRange(0, 60);
|
|
||||||
tl->setLoopCount(1);
|
|
||||||
tl->setEasingCurve(QEasingCurve::Linear);
|
|
||||||
tl->setStartFrame(0);
|
|
||||||
|
|
||||||
m_itemAnimation.setTimeLine(tl);
|
QPair<QGraphicsView *, QGraphicsItemAnimation *> pair = SwingEffect(
|
||||||
}
|
this, m_appIcon, rect(), qApp->devicePixelRatio());
|
||||||
|
|
||||||
const auto ratio = qApp->devicePixelRatio();
|
m_swingEffectView = pair.first;
|
||||||
const QRect r = rect();
|
m_itemAnimation = pair.second;
|
||||||
const QPixmap &icon = m_appIcon;
|
|
||||||
|
|
||||||
QGraphicsPixmapItem *item = m_itemScene->addPixmap(icon);
|
QTimeLine *tl = m_itemAnimation->timeLine();
|
||||||
item->setTransformationMode(Qt::SmoothTransformation);
|
connect(tl, &QTimeLine::stateChanged, [=](QTimeLine::State newState) {
|
||||||
item->setPos(QPointF(r.center()) - QPointF(icon.rect().center()) / ratio);
|
if (newState == QTimeLine::NotRunning) {
|
||||||
|
m_swingEffectView->hide();
|
||||||
m_itemAnimation.setItem(item);
|
layout()->removeWidget(m_swingEffectView);
|
||||||
m_itemScene->setSceneRect(r);
|
m_swingEffectView = nullptr;
|
||||||
m_swingEffectView->setSceneRect(r);
|
m_itemAnimation = nullptr;
|
||||||
m_swingEffectView->setFixedSize(r.size());
|
checkAttentionEffect();
|
||||||
|
}
|
||||||
const int px = qreal(-icon.rect().center().x()) / ratio;
|
});
|
||||||
const int py = qreal(-icon.rect().center().y()) / ratio - 18.;
|
|
||||||
const QPoint pos = r.center() + QPoint(0, 18);
|
|
||||||
for (int i(0); i != 60; ++i)
|
|
||||||
{
|
|
||||||
m_itemAnimation.setPosAt(i / 60.0, pos);
|
|
||||||
m_itemAnimation.setTranslationAt(i / 60.0, px, py);
|
|
||||||
m_itemAnimation.setRotationAt(i / 60.0, Frames[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTimeLine *tl = m_itemAnimation.timeLine();
|
|
||||||
connect(tl, &QTimeLine::finished, m_swingEffectView, &QGraphicsView::hide);
|
|
||||||
connect(tl, &QTimeLine::finished, this, &AppItem::checkAttentionEffect);
|
|
||||||
|
|
||||||
|
layout()->addWidget(m_swingEffectView);
|
||||||
tl->start();
|
tl->start();
|
||||||
m_swingEffectView->setVisible(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppItem::stopSwingEffect()
|
void AppItem::stopSwingEffect()
|
||||||
{
|
{
|
||||||
|
if (m_swingEffectView == nullptr || m_itemAnimation == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
// stop swing effect
|
// stop swing effect
|
||||||
m_swingEffectView->setVisible(false);
|
m_swingEffectView->setVisible(false);
|
||||||
|
|
||||||
if (m_itemAnimation.timeLine() && m_itemAnimation.timeLine()->state() != QTimeLine::NotRunning)
|
if (m_itemAnimation->timeLine() && m_itemAnimation->timeLine()->state() != QTimeLine::NotRunning)
|
||||||
m_itemAnimation.timeLine()->stop();
|
m_itemAnimation->timeLine()->stop();
|
||||||
m_itemAnimation.clear();
|
|
||||||
if (!m_itemScene->items().isEmpty())
|
|
||||||
m_itemScene->clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppItem::checkAttentionEffect()
|
void AppItem::checkAttentionEffect()
|
||||||
|
@ -95,8 +95,7 @@ private:
|
|||||||
DockEntryInter *m_itemEntryInter;
|
DockEntryInter *m_itemEntryInter;
|
||||||
|
|
||||||
QGraphicsView *m_swingEffectView;
|
QGraphicsView *m_swingEffectView;
|
||||||
QGraphicsScene *m_itemScene;
|
QGraphicsItemAnimation *m_itemAnimation;
|
||||||
QGraphicsItemAnimation m_itemAnimation;
|
|
||||||
|
|
||||||
bool m_dragging;
|
bool m_dragging;
|
||||||
bool m_active;
|
bool m_active;
|
||||||
|
129
frame/item/components/appswingeffectbuilder.h
Normal file
129
frame/item/components/appswingeffectbuilder.h
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
#ifndef SWINGEFFECT
|
||||||
|
#define SWINGEFFECT
|
||||||
|
|
||||||
|
#include <QGraphicsView>
|
||||||
|
#include <QGraphicsItemAnimation>
|
||||||
|
#include <QGraphicsPixmapItem>
|
||||||
|
#include <QTimeLine>
|
||||||
|
|
||||||
|
const static qreal Frames[] = { 0,
|
||||||
|
0.327013,
|
||||||
|
0.987033,
|
||||||
|
1.77584,
|
||||||
|
2.61157,
|
||||||
|
3.45043,
|
||||||
|
4.26461,
|
||||||
|
5.03411,
|
||||||
|
5.74306,
|
||||||
|
6.37782,
|
||||||
|
6.92583,
|
||||||
|
7.37484,
|
||||||
|
7.71245,
|
||||||
|
7.92557,
|
||||||
|
8, 7.86164,
|
||||||
|
7.43184,
|
||||||
|
6.69344,
|
||||||
|
5.64142,
|
||||||
|
4.2916,
|
||||||
|
2.68986,
|
||||||
|
0.91694,
|
||||||
|
-0.91694,
|
||||||
|
-2.68986,
|
||||||
|
-4.2916,
|
||||||
|
-5.64142,
|
||||||
|
-6.69344,
|
||||||
|
-7.43184,
|
||||||
|
-7.86164,
|
||||||
|
-8,
|
||||||
|
-7.86164,
|
||||||
|
-7.43184,
|
||||||
|
-6.69344,
|
||||||
|
-5.64142,
|
||||||
|
-4.2916,
|
||||||
|
-2.68986,
|
||||||
|
-0.91694,
|
||||||
|
0.91694,
|
||||||
|
2.68986,
|
||||||
|
4.2916,
|
||||||
|
5.64142,
|
||||||
|
6.69344,
|
||||||
|
7.43184,
|
||||||
|
7.86164,
|
||||||
|
8,
|
||||||
|
7.93082,
|
||||||
|
7.71592,
|
||||||
|
7.34672,
|
||||||
|
6.82071,
|
||||||
|
6.1458,
|
||||||
|
5.34493,
|
||||||
|
4.45847,
|
||||||
|
3.54153,
|
||||||
|
2.65507,
|
||||||
|
1.8542,
|
||||||
|
1.17929,
|
||||||
|
0.653279,
|
||||||
|
0.28408,
|
||||||
|
0.0691776,
|
||||||
|
0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static QPair<QGraphicsView *, QGraphicsItemAnimation *> SwingEffect(
|
||||||
|
QWidget *parent, const QPixmap &icon, const QRect & rect, const qreal devicePixelRatio)
|
||||||
|
{
|
||||||
|
QGraphicsView *swingEffectView = new QGraphicsView(parent);
|
||||||
|
QGraphicsScene *itemScene = new QGraphicsScene(parent);
|
||||||
|
QGraphicsItemAnimation *itemAnimation = new QGraphicsItemAnimation(parent);
|
||||||
|
|
||||||
|
swingEffectView->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
swingEffectView->setScene(itemScene);
|
||||||
|
swingEffectView->setAlignment(Qt::AlignCenter);
|
||||||
|
swingEffectView->setFrameStyle(QFrame::NoFrame);
|
||||||
|
swingEffectView->setContentsMargins(0, 0, 0, 0);
|
||||||
|
swingEffectView->setRenderHints(QPainter::SmoothPixmapTransform);
|
||||||
|
swingEffectView->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
|
||||||
|
swingEffectView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
swingEffectView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||||
|
|
||||||
|
QTimeLine *tl = itemAnimation->timeLine();
|
||||||
|
if (!tl)
|
||||||
|
{
|
||||||
|
tl = new QTimeLine(1200, parent);
|
||||||
|
tl->setFrameRange(0, 60);
|
||||||
|
tl->setLoopCount(1);
|
||||||
|
tl->setEasingCurve(QEasingCurve::Linear);
|
||||||
|
tl->setStartFrame(0);
|
||||||
|
|
||||||
|
itemAnimation->setTimeLine(tl);
|
||||||
|
}
|
||||||
|
|
||||||
|
QGraphicsPixmapItem *item = itemScene->addPixmap(icon);
|
||||||
|
item->setTransformationMode(Qt::SmoothTransformation);
|
||||||
|
item->setPos(QPointF(rect.center()) - QPointF(icon.rect().center()) / devicePixelRatio);
|
||||||
|
|
||||||
|
itemAnimation->setItem(item);
|
||||||
|
itemScene->setSceneRect(rect);
|
||||||
|
swingEffectView->setSceneRect(rect);
|
||||||
|
swingEffectView->setFixedSize(rect.size());
|
||||||
|
|
||||||
|
const int px = qreal(-icon.rect().center().x()) / devicePixelRatio;
|
||||||
|
const int py = qreal(-icon.rect().center().y()) / devicePixelRatio - 18.;
|
||||||
|
const QPoint pos = rect.center() + QPoint(0, 18);
|
||||||
|
for (int i(0); i != 60; ++i)
|
||||||
|
{
|
||||||
|
itemAnimation->setPosAt(i / 60.0, pos);
|
||||||
|
itemAnimation->setTranslationAt(i / 60.0, px, py);
|
||||||
|
itemAnimation->setRotationAt(i / 60.0, Frames[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(tl, &QTimeLine::stateChanged, [=](QTimeLine::State newState) {
|
||||||
|
if (newState == QTimeLine::NotRunning) {
|
||||||
|
itemScene->deleteLater();
|
||||||
|
swingEffectView->deleteLater();
|
||||||
|
itemAnimation->deleteLater();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return QPair<QGraphicsView *, QGraphicsItemAnimation *>(swingEffectView, itemAnimation);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ifndef SWINGEFFECT */
|
Loading…
x
Reference in New Issue
Block a user