From 07bf5bd4dfe7a500bd6fd8d209cafb0276b2ecbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=9F=B3=E5=8D=9A=E6=96=87?= Date: Mon, 18 Jul 2016 17:10:15 +0800 Subject: [PATCH] support drag from launcher Change-Id: I95d4ab25cc2fafecda17d230f8015d57583a513a --- frame/controller/dockitemcontroller.cpp | 29 +++++++-- frame/controller/dockitemcontroller.h | 8 ++- frame/dbus/dbusdock.h | 16 +++++ frame/frame.pro | 10 ++-- frame/item/appitem.cpp | 6 ++ frame/item/dockitem.h | 2 +- frame/item/placeholderitem.cpp | 9 +-- frame/item/placeholderitem.h | 3 - frame/item/stretchitem.cpp | 14 +++++ frame/item/stretchitem.h | 17 ++++++ frame/panel/mainpanel.cpp | 78 +++++++++++++++++++++---- frame/panel/mainpanel.h | 1 + frame/window/mainwindow.cpp | 19 ++++-- 13 files changed, 172 insertions(+), 40 deletions(-) create mode 100644 frame/item/stretchitem.cpp create mode 100644 frame/item/stretchitem.h diff --git a/frame/controller/dockitemcontroller.cpp b/frame/controller/dockitemcontroller.cpp index e84953064..1ac17916f 100644 --- a/frame/controller/dockitemcontroller.cpp +++ b/frame/controller/dockitemcontroller.cpp @@ -1,7 +1,7 @@ #include "dockitemcontroller.h" #include "dbus/dbusdockentry.h" #include "item/appitem.h" -#include "item/placeholderitem.h" +#include "item/stretchitem.h" #include "item/launcheritem.h" #include "item/pluginsitem.h" @@ -36,7 +36,7 @@ void DockItemController::itemMove(DockItem * const moveItem, DockItem * const re // app move if (moveType == DockItem::App) - if (replaceType != DockItem::App && replaceType != DockItem::Placeholder) + if (replaceType != DockItem::App && replaceType != DockItem::Stretch) return; // plugins move @@ -45,7 +45,7 @@ void DockItemController::itemMove(DockItem * const moveItem, DockItem * const re return; const int moveIndex = m_itemList.indexOf(moveItem); - const int replaceIndex = replaceItem->itemType() == DockItem::Placeholder ? + const int replaceIndex = replaceItem->itemType() == DockItem::Stretch ? // disable insert after placeholder item m_itemList.indexOf(replaceItem) - 1 : m_itemList.indexOf(replaceItem); @@ -59,11 +59,32 @@ void DockItemController::itemMove(DockItem * const moveItem, DockItem * const re m_appInter->MoveEntry(moveIndex - 1, replaceIndex - 1); } +void DockItemController::placeholderItemAdded(PlaceholderItem *item, DockItem *position) +{ + const int pos = m_itemList.indexOf(position); + + m_itemList.insert(pos, item); + + emit itemInserted(pos, item); +} + +void DockItemController::placeholderItemDocked(const QString &appDesktop, DockItem *position) +{ + m_appInter->RequestDock(appDesktop, m_itemList.indexOf(position) - 1).waitForFinished(); +} + +void DockItemController::placeholderItemRemoved(PlaceholderItem *item) +{ + emit itemRemoved(item); + + m_itemList.removeOne(item); +} + DockItemController::DockItemController(QObject *parent) : QObject(parent), m_appInter(new DBusDock(this)), m_pluginsInter(new DockPluginsController(this)), - m_placeholderItem(new PlaceholderItem) + m_placeholderItem(new StretchItem) { // m_placeholderItem->hide(); diff --git a/frame/controller/dockitemcontroller.h b/frame/controller/dockitemcontroller.h index 4e06bc0b5..107c2a718 100644 --- a/frame/controller/dockitemcontroller.h +++ b/frame/controller/dockitemcontroller.h @@ -5,8 +5,9 @@ #include "pluginsiteminterface.h" #include "dbus/dbusdock.h" #include "item/dockitem.h" -#include "item/placeholderitem.h" +#include "item/stretchitem.h" #include "item/appitem.h" +#include "item/placeholderitem.h" #include @@ -27,6 +28,9 @@ signals: public slots: void itemMove(DockItem * const moveItem, DockItem * const replaceItem); + void placeholderItemAdded(PlaceholderItem *item, DockItem *position); + void placeholderItemDocked(const QString &appDesktop, DockItem *position); + void placeholderItemRemoved(PlaceholderItem *item); private: explicit DockItemController(QObject *parent = 0); @@ -42,7 +46,7 @@ private: DBusDock *m_appInter; DockPluginsController *m_pluginsInter; - PlaceholderItem *m_placeholderItem; + StretchItem *m_placeholderItem; static DockItemController *INSTANCE; }; diff --git a/frame/dbus/dbusdock.h b/frame/dbus/dbusdock.h index fdbe113dd..56d5bec64 100644 --- a/frame/dbus/dbusdock.h +++ b/frame/dbus/dbusdock.h @@ -120,6 +120,22 @@ public Q_SLOTS: // METHODS return asyncCallWithArgumentList(QStringLiteral("MoveEntry"), args); } + inline QDBusPendingReply RequestDock(const QString &appDesktop, const int index = -1) + { + QList args; + args << appDesktop << index; + + return asyncCallWithArgumentList(QStringLiteral("RequestDock"), args); + } + + inline QDBusPendingReply RequestUndock(const QString &appDesktop) + { + QList args; + args << appDesktop; + + return asyncCallWithArgumentList(QStringLiteral("RequestDock"), args); + } + inline QDBusPendingReply<> SetFrontendWindowRect(const int x, const int y, const quint32 width, const quint32 height) { QList argumentList; diff --git a/frame/frame.pro b/frame/frame.pro index 1d6dbcbc6..25bf5be0e 100644 --- a/frame/frame.pro +++ b/frame/frame.pro @@ -20,7 +20,6 @@ SOURCES += main.cpp \ dbus/dbusdisplay.cpp \ item/appitem.cpp \ util/docksettings.cpp \ - item/placeholderitem.cpp \ dbus/dbusclientmanager.cpp \ dbus/dbusdock.cpp \ util/themeappicon.cpp \ @@ -31,7 +30,9 @@ SOURCES += main.cpp \ controller/dockpluginscontroller.cpp \ util/imagefactory.cpp \ util/dockpopupwindow.cpp \ - dbus/dbusxmousearea.cpp + dbus/dbusxmousearea.cpp \ + item/stretchitem.cpp \ + item/placeholderitem.cpp HEADERS += \ window/mainwindow.h \ @@ -43,7 +44,6 @@ HEADERS += \ dbus/dbusdisplay.h \ item/appitem.h \ util/docksettings.h \ - item/placeholderitem.h \ dbus/dbusclientmanager.h \ dbus/dbusdock.h \ util/themeappicon.h \ @@ -54,7 +54,9 @@ HEADERS += \ controller/dockpluginscontroller.h \ util/imagefactory.h \ util/dockpopupwindow.h \ - dbus/dbusxmousearea.h + dbus/dbusxmousearea.h \ + item/stretchitem.h \ + item/placeholderitem.h dbus_service.files += com.deepin.dde.dock.service dbus_service.path = /usr/share/dbus-1/services diff --git a/frame/item/appitem.cpp b/frame/item/appitem.cpp index f3b2fa8c6..bac4c806d 100644 --- a/frame/item/appitem.cpp +++ b/frame/item/appitem.cpp @@ -257,6 +257,10 @@ void AppItem::dragEnterEvent(QDragEnterEvent *e) if (e->source()) return; + // ignore request dock event + if (e->mimeData()->formats().contains("RequestDock")) + return e->ignore(); + e->accept(); } @@ -286,6 +290,8 @@ QWidget *AppItem::popupTips() { if (m_titles.isEmpty()) return nullptr; + if (m_draging) + return nullptr; const quint32 currentWindow = m_itemEntry->currentWindow(); Q_ASSERT(m_titles.contains(currentWindow)); diff --git a/frame/item/dockitem.h b/frame/item/dockitem.h index 644a13ce8..0bb300215 100644 --- a/frame/item/dockitem.h +++ b/frame/item/dockitem.h @@ -19,7 +19,7 @@ public: enum ItemType { Launcher, App, - Placeholder, + Stretch, Plugins, }; diff --git a/frame/item/placeholderitem.cpp b/frame/item/placeholderitem.cpp index d37f886c9..e8ba50496 100644 --- a/frame/item/placeholderitem.cpp +++ b/frame/item/placeholderitem.cpp @@ -1,14 +1,7 @@ #include "placeholderitem.h" -#include - PlaceholderItem::PlaceholderItem(QWidget *parent) - : DockItem(Placeholder, parent) + : DockItem(App, parent) { - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); -} -void PlaceholderItem::mousePressEvent(QMouseEvent *e) -{ - QWidget::mousePressEvent(e); } diff --git a/frame/item/placeholderitem.h b/frame/item/placeholderitem.h index 8573e5b32..ada516ceb 100644 --- a/frame/item/placeholderitem.h +++ b/frame/item/placeholderitem.h @@ -9,9 +9,6 @@ class PlaceholderItem : public DockItem public: explicit PlaceholderItem(QWidget *parent = 0); - -private: - void mousePressEvent(QMouseEvent *e); }; #endif // PLACEHOLDERITEM_H diff --git a/frame/item/stretchitem.cpp b/frame/item/stretchitem.cpp new file mode 100644 index 000000000..e902d60c7 --- /dev/null +++ b/frame/item/stretchitem.cpp @@ -0,0 +1,14 @@ +#include "stretchitem.h" + +#include + +StretchItem::StretchItem(QWidget *parent) + : DockItem(Stretch, parent) +{ + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); +} + +void StretchItem::mousePressEvent(QMouseEvent *e) +{ + QWidget::mousePressEvent(e); +} diff --git a/frame/item/stretchitem.h b/frame/item/stretchitem.h new file mode 100644 index 000000000..788570be7 --- /dev/null +++ b/frame/item/stretchitem.h @@ -0,0 +1,17 @@ +#ifndef STRETCHITEM_H +#define STRETCHITEM_H + +#include "dockitem.h" + +class StretchItem : public DockItem +{ + Q_OBJECT + +public: + explicit StretchItem(QWidget *parent = 0); + +private: + void mousePressEvent(QMouseEvent *e); +}; + +#endif // STRETCHITEM_H diff --git a/frame/panel/mainpanel.cpp b/frame/panel/mainpanel.cpp index 8d442296b..74618ebca 100644 --- a/frame/panel/mainpanel.cpp +++ b/frame/panel/mainpanel.cpp @@ -5,6 +5,9 @@ #include DockItem *MainPanel::DragingItem = nullptr; +PlaceholderItem *MainPanel::RequestDockItem = nullptr; + +const char *RequestDockKey = "RequestDock"; MainPanel::MainPanel(QWidget *parent) : QFrame(parent), @@ -61,7 +64,7 @@ MainPanel::MainPanel(QWidget *parent) "border-left:none;" "}"); - connect(m_itemController, &DockItemController::itemInserted, this, &MainPanel::itemInserted); + connect(m_itemController, &DockItemController::itemInserted, this, &MainPanel::itemInserted, Qt::DirectConnection); connect(m_itemController, &DockItemController::itemRemoved, this, &MainPanel::itemRemoved, Qt::DirectConnection); connect(m_itemController, &DockItemController::itemMoved, this, &MainPanel::itemMoved); connect(m_itemAdjustTimer, &QTimer::timeout, this, &MainPanel::adjustItemSize, Qt::QueuedConnection); @@ -101,7 +104,7 @@ void MainPanel::updateDockDisplayMode(const DisplayMode displayMode) // const QList itemList = m_itemController->itemList(); // for (auto item : itemList) // { -// if (item->itemType() == DockItem::Placeholder) +// if (item->itemType() == DockItem::Stretch) // item->setVisible(displayMode == Dock::Efficient); // } @@ -129,36 +132,87 @@ void MainPanel::resizeEvent(QResizeEvent *e) void MainPanel::dragEnterEvent(QDragEnterEvent *e) { DockItem *dragSourceItem = qobject_cast(e->source()); - if (!dragSourceItem) + if (dragSourceItem) + { + e->accept(); + DragingItem->show(); + return; + } + + if (!e->mimeData()->formats().contains(RequestDockKey)) return; e->accept(); - - if (dragSourceItem) - DragingItem->show(); } void MainPanel::dragMoveEvent(QDragMoveEvent *e) { + e->accept(); + DockItem *item = itemAt(e->pos()); - if (item == DragingItem) - return; - if (!item || !DragingItem) + if (!item) return; - m_itemController->itemMove(DragingItem, item); + // internal drag swap + if (e->source()) + { + if (item == DragingItem) + return; + if (!DragingItem) + return; + + m_itemController->itemMove(DragingItem, item); + } else { + if (!RequestDockItem) + { + DockItem *insertPositionItem = itemAt(e->pos()); + if (!insertPositionItem || insertPositionItem->itemType() != DockItem::App) + return; + RequestDockItem = new PlaceholderItem; + m_itemController->placeholderItemAdded(RequestDockItem, insertPositionItem); + } else { + if (item == RequestDockItem) + return; + + m_itemController->itemMove(RequestDockItem, item); + } + } } void MainPanel::dragLeaveEvent(QDragLeaveEvent *e) { Q_UNUSED(e) - DragingItem->hide(); + if (RequestDockItem) + { + const QRect r(static_cast(parent())->pos(), size()); + const QPoint p(QCursor::pos()); + + if (r.contains(p)) + return; + + m_itemController->placeholderItemRemoved(RequestDockItem); + RequestDockItem->deleteLater(); + RequestDockItem = nullptr; + } + + if (DragingItem) + DragingItem->hide(); } void MainPanel::dropEvent(QDropEvent *e) { Q_UNUSED(e) + + DragingItem = nullptr; + + if (RequestDockItem) + { + m_itemController->placeholderItemDocked(e->mimeData()->data(RequestDockKey), RequestDockItem); + m_itemController->placeholderItemRemoved(RequestDockItem); + RequestDockItem->deleteLater(); + RequestDockItem = nullptr; + } } void MainPanel::initItemConnection(DockItem *item) @@ -296,7 +350,7 @@ void MainPanel::adjustItemSize() for (auto item : itemList) { - if (item->itemType() == DockItem::Placeholder) + if (item->itemType() == DockItem::Stretch) continue; if (item->itemType() == DockItem::Plugins) if (m_displayMode != Dock::Fashion) diff --git a/frame/panel/mainpanel.h b/frame/panel/mainpanel.h index c8aad14b1..a52221b53 100644 --- a/frame/panel/mainpanel.h +++ b/frame/panel/mainpanel.h @@ -57,6 +57,7 @@ private: DockItemController *m_itemController; static DockItem *DragingItem; + static PlaceholderItem *RequestDockItem; }; #endif // MAINPANEL_H diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index c1948738e..ff5c8321b 100644 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -76,7 +76,12 @@ void MainWindow::leaveEvent(QEvent *e) void MainWindow::setFixedSize(const QSize &size) { - if (m_sizeChangeAni->state() == QPropertyAnimation::Running) + const QPropertyAnimation::State state = m_posChangeAni->state(); + + if (state == QPropertyAnimation::Stopped && this->size() == size) + return; + + if (state == QPropertyAnimation::Running) return m_sizeChangeAni->setEndValue(size); m_sizeChangeAni->setStartValue(this->size()); @@ -86,10 +91,12 @@ void MainWindow::setFixedSize(const QSize &size) void MainWindow::move(int x, int y) { - if (this->pos() == QPoint(x, y)) + const QPropertyAnimation::State state = m_posChangeAni->state(); + + if (state == QPropertyAnimation::Stopped && this->pos() == QPoint(x, y)) return; - if (m_posChangeAni->state() == QPropertyAnimation::Running) + if (state == QPropertyAnimation::Running) return m_posChangeAni->setEndValue(QPoint(x, y)); m_posChangeAni->setStartValue(pos()); @@ -119,7 +126,7 @@ void MainWindow::initComponents() void MainWindow::initConnections() { connect(m_settings, &DockSettings::dataChanged, m_positionUpdateTimer, static_cast(&QTimer::start)); - connect(m_settings, &DockSettings::windowGeometryChanged, this, &MainWindow::updateGeometry, Qt::QueuedConnection); + connect(m_settings, &DockSettings::windowGeometryChanged, this, &MainWindow::updateGeometry, Qt::DirectConnection); connect(m_settings, &DockSettings::windowHideModeChanged, this, &MainWindow::setStrutPartial, Qt::QueuedConnection); connect(m_settings, &DockSettings::windowVisibleChanegd, this, &MainWindow::updatePanelVisible, Qt::QueuedConnection); connect(m_settings, &DockSettings::autoHideChanged, this, &MainWindow::updatePanelVisible); @@ -153,12 +160,12 @@ void MainWindow::updatePosition() void MainWindow::updateGeometry() { const Position position = m_settings->position(); + QSize size = m_settings->windowSize(); - m_mainPanel->setFixedSize(m_settings->windowSize()); + m_mainPanel->setFixedSize(size); m_mainPanel->updateDockPosition(position); m_mainPanel->updateDockDisplayMode(m_settings->displayMode()); - QSize size = m_settings->windowSize(); if (m_settings->hideState() == Hide) { m_sizeChangeAni->stop();