dde-dock/frame/controller/multiwindowhelper.cpp

140 lines
4.4 KiB
C++
Raw Normal View History

// 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
#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);
}
}