From d0fdde7a505f70dbef7c87840462fdf5c1f43235 Mon Sep 17 00:00:00 2001 From: shaojun Date: Wed, 21 Aug 2019 12:52:53 +0800 Subject: [PATCH] feat(panel):MainPanelControl add drag and drop for app and plugin --- frame/controller/dockitemmanager.cpp | 34 +++---- frame/controller/dockitemmanager.h | 4 +- frame/item/appitem.cpp | 81 ++++++++--------- frame/item/dockitem.cpp | 9 +- frame/item/dockitem.h | 2 + frame/item/pluginsitem.cpp | 32 +++++-- frame/item/pluginsitem.h | 14 +-- frame/panel/mainpanelcontrol.cpp | 127 ++++++++++++++++++++++++++- frame/panel/mainpanelcontrol.h | 12 ++- frame/window/mainwindow.cpp | 2 + 10 files changed, 235 insertions(+), 82 deletions(-) diff --git a/frame/controller/dockitemmanager.cpp b/frame/controller/dockitemmanager.cpp index 5b822498e..083b89f59 100644 --- a/frame/controller/dockitemmanager.cpp +++ b/frame/controller/dockitemmanager.cpp @@ -134,18 +134,18 @@ void DockItemManager::updatePluginsItemOrderKey() int index = 0; for (auto item : m_itemList) { - if (item.isNull() || item->itemType() != DockItem::TrayPlugin) + if (item.isNull() || item->itemType() != DockItem::Plugins) continue; static_cast(item.data())->setItemSortKey(++index); } } -void DockItemManager::itemMove(DockItem *const moveItem, DockItem *const replaceItem) +void DockItemManager::itemMoved(DockItem *const sourceItem, DockItem *const targetItem) { - Q_ASSERT(moveItem != replaceItem); + Q_ASSERT(sourceItem != targetItem); - const DockItem::ItemType moveType = moveItem->itemType(); - const DockItem::ItemType replaceType = replaceItem->itemType(); + const DockItem::ItemType moveType = sourceItem->itemType(); + const DockItem::ItemType replaceType = targetItem->itemType(); // app move if (moveType == DockItem::App || moveType == DockItem::Placeholder) @@ -157,15 +157,14 @@ void DockItemManager::itemMove(DockItem *const moveItem, DockItem *const replace if (replaceType != DockItem::Plugins && replaceType != DockItem::TrayPlugin) return; - const int moveIndex = m_itemList.indexOf(moveItem); + const int moveIndex = m_itemList.indexOf(sourceItem); const int replaceIndex = replaceType == DockItem::Stretch ? // disable insert after placeholder item - m_itemList.indexOf(replaceItem) - 1 : - m_itemList.indexOf(replaceItem); + m_itemList.indexOf(targetItem) - 1 : + m_itemList.indexOf(targetItem); m_itemList.removeAt(moveIndex); - m_itemList.insert(replaceIndex, moveItem); - emit itemMoved(moveItem, replaceIndex); + m_itemList.insert(replaceIndex, sourceItem); // update plugins sort key if order changed if (moveType == DockItem::Plugins || replaceType == DockItem::Plugins @@ -284,7 +283,6 @@ void DockItemManager::pluginItemInserted(PluginsItem *item) { // check item is in container if (item->allowContainer() && item->isInContainer()) { - emit itemManaged(item); return itemDroppedIntoContainer(item); } @@ -292,7 +290,7 @@ void DockItemManager::pluginItemInserted(PluginsItem *item) int firstPluginPosition = -1; for (int i(0); i != m_itemList.size(); ++i) { DockItem::ItemType type = m_itemList[i]->itemType(); - if (type != DockItem::Plugins && type != DockItem::TrayPlugin) + if (type != DockItem::Plugins) continue; firstPluginPosition = i; @@ -324,7 +322,7 @@ void DockItemManager::pluginItemInserted(PluginsItem *item) } m_itemList.insert(insertIndex, item); - emit itemInserted(insertIndex, item); + emit itemInserted(insertIndex - firstPluginPosition, item); refreshFSTItemSpliterVisible(); } @@ -353,12 +351,12 @@ void DockItemManager::reloadAppItems() appItemAdded(path, -1); } +// 不同的模式下,插件顺序不一样 void DockItemManager::sortPluginItems() { int firstPluginIndex = -1; for (int i(0); i != m_itemList.size(); ++i) { - DockItem::ItemType type = m_itemList[i]->itemType(); - if (type == DockItem::Plugins || type == DockItem::TrayPlugin) { + if (m_itemList[i]->itemType() == DockItem::Plugins) { firstPluginIndex = i; break; } @@ -383,6 +381,8 @@ void DockItemManager::sortPluginItems() }); // reset order - for (int i(firstPluginIndex); i != m_itemList.size(); ++i) - emit itemMoved(m_itemList[i], i); + for (int i(firstPluginIndex); i != m_itemList.size(); ++i) { + emit itemRemoved(m_itemList[i]); + emit itemInserted(-1, m_itemList[i]); + } } diff --git a/frame/controller/dockitemmanager.h b/frame/controller/dockitemmanager.h index 326a3dd8f..2cd2331ad 100644 --- a/frame/controller/dockitemmanager.h +++ b/frame/controller/dockitemmanager.h @@ -53,8 +53,6 @@ public: signals: void itemInserted(const int index, DockItem *item) const; void itemRemoved(DockItem *item) const; - void itemMoved(DockItem *item, const int index) const; - void itemManaged(DockItem *item) const; void itemUpdated(DockItem *item) const; void fashionTraySizeChanged(const QSize &traySize) const; @@ -62,7 +60,7 @@ public slots: void refershItemsIcon(); void sortPluginItems(); void updatePluginsItemOrderKey(); - void itemMove(DockItem *const moveItem, DockItem *const replaceItem); + void itemMoved(DockItem *const sourceItem, DockItem *const targetItem); void itemDroppedIntoContainer(DockItem *const item); void itemDragOutFromContainer(DockItem *const item); void refreshFSTItemSpliterVisible(); diff --git a/frame/item/appitem.cpp b/frame/item/appitem.cpp index e86c4deb3..c4e49ac47 100644 --- a/frame/item/appitem.cpp +++ b/frame/item/appitem.cpp @@ -46,17 +46,20 @@ int AppItem::IconBaseSize; QPoint AppItem::MousePressPos; -static QGSettings* GSettingsByApp() { +static QGSettings *GSettingsByApp() +{ static QGSettings settings("com.deepin.dde.dock.module.app"); return &settings; } -static QGSettings* GSettingsByActiveApp() { +static QGSettings *GSettingsByActiveApp() +{ static QGSettings settings("com.deepin.dde.dock.module.activeapp"); return &settings; } -static QGSettings* GSettingsByDockApp() { +static QGSettings *GSettingsByDockApp() +{ static QGSettings settings("com.deepin.dde.dock.module.dockapp"); return &settings; } @@ -95,7 +98,10 @@ AppItem::AppItem(const QDBusObjectPath &entry, QWidget *parent) centralLayout->setSpacing(0); setAccessibleName(m_itemEntryInter->name()); - setAcceptDrops(true); + + // 拖拽已放到MainPanelControl处理 + //setAcceptDrops(true); + setLayout(centralLayout); m_id = m_itemEntryInter->id(); @@ -150,7 +156,7 @@ const bool AppItem::isValid() const void AppItem::updateWindowIconGeometries() { const QRect r(mapToGlobal(QPoint(0, 0)), - mapToGlobal(QPoint(width(),height()))); + mapToGlobal(QPoint(width(), height()))); auto *xcb_misc = XcbMisc::instance(); for (auto it(m_windowInfos.cbegin()); it != m_windowInfos.cend(); ++it) @@ -218,6 +224,8 @@ int AppItem::itemBaseHeight() void AppItem::paintEvent(QPaintEvent *e) { DockItem::paintEvent(e); + if (m_draging) + return; if (m_dragging || (m_swingEffectView != nullptr && DockDisplayMode != Fashion)) return; @@ -233,18 +241,15 @@ void AppItem::paintEvent(QPaintEvent *e) // draw background QRectF backgroundRect = itemRect; - if (DockDisplayMode == Efficient) - { + if (DockDisplayMode == Efficient) { backgroundRect = itemRect.marginsRemoved(QMargins(1, 1, 1, 1)); - if (m_active) - { + if (m_active) { painter.fillRect(backgroundRect, QColor(44, 167, 248, 255 * 0.3)); const int activeLineWidth = itemRect.height() > 50 ? 4 : 2; QRectF activeRect = backgroundRect; - switch (DockPosition) - { + switch (DockPosition) { case Top: activeRect.setBottom(activeRect.top() + activeLineWidth); break; case Bottom: activeRect.setTop(activeRect.bottom() - activeLineWidth); break; case Left: activeRect.setRight(activeRect.left() + activeLineWidth); break; @@ -252,24 +257,18 @@ void AppItem::paintEvent(QPaintEvent *e) } painter.fillRect(activeRect, QColor(44, 167, 248, 255)); - } - else if (!m_windowInfos.isEmpty()) - { + } else if (!m_windowInfos.isEmpty()) { if (hasAttention()) painter.fillRect(backgroundRect, QColor(241, 138, 46, 255 * .8)); else painter.fillRect(backgroundRect, QColor(255, 255, 255, 255 * 0.2)); } - } - else - { - if (!m_windowInfos.isEmpty()) - { + } else { + if (!m_windowInfos.isEmpty()) { QPoint p; QPixmap pixmap; QPixmap activePixmap; - switch (DockPosition) - { + switch (DockPosition) { case Top: pixmap = m_horizontalIndicator; activePixmap = m_activeHorizontalIndicator; @@ -333,7 +332,7 @@ void AppItem::mouseReleaseEvent(QMouseEvent *e) } qDebug() << "app item clicked, name:" << m_itemEntryInter->name() - << "id:" << m_itemEntryInter->id() << "my-id:" << m_id << "icon:" << m_itemEntryInter->icon(); + << "id:" << m_itemEntryInter->id() << "my-id:" << m_id << "icon:" << m_itemEntryInter->icon(); m_itemEntryInter->Activate(QX11Info::getTimestamp()); @@ -461,7 +460,7 @@ void AppItem::showEvent(QShowEvent *e) { DockItem::showEvent(e); - QTimer::singleShot(0, this, [=] { + QTimer::singleShot(0, this, [ = ] { onGSettingsChanged("enable"); }); @@ -501,8 +500,7 @@ QWidget *AppItem::popupTips() if (m_dragging) return nullptr; - if (!m_windowInfos.isEmpty()) - { + if (!m_windowInfos.isEmpty()) { const quint32 currentWindow = m_itemEntryInter->currentWindow(); Q_ASSERT(m_windowInfos.contains(currentWindow)); m_appNameTips->setText(m_windowInfos[currentWindow].title); @@ -515,6 +513,9 @@ QWidget *AppItem::popupTips() void AppItem::startDrag() { + if (!acceptDrops()) + return; + if (checkGSettingsControl()) { return; } @@ -528,7 +529,7 @@ void AppItem::startDrag() m_drag->setMimeData(new QMimeData); // handle drag finished here - connect(m_drag->appDragWidget(), &AppDragWidget::destroyed, this, [=] { + connect(m_drag->appDragWidget(), &AppDragWidget::destroyed, this, [ = ] { m_dragging = false; m_drag.clear(); setVisible(true); @@ -583,8 +584,7 @@ void AppItem::updateWindowInfos(const WindowInfoMap &info) m_updateIconGeometryTimer->start(); // process attention effect - if (hasAttention()) - { + if (hasAttention()) { if (DockDisplayMode == DisplayMode::Fashion) playSwingEffect(); } else { @@ -642,9 +642,9 @@ void AppItem::showPreview() connect(m_appPreviewTips, &PreviewContainer::requestHidePopup, this, &AppItem::hidePopup); connect(m_appPreviewTips, &PreviewContainer::requestCheckWindows, m_itemEntryInter, &DockEntryInter::Check); - connect(m_appPreviewTips, &PreviewContainer::requestActivateWindow, [=]() { m_appPreviewTips = nullptr; }); - connect(m_appPreviewTips, &PreviewContainer::requestCancelPreviewWindow, [=]() { m_appPreviewTips = nullptr; }); - connect(m_appPreviewTips, &PreviewContainer::requestHidePopup, [=]() { m_appPreviewTips = nullptr; }); + connect(m_appPreviewTips, &PreviewContainer::requestActivateWindow, [ = ]() { m_appPreviewTips = nullptr; }); + connect(m_appPreviewTips, &PreviewContainer::requestCancelPreviewWindow, [ = ]() { m_appPreviewTips = nullptr; }); + connect(m_appPreviewTips, &PreviewContainer::requestHidePopup, [ = ]() { m_appPreviewTips = nullptr; }); showPopupWindow(m_appPreviewTips, true); } @@ -658,13 +658,13 @@ void AppItem::playSwingEffect() stopSwingEffect(); QPair pair = SwingEffect( - this, m_appIcon, rect(), devicePixelRatioF()); + this, m_appIcon, rect(), devicePixelRatioF()); m_swingEffectView = pair.first; m_itemAnimation = pair.second; QTimeLine *tl = m_itemAnimation->timeLine(); - connect(tl, &QTimeLine::stateChanged, [=](QTimeLine::State newState) { + connect(tl, &QTimeLine::stateChanged, [ = ](QTimeLine::State newState) { if (newState == QTimeLine::NotRunning) { m_swingEffectView->hide(); layout()->removeWidget(m_swingEffectView); @@ -692,20 +692,21 @@ void AppItem::stopSwingEffect() void AppItem::checkAttentionEffect() { - QTimer::singleShot(1000, this, [=] { + QTimer::singleShot(1000, this, [ = ] { if (DockDisplayMode == DisplayMode::Fashion && hasAttention()) playSwingEffect(); }); } -void AppItem::onGSettingsChanged(const QString& key) { +void AppItem::onGSettingsChanged(const QString &key) +{ if (key != "enable") { return; } QGSettings *setting = m_itemEntryInter->isDocked() - ? GSettingsByDockApp() - : GSettingsByActiveApp(); + ? GSettingsByDockApp() + : GSettingsByActiveApp(); if (setting->keys().contains("enable")) { const bool isEnable = GSettingsByApp()->keys().contains("enable") && GSettingsByApp()->get("enable").toBool(); @@ -716,9 +717,9 @@ void AppItem::onGSettingsChanged(const QString& key) { bool AppItem::checkGSettingsControl() const { QGSettings *setting = m_itemEntryInter->isDocked() - ? GSettingsByDockApp() - : GSettingsByActiveApp(); + ? GSettingsByDockApp() + : GSettingsByActiveApp(); return (setting->keys().contains("control") && setting->get("control").toBool()) || - (GSettingsByApp()->keys().contains("control") && GSettingsByApp()->get("control").toBool()); + (GSettingsByApp()->keys().contains("control") && GSettingsByApp()->get("control").toBool()); } diff --git a/frame/item/dockitem.cpp b/frame/item/dockitem.cpp index 8f855f319..4be620182 100644 --- a/frame/item/dockitem.cpp +++ b/frame/item/dockitem.cpp @@ -37,12 +37,10 @@ DockItem::DockItem(QWidget *parent) m_hover(false), m_popupShown(false), m_tapAndHold(false), - + m_draging(false), m_hoverEffect(new HoverHighlightEffect(this)), - m_popupTipsDelayTimer(new QTimer(this)), m_popupAdjustDelayTimer(new QTimer(this)), - m_menuManagerInter(new DBusMenuManager(this)) { if (PopupWindow.isNull()) { @@ -391,6 +389,11 @@ void DockItem::hidePopup() emit requestWindowAutoHide(true); } +void DockItem::setDraging(bool bDrag) +{ + m_draging = bDrag; +} + void DockItem::hideNonModel() { // auto hide if popup is not model window diff --git a/frame/item/dockitem.h b/frame/item/dockitem.h index 9a1d4b830..8e04bb0ff 100644 --- a/frame/item/dockitem.h +++ b/frame/item/dockitem.h @@ -66,6 +66,7 @@ public slots: void showPopupApplet(QWidget *const applet); void hidePopup(); + virtual void setDraging(bool bDrag); signals: void dragStarted() const; @@ -106,6 +107,7 @@ protected: bool m_hover; bool m_popupShown; bool m_tapAndHold; + bool m_draging; QPointer m_lastPopupWidget; QPointer m_hoverEffect; diff --git a/frame/item/pluginsitem.cpp b/frame/item/pluginsitem.cpp index 0bdec2bbb..cf1801055 100644 --- a/frame/item/pluginsitem.cpp +++ b/frame/item/pluginsitem.cpp @@ -36,7 +36,7 @@ QPoint PluginsItem::MousePressPoint = QPoint(); -PluginsItem::PluginsItem(PluginsItemInterface* const pluginInter, const QString &itemKey, QWidget *parent) +PluginsItem::PluginsItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent) : DockItem(parent), m_pluginInter(pluginInter), m_centralWidget(m_pluginInter->itemWidget(itemKey)), @@ -120,6 +120,9 @@ void PluginsItem::paintEvent(QPaintEvent *event) { Q_UNUSED(event); + if (m_draging) + return; + DisplayMode displayMode = m_pluginInter->displayMode(); if (displayMode == Dock::DisplayMode::Fashion) { @@ -152,7 +155,8 @@ void PluginsItem::refershIcon() m_pluginInter->refreshIcon(m_itemKey); } -void PluginsItem::onGSettingsChanged(const QString& key) { +void PluginsItem::onGSettingsChanged(const QString &key) +{ if (key != "enable") { return; } @@ -213,7 +217,7 @@ void PluginsItem::mouseReleaseEvent(QMouseEvent *e) if (e->button() != Qt::LeftButton) return; - if (checkAndResetTapHoldGestureState()&& e->source() == Qt::MouseEventSynthesizedByQt) { + if (checkAndResetTapHoldGestureState() && e->source() == Qt::MouseEventSynthesizedByQt) { qDebug() << "tap and hold gesture detected, ignore the synthesized mouse release event"; return; } @@ -251,8 +255,9 @@ void PluginsItem::leaveEvent(QEvent *event) DockItem::leaveEvent(event); } -void PluginsItem::showEvent(QShowEvent* event) { - QTimer::singleShot(0, this, [=] { +void PluginsItem::showEvent(QShowEvent *event) +{ + QTimer::singleShot(0, this, [ = ] { onGSettingsChanged("enable"); }); @@ -282,7 +287,7 @@ void PluginsItem::invokedMenuItem(const QString &itemId, const bool checked) m_pluginInter->invokedMenuItem(m_itemKey, itemId, checked); } -void PluginsItem::showPopupWindow(QWidget * const content, const bool model) +void PluginsItem::showPopupWindow(QWidget *const content, const bool model) { if (isInContainer()) return; @@ -306,6 +311,9 @@ QWidget *PluginsItem::popupTips() void PluginsItem::startDrag() { + // 拖拽已放到MainPanelControl处理 + return; + const QPixmap pixmap = grab(); m_dragging = true; @@ -335,8 +343,7 @@ void PluginsItem::startDrag() void PluginsItem::mouseClicked() { const QString command = m_pluginInter->itemCommand(m_itemKey); - if (!command.isEmpty()) - { + if (!command.isEmpty()) { QProcess *proc = new QProcess(this); connect(proc, static_cast(&QProcess::finished), proc, &QProcess::deleteLater); @@ -354,5 +361,12 @@ void PluginsItem::mouseClicked() bool PluginsItem::checkGSettingsControl() const { return m_gsettings->keys().contains("control") - && m_gsettings->get("control").toBool(); + && m_gsettings->get("control").toBool(); +} + +void PluginsItem::setDraging(bool bDrag) +{ + DockItem::setDraging(bDrag); + + m_centralWidget->setVisible(!bDrag); } diff --git a/frame/item/pluginsitem.h b/frame/item/pluginsitem.h index 3307435d7..05d7ac8e0 100644 --- a/frame/item/pluginsitem.h +++ b/frame/item/pluginsitem.h @@ -31,7 +31,7 @@ class PluginsItem : public DockItem Q_OBJECT public: - explicit PluginsItem(PluginsItemInterface* const pluginInter, const QString &itemKey, QWidget *parent = 0); + explicit PluginsItem(PluginsItemInterface *const pluginInter, const QString &itemKey, QWidget *parent = 0); ~PluginsItem(); int itemSortKey() const; @@ -53,9 +53,11 @@ public: QWidget *centralWidget() const; + virtual void setDraging(bool bDrag); + public slots: void refershIcon() override; - void onGSettingsChanged(const QString& key); + void onGSettingsChanged(const QString &key); protected: void mousePressEvent(QMouseEvent *e) override; @@ -64,10 +66,10 @@ protected: void enterEvent(QEvent *event) Q_DECL_OVERRIDE; void leaveEvent(QEvent *event) Q_DECL_OVERRIDE; bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; - void showEvent(QShowEvent* event) override; + void showEvent(QShowEvent *event) override; void invokedMenuItem(const QString &itemId, const bool checked) override; - void showPopupWindow(QWidget * const content, const bool model = false) override; + void showPopupWindow(QWidget *const content, const bool model = false) override; const QString contextMenu() const override; QWidget *popupTips() override; @@ -77,7 +79,7 @@ private: bool checkGSettingsControl() const; private: - PluginsItemInterface * const m_pluginInter; + PluginsItemInterface *const m_pluginInter; QWidget *m_centralWidget; const QString m_itemKey; @@ -85,7 +87,7 @@ private: bool m_hover; static QPoint MousePressPoint; - QGSettings* m_gsettings; + QGSettings *m_gsettings; }; #endif // PLUGINSITEM_H diff --git a/frame/panel/mainpanelcontrol.cpp b/frame/panel/mainpanelcontrol.cpp index ca1fdaebe..92d27d01b 100644 --- a/frame/panel/mainpanelcontrol.cpp +++ b/frame/panel/mainpanelcontrol.cpp @@ -24,6 +24,7 @@ #include +#include #include DWIDGET_USE_NAMESPACE @@ -44,6 +45,7 @@ MainPanelControl::MainPanelControl(QWidget *parent) { init(); updateMainPanelLayout(); + setAcceptDrops(true); } MainPanelControl::~MainPanelControl() @@ -181,6 +183,8 @@ void MainPanelControl::setPositonValue(const Qt::Edge val) void MainPanelControl::insertItem(const int index, DockItem *item) { + item->installEventFilter(this); + switch (item->itemType()) { case DockItem::Launcher: addFixedAreaItem(index, item); @@ -223,11 +227,128 @@ void MainPanelControl::removeItem(DockItem *item) updateAppAreaSonWidgetSize(); } - void MainPanelControl::movedItem(const int index, DockItem *item) +void MainPanelControl::moveItem(DockItem *sourceItem, DockItem *targetItem) { + // get target index + int idx = -1; + if (targetItem->itemType() == DockItem::App) + idx = m_appAreaSonLayout->indexOf(targetItem); + else if (targetItem->itemType() == DockItem::Plugins) + idx = m_pluginLayout->indexOf(targetItem); + else + return; + // remove old item - removeItem(item); + removeItem(sourceItem); + // insert new position - insertItem(index, item); + insertItem(idx, sourceItem); } +void MainPanelControl::dragEnterEvent(QDragEnterEvent *e) +{ + e->accept(); +} + +void MainPanelControl::dragMoveEvent(QDragMoveEvent *e) +{ + DockItem *sourceItem = qobject_cast(e->source()); + if (!sourceItem) { + e->ignore(); + return; + } + + DockItem *targetItem = dropTargetItem(sourceItem, e->pos()); + if (!targetItem) { + e->ignore(); + return; + } + + e->accept(); + + if (targetItem == sourceItem) + return; + + moveItem(sourceItem, targetItem); + emit itemMoved(sourceItem, targetItem); +} + +bool MainPanelControl::eventFilter(QObject *watched, QEvent *event) +{ + if (event->type() != QEvent::MouseMove) + return false; + + QMouseEvent *mouseEvent = static_cast(event); + if (!mouseEvent || mouseEvent->buttons() != Qt::LeftButton) + return false; + + DockItem *item = qobject_cast(watched); + if (!item) + return false; + + if (item->itemType() != DockItem::App && item->itemType() != DockItem::Plugins) + return false; + + startDrag(item); + + return true; +} + +void MainPanelControl::startDrag(DockItem *item) +{ + const QPixmap pixmap = item->grab(); + + item->setDraging(true); + item->update(); + + QDrag *drag = new QDrag(item); + drag->setPixmap(pixmap); + drag->setHotSpot(pixmap.rect().center() / pixmap.devicePixelRatioF()); + drag->setMimeData(new QMimeData); + drag->exec(Qt::MoveAction); + + item->setDraging(false); + item->update(); +} + +DockItem *MainPanelControl::dropTargetItem(DockItem *sourceItem, QPoint point) +{ + QWidget *parentWidget = nullptr; + + switch (sourceItem->itemType()) { + case DockItem::App: + parentWidget = m_appAreaSonWidget; + break; + case DockItem::Plugins: + parentWidget = m_pluginAreaWidget; + break; + default: + break; + } + + if (!parentWidget) + return nullptr; + + point = parentWidget->mapFromParent(point); + QLayout *parentLayout = parentWidget->layout(); + + DockItem *targetItem = nullptr; + + for (int i = 0 ; i < parentLayout->count(); ++i) { + QLayoutItem *layoutItem = parentLayout->itemAt(i); + DockItem *dockItem = qobject_cast(layoutItem->widget()); + if (!dockItem) + continue; + + QRect rect; + rect.setTopLeft(dockItem->pos()); + rect.setSize(dockItem->size()); + + if (rect.contains(point)) { + targetItem = dockItem; + break; + } + } + + return targetItem; +} diff --git a/frame/panel/mainpanelcontrol.h b/frame/panel/mainpanelcontrol.h index 88b314d9d..3fc077524 100644 --- a/frame/panel/mainpanelcontrol.h +++ b/frame/panel/mainpanelcontrol.h @@ -43,6 +43,9 @@ public: void removePluginAreaItem(QWidget *wdg); void setPositonValue(const Qt::Edge val); +signals: + void itemMoved(DockItem *sourceItem, DockItem *targetItem); + private: void resizeEvent(QResizeEvent *event) override; @@ -50,10 +53,17 @@ private: void updateAppAreaSonWidgetSize(); void updateMainPanelLayout(); + void dragMoveEvent(QDragMoveEvent *e) override; + void dragEnterEvent(QDragEnterEvent *e) override; + bool eventFilter(QObject *watched, QEvent *event) override; + + void startDrag(DockItem *); + DockItem *dropTargetItem(DockItem *sourceItem, QPoint point); + void moveItem(DockItem *sourceItem, DockItem *targetItem); + public slots: void insertItem(const int index, DockItem *item); void removeItem(DockItem *item); - void movedItem(const int index, DockItem *item); private: QBoxLayout *m_mainPanelLayout; diff --git a/frame/window/mainwindow.cpp b/frame/window/mainwindow.cpp index 37c05c3a2..57a7c28ee 100644 --- a/frame/window/mainwindow.cpp +++ b/frame/window/mainwindow.cpp @@ -405,6 +405,8 @@ void MainWindow::initConnections() connect(DockItemManager::instance(), &DockItemManager::itemInserted, m_mainPanel, &MainPanelControl::insertItem, Qt::DirectConnection); connect(DockItemManager::instance(), &DockItemManager::itemRemoved, m_mainPanel, &MainPanelControl::removeItem, Qt::DirectConnection); + connect(m_mainPanel, &MainPanelControl::itemMoved, DockItemManager::instance(), &DockItemManager::itemMoved, Qt::DirectConnection); + } const QPoint MainWindow::x11GetWindowPos()