dde-dock/frame/controller/multiwindowhelper.cpp
donghualin 56c3019a5c feat: 增加窗口多开的功能
增加窗口多开的窗口类,用于绘制应用图标和打开窗口的图标,根据实际情况让其显示到正确的位置

Log: 增加窗口多开的功能
Influence: 控制中心开启多开窗口显示,观察应用打开的窗口是否在对应的位置显示
Task: https://pms.uniontech.com/task-view-170977.html
Change-Id: I96371b1304f5373f17dad95893ee656056e5f457
2022-08-18 15:41:57 +00:00

155 lines
5.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2022 ~ 2022 Deepin Technology Co., Ltd.
*
* Author: donghualin <donghualin@uniontech.com>
*
* Maintainer: donghualin <donghualin@uniontech.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "multiwindowhelper.h"
#include "appmultiitem.h"
#include "appitem.h"
MultiWindowHelper::MultiWindowHelper(QWidget *appWidget, QWidget *multiWindowWidget, QObject *parent)
: QObject(parent)
, m_appWidget(appWidget)
, m_multiWindowWidget(multiWindowWidget)
, m_displayMode(Dock::DisplayMode::Efficient)
{
m_appWidget->installEventFilter(this);
m_multiWindowWidget->installEventFilter(this);
}
void MultiWindowHelper::setDisplayMode(Dock::DisplayMode displayMode)
{
if (m_displayMode == displayMode)
return;
m_displayMode = displayMode;
resetMultiItemPosition();
}
void MultiWindowHelper::addMultiWindow(int, AppMultiItem *item)
{
int index = itemIndex(item);
if (m_displayMode == Dock::DisplayMode::Efficient) {
// 将多开窗口项目插入到对应的APP的后面
insertChildWidget(m_appWidget, index, item);
} else {
// 将多开窗口插入到工具区域的前面
insertChildWidget(m_multiWindowWidget, index, item);
}
}
void MultiWindowHelper::removeMultiWindow(AppMultiItem *item)
{
if (m_appWidget->children().contains(item))
m_appWidget->layout()->removeWidget(item);
else
m_multiWindowWidget->layout()->removeWidget(item);
}
bool MultiWindowHelper::eventFilter(QObject *watched, QEvent *event)
{
if (watched == m_appWidget || watched == m_multiWindowWidget) {
switch(event->type()) {
case QEvent::ChildAdded:
case QEvent::ChildRemoved: {
/* 这里用异步的方式因为收到QEvent::ChildAdded信号的时候
此时应用还没有插入到Widget中收到QEvent::ChildRemoved信号的时候
此时应用还未从任务栏上移除,通过异步的方式保证同步新增或移除成功后才执行,这样更新的界面才是最准确的
*/
QMetaObject::invokeMethod(this, &MultiWindowHelper::requestUpdate, Qt::QueuedConnection);
break;
}
default:
break;
}
}
return QObject::eventFilter(watched, event);
}
int MultiWindowHelper::itemIndex(AppMultiItem *item)
{
if (m_displayMode != Dock::DisplayMode::Efficient)
return -1;
// 高效模式,查找对应的应用或者这个应用所有的子窗口所在的位置,然后插入到最大的值的后面
int lastIndex = -1;
for (int i = 0; i < m_appWidget->layout()->count(); i++) {
DockItem *dockItem = qobject_cast<DockItem *>(m_appWidget->layout()->itemAt(i)->widget());
if (!dockItem)
continue;
if (dockItem != item->appItem()) {
AppMultiItem *multiItem = qobject_cast<AppMultiItem *>(dockItem);
if (!multiItem || multiItem->appItem() != item->appItem())
continue;
}
lastIndex = i;
}
if (lastIndex >= 0)
return ++lastIndex;
return -1;
}
void MultiWindowHelper::insertChildWidget(QWidget *parentWidget, int index, AppMultiItem *item)
{
QBoxLayout *layout = static_cast<QBoxLayout *>(parentWidget->layout());
if (index >= 0)
layout->insertWidget(index, item);
else
layout->addWidget(item);
}
void MultiWindowHelper::resetMultiItemPosition()
{
QWidget *fromWidget = nullptr;
QWidget *toWidget = nullptr;
if (m_displayMode == Dock::DisplayMode::Efficient) {
// 从时尚模式变换为高效模式
fromWidget = m_multiWindowWidget;
toWidget = m_appWidget;
} else {
// 从高效模式变换到时尚模式
fromWidget = m_appWidget;
toWidget = m_multiWindowWidget;
}
QList<AppMultiItem *> moveWidgetItem;
for (int i = 0; i < fromWidget->layout()->count(); i++) {
AppMultiItem *multiItem = qobject_cast<AppMultiItem *>(fromWidget->layout()->itemAt(i)->widget());
if (!multiItem)
continue;
moveWidgetItem << multiItem;
}
QBoxLayout *toLayout = static_cast<QBoxLayout *>(toWidget->layout());
for (AppMultiItem *item : moveWidgetItem) {
fromWidget->layout()->removeWidget(item);
int index = itemIndex(item);
if (index >= 0)
toLayout->insertWidget(index, item);
else
toLayout->addWidget(item);
}
}