2023-02-16 13:51:55 +08:00
|
|
|
|
// Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
|
|
|
|
|
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
|
|
|
|
|
//
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
|
|
|
|
2022-05-12 17:09:10 +08:00
|
|
|
|
#include "expandiconwidget.h"
|
|
|
|
|
#include "tray_gridview.h"
|
|
|
|
|
#include "tray_model.h"
|
|
|
|
|
#include "tray_delegate.h"
|
|
|
|
|
#include "dockpopupwindow.h"
|
2022-06-15 13:35:50 +00:00
|
|
|
|
#include "imageutil.h"
|
2023-01-13 15:40:20 +08:00
|
|
|
|
#include "systempluginitem.h"
|
2023-06-07 14:11:50 +08:00
|
|
|
|
#include "docksettings.h"
|
2022-05-12 17:09:10 +08:00
|
|
|
|
|
|
|
|
|
#include <DGuiApplicationHelper>
|
|
|
|
|
#include <DRegionMonitor>
|
2022-05-17 20:57:09 +08:00
|
|
|
|
#include <QBitmap>
|
2022-05-12 17:09:10 +08:00
|
|
|
|
#include <QPainter>
|
2022-05-17 20:57:09 +08:00
|
|
|
|
#include <QPainterPath>
|
2022-05-12 17:09:10 +08:00
|
|
|
|
|
2023-06-07 14:11:50 +08:00
|
|
|
|
#include <qobjectdefs.h>
|
2022-05-12 17:09:10 +08:00
|
|
|
|
#include <xcb/xproto.h>
|
|
|
|
|
|
|
|
|
|
DGUI_USE_NAMESPACE
|
|
|
|
|
|
2023-01-11 09:09:36 +08:00
|
|
|
|
using RegionMonitor = Dtk::Gui::DRegionMonitor;
|
|
|
|
|
|
2022-05-12 17:09:10 +08:00
|
|
|
|
ExpandIconWidget::ExpandIconWidget(QWidget *parent, Qt::WindowFlags f)
|
|
|
|
|
: BaseTrayWidget(parent, f)
|
|
|
|
|
, m_position(Dock::Position::Bottom)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ExpandIconWidget::~ExpandIconWidget()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
void ExpandIconWidget::setPositon(Dock::Position position)
|
2022-05-12 17:09:10 +08:00
|
|
|
|
{
|
2022-11-02 06:57:46 +00:00
|
|
|
|
if (m_position != position)
|
|
|
|
|
m_position = position;
|
2022-05-17 20:57:09 +08:00
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
TrayGridWidget::setPosition(position);
|
2022-05-12 17:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ExpandIconWidget::sendClick(uint8_t mouseButton, int x, int y)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(x);
|
|
|
|
|
Q_UNUSED(y);
|
|
|
|
|
|
|
|
|
|
if (mouseButton != XCB_BUTTON_INDEX_1)
|
|
|
|
|
return;
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
QWidget *gridParentView = popupTrayView();
|
|
|
|
|
setTrayPanelVisible(!gridParentView->isVisible());
|
2022-05-12 17:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ExpandIconWidget::setTrayPanelVisible(bool visible)
|
|
|
|
|
{
|
2022-11-02 06:57:46 +00:00
|
|
|
|
TrayGridWidget *gridParentView = popupTrayView();
|
2022-05-12 17:09:10 +08:00
|
|
|
|
if (visible) {
|
2022-11-02 06:57:46 +00:00
|
|
|
|
gridParentView->resetPosition();
|
2022-10-19 03:50:12 +00:00
|
|
|
|
gridParentView->show();
|
2022-05-12 17:09:10 +08:00
|
|
|
|
} else {
|
2022-10-19 03:50:12 +00:00
|
|
|
|
gridParentView->hide();
|
2022-05-12 17:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QPixmap ExpandIconWidget::icon()
|
|
|
|
|
{
|
|
|
|
|
return QPixmap(dropIconFile());
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
void ExpandIconWidget::paintEvent(QPaintEvent *event)
|
2022-05-12 17:09:10 +08:00
|
|
|
|
{
|
|
|
|
|
QPainter painter(this);
|
2022-06-15 13:35:50 +00:00
|
|
|
|
QPixmap pixmap = ImageUtil::loadSvg(dropIconFile(), QSize(ICON_SIZE, ICON_SIZE));
|
|
|
|
|
QRect rectOfPixmap(rect().x() + (rect().width() - ICON_SIZE) / 2,
|
|
|
|
|
rect().y() + (rect().height() - ICON_SIZE) / 2,
|
|
|
|
|
ICON_SIZE, ICON_SIZE);
|
|
|
|
|
|
|
|
|
|
painter.drawPixmap(rectOfPixmap, pixmap);
|
2022-05-12 17:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-22 10:47:20 +00:00
|
|
|
|
void ExpandIconWidget::moveEvent(QMoveEvent *event)
|
|
|
|
|
{
|
|
|
|
|
BaseTrayWidget::moveEvent(event);
|
|
|
|
|
// 当前展开按钮位置发生变化的时候,需要同时改变托盘的位置
|
|
|
|
|
QMetaObject::invokeMethod(this, [] {
|
|
|
|
|
TrayGridWidget *gridView = popupTrayView();
|
|
|
|
|
if (gridView->isVisible())
|
|
|
|
|
gridView->resetPosition();
|
|
|
|
|
}, Qt::QueuedConnection);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 17:09:10 +08:00
|
|
|
|
const QString ExpandIconWidget::dropIconFile() const
|
|
|
|
|
{
|
|
|
|
|
QString arrow;
|
|
|
|
|
switch (m_position) {
|
|
|
|
|
case Dock::Position::Bottom: {
|
|
|
|
|
arrow = "up";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Top: {
|
|
|
|
|
arrow = "down";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Left: {
|
|
|
|
|
arrow = "right";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Right: {
|
|
|
|
|
arrow = "left";
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString iconFile = QString(":/icons/resources/arrow-%1").arg(arrow);
|
|
|
|
|
if (DGuiApplicationHelper::instance()->themeType() == DGuiApplicationHelper::LightType)
|
|
|
|
|
iconFile += QString("-dark");
|
|
|
|
|
|
|
|
|
|
return iconFile + ".svg";
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
TrayGridWidget *ExpandIconWidget::popupTrayView()
|
2022-05-17 20:57:09 +08:00
|
|
|
|
{
|
2022-10-19 03:50:12 +00:00
|
|
|
|
static TrayGridWidget *gridParentView = nullptr;
|
|
|
|
|
if (gridParentView)
|
|
|
|
|
return gridParentView;
|
|
|
|
|
|
|
|
|
|
gridParentView = new TrayGridWidget(nullptr);
|
|
|
|
|
TrayGridView *trayView = new TrayGridView(gridParentView);
|
|
|
|
|
TrayDelegate *trayDelegate = new TrayDelegate(trayView, trayView);
|
2022-11-02 06:57:46 +00:00
|
|
|
|
TrayModel *trayModel = TrayModel::getIconModel();
|
2022-10-19 03:50:12 +00:00
|
|
|
|
gridParentView->setTrayGridView(trayView);
|
|
|
|
|
|
2023-03-15 12:10:07 +08:00
|
|
|
|
gridParentView->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint);
|
2022-10-19 03:50:12 +00:00
|
|
|
|
trayView->setModel(trayModel);
|
|
|
|
|
trayView->setItemDelegate(trayDelegate);
|
|
|
|
|
trayView->setSpacing(ITEM_SPACING);
|
|
|
|
|
trayView->setDragDistance(2);
|
|
|
|
|
|
|
|
|
|
QVBoxLayout *layout = new QVBoxLayout(gridParentView);
|
|
|
|
|
layout->setContentsMargins(ITEM_SPACING, ITEM_SPACING, ITEM_SPACING, ITEM_SPACING);
|
|
|
|
|
layout->setSpacing(0);
|
|
|
|
|
layout->addWidget(trayView);
|
|
|
|
|
|
|
|
|
|
auto rowCountChanged = [ = ] {
|
2022-11-09 11:03:59 +00:00
|
|
|
|
if (gridParentView->isVisible()) {
|
|
|
|
|
int count = trayModel->rowCount();
|
|
|
|
|
if (count > 0)
|
|
|
|
|
gridParentView->resetPosition();
|
|
|
|
|
else
|
|
|
|
|
gridParentView->hide();
|
|
|
|
|
}
|
2022-10-19 03:50:12 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
connect(trayModel, &TrayModel::rowCountChanged, gridParentView, rowCountChanged);
|
2022-11-09 11:03:59 +00:00
|
|
|
|
connect(trayModel, &TrayModel::requestRefreshEditor, trayView, &TrayGridView::onUpdateEditorView);
|
2022-10-19 03:50:12 +00:00
|
|
|
|
|
2023-01-13 15:40:20 +08:00
|
|
|
|
connect(trayDelegate, &TrayDelegate::requestHide, trayView, &TrayGridView::requestHide);
|
2022-11-02 06:57:46 +00:00
|
|
|
|
connect(trayDelegate, &TrayDelegate::removeRow, trayView, [ = ](const QModelIndex &index) {
|
2022-10-19 03:50:12 +00:00
|
|
|
|
trayView->model()->removeRow(index.row(),index.parent());
|
|
|
|
|
});
|
2022-11-02 06:57:46 +00:00
|
|
|
|
connect(trayModel, &TrayModel::requestOpenEditor, trayView, [ trayView ](const QModelIndex &index) {
|
|
|
|
|
trayView->openPersistentEditor(index);
|
2022-10-19 03:50:12 +00:00
|
|
|
|
});
|
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
QMetaObject::invokeMethod(gridParentView, rowCountChanged, Qt::QueuedConnection);
|
2022-10-19 03:50:12 +00:00
|
|
|
|
|
|
|
|
|
return gridParentView;
|
2022-05-12 17:09:10 +08:00
|
|
|
|
}
|
|
|
|
|
|
2022-05-17 20:57:09 +08:00
|
|
|
|
/**
|
|
|
|
|
* @brief 圆角窗体的绘制
|
|
|
|
|
* @param parent
|
|
|
|
|
*/
|
2022-06-21 16:24:39 +08:00
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
Dock::Position TrayGridWidget::m_position = Dock::Position::Bottom;
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
TrayGridWidget::TrayGridWidget(QWidget *parent)
|
2023-02-20 10:39:53 +08:00
|
|
|
|
: DBlurEffectWidget (parent)
|
2022-10-19 03:50:12 +00:00
|
|
|
|
, m_trayGridView(nullptr)
|
2022-11-09 11:03:59 +00:00
|
|
|
|
, m_referGridView(nullptr)
|
2023-01-11 09:09:36 +08:00
|
|
|
|
, m_regionInter(new RegionMonitor(this))
|
2022-05-17 20:57:09 +08:00
|
|
|
|
{
|
2022-11-22 10:47:20 +00:00
|
|
|
|
initMember();
|
2022-05-17 20:57:09 +08:00
|
|
|
|
setAttribute(Qt::WA_TranslucentBackground);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
void TrayGridWidget::setPosition(const Dock::Position &position)
|
|
|
|
|
{
|
|
|
|
|
m_position = position;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
void TrayGridWidget::setTrayGridView(TrayGridView *trayView)
|
|
|
|
|
{
|
|
|
|
|
m_trayGridView = trayView;
|
2023-01-13 15:40:20 +08:00
|
|
|
|
connect(m_trayGridView, &TrayGridView::requestHide, this, &TrayGridWidget::hide);
|
2022-10-19 03:50:12 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-11-09 11:03:59 +00:00
|
|
|
|
void TrayGridWidget::setReferGridView(TrayGridView *trayView)
|
2022-11-02 06:57:46 +00:00
|
|
|
|
{
|
2022-11-09 11:03:59 +00:00
|
|
|
|
m_referGridView = trayView;
|
2022-11-02 06:57:46 +00:00
|
|
|
|
}
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
TrayGridView *TrayGridWidget::trayView() const
|
|
|
|
|
{
|
|
|
|
|
return m_trayGridView;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-02 06:57:46 +00:00
|
|
|
|
void TrayGridWidget::resetPosition()
|
|
|
|
|
{
|
|
|
|
|
// 如果没有设置所属窗体,则无法计算位置
|
2022-11-09 11:03:59 +00:00
|
|
|
|
ExpandIconWidget *expWidget = expandWidget();
|
|
|
|
|
if (!expWidget)
|
2022-11-02 06:57:46 +00:00
|
|
|
|
return;
|
|
|
|
|
|
2022-11-09 11:03:59 +00:00
|
|
|
|
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));
|
2022-11-02 06:57:46 +00:00
|
|
|
|
switch (m_position) {
|
|
|
|
|
case Dock::Position::Bottom: {
|
|
|
|
|
ptPos.setY(topWidget->y() - height());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Top: {
|
|
|
|
|
ptPos.setY(topWidget->y() + topWidget->height());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Left: {
|
|
|
|
|
ptPos.setX(topWidget->x() + topWidget->width());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case Dock::Position::Right: {
|
|
|
|
|
ptPos.setX(topWidget->x() - width());
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
move(ptPos);
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-22 10:47:20 +00:00
|
|
|
|
void TrayGridWidget::showEvent(QShowEvent *event)
|
|
|
|
|
{
|
|
|
|
|
m_regionInter->registerRegion();
|
2023-02-20 10:39:53 +08:00
|
|
|
|
DBlurEffectWidget::showEvent(event);
|
2022-11-22 10:47:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TrayGridWidget::hideEvent(QHideEvent *event)
|
|
|
|
|
{
|
|
|
|
|
m_regionInter->unregisterRegion();
|
|
|
|
|
// 在当前托盘区域隐藏后,需要设置任务栏区域的展开按钮的托盘为隐藏状态
|
|
|
|
|
TrayModel::getDockModel()->updateOpenExpand(false);
|
2023-02-20 10:39:53 +08:00
|
|
|
|
DBlurEffectWidget::hideEvent(event);
|
2022-11-22 10:47:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void TrayGridWidget::initMember()
|
|
|
|
|
{
|
2023-01-11 09:09:36 +08:00
|
|
|
|
connect(m_regionInter, &RegionMonitor::buttonPress, this, [ = ](const QPoint &mousePos, const int flag) {
|
2022-11-22 10:47:20 +00:00
|
|
|
|
// 如果当前是隐藏,那么在点击任何地方都隐藏
|
|
|
|
|
if (!isVisible()) {
|
|
|
|
|
hide();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-01-11 09:09:36 +08:00
|
|
|
|
if ((flag != RegionMonitor::WatchedFlags::Button_Left) && (flag != RegionMonitor::WatchedFlags::Button_Right))
|
2022-11-22 10:47:20 +00:00
|
|
|
|
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<ExpandIconWidget *>(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;
|
|
|
|
|
|
2023-01-13 15:40:20 +08:00
|
|
|
|
// 查看是否存在SystemPluginItem插件,在此处判断的原因是因为当弹出右键菜单的时候,如果鼠标在菜单上点击
|
|
|
|
|
// 刚好把托盘区域给隐藏了,导致菜单也跟着隐藏,导致点击菜单的时候不生效
|
|
|
|
|
QAbstractItemModel *dataModel = m_trayGridView->model();
|
|
|
|
|
for (int i = 0; i < dataModel->rowCount(); i++) {
|
|
|
|
|
QModelIndex index = dataModel->index(i, 0);
|
2023-03-15 12:10:07 +08:00
|
|
|
|
BaseTrayWidget *widget = qobject_cast<BaseTrayWidget *>(m_trayGridView->indexWidget(index));
|
2023-01-13 15:40:20 +08:00
|
|
|
|
if (widget && widget->containsPoint(mousePos))
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-11-22 10:47:20 +00:00
|
|
|
|
hide();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-19 03:50:12 +00:00
|
|
|
|
QColor TrayGridWidget::maskColor() const
|
2022-05-17 20:57:09 +08:00
|
|
|
|
{
|
|
|
|
|
QColor color = DGuiApplicationHelper::standardPalette(DGuiApplicationHelper::instance()->themeType()).window().color();
|
2023-06-13 15:05:44 +08:00
|
|
|
|
color.setAlpha(0);
|
2022-05-17 20:57:09 +08:00
|
|
|
|
return color;
|
2022-05-12 17:09:10 +08:00
|
|
|
|
}
|
2022-11-09 11:03:59 +00:00
|
|
|
|
|
|
|
|
|
ExpandIconWidget *TrayGridWidget::expandWidget() const
|
|
|
|
|
{
|
|
|
|
|
if (!m_referGridView)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
|
|
|
|
QAbstractItemModel *dataModel = m_referGridView->model();
|
|
|
|
|
if (!dataModel)
|
|
|
|
|
return nullptr;
|
|
|
|
|
|
2022-12-01 20:49:27 +08:00
|
|
|
|
for (int i = 0; i < dataModel->rowCount(); i++) {
|
2022-11-09 11:03:59 +00:00
|
|
|
|
QModelIndex index = dataModel->index(i, 0);
|
|
|
|
|
ExpandIconWidget *widget = qobject_cast<ExpandIconWidget *>(m_referGridView->indexWidget(index));
|
|
|
|
|
if (widget)
|
|
|
|
|
return widget;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nullptr;
|
|
|
|
|
}
|