mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
feat: add cancel animation for drag to undock operation
https://github.com/linuxdeepin/internal-discussion/issues/663 Change-Id: I92daa3835fb6c5add9fcd5d1619e3a99d92d0b1f
This commit is contained in:
parent
3fbfabd340
commit
bc4608b858
Notes:
gerrit
2019-01-18 12:53:13 +08:00
Verified+1: <jenkins@deepin.com> Code-Review+2: listenerri <listenerri@gmail.com> Submitted-by: listenerri <listenerri@gmail.com> Submitted-at: Fri, 18 Jan 2019 12:53:13 +0800 Reviewed-on: https://cr.deepin.io/41378 Project: dde/dde-dock Branch: refs/heads/dev/animations
@ -163,18 +163,28 @@ void AppItem::undock()
|
||||
|
||||
QWidget *AppItem::appDragWidget()
|
||||
{
|
||||
return static_cast<AppDrag *>(m_drag)->appDragWidget();
|
||||
if (m_drag) {
|
||||
return m_drag->appDragWidget();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AppItem::setDockInfo(Dock::Position dockPosition, const QRect &dockGeometry)
|
||||
{
|
||||
static_cast<AppDrag *>(m_drag)->appDragWidget()->setDockInfo(dockPosition, dockGeometry);
|
||||
if (m_drag) {
|
||||
m_drag->appDragWidget()->setDockInfo(dockPosition, dockGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
void AppItem::moveEvent(QMoveEvent *e)
|
||||
{
|
||||
DockItem::moveEvent(e);
|
||||
|
||||
if (m_drag) {
|
||||
m_drag->appDragWidget()->setOriginPos(mapToGlobal(appIconPosition()));
|
||||
}
|
||||
|
||||
m_updateIconGeometryTimer->start();
|
||||
}
|
||||
|
||||
@ -278,16 +288,10 @@ void AppItem::paintEvent(QPaintEvent *e)
|
||||
return;
|
||||
|
||||
// icon
|
||||
const QPixmap &pixmap = m_appIcon;
|
||||
if (pixmap.isNull())
|
||||
if (m_appIcon.isNull())
|
||||
return;
|
||||
|
||||
// icon pos
|
||||
const auto ratio = qApp->devicePixelRatio();
|
||||
const int iconX = itemRect.center().x() - pixmap.rect().center().x() / ratio;
|
||||
const int iconY = itemRect.center().y() - pixmap.rect().center().y() / ratio;
|
||||
|
||||
painter.drawPixmap(iconX, iconY, pixmap);
|
||||
painter.drawPixmap(appIconPosition(), m_appIcon);
|
||||
}
|
||||
|
||||
void AppItem::mouseReleaseEvent(QMouseEvent *e)
|
||||
@ -468,8 +472,16 @@ void AppItem::startDrag()
|
||||
m_drag = new AppDrag(this);
|
||||
m_drag->setMimeData(new QMimeData);
|
||||
|
||||
// handle drag finished here
|
||||
connect(m_drag->appDragWidget(), &AppDragWidget::destroyed, this, [=] {
|
||||
m_dragging = false;
|
||||
setVisible(true);
|
||||
update();
|
||||
});
|
||||
|
||||
if (m_wmHelper->hasComposite()) {
|
||||
m_drag->setPixmap(dragPix);
|
||||
m_drag->appDragWidget()->setOriginPos(mapToGlobal(appIconPosition()));
|
||||
emit dragStarted();
|
||||
m_drag->exec(Qt::MoveAction);
|
||||
} else {
|
||||
@ -487,10 +499,6 @@ void AppItem::startDrag()
|
||||
m_itemEntryInter->RequestUndock();
|
||||
}
|
||||
}
|
||||
|
||||
m_dragging = false;
|
||||
setVisible(true);
|
||||
update();
|
||||
}
|
||||
|
||||
bool AppItem::hasAttention() const
|
||||
@ -501,6 +509,17 @@ bool AppItem::hasAttention() const
|
||||
return false;
|
||||
}
|
||||
|
||||
QPoint AppItem::appIconPosition() const
|
||||
{
|
||||
const auto ratio = qApp->devicePixelRatio();
|
||||
const QRectF itemRect = rect();
|
||||
const QRectF iconRect = m_appIcon.rect();
|
||||
const qreal iconX = itemRect.center().x() - iconRect.center().x() / ratio;
|
||||
const qreal iconY = itemRect.center().y() - iconRect.center().y() / ratio;
|
||||
|
||||
return QPoint(iconX, iconY);
|
||||
}
|
||||
|
||||
void AppItem::updateWindowInfos(const WindowInfoMap &info)
|
||||
{
|
||||
m_windowInfos = info;
|
||||
|
@ -86,6 +86,8 @@ private:
|
||||
void startDrag();
|
||||
bool hasAttention() const;
|
||||
|
||||
QPoint appIconPosition() const;
|
||||
|
||||
private slots:
|
||||
void updateWindowInfos(const WindowInfoMap &info);
|
||||
void refershIcon() Q_DECL_OVERRIDE;
|
||||
@ -106,7 +108,7 @@ private:
|
||||
|
||||
DWindowManagerHelper *m_wmHelper;
|
||||
|
||||
AppDrag *m_drag;
|
||||
QPointer<AppDrag> m_drag;
|
||||
|
||||
bool m_dragging;
|
||||
bool m_active;
|
||||
|
@ -25,9 +25,15 @@ AppDrag::AppDrag(QObject *dragSource) : QDrag(dragSource)
|
||||
{
|
||||
// delete by itself
|
||||
m_appDragWidget = new AppDragWidget;
|
||||
m_appDragWidget->setVisible(false);
|
||||
}
|
||||
|
||||
AppDrag::~AppDrag() { }
|
||||
AppDrag::~AppDrag() {
|
||||
// delete when AppDragWidget is invisible
|
||||
if (m_appDragWidget && !m_appDragWidget->isVisible()) {
|
||||
m_appDragWidget->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void AppDrag::setPixmap(const QPixmap &pix)
|
||||
{
|
||||
|
@ -40,13 +40,10 @@ public:
|
||||
Qt::DropAction exec(Qt::DropActions supportedActions = Qt::MoveAction);
|
||||
Qt::DropAction exec(Qt::DropActions supportedActions, Qt::DropAction defaultAction);
|
||||
|
||||
void setOpacity(qreal opacity);
|
||||
void showDropAnim();
|
||||
|
||||
AppDragWidget *appDragWidget();
|
||||
|
||||
private:
|
||||
AppDragWidget *m_appDragWidget;
|
||||
QPointer<AppDragWidget> m_appDragWidget;
|
||||
};
|
||||
|
||||
#endif /* DRAGAPP_H */
|
||||
|
@ -26,7 +26,7 @@
|
||||
class AppGraphicsObject : public QGraphicsObject
|
||||
{
|
||||
public:
|
||||
AppGraphicsObject(QGraphicsItem *parent = Q_NULLPTR) : QGraphicsObject(parent) {};
|
||||
AppGraphicsObject(QGraphicsItem *parent = Q_NULLPTR) : QGraphicsObject(parent) {}
|
||||
~AppGraphicsObject() { }
|
||||
|
||||
void setAppPixmap(QPixmap pix)
|
||||
@ -47,14 +47,14 @@ public:
|
||||
QRectF boundingRect() const Q_DECL_OVERRIDE
|
||||
{
|
||||
return m_appPixmap.rect();
|
||||
};
|
||||
}
|
||||
|
||||
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = Q_NULLPTR) Q_DECL_OVERRIDE
|
||||
{
|
||||
Q_ASSERT(!m_appPixmap.isNull());
|
||||
|
||||
painter->drawPixmap(QPoint(0, 0), m_appPixmap);
|
||||
};
|
||||
}
|
||||
|
||||
private:
|
||||
QPixmap m_appPixmap;
|
||||
@ -68,7 +68,8 @@ AppDragWidget::AppDragWidget(QWidget *parent) :
|
||||
m_animScale(new QPropertyAnimation(m_object, "scale", this)),
|
||||
m_animRotation(new QPropertyAnimation(m_object, "rotation", this)),
|
||||
m_animOpacity(new QPropertyAnimation(m_object, "opacity", this)),
|
||||
m_animGroup(new QParallelAnimationGroup(this))
|
||||
m_animGroup(new QParallelAnimationGroup(this)),
|
||||
m_goBackAnim(new QPropertyAnimation(this, "pos", this))
|
||||
{
|
||||
m_scene->addItem(m_object);
|
||||
setScene(m_scene);
|
||||
@ -92,20 +93,22 @@ AppDragWidget::AppDragWidget(QWidget *parent) :
|
||||
m_followMouseTimer->start();
|
||||
}
|
||||
|
||||
AppDragWidget::~AppDragWidget() { }
|
||||
AppDragWidget::~AppDragWidget() {
|
||||
}
|
||||
|
||||
void AppDragWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QGraphicsView::mouseMoveEvent(event);
|
||||
// hide widget when receiving mouseMoveEvent because this means drag-and-drop has been finished
|
||||
hide();
|
||||
if (m_goBackAnim->state() != QPropertyAnimation::State::Running
|
||||
&& m_animGroup->state() != QParallelAnimationGroup::Running) {
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void AppDragWidget::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
|
||||
m_dragStartPoint = event->pos();
|
||||
}
|
||||
|
||||
void AppDragWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||
@ -128,7 +131,7 @@ void AppDragWidget::dropEvent(QDropEvent *event)
|
||||
AppItem *appItem = static_cast<AppItem *>(event->source());
|
||||
appItem->undock();
|
||||
} else {
|
||||
hide();
|
||||
showGoBackAnimation();;
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,7 +142,7 @@ void AppDragWidget::hideEvent(QHideEvent *event)
|
||||
|
||||
void AppDragWidget::setAppPixmap(const QPixmap &pix)
|
||||
{
|
||||
setFixedSize(pix.size() + QSize(10,10));
|
||||
setFixedSize(pix.size());
|
||||
|
||||
m_object->setAppPixmap(pix);
|
||||
m_object->setTransformOriginPoint(pix.rect().center());
|
||||
@ -151,6 +154,11 @@ void AppDragWidget::setDockInfo(Dock::Position dockPosition, const QRect &dockGe
|
||||
m_dockGeometry = dockGeometry;
|
||||
}
|
||||
|
||||
void AppDragWidget::setOriginPos(const QPoint position)
|
||||
{
|
||||
m_originPoint = position;
|
||||
}
|
||||
|
||||
void AppDragWidget::initAnimations()
|
||||
{
|
||||
m_animScale->setDuration(300);
|
||||
@ -171,6 +179,7 @@ void AppDragWidget::initAnimations()
|
||||
|
||||
connect(m_animGroup, &QParallelAnimationGroup::stateChanged,
|
||||
this, &AppDragWidget::onRemoveAnimationStateChanged);
|
||||
connect(m_goBackAnim, &QPropertyAnimation::finished, this, &AppDragWidget::hide);
|
||||
}
|
||||
|
||||
void AppDragWidget::showRemoveAnimation()
|
||||
@ -182,6 +191,14 @@ void AppDragWidget::showRemoveAnimation()
|
||||
m_animGroup->start();
|
||||
}
|
||||
|
||||
void AppDragWidget::showGoBackAnimation()
|
||||
{
|
||||
m_goBackAnim->setDuration(300);
|
||||
m_goBackAnim->setStartValue(pos());
|
||||
m_goBackAnim->setEndValue(m_originPoint);
|
||||
m_goBackAnim->start();
|
||||
}
|
||||
|
||||
void AppDragWidget::onRemoveAnimationStateChanged(QAbstractAnimation::State newState,
|
||||
QAbstractAnimation::State oldState)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
|
||||
void setAppPixmap(const QPixmap &pix);
|
||||
void setDockInfo(Dock::Position dockPosition, const QRect &dockGeometry);
|
||||
void setOriginPos(const QPoint position);
|
||||
|
||||
protected:
|
||||
void mouseMoveEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||
@ -54,6 +55,7 @@ protected:
|
||||
private:
|
||||
void initAnimations();
|
||||
void showRemoveAnimation();
|
||||
void showGoBackAnimation();
|
||||
void onRemoveAnimationStateChanged(QAbstractAnimation::State newState,
|
||||
QAbstractAnimation::State oldState);
|
||||
bool isRemoveAble();
|
||||
@ -66,10 +68,11 @@ private:
|
||||
QPropertyAnimation *m_animRotation;
|
||||
QPropertyAnimation *m_animOpacity;
|
||||
QParallelAnimationGroup *m_animGroup;
|
||||
QPropertyAnimation *m_goBackAnim;
|
||||
|
||||
Dock::Position m_dockPosition;
|
||||
QRect m_dockGeometry;
|
||||
QPoint m_dragStartPoint;
|
||||
QPoint m_originPoint;
|
||||
};
|
||||
|
||||
#endif /* APPDRAGWIDGET_H */
|
||||
|
@ -312,8 +312,9 @@ void MainPanel::dragLeaveEvent(QDragLeaveEvent *e)
|
||||
|
||||
if (DraggingItem) {
|
||||
DockItem::ItemType type = DraggingItem->itemType();
|
||||
if (type != DockItem::Plugins && type != DockItem::TrayPlugin)
|
||||
if (type != DockItem::Plugins && type != DockItem::TrayPlugin) {
|
||||
DraggingItem->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user