diff --git a/frame/window/docktraywindow.cpp b/frame/window/docktraywindow.cpp index 640bca6f1..761e8a2c1 100644 --- a/frame/window/docktraywindow.cpp +++ b/frame/window/docktraywindow.cpp @@ -68,13 +68,10 @@ void DockTrayWindow::setPositon(const Dock::Position &position) m_quickIconWidget->setPositon(position); m_trayView->setPosition(position); m_delegate->setPositon(position); - if (m_model->hasExpand()) { - // 切换位置的时候,需要重新关闭编辑器,然后在model的flag函数中再打开,防止图标的方向没有切换过来 - QModelIndex index = m_model->index(0, 0); - m_trayView->closePersistentEditor(index); - } + // 改变位置的时候,需要切换编辑器,以适应正确的位置 + m_trayView->onUpdateEditorView(); updateLayout(position); - onResetLayout(); + onUpdateComponentSize(); } void DockTrayWindow::setDisplayMode(const Dock::DisplayMode &displayMode) @@ -125,20 +122,10 @@ void DockTrayWindow::layoutWidget() void DockTrayWindow::resizeEvent(QResizeEvent *event) { - Q_EMIT requestUpdate(); // 当尺寸发生变化的时候,通知托盘区域刷新尺寸,让托盘图标始终保持居中显示 Q_EMIT m_delegate->sizeHintChanged(m_model->index(0, 0)); QWidget::resizeEvent(event); - switch (m_position) { - case Dock::Position::Left: - case Dock::Position::Right: - m_toolLineLabel->setFixedSize(width() * 0.6, SPLITERSIZE); - break; - case Dock::Position::Top: - case Dock::Position::Bottom: - m_toolLineLabel->setFixedSize(SPLITERSIZE, height() * 0.6); - break; - } + onUpdateComponentSize(); } void DockTrayWindow::paintEvent(QPaintEvent *event) @@ -310,16 +297,16 @@ void DockTrayWindow::initUi() void DockTrayWindow::initConnection() { - connect(m_systemPuginWidget, &SystemPluginWindow::itemChanged, this, &DockTrayWindow::onResetLayout); - connect(m_dateTimeWidget, &DateTimeDisplayer::requestUpdate, this, &DockTrayWindow::onResetLayout); - connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, &DockTrayWindow::onResetLayout); + connect(m_systemPuginWidget, &SystemPluginWindow::itemChanged, this, &DockTrayWindow::onUpdateComponentSize); + connect(m_dateTimeWidget, &DateTimeDisplayer::requestUpdate, this, &DockTrayWindow::onUpdateComponentSize); + connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, &DockTrayWindow::onUpdateComponentSize); connect(m_quickIconWidget, &QuickPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon); connect(m_systemPuginWidget, &SystemPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon); - connect(m_model, &TrayModel::rowCountChanged, this, &DockTrayWindow::onResetLayout); + connect(m_model, &TrayModel::rowCountChanged, this, &DockTrayWindow::onUpdateComponentSize); connect(m_model, &TrayModel::rowCountChanged, m_trayView, &TrayGridView::onUpdateEditorView); connect(m_model, &TrayModel::requestRefreshEditor, m_trayView, &TrayGridView::onUpdateEditorView); connect(m_trayView, &TrayGridView::requestRemove, m_model, &TrayModel::removeRow); - connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onResetLayout); + connect(m_trayView, &TrayGridView::requestRemove, this, &DockTrayWindow::onUpdateComponentSize); connect(m_trayView, &TrayGridView::dragFinished, this, [ this ] { // 如果拖拽结束,则隐藏托盘 Q_EMIT m_delegate->requestDrag(false); @@ -360,26 +347,26 @@ void DockTrayWindow::initAttribute() m_trayView->installEventFilter(this); } -void DockTrayWindow::onResetLayout() +void DockTrayWindow::onUpdateComponentSize() { - switch(m_position) { + switch (m_position) { case Dock::Position::Left: - case Dock::Position::Right: { + case Dock::Position::Right: + m_toolLineLabel->setFixedSize(width() * 0.6, SPLITERSIZE); m_dateTimeWidget->setFixedSize(QWIDGETSIZE_MAX, m_dateTimeWidget->suitableSize().height()); m_systemPuginWidget->setFixedSize(QWIDGETSIZE_MAX, m_systemPuginWidget->suitableSize().height()); m_quickIconWidget->setFixedSize(QWIDGETSIZE_MAX, m_quickIconWidget->suitableSize().height()); m_trayView->setFixedSize(QWIDGETSIZE_MAX, m_trayView->suitableSize().height()); break; - } case Dock::Position::Top: - case Dock::Position::Bottom: { + case Dock::Position::Bottom: + m_toolLineLabel->setFixedSize(SPLITERSIZE, height() * 0.6); m_dateTimeWidget->setFixedSize(m_dateTimeWidget->suitableSize().width(), QWIDGETSIZE_MAX); m_systemPuginWidget->setFixedSize(m_systemPuginWidget->suitableSize().width(), QWIDGETSIZE_MAX); m_quickIconWidget->setFixedSize(m_quickIconWidget->suitableSize().width(), QWIDGETSIZE_MAX); m_trayView->setFixedSize(m_trayView->suitableSize().width(), QWIDGETSIZE_MAX); break; } - } Q_EMIT requestUpdate(); } diff --git a/frame/window/docktraywindow.h b/frame/window/docktraywindow.h index eb5f2def9..4f12df02b 100644 --- a/frame/window/docktraywindow.h +++ b/frame/window/docktraywindow.h @@ -70,7 +70,7 @@ private: void moveToolPlugin(); private Q_SLOTS: - void onResetLayout(); + void onUpdateComponentSize(); void onItemAdded(PluginsItemInterface *itemInter); void onItemRemove(PluginsItemInterface *itemInter); void onDropIcon(QDropEvent *dropEvent); diff --git a/frame/window/tray/tray_delegate.cpp b/frame/window/tray/tray_delegate.cpp index 3e843ff42..3945e8d57 100644 --- a/frame/window/tray/tray_delegate.cpp +++ b/frame/window/tray/tray_delegate.cpp @@ -134,12 +134,14 @@ void TrayDelegate::onUpdateExpand(bool on) model->setExpandVisible(true, true); } } else { + // 获取托盘内图标的数量 + int trayIconCount = TrayModel::getIconModel()->rowCount(); if (expandwidget) { // 如果释放鼠标,则判断当前鼠标的位置是否在托盘内部,如果在,则无需隐藏 QPoint currentPoint = QCursor::pos(); TrayGridWidget *view = ExpandIconWidget::popupTrayView(); - expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint)); - } else { + expandwidget->setTrayPanelVisible(view->geometry().contains(currentPoint) && (trayIconCount > 0)); + } else if (trayIconCount == 0) { ExpandIconWidget::popupTrayView()->hide(); } } diff --git a/frame/window/tray/tray_gridview.cpp b/frame/window/tray/tray_gridview.cpp index 525dd294a..35c55e82a 100644 --- a/frame/window/tray/tray_gridview.cpp +++ b/frame/window/tray/tray_gridview.cpp @@ -413,7 +413,7 @@ void TrayGridView::handleDropEvent(QDropEvent *e) info.pluginInter = (PluginsItemInterface *)(e->mimeData()->imageData().value()); QModelIndex targetIndex = getIndexFromPos(e->pos()); int index = -1; - if (targetIndex.isValid() && targetIndex.row() < dataModel->rowCount() - 1) { + if (targetIndex.isValid() && targetIndex.row() < dataModel->rowCount()) { // 如果拖动的位置是合法的位置,则让其插入到当前的位置 index = targetIndex.row(); dataModel->insertRow(index, info); @@ -435,8 +435,17 @@ void TrayGridView::onUpdateEditorView() for (int i = 0; i < model()->rowCount(); i++) { QModelIndex index = model()->index(i, 0); closePersistentEditor(index); - openPersistentEditor(index); } + // 在关闭QWidget后不要立即调用openPersistentEditor来打开 + // 因为closePersistentEditor后,异步删除QWidget,在关闭后,如果立即调用openPersistentEditor,在删除的时候,会把 + // 通过openPersistentEditor新建的QWidget给删除,引起bug,因此,在所有的都closePersistentEditor后,异步来调用 + // openPersistentEditor就不会出现这种问题 + QMetaObject::invokeMethod(this, [ = ] { + for (int i = 0; i < model()->rowCount(); i++) { + QModelIndex index = model()->index(i, 0); + openPersistentEditor(index); + } + }, Qt::QueuedConnection); } bool TrayGridView::beginDrag(Qt::DropActions supportedActions) @@ -492,27 +501,45 @@ bool TrayGridView::beginDrag(Qt::DropActions supportedActions) m_pressed = false; if (dropAct == Qt::IgnoreAction) { - QPropertyAnimation *posAni = new QPropertyAnimation(pixLabel, "pos", 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()); + if (listModel->isIconTray()) { + // 如果当前是从托盘区域释放,按照原来的流程走 + QPropertyAnimation *posAni = new QPropertyAnimation(pixLabel, "pos", 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(); + m_dropPos = QPoint(); + m_dragPos = QPoint(); + + onUpdateEditorView(); + Q_EMIT dragFinished(); + }); + + posAni->setEasingCurve(QEasingCurve::Linear); + posAni->setDuration(m_aniDuringTime); + posAni->setStartValue((QCursor::pos() - QPoint(0, pixLabel->height() / 2))); + posAni->setEndValue(mapToGlobal(m_dropPos) - QPoint(0, pixLabel->height() / 2)); + pixLabel->show(); + posAni->start(QAbstractAnimation::DeleteWhenStopped); - onUpdateEditorView(); Q_EMIT dragFinished(); - }); - posAni->setEasingCurve(QEasingCurve::Linear); - posAni->setDuration(m_aniDuringTime); - posAni->setStartValue((QCursor::pos() - QPoint(0, pixLabel->height() / 2))); - posAni->setEndValue(mapToGlobal(m_dropPos) - QPoint(0, pixLabel->height() / 2)); - pixLabel->show(); - posAni->start(QAbstractAnimation::DeleteWhenStopped); + } else { + // 如果当前是从任务栏区域释放,则将释放后的图标放到托盘 + listModel->setDragKey(QString()); + clearDragModelIndex(); + TrayModel *trayModel = TrayModel::getIconModel(); + trayModel->addRow(winInfo); + + m_dragPos = QPoint(); + m_dropPos = QPoint(); + + trayModel->saveConfig(-1, winInfo); + Q_EMIT dragFinished(); + } } else { listModel->setDragKey(QString()); clearDragModelIndex(); diff --git a/frame/window/tray/tray_model.cpp b/frame/window/tray/tray_model.cpp index 2f7c6f071..4ef2876b7 100644 --- a/frame/window/tray/tray_model.cpp +++ b/frame/window/tray/tray_model.cpp @@ -180,6 +180,14 @@ void TrayModel::setExpandVisible(bool visible, bool openExpand) } } +void TrayModel::updateOpenExpand(bool openExpand) +{ + for (WinInfo &winInfo : m_winInfos) { + if (winInfo.type == TrayIconType::ExpandIcon) + winInfo.expand = openExpand; + } +} + void TrayModel::setDragKey(const QString &key) { m_dragKey = key; @@ -765,10 +773,10 @@ void TrayModel::addRow(WinInfo info) return; } - beginInsertRows(QModelIndex(), rowCount(), rowCount()); + beginResetModel(); m_winInfos.append(info); sortItems(); - endInsertRows(); + endResetModel(); Q_EMIT requestRefreshEditor(); Q_EMIT rowCountChanged(); diff --git a/frame/window/tray/tray_model.h b/frame/window/tray/tray_model.h index 63887d28d..7eb6e25a6 100644 --- a/frame/window/tray/tray_model.h +++ b/frame/window/tray/tray_model.h @@ -97,6 +97,7 @@ public: void setDragingIndex(const QModelIndex index); void setDragDropIndex(const QModelIndex index); void setExpandVisible(bool visible, bool openExpand = false); + void updateOpenExpand(bool openExpand); void setDragKey(const QString &key); diff --git a/frame/window/tray/widgets/expandiconwidget.cpp b/frame/window/tray/widgets/expandiconwidget.cpp index 79c3e5bf1..4e34c59d8 100644 --- a/frame/window/tray/widgets/expandiconwidget.cpp +++ b/frame/window/tray/widgets/expandiconwidget.cpp @@ -37,31 +37,8 @@ DGUI_USE_NAMESPACE ExpandIconWidget::ExpandIconWidget(QWidget *parent, Qt::WindowFlags f) : BaseTrayWidget(parent, f) - , m_regionInter(new DRegionMonitor(this)) , m_position(Dock::Position::Bottom) { - connect(m_regionInter, &DRegionMonitor::buttonPress, this, [ = ](const QPoint &mousePos, const int flag) { - TrayGridWidget *gridView = popupTrayView(); - // 如果当前是隐藏,那么在点击任何地方都隐藏 - if (!isVisible()) { - gridView->hide(); - return; - } - - if ((flag != DRegionMonitor::WatchedFlags::Button_Left) && (flag != DRegionMonitor::WatchedFlags::Button_Right)) - return; - - QPoint ptPos = parentWidget()->mapToGlobal(this->pos()); - const QRect rect = QRect(ptPos, size()); - if (rect.contains(mousePos)) - return; - - const QRect rctView(gridView->pos(), gridView->size()); - if (rctView.contains(mousePos)) - return; - - gridView->hide(); - }); } ExpandIconWidget::~ExpandIconWidget() @@ -94,10 +71,8 @@ void ExpandIconWidget::setTrayPanelVisible(bool visible) if (visible) { gridParentView->resetPosition(); gridParentView->show(); - m_regionInter->registerRegion(); } else { gridParentView->hide(); - m_regionInter->unregisterRegion(); } } @@ -117,6 +92,17 @@ void ExpandIconWidget::paintEvent(QPaintEvent *event) painter.drawPixmap(rectOfPixmap, pixmap); } +void ExpandIconWidget::moveEvent(QMoveEvent *event) +{ + BaseTrayWidget::moveEvent(event); + // 当前展开按钮位置发生变化的时候,需要同时改变托盘的位置 + QMetaObject::invokeMethod(this, [] { + TrayGridWidget *gridView = popupTrayView(); + if (gridView->isVisible()) + gridView->resetPosition(); + }, Qt::QueuedConnection); +} + const QString ExpandIconWidget::dropIconFile() const { QString arrow; @@ -207,7 +193,9 @@ TrayGridWidget::TrayGridWidget(QWidget *parent) , m_dockInter(new DockInter(dockServiceName(), dockServicePath(), QDBusConnection::sessionBus(), this)) , m_trayGridView(nullptr) , m_referGridView(nullptr) + , m_regionInter(new DRegionMonitor(this)) { + initMember(); setAttribute(Qt::WA_TranslucentBackground); } @@ -278,6 +266,58 @@ void TrayGridWidget::paintEvent(QPaintEvent *event) painter.fillPath(path, maskColor()); } +void TrayGridWidget::showEvent(QShowEvent *event) +{ + m_regionInter->registerRegion(); + QWidget::showEvent(event); +} + +void TrayGridWidget::hideEvent(QHideEvent *event) +{ + m_regionInter->unregisterRegion(); + // 在当前托盘区域隐藏后,需要设置任务栏区域的展开按钮的托盘为隐藏状态 + TrayModel::getDockModel()->updateOpenExpand(false); + QWidget::hideEvent(event); +} + +void TrayGridWidget::initMember() +{ + connect(m_regionInter, &DRegionMonitor::buttonPress, this, [ = ](const QPoint &mousePos, const int flag) { + // 如果当前是隐藏,那么在点击任何地方都隐藏 + if (!isVisible()) { + hide(); + return; + } + + if ((flag != DRegionMonitor::WatchedFlags::Button_Left) && (flag != DRegionMonitor::WatchedFlags::Button_Right)) + return; + + QPoint ptPos = parentWidget()->mapToGlobal(this->pos()); + const QRect rect = QRect(ptPos, size()); + if (rect.contains(mousePos)) + return; + // 如果点击的是展开区域,则不做任何处理,因为点击展开区域自己会处理 + if (m_referGridView) { + QAbstractItemModel *model = m_referGridView->model(); + for (int i = 0; i < model->rowCount(); i++) { + ExpandIconWidget *widget = qobject_cast(m_referGridView->indexWidget(model->index(i, 0))); + if (!widget) + continue; + + QRect rectExpandWidget(widget->mapToGlobal(QPoint(0, 0)), widget->size()); + if (rectExpandWidget.contains(mousePos)) + return; + } + } + + const QRect rctView(pos(), size()); + if (rctView.contains(mousePos)) + return; + + hide(); + }); +} + QColor TrayGridWidget::maskColor() const { QColor color = DGuiApplicationHelper::standardPalette(DGuiApplicationHelper::instance()->themeType()).window().color(); diff --git a/frame/window/tray/widgets/expandiconwidget.h b/frame/window/tray/widgets/expandiconwidget.h index 0aa5f57eb..bbf0918d3 100644 --- a/frame/window/tray/widgets/expandiconwidget.h +++ b/frame/window/tray/widgets/expandiconwidget.h @@ -50,10 +50,10 @@ public: protected: void paintEvent(QPaintEvent *event) override; + void moveEvent(QMoveEvent *event) override; const QString dropIconFile() const; private: - Dtk::Gui::DRegionMonitor *m_regionInter; Dock::Position m_position; }; @@ -73,8 +73,11 @@ public: protected: void paintEvent(QPaintEvent *event) override; + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; private: + void initMember(); QColor maskColor() const; ExpandIconWidget *expandWidget() const; @@ -82,6 +85,7 @@ private: DockInter *m_dockInter; TrayGridView *m_trayGridView; TrayGridView *m_referGridView; + Dtk::Gui::DRegionMonitor *m_regionInter; static Dock::Position m_position; }; diff --git a/frame/window/traymanagerwindow.cpp b/frame/window/traymanagerwindow.cpp index bf7b12d2b..8facb65f0 100644 --- a/frame/window/traymanagerwindow.cpp +++ b/frame/window/traymanagerwindow.cpp @@ -129,11 +129,7 @@ void TrayManagerWindow::setPositon(Dock::Position position) m_quickIconWidget->setPositon(position); m_dateTimeWidget->setPositon(position); m_systemPluginWidget->setPositon(position); - if (m_model->hasExpand()) { - // 切换位置的时候,需要先关闭编辑器,然后在model函数的flag方法中打开 - m_trayView->closePersistentEditor(m_model->index(0, 0)); - } - + m_trayView->onUpdateEditorView(); updateLayout(); }