feat: add a container widget for hold on trays

Change-Id: Ie3ff32b18840440482289267d0b8496bfb982ea2
This commit is contained in:
listenerri 2018-12-26 15:58:08 +08:00
parent 740d95ff1a
commit aae408d5b7
Notes: gerrit 2018-12-26 16:13:11 +08:00
Verified+1: <jenkins@deepin.com>
Code-Review+2: listenerri <listenerri@gmail.com>
Submitted-by: listenerri <listenerri@gmail.com>
Submitted-at: Wed, 26 Dec 2018 16:13:10 +0800
Reviewed-on: https://cr.deepin.io/40899
Project: dde/dde-dock
Branch: refs/heads/dev/drag-and-hold-tray
4 changed files with 208 additions and 21 deletions

View File

@ -0,0 +1,115 @@
#include "fashiontrayholdcontainer.h"
#include "fashiontrayitem.h"
#define SpliterSize 2
#define TraySpace 10
FashionTrayHoldContainer::FashionTrayHoldContainer(Dock::Position dockPosistion, QWidget *parent)
: QWidget(parent),
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
m_holdSpliter(new QLabel),
m_dockPosistion(dockPosistion)
{
setAcceptDrops(true);
m_holdSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
m_mainBoxLayout->setMargin(0);
m_mainBoxLayout->setContentsMargins(0, 0, 0, 0);
m_mainBoxLayout->setSpacing(TraySpace);
m_mainBoxLayout->addWidget(m_holdSpliter);
m_mainBoxLayout->setAlignment(Qt::AlignCenter);
m_mainBoxLayout->setAlignment(m_holdSpliter, Qt::AlignCenter);
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setLayout(m_mainBoxLayout);
}
void FashionTrayHoldContainer::setDockPostion(Dock::Position pos)
{
m_dockPosistion = pos;
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
m_mainBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
} else{
m_mainBoxLayout->setDirection(QBoxLayout::Direction::TopToBottom);
}
}
void FashionTrayHoldContainer::setTrayExpand(const bool expand)
{
m_expand = expand;
// 将显示与隐藏放在 timer 里做以避免收起动画的一些抖动发生
QTimer::singleShot(200, this, [=] {
// 这行代码的逻辑与下面被注释掉的部分相同
setVisible(!(!m_expand && m_holdWrapperList.isEmpty()));
// if (m_expand) {
// setVisible(true);
// } else {
// if (m_holdWrapperList.isEmpty()) {
// setVisible(false);
// } else {
// setVisible(true);
// }
// }
});
}
QSize FashionTrayHoldContainer::sizeHint() const
{
QSize size;
const int TrayWidgetWidth = FashionTrayItem::trayWidgetWidth();
const int TrayWidgetHeight = FashionTrayItem::trayWidgetHeight();
if (m_expand) {
if (m_dockPosistion == Dock::Position::Top || m_dockPosistion == Dock::Position::Bottom) {
size.setWidth(
m_holdWrapperList.size() * TrayWidgetWidth // 所有保留显示的托盘图标
+ SpliterSize // 一个分隔条
+ (m_holdWrapperList.size() + 1) * TraySpace // 所有托盘图标之间的 space + 一个分隔条的 space
);
size.setHeight(height());
} else {
size.setWidth(width());
size.setHeight(
m_holdWrapperList.size() * TrayWidgetHeight // 所有保留显示的托盘图标
+ SpliterSize // 一个分隔条
+ (m_holdWrapperList.size() + 1) * TraySpace // 所有托盘图标之间的 space + 一个分隔条的 space
);
}
} else {
if (m_dockPosistion == Dock::Position::Top || m_dockPosistion == Dock::Position::Bottom) {
size.setWidth(
m_holdWrapperList.size() * TrayWidgetWidth // 所有保留显示的托盘图标
+ m_holdWrapperList.size() * TraySpace // 所有托盘图标之间的 space
);
size.setHeight(height());
} else {
size.setWidth(width());
size.setHeight(
m_holdWrapperList.size() * TrayWidgetHeight // 所有保留显示的托盘图标
+ m_holdWrapperList.size() * TraySpace // 所有托盘图标之间的 space
);
}
}
return size;
}
void FashionTrayHoldContainer::resizeEvent(QResizeEvent *event)
{
const QSize &mSize = event->size();
if (m_dockPosistion == Dock::Position::Top || m_dockPosistion == Dock::Position::Bottom) {
m_holdSpliter->setFixedSize(SpliterSize, mSize.height() * 0.3);
} else{
m_holdSpliter->setFixedSize(mSize.width() * 0.3, SpliterSize);
}
QWidget::resizeEvent(event);
}

View File

@ -0,0 +1,35 @@
#ifndef FASHIONTRAYHOLDCONTAINER_H
#define FASHIONTRAYHOLDCONTAINER_H
#include "constants.h"
#include "fashiontraywidgetwrapper.h"
#include <QWidget>
#include <QBoxLayout>
#include <QLabel>
class FashionTrayHoldContainer : public QWidget
{
Q_OBJECT
public:
explicit FashionTrayHoldContainer(Dock::Position dockPosistion, QWidget *parent = nullptr);
void setDockPostion(Dock::Position pos);
void setTrayExpand(const bool expand);
public:
QSize sizeHint() const Q_DECL_OVERRIDE;
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
private:
QBoxLayout *m_mainBoxLayout;
QLabel *m_holdSpliter;
bool m_expand;
Dock::Position m_dockPosistion;
QList<QPointer<FashionTrayWidgetWrapper>> m_holdWrapperList;
};
#endif // FASHIONTRAYHOLDCONTAINER_H

View File

@ -46,7 +46,8 @@ FashionTrayItem::FashionTrayItem(TrayPlugin *trayPlugin, QWidget *parent)
m_trayPlugin(trayPlugin),
m_controlWidget(new FashionTrayControlWidget(m_dockPosistion)),
m_currentAttentionTray(nullptr),
m_currentDraggingTray(nullptr)
m_currentDraggingTray(nullptr),
m_holdContainer(new FashionTrayHoldContainer(m_dockPosistion))
{
setAcceptDrops(true);
@ -65,12 +66,14 @@ FashionTrayItem::FashionTrayItem(TrayPlugin *trayPlugin, QWidget *parent)
m_mainBoxLayout->addWidget(m_leftSpliter);
m_mainBoxLayout->addLayout(m_trayBoxLayout);
m_mainBoxLayout->addWidget(m_holdContainer);
m_mainBoxLayout->addWidget(m_controlWidget);
m_mainBoxLayout->addWidget(m_rightSpliter);
m_mainBoxLayout->setAlignment(Qt::AlignCenter);
m_trayBoxLayout->setAlignment(Qt::AlignCenter);
m_mainBoxLayout->setAlignment(m_leftSpliter, Qt::AlignCenter);
m_mainBoxLayout->setAlignment(m_holdContainer, Qt::AlignCenter);
m_mainBoxLayout->setAlignment(m_controlWidget, Qt::AlignCenter);
m_mainBoxLayout->setAlignment(m_rightSpliter, Qt::AlignCenter);
@ -180,6 +183,8 @@ void FashionTrayItem::setDockPostion(Dock::Position pos)
m_controlWidget->setDockPostion(m_dockPosistion);
SystemTrayItem::setDockPostion(m_dockPosistion);
m_holdContainer->setDockPostion(m_dockPosistion);
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
m_mainBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
m_trayBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
@ -195,6 +200,9 @@ void FashionTrayItem::onTrayListExpandChanged(const bool expand)
{
m_trayPlugin->saveValue(ExpandedKey, expand);
m_holdContainer->setTrayExpand(expand);
refreshHoldContainerPosition();
if (!isVisible())
return;
@ -307,35 +315,50 @@ QSize FashionTrayItem::wantedTotalSize() const
{
QSize size;
// 保留区域的边界后面跟着的一个 space 由其自己计算
if (m_controlWidget->expanded()) {
if (m_dockPosistion == Dock::Position::Top || m_dockPosistion == Dock::Position::Bottom) {
size.setWidth(m_wrapperList.size() * TrayWidgetWidth // 所有插件
+ TrayWidgetWidth // 控制按钮
+ SpliterSize * 2 // 两个分隔条
+ 3 * TraySpace // MainBoxLayout所有space
+ (m_wrapperList.size() - 1) * TraySpace); // TrayBoxLayout所有space
size.setWidth(
m_wrapperList.size() * TrayWidgetWidth // 所有托盘图标
+ TrayWidgetWidth // 控制按钮
+ SpliterSize * 2 // 两个分隔条
+ TraySpace * 2 // 两个分隔条旁边的 space
+ m_wrapperList.size() * TraySpace // TrayBoxLayout 中所有 space + 后面跟一个 space
+ m_holdContainer->sizeHint().width() // 保留区域的宽
);
size.setHeight(height());
} else {
size.setWidth(width());
size.setHeight(m_wrapperList.size() * TrayWidgetHeight // 所有插件
+ TrayWidgetHeight // 控制按钮
+ SpliterSize * 2 // 两个分隔条
+ 3 * TraySpace // MainBoxLayout所有space
+ (m_wrapperList.size() - 1) * TraySpace); // TrayBoxLayout所有space
size.setHeight(
m_wrapperList.size() * TrayWidgetHeight // 所有托盘图标
+ TrayWidgetHeight // 控制按钮
+ SpliterSize * 2 // 两个分隔条
+ TraySpace * 2 // 两个分隔条旁边的 space
+ m_wrapperList.size() * TraySpace // TrayBoxLayout 中所有 space + 后面跟一个 space
+ m_holdContainer->sizeHint().height() // 保留区域的高
);
}
} else {
if (m_dockPosistion == Dock::Position::Top || m_dockPosistion == Dock::Position::Bottom) {
size.setWidth(TrayWidgetWidth // 控制按钮
+ (m_currentAttentionTray ? TrayWidgetWidth : 0) // 活动状态的tray
+ SpliterSize * 2 // 两个分隔条
+ 3 * TraySpace); // MainBoxLayout所有space
size.setWidth(
TrayWidgetWidth // 控制按钮
+ (m_currentAttentionTray ? TrayWidgetWidth : 0) // 活动状态的 tray
+ SpliterSize * 2 // 两个分隔条
+ TraySpace * 2 // 两个分隔条旁边的 space
+ (m_currentAttentionTray ? TraySpace : 0) // 活动状态的 tray 的 space
+ m_holdContainer->sizeHint().width() // 保留区域的宽
);
size.setHeight(height());
} else {
size.setWidth(width());
size.setHeight(TrayWidgetHeight // 控制按钮
+ (m_currentAttentionTray ? TrayWidgetHeight : 0) // 活动状态的tray
+ SpliterSize * 2 // 两个分隔条
+ 3 * TraySpace); // MainBoxLayout所有space
size.setHeight(
TrayWidgetHeight // 控制按钮
+ (m_currentAttentionTray ? TrayWidgetWidth : 0) // 活动状态的tray
+ SpliterSize * 2 // 两个分隔条
+ TraySpace * 2 // 两个分隔条旁边的 space
+ (m_currentAttentionTray ? TraySpace : 0) // 活动状态的 tray 的 space
+ m_holdContainer->sizeHint().height() // 保留区域的高
);
}
}
@ -540,10 +563,10 @@ void FashionTrayItem::setCurrentAttentionTray(FashionTrayWidgetWrapper *attentio
if (m_currentAttentionTray == attentionWrapper) {
return;
}
moveInAttionTray();
moveInAttionTray(); // move current attention tray to hide area
bool sizeChanged = !m_currentAttentionTray;
m_currentAttentionTray = attentionWrapper;
moveOutAttionTray();
moveOutAttionTray(); // move out current attention tray
if (sizeChanged) {
requestResize();
}
@ -598,6 +621,14 @@ void FashionTrayItem::switchAttionTray(FashionTrayWidgetWrapper *attentionWrappe
m_currentAttentionTray = attentionWrapper;
}
void FashionTrayItem::refreshHoldContainerPosition()
{
const int destIndex = m_mainBoxLayout->indexOf(m_controlWidget)
+ (m_controlWidget->expanded() ? 0 : 1);
m_mainBoxLayout->insertWidget(destIndex, m_holdContainer);
}
void FashionTrayItem::refreshTraysVisible()
{
const bool expand = m_controlWidget->expanded();

View File

@ -26,6 +26,7 @@
#include "trayplugin.h"
#include "fashiontraywidgetwrapper.h"
#include "fashiontraycontrolwidget.h"
#include "fashiontrayholdcontainer.h"
#include <QWidget>
#include <QPointer>
@ -48,6 +49,9 @@ public:
void setDockPostion(Dock::Position pos);
inline static int trayWidgetWidth() {return TrayWidgetWidth;}
inline static int trayWidgetHeight() {return TrayWidgetHeight;}
public slots:
void onTrayListExpandChanged(const bool expand);
void setSuggestIconSize(QSize size);
@ -77,6 +81,7 @@ private Q_SLOTS:
void moveOutAttionTray();
void moveInAttionTray();
void switchAttionTray(FashionTrayWidgetWrapper *attentionWrapper);
void refreshHoldContainerPosition();
void refreshTraysVisible();
void onItemDragStart();
void onItemDragStop();
@ -95,6 +100,7 @@ private:
FashionTrayControlWidget *m_controlWidget;
FashionTrayWidgetWrapper *m_currentAttentionTray;
FashionTrayWidgetWrapper *m_currentDraggingTray;
FashionTrayHoldContainer *m_holdContainer;
QList<QPointer<FashionTrayWidgetWrapper>> m_wrapperList;