From 43f99c931cd3f353444afe35f07560d604c35ddb Mon Sep 17 00:00:00 2001 From: wangnengdeng Date: Fri, 24 Jul 2020 09:37:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BA=94=E7=94=A8=E5=8C=BA=E5=9F=9F?= =?UTF-8?q?=E7=A7=BB=E9=99=A4=E9=A9=BB=E7=95=99=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 鼠标拖动驻留应用图标出任务栏时显示提示:移除【类似tooltip效果】,鼠标拖动引用远离 任务栏超过1.5倍(倍数可配置)显示。1.5倍以内则不显示“移除”提示 Log: 当拖拽任务栏应用区上的应用远离任务栏一定距离可以移除的应用显示“移除”提示 Task: https://pms.uniontech.com/zentao/task-view-30900.html Change-Id: I7d339a6f3713dc6ab6932567bb1eecefaff1fa60 Reviewed-on: http://gerrit.uniontech.com/c/dde-dock/+/545 Reviewed-by: fanpengcheng Tested-by: yekaisheng --- frame/item/components/appdragwidget.cpp | 111 ++++++++++++++++-- frame/item/components/appdragwidget.h | 12 ++ .../com.deepin.dde.dock.module.gschema.xml | 11 ++ 3 files changed, 126 insertions(+), 8 deletions(-) diff --git a/frame/item/components/appdragwidget.cpp b/frame/item/components/appdragwidget.cpp index a56a94f53..91eb65df9 100644 --- a/frame/item/components/appdragwidget.cpp +++ b/frame/item/components/appdragwidget.cpp @@ -19,10 +19,11 @@ * along with this program. If not, see . */ -#include "appdragwidget.h" - #include "../appitem.h" +#include "appdragwidget.h" +#include +QPointer AppDragWidget::PopupWindow(nullptr); class AppGraphicsObject : public QGraphicsObject { public: @@ -68,8 +69,24 @@ AppDragWidget::AppDragWidget(QWidget *parent) : m_animRotation(new QPropertyAnimation(m_object, "rotation", this)), m_animOpacity(new QPropertyAnimation(m_object, "opacity", this)), m_animGroup(new QParallelAnimationGroup(this)), - m_goBackAnim(new QPropertyAnimation(this, "pos", this)) + m_goBackAnim(new QPropertyAnimation(this, "pos", this)), + m_removeTips(new TipsWidget(this)) { + m_removeTips->setText(tr("Remove")); + m_removeTips->setObjectName("AppRemoveTips"); + m_removeTips->setVisible(false); + m_removeTips->installEventFilter(this); + + DockPopupWindow *arrowRectangle = new DockPopupWindow(nullptr); + arrowRectangle->setShadowBlurRadius(20); + arrowRectangle->setRadius(18); + arrowRectangle->setShadowYOffset(2); + arrowRectangle->setShadowXOffset(0); + arrowRectangle->setArrowWidth(18); + arrowRectangle->setArrowHeight(10); + PopupWindow = arrowRectangle; + PopupWindow->setRadius(18); + m_scene->addItem(m_object); setScene(m_scene); @@ -84,6 +101,7 @@ AppDragWidget::AppDragWidget(QWidget *parent) : setAcceptDrops(true); initAnimations(); + initConfigurations(); m_followMouseTimer->setSingleShot(false); m_followMouseTimer->setInterval(1); @@ -115,15 +133,74 @@ void AppDragWidget::dragEnterEvent(QDragEnterEvent *event) void AppDragWidget::dragMoveEvent(QDragMoveEvent *event) { + bool model = true; + Dock::Position pos = Dock::Position::Bottom; + + DockPopupWindow *popup = PopupWindow.data(); if (isRemoveAble()) { + QWidget *lastContent = popup->getContent(); + if (lastContent) + lastContent->setVisible(false); + + switch (pos) { + case Top: popup->setArrowDirection(DockPopupWindow::ArrowTop); break; + case Bottom: popup->setArrowDirection(DockPopupWindow::ArrowBottom); break; + case Left: popup->setArrowDirection(DockPopupWindow::ArrowLeft); break; + case Right: popup->setArrowDirection(DockPopupWindow::ArrowRight); break; + } + popup->resize(m_removeTips->sizeHint()); + popup->setContent(m_removeTips); + + const QPoint p = popupMarkPoint(pos); + if (!popup->isVisible()) + QMetaObject::invokeMethod(popup, "show", Qt::QueuedConnection, Q_ARG(QPoint, p), Q_ARG(bool, model)); + else + popup->show(p, model); + m_object->setOpacity(0.5); m_animOpacity->setStartValue(0.5); } else { m_object->setOpacity(1.0); m_animOpacity->setStartValue(1.0); + if (popup->isVisible()) + popup->setVisible(false); } } +const QPoint AppDragWidget::topleftPoint() const +{ + QPoint p; + const QWidget *w = this; + do { + p += w->pos(); + w = qobject_cast(w->parent()); + } while (w); + + return p; +} + +const QPoint AppDragWidget::popupMarkPoint(Dock::Position pos) +{ + QPoint p(topleftPoint()); + + const QRect r = rect(); + switch (pos) { + case Top: + p += QPoint(r.width() / 2, r.height()); + break; + case Bottom: + p += QPoint(r.width() / 2, 0); + break; + case Left: + p += QPoint(r.width(), r.height() / 2); + break; + case Right: + p += QPoint(0, r.height() / 2); + break; + } + return p; +} + void AppDragWidget::dropEvent(QDropEvent *event) { m_followMouseTimer->stop(); @@ -132,8 +209,9 @@ void AppDragWidget::dropEvent(QDropEvent *event) showRemoveAnimation(); AppItem *appItem = static_cast(event->source()); appItem->undock(); + PopupWindow->setVisible(false); } else { - showGoBackAnimation();; + showGoBackAnimation(); } } @@ -185,6 +263,23 @@ void AppDragWidget::initAnimations() connect(m_goBackAnim, &QPropertyAnimation::finished, this, &AppDragWidget::hide); } +void AppDragWidget::initConfigurations() +{ + const QString &cschema = "com.deepin.dde.dock.distancemultiple"; + const QString &cpath = "/com/deepin/dde/dock/distancemultiple/"; + + const QByteArray &schema_id { + cschema.toUtf8() + }; + + const QByteArray &path_id { + cpath.toUtf8() + }; + + QGSettings gsetting(schema_id, path_id); + m_distanceMultiple = gsetting.get("distance-multiple").toDouble(); +} + void AppDragWidget::showRemoveAnimation() { if (m_animGroup->state() == QParallelAnimationGroup::Running) { @@ -214,22 +309,22 @@ bool AppDragWidget::isRemoveAble() const QPoint &p = QCursor::pos(); switch (m_dockPosition) { case Dock::Position::Left: - if ((p.x() - m_dockGeometry.topRight().x()) > (m_dockGeometry.width() * 3)) { + if ((p.x() - m_dockGeometry.topRight().x()) > (m_dockGeometry.width() * m_distanceMultiple)) { return true; } break; case Dock::Position::Top: - if ((p.y() - m_dockGeometry.bottomLeft().y()) > (m_dockGeometry.height() * 3)) { + if ((p.y() - m_dockGeometry.bottomLeft().y()) > (m_dockGeometry.height() * m_distanceMultiple)) { return true; } break; case Dock::Position::Right: - if ((m_dockGeometry.topLeft().x() - p.x()) > (m_dockGeometry.width() * 3)) { + if ((m_dockGeometry.topLeft().x() - p.x()) > (m_dockGeometry.width() * m_distanceMultiple)) { return true; } break; case Dock::Position::Bottom: - if ((m_dockGeometry.topLeft().y() - p.y()) > (m_dockGeometry.height() * 3)) { + if ((m_dockGeometry.topLeft().y() - p.y()) > (m_dockGeometry.height() * m_distanceMultiple)) { return true; } break; diff --git a/frame/item/components/appdragwidget.h b/frame/item/components/appdragwidget.h index a2bfccc07..52f616bb0 100644 --- a/frame/item/components/appdragwidget.h +++ b/frame/item/components/appdragwidget.h @@ -33,6 +33,8 @@ #include #include #include +#include "../widgets/tipswidget.h" +#include "util/dockpopupwindow.h" class AppGraphicsObject; class AppDragWidget : public QGraphicsView @@ -55,10 +57,13 @@ protected: private: void initAnimations(); + void initConfigurations(); void showRemoveAnimation(); void showGoBackAnimation(); void onRemoveAnimationStateChanged(QAbstractAnimation::State newState, QAbstractAnimation::State oldState); + const QPoint popupMarkPoint(Dock::Position pos); + const QPoint topleftPoint() const; private: AppGraphicsObject *m_object; @@ -73,6 +78,13 @@ private: Dock::Position m_dockPosition; QRect m_dockGeometry; QPoint m_originPoint; + Dock::TipsWidget * m_removeTips; + static QPointer PopupWindow; + /** + * @brief m_distanceMultiple: 倍数 + * dock栏上应用区驻留应用被拖拽远离dock的距离除以dock的宽或者高(更小的一个)的比值 + */ + double m_distanceMultiple; }; #endif /* APPDRAGWIDGET_H */ diff --git a/gschema/com.deepin.dde.dock.module.gschema.xml b/gschema/com.deepin.dde.dock.module.gschema.xml index 1107352a3..21cdb85d2 100644 --- a/gschema/com.deepin.dde.dock.module.gschema.xml +++ b/gschema/com.deepin.dde.dock.module.gschema.xml @@ -23,6 +23,17 @@ dock disable loading plugins + + + 1.5 + + the distance multiple factor between the dragged resident app and the dock + + + The distance away from the dock of the drag resident application divided by the width or height of the dock (the smaller one) + + + false