diff --git a/frame/item/appitem.cpp b/frame/item/appitem.cpp index 4ed47c1f9..dd549d65b 100644 --- a/frame/item/appitem.cpp +++ b/frame/item/appitem.cpp @@ -163,18 +163,28 @@ void AppItem::undock() QWidget *AppItem::appDragWidget() { - return static_cast(m_drag)->appDragWidget(); + if (m_drag) { + return m_drag->appDragWidget(); + } + + return nullptr; } void AppItem::setDockInfo(Dock::Position dockPosition, const QRect &dockGeometry) { - static_cast(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; diff --git a/frame/item/appitem.h b/frame/item/appitem.h index 28881ea3d..5b7b8ce25 100644 --- a/frame/item/appitem.h +++ b/frame/item/appitem.h @@ -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 m_drag; bool m_dragging; bool m_active; diff --git a/frame/item/components/appdrag.cpp b/frame/item/components/appdrag.cpp index c5b8fd0c4..7ed9dfbf9 100644 --- a/frame/item/components/appdrag.cpp +++ b/frame/item/components/appdrag.cpp @@ -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) { diff --git a/frame/item/components/appdrag.h b/frame/item/components/appdrag.h index 68719962e..6858235d0 100644 --- a/frame/item/components/appdrag.h +++ b/frame/item/components/appdrag.h @@ -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 m_appDragWidget; }; #endif /* DRAGAPP_H */ diff --git a/frame/item/components/appdragwidget.cpp b/frame/item/components/appdragwidget.cpp index 99c2de44d..b042b657b 100644 --- a/frame/item/components/appdragwidget.cpp +++ b/frame/item/components/appdragwidget.cpp @@ -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(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) { diff --git a/frame/item/components/appdragwidget.h b/frame/item/components/appdragwidget.h index f5eb769f4..b4277dbae 100644 --- a/frame/item/components/appdragwidget.h +++ b/frame/item/components/appdragwidget.h @@ -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 */ diff --git a/frame/panel/mainpanel.cpp b/frame/panel/mainpanel.cpp index 5d03a4d27..03dfd7164 100644 --- a/frame/panel/mainpanel.cpp +++ b/frame/panel/mainpanel.cpp @@ -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(); + } } }