diff --git a/frame/window/docktraywindow.cpp b/frame/window/docktraywindow.cpp index 759c1add8..640bca6f1 100644 --- a/frame/window/docktraywindow.cpp +++ b/frame/window/docktraywindow.cpp @@ -28,6 +28,7 @@ #include "quicksettingcontroller.h" #include "pluginsitem.h" #include "quicksettingcontainer.h" +#include "expandiconwidget.h" #include @@ -80,6 +81,9 @@ void DockTrayWindow::setDisplayMode(const Dock::DisplayMode &displayMode) { m_displayMode = displayMode; moveToolPlugin(); + // 如果当前模式为高效模式,则设置当前的trayView为其计算位置的参照 + if (displayMode == Dock::DisplayMode::Efficient) + ExpandIconWidget::popupTrayView()->setReferGridView(m_trayView); } QSize DockTrayWindow::suitableSize(const Dock::Position &position, const int &, const double &) const @@ -311,18 +315,19 @@ void DockTrayWindow::initConnection() connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, &DockTrayWindow::onResetLayout); connect(m_quickIconWidget, &QuickPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon); connect(m_systemPuginWidget, &SystemPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon); - connect(m_trayView, &TrayGridView::requestRemove, m_model, &TrayModel::removeRow); - connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onResetLayout); connect(m_model, &TrayModel::rowCountChanged, this, &DockTrayWindow::onResetLayout); connect(m_model, &TrayModel::rowCountChanged, m_trayView, &TrayGridView::onUpdateEditorView); connect(m_model, &TrayModel::requestRefreshEditor, m_trayView, &TrayGridView::onUpdateEditorView); - - connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ]{ - Q_EMIT m_delegate->requestDrag(true); - }); - connect(m_trayView, &TrayGridView::dragEntered, m_delegate, [ this ]{ + connect(m_trayView, &TrayGridView::requestRemove, m_model, &TrayModel::removeRow); + connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onResetLayout); + connect(m_trayView, &TrayGridView::dragFinished, this, [ this ] { + // 如果拖拽结束,则隐藏托盘 Q_EMIT m_delegate->requestDrag(false); }); + + connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ] { + Q_EMIT m_delegate->requestDrag(true); + }); connect(QuickSettingController::instance(), &QuickSettingController::pluginInserted, this, [ this ] (PluginsItemInterface *itemInter, const QuickSettingController::PluginAttribute pluginAttr) { switch (pluginAttr) { case QuickSettingController::PluginAttribute::Tool: diff --git a/frame/window/mainpanelcontrol.cpp b/frame/window/mainpanelcontrol.cpp index e1761b1ec..37e1b0660 100755 --- a/frame/window/mainpanelcontrol.cpp +++ b/frame/window/mainpanelcontrol.cpp @@ -205,9 +205,6 @@ void MainPanelControl::initConnection() */ void MainPanelControl::setDisplayMode(DisplayMode dislayMode) { - if (dislayMode == m_displayMode) - return; - m_displayMode = dislayMode; m_recentHelper->setDisplayMode(dislayMode); m_tray->setDisplayMode(dislayMode); diff --git a/frame/window/tray/tray_delegate.cpp b/frame/window/tray/tray_delegate.cpp index 4e14e8243..6f44b3658 100644 --- a/frame/window/tray/tray_delegate.cpp +++ b/frame/window/tray/tray_delegate.cpp @@ -125,19 +125,23 @@ void TrayDelegate::onUpdateExpand(bool on) ExpandIconWidget *expandwidget = expandWidget(); if (on) { - if (!expandwidget) { + if (expandwidget) { + expandwidget->setTrayPanelVisible(true); + } else { // 如果三角按钮不存在,那么就设置三角按钮可见,此时它会自动创建一个三角按钮 TrayModel *model = qobject_cast(m_listView->model()); if (model) model->setExpandVisible(true, true); - } else { - expandwidget->setTrayPanelVisible(true); } - } else if (expandwidget) { - // 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏 - QPoint currentPoint = QCursor::pos(); - TrayGridWidget *view = ExpandIconWidget::popupTrayView(); - expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint)); + } else { + if (expandwidget) { + // 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏 + QPoint currentPoint = QCursor::pos(); + TrayGridWidget *view = ExpandIconWidget::popupTrayView(); + expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint)); + } else { + ExpandIconWidget::popupTrayView()->hide(); + } } } diff --git a/frame/window/tray/tray_gridview.cpp b/frame/window/tray/tray_gridview.cpp index b62757f3c..9d397c0ec 100644 --- a/frame/window/tray/tray_gridview.cpp +++ b/frame/window/tray/tray_gridview.cpp @@ -467,8 +467,6 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions) pixLabel->setPixmap(pixmap); pixLabel->setFixedSize(indexRect(modelIndex).size() / ratio); - QRect rectIcon(pixLabel->rect().topLeft(), pixLabel->size()); - QDrag *drag = new QDrag(this); pixmap.scaled(pixmap.size() * ratio, Qt::KeepAspectRatio, Qt::SmoothTransformation); pixmap.setDevicePixelRatio(ratio); @@ -486,6 +484,8 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions) listModel->setDragKey(itemKey); listModel->setDragingIndex(modelIndex); + // 删除当前的图标 + WinInfo winInfo = listModel->takeIndex(modelIndex); Qt::DropAction dropAct = drag->exec(supportedActions); @@ -493,18 +493,20 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions) m_aniStartTime->stop(); m_pressed = false; - Q_EMIT dragEntered(); if (dropAct == Qt::IgnoreAction) { QPropertyAnimation *posAni = new QPropertyAnimation(pixLabel, "pos", pixLabel); - connect(posAni, &QPropertyAnimation::finished, [ &, listModel, pixLabel ] () { + connect(posAni, &QPropertyAnimation::finished, [ this, listModel, pixLabel, modelIndex, winInfo ] () { pixLabel->hide(); pixLabel->deleteLater(); listModel->setDragKey(QString()); + listModel->insertRow(modelIndex.row(), winInfo); clearDragModelIndex(); listModel->setExpandVisible(!TrayModel::getIconModel()->isEmpty()); m_dropPos = QPoint(); m_dragPos = QPoint(); + + Q_EMIT dragFinished(); }); posAni->setEasingCurve(QEasingCurve::Linear); posAni->setDuration(m_aniDuringTime); @@ -518,8 +520,6 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions) m_dropPos = QPoint(); m_dragPos = QPoint(); - - Q_EMIT requestRemove(itemKey); } return true; diff --git a/frame/window/tray/tray_gridview.h b/frame/window/tray/tray_gridview.h index 3a5e25b28..3951de3c6 100644 --- a/frame/window/tray/tray_gridview.h +++ b/frame/window/tray/tray_gridview.h @@ -54,6 +54,7 @@ Q_SIGNALS: void requestRemove(const QString &); void dragLeaved(); void dragEntered(); + void dragFinished(); private Q_SLOTS: void clearDragModelIndex(); diff --git a/frame/window/tray/tray_model.cpp b/frame/window/tray/tray_model.cpp index aa460d4cc..865a47241 100644 --- a/frame/window/tray/tray_model.cpp +++ b/frame/window/tray/tray_model.cpp @@ -340,6 +340,22 @@ void TrayModel::clear() Q_EMIT rowCountChanged(); } +WinInfo TrayModel::takeIndex(const QModelIndex &index) +{ + int row = index.row(); + if (row < 0 || row >= m_winInfos.size()) + return WinInfo(); + + WinInfo win = m_winInfos[row]; + beginResetModel(); + m_winInfos.removeAt(row); + endResetModel(); + + Q_EMIT rowCountChanged(); + + return win; +} + void TrayModel::onXEmbedTrayAdded(quint32 winId) { if (!xembedCanExport(winId)) @@ -357,6 +373,7 @@ void TrayModel::onXEmbedTrayAdded(quint32 winId) info.itemKey = xembedItemKey(winId); info.winId = winId; m_winInfos.append(info); + sortItems(); endInsertRows(); Q_EMIT rowCountChanged(); @@ -471,6 +488,48 @@ bool TrayModel::systemItemCanExport(const QString &pluginName) const return inTrayConfig(systemItemKey(pluginName)); } +void TrayModel::sortItems() +{ + // 如果当前是展开托盘的内容,则无需排序 + if (m_isTrayIcon) + return; + + // 数据排列,展开按钮始终排在最前面,输入法始终排在最后面 + WinInfos expandWin; + WinInfos inputMethodWin; + // 从列表中获取输入法和展开按钮 + for (const WinInfo &winInfo : m_winInfos) { + switch (winInfo.type) { + case TrayIconType::ExpandIcon: { + expandWin << winInfo; + break; + } + case TrayIconType::Sni: { + if (winInfo.isTypeWriting) + inputMethodWin << winInfo; + break; + } + default: + break; + } + } + // 从列表中移除展开按钮 + for (const WinInfo &winInfo : expandWin) + m_winInfos.removeOne(winInfo); + + // 从列表中移除输入法 + for (const WinInfo &winInfo : inputMethodWin) + m_winInfos.removeOne(winInfo); + + // 将展开按钮添加到列表的最前面 + for (int i = expandWin.size() - 1; i >= 0; i--) + m_winInfos.push_front(expandWin[i]); + + // 将输入法添加到列表的最后面 + for (int i = 0; i < inputMethodWin.size(); i++) + m_winInfos.push_back(inputMethodWin[i]); +} + void TrayModel::onSniTrayAdded(const QString &servicePath) { if (!sniCanExport(servicePath)) @@ -478,16 +537,6 @@ void TrayModel::onSniTrayAdded(const QString &servicePath) bool typeWriting = isTypeWriting(servicePath); - int citxIndex = -1; - for (int i = 0; i < m_winInfos.size(); i++) { - WinInfo info = m_winInfos[i]; - if (info.servicePath == servicePath) - return; - - if (typeWriting && info.isTypeWriting) - citxIndex = i; - } - beginInsertRows(QModelIndex(), rowCount(), rowCount()); WinInfo info; info.type = Sni; @@ -495,23 +544,12 @@ void TrayModel::onSniTrayAdded(const QString &servicePath) info.itemKey = sniItemKey(servicePath); info.servicePath = servicePath; info.isTypeWriting = typeWriting; // 是否为输入法 - if (typeWriting) { - if (citxIndex < 0) { - m_winInfos.append(info); - } else { - // 如果输入法在指定位置,则将输入法移动到指定位置 - m_winInfos[citxIndex] = info; - QTimer::singleShot(150, this, [ = ] { - // 对比需要变化的图标 - emit requestUpdateWidget({ citxIndex }); - }); - } - } else { - m_winInfos.append(info); + m_winInfos.append(info); - Q_EMIT rowCountChanged(); - } + sortItems(); endInsertRows(); + + Q_EMIT rowCountChanged(); } void TrayModel::onSniTrayRemoved(const QString &servicePath) @@ -584,6 +622,8 @@ void TrayModel::onIndicatorAdded(const QString &indicatorName) info.key = itemKey; info.itemKey = IndicatorTrayItem::toIndicatorKey(indicatorName); m_winInfos.append(info); + + sortItems(); endInsertRows(); Q_EMIT rowCountChanged(); @@ -613,6 +653,7 @@ void TrayModel::onSystemTrayAdded(PluginsItemInterface *itemInter) info.itemKey = systemItemKey(itemInter->pluginName()); m_winInfos.append(info); + sortItems(); endInsertRows(); Q_EMIT rowCountChanged(); @@ -699,6 +740,7 @@ void TrayModel::addRow(WinInfo info) beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_winInfos.append(info); + sortItems(); endInsertRows(); Q_EMIT requestRefreshEditor(); @@ -718,6 +760,8 @@ void TrayModel::insertRow(int index, WinInfo info) } beginInsertRows(QModelIndex(), index, index); m_winInfos.insert(index, info); + sortItems(); + endInsertRows(); Q_EMIT requestRefreshEditor(); diff --git a/frame/window/tray/tray_model.h b/frame/window/tray/tray_model.h index 0e5b9f95e..63887d28d 100644 --- a/frame/window/tray/tray_model.h +++ b/frame/window/tray/tray_model.h @@ -110,11 +110,11 @@ public: bool isEmpty() const; void clear(); + WinInfo takeIndex(const QModelIndex &index); void saveConfig(int index, const WinInfo &winInfo); Q_SIGNALS: void requestUpdateIcon(quint32); - void requestUpdateWidget(const QList &); void requestOpenEditor(const QModelIndex &index, bool isOpen = true) const; void rowCountChanged(); void requestRefreshEditor(); @@ -142,6 +142,14 @@ private Q_SLOTS: void onSettingChanged(const QString &key, const QVariant &value); +protected: + QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE; + QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; + bool removeRows(int row, int count, const QModelIndex &parent) Q_DECL_OVERRIDE; + bool canDropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) const Q_DECL_OVERRIDE; + Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + private: bool exist(const QString &itemKey); QString fileNameByServiceName(const QString &serviceName) const; @@ -155,14 +163,7 @@ private: bool indicatorCanExport(const QString &indicatorName) const; QString systemItemKey(const QString &pluginName) const; bool systemItemCanExport(const QString &pluginName) const; - -protected: - QMimeData *mimeData(const QModelIndexList &indexes) const Q_DECL_OVERRIDE; - QVariant data(const QModelIndex &index, int role) const Q_DECL_OVERRIDE; - bool removeRows(int row, int count, const QModelIndex &parent) Q_DECL_OVERRIDE; - bool canDropMimeData(const QMimeData *data, Qt::DropAction action, - int row, int column, const QModelIndex &parent) const Q_DECL_OVERRIDE; - Qt::ItemFlags flags(const QModelIndex &index) const Q_DECL_OVERRIDE; + void sortItems(); private: WinInfos m_winInfos; diff --git a/frame/window/tray/widgets/expandiconwidget.cpp b/frame/window/tray/widgets/expandiconwidget.cpp index 9ffee3f9f..79c3e5bf1 100644 --- a/frame/window/tray/widgets/expandiconwidget.cpp +++ b/frame/window/tray/widgets/expandiconwidget.cpp @@ -66,9 +66,6 @@ ExpandIconWidget::ExpandIconWidget(QWidget *parent, Qt::WindowFlags f) ExpandIconWidget::~ExpandIconWidget() { - TrayGridWidget *gridView = popupTrayView(); - gridView->setOwnerWidget(nullptr); - setTrayPanelVisible(false); } void ExpandIconWidget::setPositon(Dock::Position position) @@ -84,10 +81,6 @@ void ExpandIconWidget::sendClick(uint8_t mouseButton, int x, int y) Q_UNUSED(x); Q_UNUSED(y); - // 如果当前图标不可见,则不让展开托盘列表 - if (popupTrayView()->trayView()->model()->rowCount() == 0) - return; - if (mouseButton != XCB_BUTTON_INDEX_1) return; @@ -115,10 +108,6 @@ QPixmap ExpandIconWidget::icon() void ExpandIconWidget::paintEvent(QPaintEvent *event) { - TrayGridWidget *gridView = popupTrayView(); - if (gridView->trayView()->model()->rowCount() == 0) - return BaseTrayWidget::paintEvent(event); - QPainter painter(this); QPixmap pixmap = ImageUtil::loadSvg(dropIconFile(), QSize(ICON_SIZE, ICON_SIZE)); QRect rectOfPixmap(rect().x() + (rect().width() - ICON_SIZE) / 2, @@ -126,8 +115,6 @@ void ExpandIconWidget::paintEvent(QPaintEvent *event) ICON_SIZE, ICON_SIZE); painter.drawPixmap(rectOfPixmap, pixmap); - - gridView->setOwnerWidget(this); } const QString ExpandIconWidget::dropIconFile() const @@ -183,14 +170,17 @@ TrayGridWidget *ExpandIconWidget::popupTrayView() layout->addWidget(trayView); auto rowCountChanged = [ = ] { - int count = trayModel->rowCount(); - if (count > 0) - gridParentView->resetPosition(); - else if (gridParentView->isVisible()) - gridParentView->hide(); + if (gridParentView->isVisible()) { + int count = trayModel->rowCount(); + if (count > 0) + gridParentView->resetPosition(); + else + gridParentView->hide(); + } }; connect(trayModel, &TrayModel::rowCountChanged, gridParentView, rowCountChanged); + connect(trayModel, &TrayModel::requestRefreshEditor, trayView, &TrayGridView::onUpdateEditorView); connect(trayDelegate, &TrayDelegate::removeRow, trayView, [ = ](const QModelIndex &index) { trayView->model()->removeRow(index.row(),index.parent()); @@ -216,7 +206,7 @@ TrayGridWidget::TrayGridWidget(QWidget *parent) : QWidget (parent) , m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this)) , m_trayGridView(nullptr) - , m_ownerWidget(nullptr) + , m_referGridView(nullptr) { setAttribute(Qt::WA_TranslucentBackground); } @@ -231,10 +221,9 @@ void TrayGridWidget::setTrayGridView(TrayGridView *trayView) m_trayGridView = trayView; } -void TrayGridWidget::setOwnerWidget(QWidget *widget) +void TrayGridWidget::setReferGridView(TrayGridView *trayView) { - // 设置所属的Widget,目的是为了计算当前窗体的具体位置 - m_ownerWidget = widget; + m_referGridView = trayView; } TrayGridView *TrayGridWidget::trayView() const @@ -245,20 +234,22 @@ TrayGridView *TrayGridWidget::trayView() const void TrayGridWidget::resetPosition() { // 如果没有设置所属窗体,则无法计算位置 - if (!m_ownerWidget || !m_ownerWidget->parentWidget()) + ExpandIconWidget *expWidget = expandWidget(); + if (!expWidget) return; - QWidget *topWidget = m_ownerWidget->topLevelWidget(); - QPoint ptPos = m_ownerWidget->parentWidget()->mapToGlobal(m_ownerWidget->pos()); + m_trayGridView->setFixedSize(m_trayGridView->suitableSize()); + setFixedSize(m_trayGridView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2)); + + QWidget *topWidget = expWidget->topLevelWidget(); + QPoint ptPos = expWidget->mapToGlobal(QPoint(0, 0)); switch (m_position) { case Dock::Position::Bottom: { - ptPos.setX(ptPos.x() - width()); ptPos.setY(topWidget->y() - height()); break; } case Dock::Position::Top: { ptPos.setY(topWidget->y() + topWidget->height()); - ptPos.setX(ptPos.x() - width()); break; } case Dock::Position::Left: { @@ -270,8 +261,6 @@ void TrayGridWidget::resetPosition() break; } } - m_trayGridView->setFixedSize(m_trayGridView->suitableSize()); - setFixedSize(m_trayGridView->size() + QSize(ITEM_SPACING * 2, ITEM_SPACING * 2)); move(ptPos); } @@ -296,3 +285,22 @@ QColor TrayGridWidget::maskColor() const color.setAlpha(maskAlpha); return color; } + +ExpandIconWidget *TrayGridWidget::expandWidget() const +{ + if (!m_referGridView) + return nullptr; + + QAbstractItemModel *dataModel = m_referGridView->model(); + if (!dataModel) + return nullptr; + + for (int i = 0; i < dataModel->rowCount() - 1; i++) { + QModelIndex index = dataModel->index(i, 0); + ExpandIconWidget *widget = qobject_cast(m_referGridView->indexWidget(index)); + if (widget) + return widget; + } + + return nullptr; +} diff --git a/frame/window/tray/widgets/expandiconwidget.h b/frame/window/tray/widgets/expandiconwidget.h index 8a178492b..0aa5f57eb 100644 --- a/frame/window/tray/widgets/expandiconwidget.h +++ b/frame/window/tray/widgets/expandiconwidget.h @@ -67,7 +67,7 @@ public: static void setPosition(const Dock::Position &position); void setTrayGridView(TrayGridView *trayView); - void setOwnerWidget(QWidget *widget); + void setReferGridView(TrayGridView *trayView); TrayGridView *trayView() const; void resetPosition(); @@ -76,12 +76,13 @@ protected: private: QColor maskColor() const; + ExpandIconWidget *expandWidget() const; private: DockInter *m_dockInter; TrayGridView *m_trayGridView; + TrayGridView *m_referGridView; static Dock::Position m_position; - QWidget *m_ownerWidget; }; #endif // EXPANDICONWIDGET_H diff --git a/frame/window/traymanagerwindow.cpp b/frame/window/traymanagerwindow.cpp index a0b493246..bf7b12d2b 100644 --- a/frame/window/traymanagerwindow.cpp +++ b/frame/window/traymanagerwindow.cpp @@ -27,6 +27,7 @@ #include "quicksettingcontainer.h" #include "systempluginwindow.h" #include "datetimedisplayer.h" +#include "expandiconwidget.h" #include #include @@ -141,6 +142,9 @@ void TrayManagerWindow::setDisplayMode(Dock::DisplayMode displayMode) m_displayMode = displayMode; // 从时尚模式切换到高效模式的时候,需要重新布局 onTrayCountChanged(); + // 如果当前模式为高效模式,则设置当前的trayView为其计算位置的参照 + if (displayMode == Dock::DisplayMode::Fashion) + ExpandIconWidget::popupTrayView()->setReferGridView(m_trayView); } int TrayManagerWindow::appDatetimeSize(const Dock::Position &position) const @@ -223,18 +227,6 @@ void TrayManagerWindow::onTrayCountChanged() Q_EMIT requestUpdate(); } -void TrayManagerWindow::onRequestUpdateWidget(const QList &idxs) -{ - for (int i = 0; i < idxs.size(); i++) { - int idx = idxs[i]; - if (idx < m_model->rowCount()) { - QModelIndex index = m_model->index(idx); - m_trayView->closePersistentEditor(index); - m_trayView->openPersistentEditor(index); - } - } -} - void TrayManagerWindow::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); @@ -303,10 +295,12 @@ void TrayManagerWindow::initConnection() connect(m_trayView, &TrayGridView::dragLeaved, m_delegate, [ this ]{ Q_EMIT m_delegate->requestDrag(true); }); - connect(m_trayView, &TrayGridView::dragEntered, m_delegate, [ this ]{ + connect(m_trayView, &TrayGridView::dragFinished, this, [ this ] { + // 如果拖拽结束,则隐藏托盘 Q_EMIT m_delegate->requestDrag(false); }); - connect(m_model, &TrayModel::requestUpdateWidget, this, &TrayManagerWindow::onRequestUpdateWidget); + + connect(m_model, &TrayModel::rowCountChanged, m_trayView, &TrayGridView::onUpdateEditorView); connect(m_dateTimeWidget, &DateTimeDisplayer::requestUpdate, this, &TrayManagerWindow::requestUpdate); m_trayView->installEventFilter(this); diff --git a/frame/window/traymanagerwindow.h b/frame/window/traymanagerwindow.h index 4068e9a45..7631dc43a 100644 --- a/frame/window/traymanagerwindow.h +++ b/frame/window/traymanagerwindow.h @@ -86,7 +86,6 @@ private: private Q_SLOTS: void onTrayCountChanged(); - void onRequestUpdateWidget(const QList &idxs); private: QWidget *m_appPluginDatetimeWidget;