2023-02-16 15:08:28 +08:00

292 lines
8.6 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) 2011 ~ 2018 Deepin Technology Co., Ltd.
// SPDX-FileCopyrightText: 2018 - 2023 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "normalcontainer.h"
#include "../fashiontrayconstants.h"
NormalContainer::NormalContainer(TrayPlugin *trayPlugin, QWidget *parent)
: AbstractContainer(trayPlugin, parent)
, m_sizeAnimation(new QVariantAnimation(this))
{
m_sizeAnimation->setEasingCurve(QEasingCurve::InOutCubic);
connect(m_sizeAnimation, &QVariantAnimation::valueChanged, [ = ](const QVariant & value) {
if (m_sizeAnimation->state() != QVariantAnimation::Running)
return;
adjustMaxSize(value.toSize());
});
connect(m_sizeAnimation, &QVariantAnimation::finished, [ = ]() {
this->setVisible(expand());
});
connect(DWindowManagerHelper::instance(), &DWindowManagerHelper::hasCompositeChanged, this, &NormalContainer::compositeChanged, Qt::QueuedConnection);
QTimer::singleShot(1, this, &NormalContainer::compositeChanged);
}
void NormalContainer::compositeChanged()
{
int duration = DWindowManagerHelper::instance()->hasComposite() ? 300 : 1;
if (isEmpty())
duration = 0;
m_sizeAnimation->setDuration(duration);
}
QSize NormalContainer::sizeHint() const
{
return totalSize();
}
void NormalContainer::resizeEvent(QResizeEvent *event)
{
if (QPropertyAnimation::Stopped == m_sizeAnimation->state()) {
if (dockPosition() == Dock::Top || dockPosition() == Dock::Bottom)
setMaximumWidth(totalSize().width());
else {
setMaximumHeight(totalSize().height());
}
}
AbstractContainer::resizeEvent(event);
}
bool NormalContainer::acceptWrapper(FashionTrayWidgetWrapper *wrapper)
{
Q_UNUSED(wrapper);
return true;
}
void NormalContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
{
AbstractContainer::addWrapper(wrapper);
if (containsWrapper(wrapper)) {
const QString &key = HoldKeyPrefix + wrapper->absTrayWidget()->itemKeyForConfig();
trayPlugin()->saveValue(wrapper->itemKey(), key, false);
}
}
void NormalContainer::refreshVisible()
{
AbstractContainer::refreshVisible();
for (auto w : wrapperList()) {
if (dockPosition() == Dock::Top || dockPosition() == Dock::Bottom)
w->setFixedSize(itemSize(), QWIDGETSIZE_MAX);
else
w->setFixedSize(QWIDGETSIZE_MAX, itemSize());
}
if (isEmpty()) {
// set the minimum size to 1 to avoid can not drag back wrappers when
// all wrappers has been drag out
setMinimumSize(TraySpace, TraySpace);
} else {
// set the minimum size back to 0 in order to make the fold animation works correctly
setMinimumSize(0, 0);
}
compositeChanged();
QSize endSize = expand() ? totalSize() : QSize(0, 0);
const QPropertyAnimation::State state = m_sizeAnimation->state();
if (state == QPropertyAnimation::Stopped && size() == endSize) {
setVisible(expand());
return;
}
if (state == QPropertyAnimation::Running)
return m_sizeAnimation->setEndValue(endSize);
m_sizeAnimation->setStartValue(size());
m_sizeAnimation->setEndValue(endSize);
if (isVisible() == expand()) {
// 非x86平台第一次启动setEndValue时不进QVariantAnimation::valueChanged
adjustMaxSize(endSize);
return;
}
if (expand()) {
setVisible(true);
}
m_sizeAnimation->start();
}
void NormalContainer::adjustMaxSize(const QSize size)
{
if (dockPosition() == Dock::Top || dockPosition() == Dock::Bottom) {
this->setMaximumWidth(size.width());
this->setMaximumHeight(DOCK_MAX_SIZE);
} else {
this->setMaximumWidth(DOCK_MAX_SIZE);
this->setMaximumHeight(size.height());
}
}
int NormalContainer::itemCount()
{
if (expand())
return AbstractContainer::itemCount();
else
return 0;
}
void NormalContainer::setExpand(const bool expand)
{
// int itemSize;
// if (dockPosition() == Dock::Position::Top || dockPosition() == Dock::Position::Bottom)
// itemSize = std::min(parentWidget()->height(), PLUGIN_BACKGROUND_MAX_SIZE);
// else
// itemSize = std::min(parentWidget()->width(), PLUGIN_BACKGROUND_MAX_SIZE);
for (auto w : wrapperList()) {
w->setAttention(false);
// w->setFixedSize(itemSize, itemSize);
}
AbstractContainer::setExpand(expand);
}
int NormalContainer::whereToInsert(FashionTrayWidgetWrapper *wrapper)
{
// 如果已经对图标进行过排序则完全按照从配置文件中获取的顺序来插入图标(即父类的实现)
if (trayPlugin()->traysSortedInFashionMode()) {
return AbstractContainer::whereToInsert(wrapper);
}
// 如果没有对图标进行过排序则使用下面的默认排序算法:
// 所有应用图标在系统图标的左侧
// 新的应用图标在最左侧的应用图标处插入
// 系统图标按插件默认顺序(收缩箭头起从右往左由大到小排)在应用图标右侧插入
return whereToInsertByDefault(wrapper);
}
int NormalContainer::whereToInsertByDefault(FashionTrayWidgetWrapper *wrapper) const
{
int index = 0;
switch (wrapper->absTrayWidget()->trayTyep()) {
case AbstractTrayWidget::TrayType::ApplicationTray:
index = whereToInsertAppTrayByDefault(wrapper);
break;
case AbstractTrayWidget::TrayType::SystemTray:
index = whereToInsertSystemTrayByDefault(wrapper);
break;
default:
Q_UNREACHABLE();
break;
}
return index;
}
int NormalContainer::whereToInsertAppTrayByDefault(FashionTrayWidgetWrapper *wrapper) const
{
if (wrapperList().isEmpty() || wrapper->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::ApplicationTray) {
return 0;
}
int lastAppTrayIndex = -1;
for (int i = 0; i < wrapperList().size(); ++i) {
if (wrapperList().at(i)->absTrayWidget()->trayTyep() == AbstractTrayWidget::TrayType::ApplicationTray) {
lastAppTrayIndex = i;
continue;
}
break;
}
// there is no AppTray
if (lastAppTrayIndex == -1) {
return 0;
}
// the inserting tray is not a AppTray
if (wrapper->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::ApplicationTray) {
return lastAppTrayIndex + 1;
}
int insertIndex = trayPlugin()->itemSortKey(wrapper->itemKey());
// invalid index
if (insertIndex < -1) {
return 0;
}
for (int i = 0; i < wrapperList().size(); ++i) {
if (wrapperList().at(i)->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::ApplicationTray) {
insertIndex = i;
break;
}
if (insertIndex > trayPlugin()->itemSortKey(wrapperList().at(i)->itemKey())) {
continue;
}
insertIndex = i;
break;
}
if (insertIndex > lastAppTrayIndex + 1) {
insertIndex = lastAppTrayIndex + 1;
}
return insertIndex;
}
int NormalContainer::whereToInsertSystemTrayByDefault(FashionTrayWidgetWrapper *wrapper) const
{
if (wrapperList().isEmpty()) {
return 0;
}
int firstSystemTrayIndex = -1;
for (int i = 0; i < wrapperList().size(); ++i) {
if (wrapperList().at(i)->absTrayWidget()->trayTyep() == AbstractTrayWidget::TrayType::SystemTray) {
firstSystemTrayIndex = i;
break;
}
}
// there is no SystemTray
if (firstSystemTrayIndex == -1) {
return wrapperList().size();
}
// the inserting tray is not a SystemTray
if (wrapper->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::SystemTray) {
return firstSystemTrayIndex;
}
int insertIndex = trayPlugin()->itemSortKey(wrapper->itemKey());
// invalid index
if (insertIndex < -1) {
return firstSystemTrayIndex;
}
for (int i = 0; i < wrapperList().size(); ++i) {
if (wrapperList().at(i)->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::SystemTray) {
continue;
}
if (insertIndex > trayPlugin()->itemSortKey(wrapperList().at(i)->itemKey())) {
continue;
}
insertIndex = i;
break;
}
if (insertIndex < firstSystemTrayIndex) {
return firstSystemTrayIndex;
}
return insertIndex;
}
void NormalContainer::updateSize()
{
if (QPropertyAnimation::Stopped == m_sizeAnimation->state()) {
if (dockPosition() == Dock::Top || dockPosition() == Dock::Bottom)
setMaximumWidth(totalSize().width());
else {
setMaximumHeight(totalSize().height());
}
}
}