mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-04 17:33:05 +00:00
Merge branch 'dev/drag-and-hold-tray' into merge-dev/drag-and-hold-tray
Change-Id: I9ca2e4cbdd7579d65667e78f611cd5400ca851c2
This commit is contained in:
commit
8bc429af27
Notes:
gerrit
2019-01-07 11:12:18 +08:00
Verified+1: <jenkins@deepin.com> Code-Review+2: listenerri <listenerri@gmail.com> Submitted-by: listenerri <listenerri@gmail.com> Submitted-at: Mon, 07 Jan 2019 11:12:18 +0800 Reviewed-on: https://cr.deepin.io/41127 Project: dde/dde-dock Branch: refs/heads/master
370
plugins/tray/fashiontray/containers/abstractcontainer.cpp
Normal file
370
plugins/tray/fashiontray/containers/abstractcontainer.cpp
Normal file
@ -0,0 +1,370 @@
|
||||
#include "abstractcontainer.h"
|
||||
#include "../fashiontrayconstants.h"
|
||||
|
||||
AbstractContainer::AbstractContainer(TrayPlugin *trayPlugin, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_trayPlugin(trayPlugin),
|
||||
m_wrapperLayout(new QBoxLayout(QBoxLayout::LeftToRight)),
|
||||
m_currentDraggingWrapper(nullptr),
|
||||
m_expand(true),
|
||||
m_dockPosition(Dock::Position::Bottom),
|
||||
m_wrapperSize(QSize(TrayWidgetWidthMin, TrayWidgetHeightMin))
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
|
||||
m_wrapperLayout->setMargin(0);
|
||||
m_wrapperLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_wrapperLayout->setSpacing(TraySpace);
|
||||
|
||||
m_wrapperLayout->setAlignment(Qt::AlignCenter);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setLayout(m_wrapperLayout);
|
||||
}
|
||||
|
||||
void AbstractContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
if (containsWrapper(wrapper)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int index = whereToInsert(wrapper);
|
||||
m_wrapperLayout->insertWidget(index, wrapper);
|
||||
m_wrapperList.insert(index, wrapper);
|
||||
|
||||
wrapper->setAttention(false);
|
||||
wrapper->setFixedSize(m_wrapperSize);
|
||||
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::attentionChanged, this, &AbstractContainer::onWrapperAttentionhChanged, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::dragStart, this, &AbstractContainer::onWrapperDragStart, Qt::UniqueConnection);
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::dragStop, this, &AbstractContainer::onWrapperDragStop, Qt::UniqueConnection);
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::requestSwapWithDragging, this, &AbstractContainer::onWrapperRequestSwapWithDragging, Qt::UniqueConnection);
|
||||
|
||||
refreshVisible();
|
||||
}
|
||||
|
||||
bool AbstractContainer::removeWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
FashionTrayWidgetWrapper *w = takeWrapper(wrapper);
|
||||
if (!w) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// do not delete real tray object, just delete it's wrapper object
|
||||
// the real tray object should be deleted in TrayPlugin class
|
||||
w->absTrayWidget()->setParent(nullptr);
|
||||
w->deleteLater();
|
||||
|
||||
refreshVisible();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AbstractContainer::removeWrapperByTrayWidget(AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
FashionTrayWidgetWrapper *w = wrapperByTrayWidget(trayWidget);
|
||||
if (!w) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return removeWrapper(w);
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *AbstractContainer::takeWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
if (!containsWrapper(wrapper)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (m_currentDraggingWrapper == wrapper) {
|
||||
m_currentDraggingWrapper = nullptr;
|
||||
}
|
||||
|
||||
wrapper->disconnect();
|
||||
m_wrapperLayout->removeWidget(wrapper);
|
||||
m_wrapperList.removeAll(wrapper);
|
||||
|
||||
refreshVisible();
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
void AbstractContainer::setDockPosition(const Dock::Position pos)
|
||||
{
|
||||
m_dockPosition = pos;
|
||||
|
||||
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
|
||||
m_wrapperLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
} else{
|
||||
m_wrapperLayout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
}
|
||||
|
||||
refreshVisible();
|
||||
}
|
||||
|
||||
void AbstractContainer::setExpand(const bool expand)
|
||||
{
|
||||
m_expand = expand;
|
||||
|
||||
refreshVisible();
|
||||
}
|
||||
|
||||
QSize AbstractContainer::totalSize() const
|
||||
{
|
||||
QSize size;
|
||||
|
||||
const int wrapperWidth = m_wrapperSize.width();
|
||||
const int wrapperHeight = m_wrapperSize.height();
|
||||
|
||||
if (m_dockPosition == Dock::Position::Top || m_dockPosition == Dock::Position::Bottom) {
|
||||
size.setWidth(
|
||||
m_wrapperList.size() * wrapperWidth // 所有托盘图标
|
||||
+ m_wrapperList.size() * TraySpace // 所有托盘图标之间 + 一个尾部的 space
|
||||
);
|
||||
size.setHeight(height());
|
||||
} else {
|
||||
size.setWidth(width());
|
||||
size.setHeight(
|
||||
m_wrapperList.size() * wrapperHeight // 所有托盘图标
|
||||
+ m_wrapperList.size() * TraySpace // 所有托盘图标之间 + 一个尾部的 space
|
||||
);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
QSize AbstractContainer::sizeHint() const
|
||||
{
|
||||
return totalSize();
|
||||
}
|
||||
|
||||
void AbstractContainer::clearWrapper()
|
||||
{
|
||||
QList<QPointer<FashionTrayWidgetWrapper>> mList = m_wrapperList;
|
||||
|
||||
for (auto wrapper : mList) {
|
||||
removeWrapper(wrapper);
|
||||
}
|
||||
|
||||
m_wrapperList.clear();
|
||||
|
||||
refreshVisible();
|
||||
}
|
||||
|
||||
void AbstractContainer::saveCurrentOrderToConfig()
|
||||
{
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
m_trayPlugin->setSortKey(m_wrapperList.at(i)->itemKey(), i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void AbstractContainer::setWrapperSize(QSize size)
|
||||
{
|
||||
m_wrapperSize = size;
|
||||
|
||||
for (auto w : m_wrapperList) {
|
||||
w->setFixedSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
bool AbstractContainer::isEmpty()
|
||||
{
|
||||
return m_wrapperList.isEmpty();
|
||||
}
|
||||
|
||||
bool AbstractContainer::containsWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
for (auto w : m_wrapperList) {
|
||||
if (w == wrapper) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractContainer::containsWrapperByTrayWidget(AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
if (wrapperByTrayWidget(trayWidget)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *AbstractContainer::wrapperByTrayWidget(AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
for (auto w : m_wrapperList) {
|
||||
if (w->absTrayWidget() == trayWidget) {
|
||||
return w;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void AbstractContainer::addDraggingWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
addWrapper(wrapper);
|
||||
|
||||
if (containsWrapper(wrapper)) {
|
||||
m_currentDraggingWrapper = wrapper;
|
||||
}
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *AbstractContainer::takeDraggingWrapper()
|
||||
{
|
||||
if (!m_currentDraggingWrapper) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return takeWrapper(m_currentDraggingWrapper);
|
||||
}
|
||||
|
||||
int AbstractContainer::whereToInsert(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
if (m_wrapperList.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//根据配置文件记录的顺序排序
|
||||
const int destSortKey = m_trayPlugin->itemSortKey(wrapper->itemKey());
|
||||
|
||||
if (destSortKey < -1) {
|
||||
return 0;
|
||||
}
|
||||
if (destSortKey == -1) {
|
||||
return m_wrapperList.size();
|
||||
}
|
||||
|
||||
// 当目标插入位置为列表的大小时将从最后面追加到列表中
|
||||
int destIndex = m_wrapperList.size();
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
if (destSortKey > m_trayPlugin->itemSortKey(m_wrapperList.at(i)->itemKey())) {
|
||||
continue;
|
||||
}
|
||||
destIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return destIndex;
|
||||
}
|
||||
|
||||
TrayPlugin *AbstractContainer::trayPlugin() const
|
||||
{
|
||||
return m_trayPlugin;
|
||||
}
|
||||
|
||||
QList<QPointer<FashionTrayWidgetWrapper> > AbstractContainer::wrapperList() const
|
||||
{
|
||||
return m_wrapperList;
|
||||
}
|
||||
|
||||
QBoxLayout *AbstractContainer::wrapperLayout() const
|
||||
{
|
||||
return m_wrapperLayout;
|
||||
}
|
||||
|
||||
// replace current WrapperLayout by "layout"
|
||||
// but will not setLayout here, so the caller should handle the new WrapperLayout
|
||||
void AbstractContainer::setWrapperLayout(QBoxLayout *layout)
|
||||
{
|
||||
delete m_wrapperLayout;
|
||||
m_wrapperLayout = layout;
|
||||
}
|
||||
|
||||
bool AbstractContainer::expand() const
|
||||
{
|
||||
return m_expand;
|
||||
}
|
||||
|
||||
Dock::Position AbstractContainer::dockPosition() const
|
||||
{
|
||||
return m_dockPosition;
|
||||
}
|
||||
|
||||
QSize AbstractContainer::wrapperSize() const
|
||||
{
|
||||
return m_wrapperSize;
|
||||
}
|
||||
|
||||
void AbstractContainer::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat(TRAY_ITEM_DRAG_MIMEDATA) && !m_currentDraggingWrapper) {
|
||||
event->accept();
|
||||
Q_EMIT requestDraggingWrapper();
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget::dragEnterEvent(event);
|
||||
}
|
||||
|
||||
void AbstractContainer::onWrapperAttentionhChanged(const bool attention)
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = dynamic_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
Q_EMIT attentionChanged(wrapper, attention);
|
||||
}
|
||||
|
||||
void AbstractContainer::onWrapperDragStart()
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentDraggingWrapper = wrapper;
|
||||
|
||||
Q_EMIT draggingStateChanged(wrapper, true);
|
||||
}
|
||||
|
||||
void AbstractContainer::onWrapperDragStop()
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_currentDraggingWrapper == wrapper) {
|
||||
m_currentDraggingWrapper = nullptr;
|
||||
} else {
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
saveCurrentOrderToConfig();
|
||||
|
||||
Q_EMIT draggingStateChanged(wrapper, false);
|
||||
}
|
||||
|
||||
void AbstractContainer::onWrapperRequestSwapWithDragging()
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
if (!wrapper || wrapper == m_currentDraggingWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
// the current dragging wrapper is null means that the dragging wrapper is contains by
|
||||
// another container, so this container need to emit requireDraggingWrapper() signal
|
||||
// to notify FashionTrayItem, the FashionTrayItem will move the dragging wrapper to this container
|
||||
if (!m_currentDraggingWrapper) {
|
||||
Q_EMIT requestDraggingWrapper();
|
||||
// here have to give up if dragging wrapper is still null
|
||||
if (!m_currentDraggingWrapper) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const int indexOfDest = m_wrapperLayout->indexOf(wrapper);
|
||||
const int indexOfDragging = m_wrapperLayout->indexOf(m_currentDraggingWrapper);
|
||||
|
||||
m_wrapperLayout->removeWidget(m_currentDraggingWrapper);
|
||||
m_wrapperLayout->insertWidget(indexOfDest, m_currentDraggingWrapper);
|
||||
|
||||
m_wrapperList.insert(indexOfDest, m_wrapperList.takeAt(indexOfDragging));
|
||||
}
|
78
plugins/tray/fashiontray/containers/abstractcontainer.h
Normal file
78
plugins/tray/fashiontray/containers/abstractcontainer.h
Normal file
@ -0,0 +1,78 @@
|
||||
#ifndef ABSTRACTCONTAINER_H
|
||||
#define ABSTRACTCONTAINER_H
|
||||
|
||||
#include "constants.h"
|
||||
#include "trayplugin.h"
|
||||
#include "../fashiontraywidgetwrapper.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
class AbstractContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AbstractContainer(TrayPlugin *trayPlugin, QWidget *parent = nullptr);
|
||||
|
||||
virtual bool acceptWrapper(FashionTrayWidgetWrapper *wrapper) = 0;
|
||||
virtual void refreshVisible() = 0;
|
||||
|
||||
virtual void addWrapper(FashionTrayWidgetWrapper *wrapper);
|
||||
virtual bool removeWrapper(FashionTrayWidgetWrapper *wrapper);
|
||||
virtual bool removeWrapperByTrayWidget(AbstractTrayWidget *trayWidget);
|
||||
virtual FashionTrayWidgetWrapper *takeWrapper(FashionTrayWidgetWrapper *wrapper);
|
||||
virtual void setDockPosition(const Dock::Position pos);
|
||||
virtual void setExpand(const bool expand);
|
||||
virtual QSize totalSize() const;
|
||||
|
||||
QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
|
||||
void clearWrapper();
|
||||
void saveCurrentOrderToConfig();
|
||||
void setWrapperSize(QSize size);
|
||||
bool isEmpty();
|
||||
bool containsWrapper(FashionTrayWidgetWrapper *wrapper);
|
||||
bool containsWrapperByTrayWidget(AbstractTrayWidget *trayWidget);
|
||||
FashionTrayWidgetWrapper *wrapperByTrayWidget(AbstractTrayWidget *trayWidget);
|
||||
|
||||
void addDraggingWrapper(FashionTrayWidgetWrapper *wrapper);
|
||||
FashionTrayWidgetWrapper *takeDraggingWrapper();
|
||||
|
||||
Q_SIGNALS:
|
||||
void attentionChanged(FashionTrayWidgetWrapper *wrapper, const bool attention);
|
||||
void requestDraggingWrapper();
|
||||
void draggingStateChanged(FashionTrayWidgetWrapper *wrapper, const bool dragging);
|
||||
|
||||
protected:
|
||||
virtual int whereToInsert(FashionTrayWidgetWrapper *wrapper);
|
||||
|
||||
TrayPlugin *trayPlugin() const;
|
||||
QList<QPointer<FashionTrayWidgetWrapper>> wrapperList() const;
|
||||
QBoxLayout *wrapperLayout() const;
|
||||
void setWrapperLayout(QBoxLayout *layout);
|
||||
bool expand() const;
|
||||
Dock::Position dockPosition() const;
|
||||
QSize wrapperSize() const;
|
||||
|
||||
protected:
|
||||
void dragEnterEvent(QDragEnterEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onWrapperAttentionhChanged(const bool attention);
|
||||
void onWrapperDragStart();
|
||||
void onWrapperDragStop();
|
||||
void onWrapperRequestSwapWithDragging();
|
||||
|
||||
private:
|
||||
TrayPlugin *m_trayPlugin;
|
||||
QBoxLayout *m_wrapperLayout;
|
||||
|
||||
QPointer<FashionTrayWidgetWrapper> m_currentDraggingWrapper;
|
||||
QList<QPointer<FashionTrayWidgetWrapper>> m_wrapperList;
|
||||
|
||||
bool m_expand;
|
||||
Dock::Position m_dockPosition;
|
||||
|
||||
QSize m_wrapperSize;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTCONTAINER_H
|
36
plugins/tray/fashiontray/containers/attentioncontainer.cpp
Normal file
36
plugins/tray/fashiontray/containers/attentioncontainer.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "attentioncontainer.h"
|
||||
|
||||
AttentionContainer::AttentionContainer(TrayPlugin *trayPlugin, QWidget *parent)
|
||||
: AbstractContainer(trayPlugin, parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *AttentionContainer::takeAttentionWrapper()
|
||||
{
|
||||
if (isEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return takeWrapper(wrapperList().first());
|
||||
}
|
||||
|
||||
bool AttentionContainer::acceptWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AttentionContainer::refreshVisible()
|
||||
{
|
||||
setVisible(!isEmpty());
|
||||
}
|
||||
|
||||
void AttentionContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
if (!isEmpty()) {
|
||||
qDebug() << "Reject! Already contains a attention wrapper!";
|
||||
return;
|
||||
}
|
||||
|
||||
AbstractContainer::addWrapper(wrapper);
|
||||
}
|
21
plugins/tray/fashiontray/containers/attentioncontainer.h
Normal file
21
plugins/tray/fashiontray/containers/attentioncontainer.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef ATTENTIONCONTAINER_H
|
||||
#define ATTENTIONCONTAINER_H
|
||||
|
||||
#include "abstractcontainer.h"
|
||||
|
||||
class AttentionContainer : public AbstractContainer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AttentionContainer(TrayPlugin *trayPlugin, QWidget *parent = nullptr);
|
||||
|
||||
FashionTrayWidgetWrapper *takeAttentionWrapper();
|
||||
|
||||
// AbstractContainer interface
|
||||
public:
|
||||
bool acceptWrapper(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
void refreshVisible() Q_DECL_OVERRIDE;
|
||||
void addWrapper(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
};
|
||||
|
||||
#endif // ATTENTIONCONTAINER_H
|
124
plugins/tray/fashiontray/containers/holdcontainer.cpp
Normal file
124
plugins/tray/fashiontray/containers/holdcontainer.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "holdcontainer.h"
|
||||
#include "../fashiontrayconstants.h"
|
||||
|
||||
HoldContainer::HoldContainer(TrayPlugin *trayPlugin, QWidget *parent)
|
||||
: AbstractContainer(trayPlugin, parent),
|
||||
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
|
||||
m_holdSpliter(new SpliterAnimated(this))
|
||||
{
|
||||
m_mainBoxLayout->setMargin(0);
|
||||
m_mainBoxLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_mainBoxLayout->setSpacing(TraySpace);
|
||||
|
||||
QBoxLayout *preLayout = wrapperLayout();
|
||||
QBoxLayout *newLayout = new QBoxLayout(QBoxLayout::Direction::LeftToRight);
|
||||
for (int i = 0; i < preLayout->count(); ++i) {
|
||||
newLayout->addItem(preLayout->takeAt(i));
|
||||
}
|
||||
setWrapperLayout(newLayout);
|
||||
|
||||
m_mainBoxLayout->addWidget(m_holdSpliter);
|
||||
m_mainBoxLayout->addLayout(newLayout);
|
||||
|
||||
m_mainBoxLayout->setAlignment(m_holdSpliter, Qt::AlignCenter);
|
||||
m_mainBoxLayout->setAlignment(newLayout, Qt::AlignCenter);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setLayout(m_mainBoxLayout);
|
||||
}
|
||||
|
||||
bool HoldContainer::acceptWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
const QString &key = wrapper->itemKey() + HoldKeySuffix;
|
||||
return trayPlugin()->getValue(wrapper->itemKey(), key, false).toBool();
|
||||
}
|
||||
|
||||
void HoldContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
AbstractContainer::addWrapper(wrapper);
|
||||
|
||||
if (containsWrapper(wrapper)) {
|
||||
const QString &key = wrapper->itemKey() + HoldKeySuffix;
|
||||
trayPlugin()->saveValue(wrapper->itemKey(), key, true);
|
||||
}
|
||||
}
|
||||
|
||||
void HoldContainer::refreshVisible()
|
||||
{
|
||||
setVisible(expand() || !isEmpty());
|
||||
}
|
||||
|
||||
void HoldContainer::setDockPosition(const Dock::Position pos)
|
||||
{
|
||||
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
|
||||
m_mainBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
} else{
|
||||
m_mainBoxLayout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
}
|
||||
|
||||
m_holdSpliter->setDockPosition(pos);
|
||||
|
||||
AbstractContainer::setDockPosition(pos);
|
||||
}
|
||||
|
||||
void HoldContainer::setExpand(const bool expand)
|
||||
{
|
||||
m_holdSpliter->setVisible(expand);
|
||||
|
||||
AbstractContainer::setExpand(expand);
|
||||
}
|
||||
|
||||
QSize HoldContainer::totalSize() const
|
||||
{
|
||||
QSize size = AbstractContainer::totalSize();
|
||||
|
||||
if (expand()) {
|
||||
if (dockPosition() == Dock::Position::Top || dockPosition() == Dock::Position::Bottom) {
|
||||
size.setWidth(
|
||||
size.width()
|
||||
+ SpliterSize
|
||||
+ TraySpace
|
||||
);
|
||||
size.setHeight(height());
|
||||
} else {
|
||||
size.setWidth(width());
|
||||
size.setHeight(
|
||||
size.height()
|
||||
+ SpliterSize
|
||||
+ TraySpace
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void HoldContainer::setDragging(const bool dragging)
|
||||
{
|
||||
if (dragging) {
|
||||
m_holdSpliter->startAnimation();
|
||||
} else {
|
||||
m_holdSpliter->stopAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
void HoldContainer::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
const QSize &mSize = event->size();
|
||||
const Dock::Position dockPosition = trayPlugin()->dockPosition();
|
||||
|
||||
if (dockPosition == Dock::Position::Top || dockPosition == Dock::Position::Bottom) {
|
||||
m_holdSpliterMiniSize = QSize(SpliterSize, mSize.height() * 0.3);
|
||||
m_holdSpliterMaxSize = QSize(SpliterSize, mSize.height() * 0.5);
|
||||
m_holdSpliter->setFixedSize(SpliterSize, mSize.height());
|
||||
} else{
|
||||
m_holdSpliterMiniSize = QSize(mSize.width() * 0.3, SpliterSize);
|
||||
m_holdSpliterMaxSize = QSize(mSize.width() * 0.5, SpliterSize);
|
||||
m_holdSpliter->setFixedSize(mSize.width(), SpliterSize);
|
||||
}
|
||||
|
||||
m_holdSpliter->setStartValue(m_holdSpliterMiniSize);
|
||||
m_holdSpliter->setEndValue(m_holdSpliterMaxSize);
|
||||
|
||||
AbstractContainer::resizeEvent(event);
|
||||
}
|
34
plugins/tray/fashiontray/containers/holdcontainer.h
Normal file
34
plugins/tray/fashiontray/containers/holdcontainer.h
Normal file
@ -0,0 +1,34 @@
|
||||
#ifndef HOLDCONTAINER_H
|
||||
#define HOLDCONTAINER_H
|
||||
|
||||
#include "abstractcontainer.h"
|
||||
#include "spliteranimated.h"
|
||||
|
||||
class HoldContainer : public AbstractContainer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HoldContainer(TrayPlugin *trayPlugin, QWidget *parent = nullptr);
|
||||
|
||||
public:
|
||||
bool acceptWrapper(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
void addWrapper(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
void refreshVisible() Q_DECL_OVERRIDE;
|
||||
void setDockPosition(const Dock::Position pos) Q_DECL_OVERRIDE;
|
||||
void setExpand(const bool expand) Q_DECL_OVERRIDE;
|
||||
QSize totalSize() const Q_DECL_OVERRIDE;
|
||||
|
||||
void setDragging(const bool dragging);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QBoxLayout *m_mainBoxLayout;
|
||||
SpliterAnimated *m_holdSpliter;
|
||||
|
||||
QSize m_holdSpliterMiniSize;
|
||||
QSize m_holdSpliterMaxSize;
|
||||
};
|
||||
|
||||
#endif // HOLDCONTAINER_H
|
169
plugins/tray/fashiontray/containers/normalcontainer.cpp
Normal file
169
plugins/tray/fashiontray/containers/normalcontainer.cpp
Normal file
@ -0,0 +1,169 @@
|
||||
#include "normalcontainer.h"
|
||||
#include "../fashiontrayconstants.h"
|
||||
|
||||
NormalContainer::NormalContainer(TrayPlugin *trayPlugin, QWidget *parent)
|
||||
: AbstractContainer(trayPlugin, parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool NormalContainer::acceptWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
Q_UNUSED(wrapper);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NormalContainer::addWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
AbstractContainer::addWrapper(wrapper);
|
||||
|
||||
if (containsWrapper(wrapper)) {
|
||||
const QString &key = wrapper->itemKey() + HoldKeySuffix;
|
||||
trayPlugin()->saveValue(wrapper->itemKey(), key, false);
|
||||
}
|
||||
}
|
||||
|
||||
void NormalContainer::refreshVisible()
|
||||
{
|
||||
if (isEmpty()) {
|
||||
// set the minimum size to 1 to avoid can not drag back wrappers when
|
||||
// all wrappers has been drag out
|
||||
setMinimumSize(1, 1);
|
||||
} else {
|
||||
// set the minimum size back to 0 in order to make the fold animation works correctly
|
||||
setMinimumSize(0, 0);
|
||||
}
|
||||
|
||||
setVisible(expand());
|
||||
}
|
||||
|
||||
void NormalContainer::setExpand(const bool expand)
|
||||
{
|
||||
for (auto w : wrapperList()) {
|
||||
// reset all tray item attention state
|
||||
w->setAttention(false);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
28
plugins/tray/fashiontray/containers/normalcontainer.h
Normal file
28
plugins/tray/fashiontray/containers/normalcontainer.h
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef NORMALCONTAINER_H
|
||||
#define NORMALCONTAINER_H
|
||||
|
||||
#include "abstractcontainer.h"
|
||||
|
||||
class NormalContainer : public AbstractContainer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit NormalContainer(TrayPlugin *trayPlugin, QWidget *parent = nullptr);
|
||||
|
||||
// AbstractContainer interface
|
||||
public:
|
||||
bool acceptWrapper(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
void addWrapper(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
void refreshVisible() Q_DECL_OVERRIDE;
|
||||
void setExpand(const bool expand) Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
int whereToInsert(FashionTrayWidgetWrapper *wrapper) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
int whereToInsertByDefault(FashionTrayWidgetWrapper *wrapper) const;
|
||||
int whereToInsertAppTrayByDefault(FashionTrayWidgetWrapper *wrapper) const;
|
||||
int whereToInsertSystemTrayByDefault(FashionTrayWidgetWrapper *wrapper) const;
|
||||
};
|
||||
|
||||
#endif // NORMALCONTAINER_H
|
107
plugins/tray/fashiontray/containers/spliteranimated.cpp
Normal file
107
plugins/tray/fashiontray/containers/spliteranimated.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
#include "spliteranimated.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QDebug>
|
||||
|
||||
#define OpacityMax 0.3
|
||||
#define OpacityMini 0.1
|
||||
|
||||
SpliterAnimated::SpliterAnimated(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_sizeAnimation(new QVariantAnimation(this)),
|
||||
m_currentOpacity(OpacityMini),
|
||||
m_dockPosition(Dock::Position::Bottom)
|
||||
{
|
||||
m_sizeAnimation->setDuration(500);
|
||||
m_sizeAnimation->setLoopCount(-1);
|
||||
|
||||
connect(m_sizeAnimation, &QVariantAnimation::valueChanged, this, &SpliterAnimated::onSizeAnimationValueChanged);
|
||||
}
|
||||
|
||||
void SpliterAnimated::setStartValue(const QVariant &value)
|
||||
{
|
||||
m_sizeAnimation->setStartValue(value);
|
||||
}
|
||||
|
||||
void SpliterAnimated::setEndValue(const QVariant &value)
|
||||
{
|
||||
m_sizeAnimation->setEndValue(value);
|
||||
}
|
||||
|
||||
void SpliterAnimated::startAnimation()
|
||||
{
|
||||
if (!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentOpacity = OpacityMini;
|
||||
|
||||
if (m_dockPosition == Dock::Position::Top || m_dockPosition == Dock::Position::Bottom) {
|
||||
m_opacityChangeStep = (OpacityMax - OpacityMini) /
|
||||
(m_sizeAnimation->endValue().toSizeF().height() -
|
||||
m_sizeAnimation->startValue().toSizeF().height());
|
||||
} else {
|
||||
m_opacityChangeStep = (OpacityMax - OpacityMini) /
|
||||
(m_sizeAnimation->endValue().toSizeF().width() -
|
||||
m_sizeAnimation->startValue().toSizeF().width());
|
||||
}
|
||||
|
||||
m_sizeAnimation->start();
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void SpliterAnimated::stopAnimation()
|
||||
{
|
||||
m_sizeAnimation->stop();
|
||||
m_currentOpacity = OpacityMini;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void SpliterAnimated::setDockPosition(const Dock::Position position)
|
||||
{
|
||||
m_dockPosition = position;
|
||||
}
|
||||
|
||||
void SpliterAnimated::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
Q_UNUSED(event);
|
||||
|
||||
QSizeF destSize = m_sizeAnimation->state() == QVariantAnimation::Running
|
||||
? m_sizeAnimation->currentValue().toSizeF()
|
||||
: m_sizeAnimation->startValue().toSizeF();
|
||||
|
||||
QRectF destRect(rect().topLeft(), destSize);
|
||||
destRect.moveCenter(QRectF(rect()).center());
|
||||
|
||||
QPainterPath path;
|
||||
path.addRect(destRect);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setOpacity(m_currentOpacity);
|
||||
painter.fillPath(path, QColor::fromRgb(255, 255, 255));
|
||||
}
|
||||
|
||||
void SpliterAnimated::onSizeAnimationValueChanged(const QVariant &value)
|
||||
{
|
||||
if (m_sizeAnimation->direction() == QVariantAnimation::Direction::Forward) {
|
||||
m_currentOpacity += m_opacityChangeStep;
|
||||
if (m_currentOpacity > OpacityMax) {
|
||||
m_currentOpacity = OpacityMax;
|
||||
}
|
||||
} else {
|
||||
m_currentOpacity -= m_opacityChangeStep;
|
||||
if (m_currentOpacity < OpacityMini) {
|
||||
m_currentOpacity = OpacityMini;
|
||||
}
|
||||
}
|
||||
|
||||
if (value == m_sizeAnimation->endValue()) {
|
||||
m_sizeAnimation->setDirection(QVariantAnimation::Direction::Backward);
|
||||
} else if (value == m_sizeAnimation->startValue()) {
|
||||
m_sizeAnimation->setDirection(QVariantAnimation::Direction::Forward);
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
36
plugins/tray/fashiontray/containers/spliteranimated.h
Normal file
36
plugins/tray/fashiontray/containers/spliteranimated.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef SPLITERANIMATED_H
|
||||
#define SPLITERANIMATED_H
|
||||
|
||||
#include <constants.h>
|
||||
|
||||
#include <QWidget>
|
||||
#include <QVariantAnimation>
|
||||
|
||||
class SpliterAnimated : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SpliterAnimated(QWidget *parent = nullptr);
|
||||
|
||||
void setStartValue(const QVariant &value);
|
||||
void setEndValue(const QVariant &value);
|
||||
void startAnimation();
|
||||
void stopAnimation();
|
||||
void setDockPosition(const Dock::Position position);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onSizeAnimationValueChanged(const QVariant &value);
|
||||
|
||||
private:
|
||||
QVariantAnimation *m_sizeAnimation;
|
||||
|
||||
qreal m_opacityChangeStep;
|
||||
qreal m_currentOpacity;
|
||||
|
||||
Dock::Position m_dockPosition;
|
||||
};
|
||||
|
||||
#endif // SPLITERANIMATED_H
|
16
plugins/tray/fashiontray/fashiontrayconstants.h
Normal file
16
plugins/tray/fashiontray/fashiontrayconstants.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef FASHIONTRAYCONSTANTS_H
|
||||
#define FASHIONTRAYCONSTANTS_H
|
||||
|
||||
namespace Dock {
|
||||
|
||||
#define SpliterSize 2
|
||||
#define TraySpace 10
|
||||
#define TrayWidgetWidthMin 24
|
||||
#define TrayWidgetHeightMin 24
|
||||
|
||||
|
||||
#define HoldKeySuffix "-holded"
|
||||
|
||||
}
|
||||
|
||||
#endif // FASHIONTRAYCONSTANTS_H
|
453
plugins/tray/fashiontray/fashiontrayitem.cpp
Normal file
453
plugins/tray/fashiontray/fashiontrayitem.cpp
Normal file
@ -0,0 +1,453 @@
|
||||
/*
|
||||
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: listenerri <listenerri@gmail.com>
|
||||
*
|
||||
* Maintainer: listenerri <listenerri@gmail.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 "fashiontrayitem.h"
|
||||
#include "fashiontray/fashiontrayconstants.h"
|
||||
#include "system-trays/systemtrayitem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QResizeEvent>
|
||||
|
||||
#define ExpandedKey "fashion-tray-expanded"
|
||||
|
||||
int FashionTrayItem::TrayWidgetWidth = TrayWidgetWidthMin;
|
||||
int FashionTrayItem::TrayWidgetHeight = TrayWidgetHeightMin;
|
||||
|
||||
FashionTrayItem::FashionTrayItem(TrayPlugin *trayPlugin, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
|
||||
m_leftSpliter(new QLabel),
|
||||
m_rightSpliter(new QLabel),
|
||||
m_attentionDelayTimer(new QTimer(this)),
|
||||
m_trayPlugin(trayPlugin),
|
||||
m_controlWidget(new FashionTrayControlWidget(trayPlugin->dockPosition())),
|
||||
m_currentDraggingTray(nullptr),
|
||||
m_normalContainer(new NormalContainer(m_trayPlugin)),
|
||||
m_attentionContainer(new AttentionContainer(m_trayPlugin)),
|
||||
m_holdContainer(new HoldContainer(m_trayPlugin))
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
|
||||
m_leftSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
|
||||
m_rightSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
|
||||
|
||||
m_controlWidget->setFixedSize(QSize(TrayWidgetWidth, TrayWidgetHeight));
|
||||
|
||||
m_normalContainer->setVisible(false);
|
||||
m_attentionContainer->setVisible(false);
|
||||
m_holdContainer->setVisible(false);
|
||||
|
||||
m_mainBoxLayout->setMargin(0);
|
||||
m_mainBoxLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_mainBoxLayout->setSpacing(TraySpace);
|
||||
|
||||
m_mainBoxLayout->addWidget(m_leftSpliter);
|
||||
m_mainBoxLayout->addWidget(m_normalContainer);
|
||||
m_mainBoxLayout->addWidget(m_holdContainer);
|
||||
m_mainBoxLayout->addWidget(m_controlWidget);
|
||||
m_mainBoxLayout->addWidget(m_attentionContainer);
|
||||
m_mainBoxLayout->addWidget(m_rightSpliter);
|
||||
|
||||
m_mainBoxLayout->setAlignment(m_leftSpliter, Qt::AlignCenter);
|
||||
m_mainBoxLayout->setAlignment(m_controlWidget, Qt::AlignCenter);
|
||||
m_mainBoxLayout->setAlignment(m_rightSpliter, Qt::AlignCenter);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setLayout(m_mainBoxLayout);
|
||||
|
||||
m_attentionDelayTimer->setInterval(3000);
|
||||
m_attentionDelayTimer->setSingleShot(true);
|
||||
|
||||
connect(m_controlWidget, &FashionTrayControlWidget::expandChanged, this, &FashionTrayItem::onExpandChanged);
|
||||
connect(m_normalContainer, &NormalContainer::attentionChanged, this, &FashionTrayItem::onWrapperAttentionChanged);
|
||||
connect(m_attentionContainer, &AttentionContainer::attentionChanged, this, &FashionTrayItem::onWrapperAttentionChanged);
|
||||
connect(m_normalContainer, &NormalContainer::requestDraggingWrapper, this, &FashionTrayItem::onRequireDraggingWrapper);
|
||||
connect(m_holdContainer, &HoldContainer::requestDraggingWrapper, this, &FashionTrayItem::onRequireDraggingWrapper);
|
||||
connect(m_normalContainer, &NormalContainer::draggingStateChanged, this, &FashionTrayItem::onContainerDraggingStateChanged);
|
||||
connect(m_holdContainer, &HoldContainer::draggingStateChanged, this, &FashionTrayItem::onContainerDraggingStateChanged);
|
||||
|
||||
// do not call init immediately the TrayPlugin has not be constructed for now
|
||||
QTimer::singleShot(0, this, &FashionTrayItem::init);
|
||||
}
|
||||
|
||||
void FashionTrayItem::setTrayWidgets(const QMap<QString, AbstractTrayWidget *> &itemTrayMap)
|
||||
{
|
||||
clearTrayWidgets();
|
||||
|
||||
for (auto it = itemTrayMap.constBegin(); it != itemTrayMap.constEnd(); ++it) {
|
||||
trayWidgetAdded(it.key(), it.value());
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::trayWidgetAdded(const QString &itemKey, AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
if (m_normalContainer->containsWrapperByTrayWidget(trayWidget)) {
|
||||
qDebug() << "Reject! want to insert duplicate trayWidget:" << itemKey << trayWidget;
|
||||
return;
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *wrapper = new FashionTrayWidgetWrapper(itemKey, trayWidget);
|
||||
|
||||
do {
|
||||
if (m_holdContainer->acceptWrapper(wrapper)) {
|
||||
m_holdContainer->addWrapper(wrapper);
|
||||
break;
|
||||
}
|
||||
if (m_normalContainer->acceptWrapper(wrapper)) {
|
||||
m_normalContainer->addWrapper(wrapper);
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::trayWidgetRemoved(AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
bool deleted = false;
|
||||
|
||||
do {
|
||||
if (m_normalContainer->removeWrapperByTrayWidget(trayWidget)) {
|
||||
deleted = true;
|
||||
break;
|
||||
}
|
||||
if (m_attentionContainer->removeWrapperByTrayWidget(trayWidget)) {
|
||||
deleted = true;
|
||||
break;
|
||||
}
|
||||
if (m_holdContainer->removeWrapperByTrayWidget(trayWidget)) {
|
||||
deleted = true;
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
if (!deleted) {
|
||||
qDebug() << "Error! can not find the tray widget in fashion tray list" << trayWidget;
|
||||
}
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::clearTrayWidgets()
|
||||
{
|
||||
m_normalContainer->clearWrapper();
|
||||
m_attentionContainer->clearWrapper();
|
||||
m_holdContainer->clearWrapper();
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::setDockPosition(Dock::Position pos)
|
||||
{
|
||||
m_controlWidget->setDockPostion(pos);
|
||||
SystemTrayItem::setDockPostion(pos);
|
||||
|
||||
m_normalContainer->setDockPosition(pos);
|
||||
m_attentionContainer->setDockPosition(pos);
|
||||
m_holdContainer->setDockPosition(pos);
|
||||
|
||||
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
|
||||
m_mainBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
} else{
|
||||
m_mainBoxLayout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
}
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::onExpandChanged(const bool expand)
|
||||
{
|
||||
m_trayPlugin->saveValue(FASHION_MODE_ITEM_KEY, ExpandedKey, expand);
|
||||
|
||||
refreshHoldContainerPosition();
|
||||
|
||||
if (expand) {
|
||||
m_normalContainer->setExpand(expand);
|
||||
} else {
|
||||
// hide all tray immediately if Dock is in maxed size
|
||||
// the property "DockIsMaxiedSize" of qApp is set by DockSettings class
|
||||
if (qApp->property("DockIsMaxiedSize").toBool()) {
|
||||
m_normalContainer->setExpand(expand);
|
||||
} else {
|
||||
// hide all tray widget delay for fold animation
|
||||
QTimer::singleShot(350, this, [=] {
|
||||
m_normalContainer->setExpand(expand);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
m_attentionContainer->setExpand(expand);
|
||||
m_holdContainer->setExpand(expand);
|
||||
|
||||
m_attentionDelayTimer->start();
|
||||
|
||||
attentionWrapperToNormalWrapper();
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
// used by QMetaObject::invokeMethod in TrayPluginItem / MainPanel class
|
||||
void FashionTrayItem::setSuggestIconSize(QSize size)
|
||||
{
|
||||
size = size * 0.6;
|
||||
|
||||
int length = qMin(size.width(), size.height());
|
||||
// 设置最小值
|
||||
// length = qMax(length, TrayWidgetWidthMin);
|
||||
|
||||
if (length == TrayWidgetWidth || length == TrayWidgetHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
TrayWidgetWidth = length;
|
||||
TrayWidgetHeight = length;
|
||||
|
||||
QSize newSize(length, length);
|
||||
|
||||
m_controlWidget->setFixedSize(newSize);
|
||||
|
||||
m_normalContainer->setWrapperSize(newSize);
|
||||
m_attentionContainer->setWrapperSize(newSize);
|
||||
m_holdContainer->setWrapperSize(newSize);
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::setRightSplitVisible(const bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
m_rightSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
|
||||
} else {
|
||||
m_rightSpliter->setStyleSheet("background-color: transparent;");
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::showEvent(QShowEvent *event)
|
||||
{
|
||||
requestResize();
|
||||
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void FashionTrayItem::hideEvent(QHideEvent *event)
|
||||
{
|
||||
requestResize();
|
||||
|
||||
QWidget::hideEvent(event);
|
||||
}
|
||||
|
||||
void FashionTrayItem::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
const QSize &mSize = event->size();
|
||||
const Dock::Position dockPosition = m_trayPlugin->dockPosition();
|
||||
|
||||
if (dockPosition == Dock::Position::Top || dockPosition == Dock::Position::Bottom) {
|
||||
m_leftSpliter->setFixedSize(SpliterSize, mSize.height() * 0.8);
|
||||
m_rightSpliter->setFixedSize(SpliterSize, mSize.height() * 0.8);
|
||||
} else{
|
||||
m_leftSpliter->setFixedSize(mSize.width() * 0.8, SpliterSize);
|
||||
m_rightSpliter->setFixedSize(mSize.width() * 0.8, SpliterSize);
|
||||
}
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void FashionTrayItem::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
// accept but do not handle the trays drag event
|
||||
// in order to avoid the for forbidden label displayed on the mouse
|
||||
if (event->mimeData()->hasFormat(TRAY_ITEM_DRAG_MIMEDATA)) {
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget::dragEnterEvent(event);
|
||||
}
|
||||
|
||||
QSize FashionTrayItem::sizeHint() const
|
||||
{
|
||||
return wantedTotalSize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::init()
|
||||
{
|
||||
qDebug() << "init Fashion mode tray plugin item";
|
||||
m_controlWidget->setExpanded(m_trayPlugin->getValue(FASHION_MODE_ITEM_KEY, ExpandedKey, true).toBool());
|
||||
setDockPosition(m_trayPlugin->dockPosition());
|
||||
onExpandChanged(m_controlWidget->expanded());
|
||||
}
|
||||
|
||||
QSize FashionTrayItem::wantedTotalSize() const
|
||||
{
|
||||
QSize size;
|
||||
const Dock::Position dockPosition = m_trayPlugin->dockPosition();
|
||||
|
||||
if (m_controlWidget->expanded()) {
|
||||
if (dockPosition == Dock::Position::Top || dockPosition == Dock::Position::Bottom) {
|
||||
size.setWidth(
|
||||
SpliterSize * 2 // 两个分隔条
|
||||
+ TraySpace * 2 // 两个分隔条旁边的 space
|
||||
+ TrayWidgetWidth // 控制按钮
|
||||
+ m_normalContainer->sizeHint().width() // 普通区域
|
||||
+ m_holdContainer->sizeHint().width() // 保留区域
|
||||
+ m_attentionContainer->sizeHint().width() // 活动区域
|
||||
);
|
||||
size.setHeight(height());
|
||||
} else {
|
||||
size.setWidth(width());
|
||||
size.setHeight(
|
||||
SpliterSize * 2 // 两个分隔条
|
||||
+ TraySpace * 2 // 两个分隔条旁边的 space
|
||||
+ TrayWidgetWidth // 控制按钮
|
||||
+ m_normalContainer->sizeHint().height() // 普通区域
|
||||
+ m_holdContainer->sizeHint().height() // 保留区域
|
||||
+ m_attentionContainer->sizeHint().height() // 活动区域
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (dockPosition == Dock::Position::Top || dockPosition == Dock::Position::Bottom) {
|
||||
size.setWidth(
|
||||
SpliterSize * 2 // 两个分隔条
|
||||
+ TraySpace * 2 // 两个分隔条旁边的 space
|
||||
+ TrayWidgetWidth // 控制按钮
|
||||
+ m_holdContainer->sizeHint().width() // 保留区域
|
||||
+ m_attentionContainer->sizeHint().width() // 活动区域
|
||||
);
|
||||
size.setHeight(height());
|
||||
} else {
|
||||
size.setWidth(width());
|
||||
size.setHeight(
|
||||
SpliterSize * 2 // 两个分隔条
|
||||
+ TraySpace * 2 // 两个分隔条旁边的 space
|
||||
+ TrayWidgetWidth // 控制按钮
|
||||
+ m_holdContainer->sizeHint().height() // 保留区域
|
||||
+ m_attentionContainer->sizeHint().height() // 活动区域
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void FashionTrayItem::onWrapperAttentionChanged(FashionTrayWidgetWrapper *wrapper, const bool attention)
|
||||
{
|
||||
if (m_controlWidget->expanded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 在timer处于Active状态期间不设置新的活动图标
|
||||
if (attention && m_attentionDelayTimer->isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attention) {
|
||||
// ignore the attention which is come from AttentionContainer
|
||||
if (m_attentionContainer->containsWrapper(wrapper)) {
|
||||
return;
|
||||
}
|
||||
// move previous attention wrapper from AttentionContainer to NormalContainer
|
||||
attentionWrapperToNormalWrapper();
|
||||
// move current attention wrapper from NormalContainer to AttentionContainer
|
||||
normalWrapperToAttentionWrapper(wrapper);
|
||||
} else {
|
||||
// only focus the disattention from AttentionContainer
|
||||
if (m_attentionContainer->containsWrapper(wrapper)) {
|
||||
attentionWrapperToNormalWrapper();
|
||||
}
|
||||
}
|
||||
|
||||
m_attentionDelayTimer->start();
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::attentionWrapperToNormalWrapper()
|
||||
{
|
||||
FashionTrayWidgetWrapper *preAttentionWrapper = m_attentionContainer->takeAttentionWrapper();
|
||||
if (preAttentionWrapper) {
|
||||
m_normalContainer->addWrapper(preAttentionWrapper);
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::normalWrapperToAttentionWrapper(FashionTrayWidgetWrapper *wrapper)
|
||||
{
|
||||
FashionTrayWidgetWrapper *attentionWrapper = m_normalContainer->takeWrapper(wrapper);
|
||||
if (attentionWrapper) {
|
||||
m_attentionContainer->addWrapper(attentionWrapper);
|
||||
} else {
|
||||
qDebug() << "Warnning: not find the attention wrapper in NormalContainer";
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::requestResize()
|
||||
{
|
||||
// reset property "FashionTraySize" to notify dock resize
|
||||
// DockPluginsController will watch this property
|
||||
setProperty("FashionTraySize", sizeHint());
|
||||
}
|
||||
|
||||
void FashionTrayItem::refreshHoldContainerPosition()
|
||||
{
|
||||
m_mainBoxLayout->removeWidget(m_holdContainer);
|
||||
|
||||
int destIndex = 0;
|
||||
if (m_controlWidget->expanded()) {
|
||||
destIndex = m_mainBoxLayout->indexOf(m_controlWidget);
|
||||
} else {
|
||||
destIndex = m_mainBoxLayout->indexOf(m_attentionContainer);
|
||||
}
|
||||
|
||||
m_mainBoxLayout->insertWidget(destIndex, m_holdContainer);
|
||||
}
|
||||
|
||||
void FashionTrayItem::onRequireDraggingWrapper()
|
||||
{
|
||||
AbstractContainer *container = dynamic_cast<AbstractContainer *>(sender());
|
||||
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *draggingWrapper = nullptr;
|
||||
do {
|
||||
draggingWrapper = m_normalContainer->takeDraggingWrapper();
|
||||
if (draggingWrapper) {
|
||||
break;
|
||||
}
|
||||
draggingWrapper = m_holdContainer->takeDraggingWrapper();
|
||||
if (draggingWrapper) {
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
if (!draggingWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
container->addDraggingWrapper(draggingWrapper);
|
||||
}
|
||||
|
||||
void FashionTrayItem::onContainerDraggingStateChanged(FashionTrayWidgetWrapper *wrapper, const bool dragging)
|
||||
{
|
||||
Q_UNUSED(wrapper);
|
||||
|
||||
m_holdContainer->setDragging(dragging);
|
||||
}
|
@ -26,6 +26,9 @@
|
||||
#include "trayplugin.h"
|
||||
#include "fashiontraywidgetwrapper.h"
|
||||
#include "fashiontraycontrolwidget.h"
|
||||
#include "containers/normalcontainer.h"
|
||||
#include "containers/attentioncontainer.h"
|
||||
#include "containers/holdcontainer.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QPointer>
|
||||
@ -34,6 +37,8 @@
|
||||
|
||||
#include <abstracttraywidget.h>
|
||||
|
||||
#define FASHION_MODE_ITEM_KEY "fashion-mode-item"
|
||||
|
||||
class FashionTrayItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -46,10 +51,13 @@ public:
|
||||
void trayWidgetRemoved(AbstractTrayWidget *trayWidget);
|
||||
void clearTrayWidgets();
|
||||
|
||||
void setDockPostion(Dock::Position pos);
|
||||
void setDockPosition(Dock::Position pos);
|
||||
|
||||
inline static int trayWidgetWidth() {return TrayWidgetWidth;}
|
||||
inline static int trayWidgetHeight() {return TrayWidgetHeight;}
|
||||
|
||||
public slots:
|
||||
void onTrayListExpandChanged(const bool expand);
|
||||
void onExpandChanged(const bool expand);
|
||||
void setSuggestIconSize(QSize size);
|
||||
void setRightSplitVisible(const bool visible);
|
||||
|
||||
@ -63,40 +71,29 @@ protected:
|
||||
private:
|
||||
void init();
|
||||
QSize wantedTotalSize() const;
|
||||
int whereToInsert(FashionTrayWidgetWrapper *wrapper) const;
|
||||
int whereToInsertBySortKey(FashionTrayWidgetWrapper *wrapper) const;
|
||||
int whereToInsertByDefault(FashionTrayWidgetWrapper *wrapper) const;
|
||||
int whereToInsertAppTrayByDefault(FashionTrayWidgetWrapper *wrapper) const;
|
||||
int whereToInsertSystemTrayByDefault(FashionTrayWidgetWrapper *wrapper) const;
|
||||
void saveCurrentOrderToConfig();
|
||||
|
||||
private Q_SLOTS:
|
||||
void onTrayAttentionChanged(const bool attention);
|
||||
void setCurrentAttentionTray(FashionTrayWidgetWrapper *attentionWrapper);
|
||||
void onWrapperAttentionChanged(FashionTrayWidgetWrapper *wrapper, const bool attention);
|
||||
void attentionWrapperToNormalWrapper();
|
||||
void normalWrapperToAttentionWrapper(FashionTrayWidgetWrapper *wrapper);
|
||||
void requestResize();
|
||||
void moveOutAttionTray();
|
||||
void moveInAttionTray();
|
||||
void switchAttionTray(FashionTrayWidgetWrapper *attentionWrapper);
|
||||
void refreshTraysVisible();
|
||||
void onItemDragStart();
|
||||
void onItemDragStop();
|
||||
void onItemRequestSwapWithDragging();
|
||||
void refreshHoldContainerPosition();
|
||||
void onRequireDraggingWrapper();
|
||||
void onContainerDraggingStateChanged(FashionTrayWidgetWrapper *wrapper, const bool dragging);
|
||||
|
||||
private:
|
||||
QBoxLayout *m_mainBoxLayout;
|
||||
QBoxLayout *m_trayBoxLayout;
|
||||
QLabel *m_leftSpliter;
|
||||
QLabel *m_rightSpliter;
|
||||
QTimer *m_attentionDelayTimer;
|
||||
|
||||
Dock::Position m_dockPosistion;
|
||||
|
||||
TrayPlugin *m_trayPlugin;
|
||||
FashionTrayControlWidget *m_controlWidget;
|
||||
FashionTrayWidgetWrapper *m_currentAttentionTray;
|
||||
FashionTrayWidgetWrapper *m_currentDraggingTray;
|
||||
|
||||
QList<QPointer<FashionTrayWidgetWrapper>> m_wrapperList;
|
||||
NormalContainer *m_normalContainer;
|
||||
AttentionContainer *m_attentionContainer;
|
||||
HoldContainer *m_holdContainer;
|
||||
|
||||
static int TrayWidgetWidth;
|
||||
static int TrayWidgetHeight;
|
@ -1,668 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2011 ~ 2018 Deepin Technology Co., Ltd.
|
||||
*
|
||||
* Author: listenerri <listenerri@gmail.com>
|
||||
*
|
||||
* Maintainer: listenerri <listenerri@gmail.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 "fashiontrayitem.h"
|
||||
#include "system-trays/systemtrayitem.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QResizeEvent>
|
||||
|
||||
#define SpliterSize 2
|
||||
#define TraySpace 10
|
||||
#define TrayWidgetWidthMin 24
|
||||
#define TrayWidgetHeightMin 24
|
||||
|
||||
#define ExpandedKey "fashion-tray-expanded"
|
||||
|
||||
int FashionTrayItem::TrayWidgetWidth = TrayWidgetWidthMin;
|
||||
int FashionTrayItem::TrayWidgetHeight = TrayWidgetHeightMin;
|
||||
|
||||
FashionTrayItem::FashionTrayItem(TrayPlugin *trayPlugin, QWidget *parent)
|
||||
: QWidget(parent),
|
||||
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
|
||||
m_trayBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
|
||||
m_leftSpliter(new QLabel),
|
||||
m_rightSpliter(new QLabel),
|
||||
m_attentionDelayTimer(new QTimer(this)),
|
||||
m_dockPosistion(trayPlugin->dockPosition()),
|
||||
m_trayPlugin(trayPlugin),
|
||||
m_controlWidget(new FashionTrayControlWidget(m_dockPosistion)),
|
||||
m_currentAttentionTray(nullptr),
|
||||
m_currentDraggingTray(nullptr)
|
||||
{
|
||||
setAcceptDrops(true);
|
||||
|
||||
m_leftSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
|
||||
m_rightSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
|
||||
|
||||
m_controlWidget->setFixedSize(QSize(TrayWidgetWidth, TrayWidgetHeight));
|
||||
|
||||
m_mainBoxLayout->setMargin(0);
|
||||
m_mainBoxLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_mainBoxLayout->setSpacing(TraySpace);
|
||||
|
||||
m_trayBoxLayout->setMargin(0);
|
||||
m_trayBoxLayout->setContentsMargins(0, 0, 0, 0);
|
||||
m_trayBoxLayout->setSpacing(TraySpace);
|
||||
|
||||
m_mainBoxLayout->addWidget(m_leftSpliter);
|
||||
m_mainBoxLayout->addLayout(m_trayBoxLayout);
|
||||
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_controlWidget, Qt::AlignCenter);
|
||||
m_mainBoxLayout->setAlignment(m_rightSpliter, Qt::AlignCenter);
|
||||
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setLayout(m_mainBoxLayout);
|
||||
|
||||
m_attentionDelayTimer->setInterval(3000);
|
||||
m_attentionDelayTimer->setSingleShot(true);
|
||||
|
||||
connect(m_controlWidget, &FashionTrayControlWidget::expandChanged, this, &FashionTrayItem::onTrayListExpandChanged);
|
||||
|
||||
// do not call init immediately the TrayPlugin has not be constructed for now
|
||||
QTimer::singleShot(0, this, &FashionTrayItem::init);
|
||||
}
|
||||
|
||||
void FashionTrayItem::setTrayWidgets(const QMap<QString, AbstractTrayWidget *> &itemTrayMap)
|
||||
{
|
||||
clearTrayWidgets();
|
||||
|
||||
for (auto it = itemTrayMap.constBegin(); it != itemTrayMap.constEnd(); ++it) {
|
||||
trayWidgetAdded(it.key(), it.value());
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::trayWidgetAdded(const QString &itemKey, AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
for (auto w : m_wrapperList) {
|
||||
if (w->absTrayWidget() == trayWidget) {
|
||||
qDebug() << "Reject! want to isert duplicate trayWidget:" << itemKey << trayWidget;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *wrapper = new FashionTrayWidgetWrapper(itemKey, trayWidget);
|
||||
wrapper->setFixedSize(QSize(TrayWidgetWidth, TrayWidgetHeight));
|
||||
|
||||
const int index = whereToInsert(wrapper);
|
||||
m_trayBoxLayout->insertWidget(index, wrapper);
|
||||
m_wrapperList.insert(index, wrapper);
|
||||
|
||||
wrapper->setVisible(m_controlWidget->expanded());
|
||||
|
||||
if (wrapper->attention()) {
|
||||
setCurrentAttentionTray(wrapper);
|
||||
}
|
||||
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::attentionChanged, this, &FashionTrayItem::onTrayAttentionChanged, static_cast<Qt::ConnectionType>(Qt::QueuedConnection | Qt::UniqueConnection));
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::dragStart, this, &FashionTrayItem::onItemDragStart, Qt::UniqueConnection);
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::dragStop, this, &FashionTrayItem::onItemDragStop, Qt::UniqueConnection);
|
||||
connect(wrapper, &FashionTrayWidgetWrapper::requestSwapWithDragging, this, &FashionTrayItem::onItemRequestSwapWithDragging, Qt::UniqueConnection);
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::trayWidgetRemoved(AbstractTrayWidget *trayWidget)
|
||||
{
|
||||
bool founded = false;
|
||||
|
||||
for (auto wrapper : m_wrapperList) {
|
||||
// found the removed tray
|
||||
if (wrapper->absTrayWidget() == trayWidget) {
|
||||
// the removed tray is a attention tray
|
||||
if (m_currentAttentionTray == wrapper) {
|
||||
if (m_controlWidget->expanded()) {
|
||||
m_trayBoxLayout->removeWidget(m_currentAttentionTray);
|
||||
} else {
|
||||
m_mainBoxLayout->removeWidget(m_currentAttentionTray);
|
||||
}
|
||||
m_currentAttentionTray = nullptr;
|
||||
} else {
|
||||
m_trayBoxLayout->removeWidget(wrapper);
|
||||
}
|
||||
// do not delete real tray object, just delete it's wrapper object
|
||||
// the real tray object should be deleted in TrayPlugin class
|
||||
trayWidget->setParent(nullptr);
|
||||
wrapper->deleteLater();
|
||||
m_wrapperList.removeAll(wrapper);
|
||||
founded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!founded) {
|
||||
qDebug() << "Error! can not find the tray widget in fashion tray list" << trayWidget;
|
||||
}
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::clearTrayWidgets()
|
||||
{
|
||||
QList<QPointer<FashionTrayWidgetWrapper>> mList = m_wrapperList;
|
||||
|
||||
for (auto wrapper : mList) {
|
||||
trayWidgetRemoved(wrapper->absTrayWidget());
|
||||
}
|
||||
|
||||
m_wrapperList.clear();
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::setDockPostion(Dock::Position pos)
|
||||
{
|
||||
m_dockPosistion = pos;
|
||||
|
||||
m_controlWidget->setDockPostion(m_dockPosistion);
|
||||
SystemTrayItem::setDockPostion(m_dockPosistion);
|
||||
|
||||
if (pos == Dock::Position::Top || pos == Dock::Position::Bottom) {
|
||||
m_mainBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
m_trayBoxLayout->setDirection(QBoxLayout::Direction::LeftToRight);
|
||||
} else{
|
||||
m_mainBoxLayout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
m_trayBoxLayout->setDirection(QBoxLayout::Direction::TopToBottom);
|
||||
}
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::onTrayListExpandChanged(const bool expand)
|
||||
{
|
||||
m_trayPlugin->saveValue(ExpandedKey, expand);
|
||||
|
||||
if (!isVisible())
|
||||
return;
|
||||
|
||||
if (expand) {
|
||||
refreshTraysVisible();
|
||||
} else {
|
||||
// hide all tray immediately if Dock is in maxed size
|
||||
// the property "DockIsMaxiedSize" of qApp is set by DockSettings class
|
||||
if (qApp->property("DockIsMaxiedSize").toBool()) {
|
||||
refreshTraysVisible();
|
||||
} else {
|
||||
// hide all tray widget delay for fold animation
|
||||
QTimer::singleShot(350, this, [=] {refreshTraysVisible();});
|
||||
}
|
||||
requestResize();
|
||||
}
|
||||
}
|
||||
|
||||
// used by QMetaObject::invokeMethod in TrayPluginItem / MainPanel class
|
||||
void FashionTrayItem::setSuggestIconSize(QSize size)
|
||||
{
|
||||
size = size * 0.6;
|
||||
|
||||
int length = qMin(size.width(), size.height());
|
||||
// 设置最小值
|
||||
// length = qMax(length, TrayWidgetWidthMin);
|
||||
|
||||
if (length == TrayWidgetWidth || length == TrayWidgetHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
TrayWidgetWidth = length;
|
||||
TrayWidgetHeight = length;
|
||||
|
||||
QSize newSize(length, length);
|
||||
|
||||
m_controlWidget->setFixedSize(newSize);
|
||||
|
||||
for (auto wrapper : m_wrapperList) {
|
||||
wrapper->setFixedSize(newSize);
|
||||
}
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::setRightSplitVisible(const bool visible)
|
||||
{
|
||||
if (visible) {
|
||||
m_rightSpliter->setStyleSheet("background-color: rgba(255, 255, 255, 0.1);");
|
||||
} else {
|
||||
m_rightSpliter->setStyleSheet("background-color: transparent;");
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::showEvent(QShowEvent *event)
|
||||
{
|
||||
requestResize();
|
||||
|
||||
QWidget::showEvent(event);
|
||||
}
|
||||
|
||||
void FashionTrayItem::hideEvent(QHideEvent *event)
|
||||
{
|
||||
requestResize();
|
||||
|
||||
QWidget::hideEvent(event);
|
||||
}
|
||||
|
||||
void FashionTrayItem::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
const QSize &mSize = event->size();
|
||||
|
||||
if (m_dockPosistion == Dock::Position::Top || m_dockPosistion == Dock::Position::Bottom) {
|
||||
m_leftSpliter->setFixedSize(SpliterSize, mSize.height() * 0.8);
|
||||
m_rightSpliter->setFixedSize(SpliterSize, mSize.height() * 0.8);
|
||||
} else{
|
||||
m_leftSpliter->setFixedSize(mSize.width() * 0.8, SpliterSize);
|
||||
m_rightSpliter->setFixedSize(mSize.width() * 0.8, SpliterSize);
|
||||
}
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
||||
void FashionTrayItem::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
// accept but do not handle the trays drag event
|
||||
// in order to avoid the for forbidden label displayed on the mouse
|
||||
if (event->mimeData()->hasFormat(TRAY_ITEM_DRAG_MIMEDATA)) {
|
||||
event->accept();
|
||||
return;
|
||||
}
|
||||
|
||||
QWidget::dragEnterEvent(event);
|
||||
}
|
||||
|
||||
QSize FashionTrayItem::sizeHint() const
|
||||
{
|
||||
return wantedTotalSize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::init()
|
||||
{
|
||||
qDebug() << "init Fashion mode tray plugin item";
|
||||
m_controlWidget->setExpanded(m_trayPlugin->getValue(ExpandedKey, true).toBool());
|
||||
setDockPostion(m_dockPosistion);
|
||||
onTrayListExpandChanged(m_controlWidget->expanded());
|
||||
}
|
||||
|
||||
QSize FashionTrayItem::wantedTotalSize() const
|
||||
{
|
||||
QSize size;
|
||||
|
||||
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.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
|
||||
}
|
||||
} 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.setHeight(height());
|
||||
} else {
|
||||
size.setWidth(width());
|
||||
size.setHeight(TrayWidgetHeight // 控制按钮
|
||||
+ (m_currentAttentionTray ? TrayWidgetHeight : 0) // 活动状态的tray
|
||||
+ SpliterSize * 2 // 两个分隔条
|
||||
+ 3 * TraySpace); // MainBoxLayout所有space
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int FashionTrayItem::whereToInsert(FashionTrayWidgetWrapper *wrapper) const
|
||||
{
|
||||
// 如果已经对图标进行过排序则完全按照从配置文件中获取的顺序来插入图标
|
||||
if (m_trayPlugin->traysSortedInFashionMode()) {
|
||||
return whereToInsertBySortKey(wrapper);
|
||||
}
|
||||
|
||||
// 如果没有对图标进行过排序则使用下面的默认排序算法:
|
||||
// 所有应用图标在系统图标的左侧
|
||||
// 新的应用图标在最左侧的应用图标处插入
|
||||
// 新的系统图标在最左侧的系统图标处插入
|
||||
return whereToInsertByDefault(wrapper);
|
||||
}
|
||||
|
||||
int FashionTrayItem::whereToInsertBySortKey(FashionTrayWidgetWrapper *wrapper) const
|
||||
{
|
||||
if (m_wrapperList.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int destSortKey = m_trayPlugin->itemSortKey(wrapper->itemKey());
|
||||
|
||||
if (destSortKey < -1) {
|
||||
return 0;
|
||||
}
|
||||
if (destSortKey == -1) {
|
||||
return m_wrapperList.size();
|
||||
}
|
||||
|
||||
// 当目标插入位置为列表的大小时将从最后面追加到列表中
|
||||
int destIndex = m_wrapperList.size();
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
if (destSortKey > m_trayPlugin->itemSortKey(m_wrapperList.at(i)->itemKey())) {
|
||||
continue;
|
||||
}
|
||||
destIndex = i;
|
||||
break;
|
||||
}
|
||||
|
||||
return destIndex;
|
||||
}
|
||||
|
||||
int FashionTrayItem::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 FashionTrayItem::whereToInsertAppTrayByDefault(FashionTrayWidgetWrapper *wrapper) const
|
||||
{
|
||||
if (m_wrapperList.isEmpty() || wrapper->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::ApplicationTray) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lastAppTrayIndex = -1;
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
if (m_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 = m_trayPlugin->itemSortKey(wrapper->itemKey());
|
||||
// invalid index
|
||||
if (insertIndex < -1) {
|
||||
return 0;
|
||||
}
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
if (m_wrapperList.at(i)->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::ApplicationTray) {
|
||||
insertIndex = i;
|
||||
break;
|
||||
}
|
||||
if (insertIndex > m_trayPlugin->itemSortKey(m_wrapperList.at(i)->itemKey())) {
|
||||
continue;
|
||||
}
|
||||
insertIndex = i;
|
||||
break;
|
||||
}
|
||||
if (insertIndex > lastAppTrayIndex + 1) {
|
||||
insertIndex = lastAppTrayIndex + 1;
|
||||
}
|
||||
|
||||
return insertIndex;
|
||||
}
|
||||
|
||||
int FashionTrayItem::whereToInsertSystemTrayByDefault(FashionTrayWidgetWrapper *wrapper) const
|
||||
{
|
||||
if (m_wrapperList.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int firstSystemTrayIndex = -1;
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
if (m_wrapperList.at(i)->absTrayWidget()->trayTyep() == AbstractTrayWidget::TrayType::SystemTray) {
|
||||
firstSystemTrayIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// there is no SystemTray
|
||||
if (firstSystemTrayIndex == -1) {
|
||||
return m_wrapperList.size();
|
||||
}
|
||||
// the inserting tray is not a SystemTray
|
||||
if (wrapper->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::SystemTray) {
|
||||
return firstSystemTrayIndex;
|
||||
}
|
||||
|
||||
int insertIndex = m_trayPlugin->itemSortKey(wrapper->itemKey());
|
||||
// invalid index
|
||||
if (insertIndex < -1) {
|
||||
return firstSystemTrayIndex;
|
||||
}
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
if (m_wrapperList.at(i)->absTrayWidget()->trayTyep() != AbstractTrayWidget::TrayType::SystemTray) {
|
||||
continue;
|
||||
}
|
||||
if (insertIndex > m_trayPlugin->itemSortKey(m_wrapperList.at(i)->itemKey())) {
|
||||
continue;
|
||||
}
|
||||
insertIndex = i;
|
||||
break;
|
||||
}
|
||||
if (insertIndex < firstSystemTrayIndex) {
|
||||
return firstSystemTrayIndex;
|
||||
}
|
||||
|
||||
return insertIndex;
|
||||
}
|
||||
|
||||
void FashionTrayItem::saveCurrentOrderToConfig()
|
||||
{
|
||||
for (int i = 0; i < m_wrapperList.size(); ++i) {
|
||||
m_trayPlugin->setSortKey(m_wrapperList.at(i)->itemKey(), i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::onTrayAttentionChanged(const bool attention)
|
||||
{
|
||||
// 设置attention为false之后,启动timer,在timer处于Active状态期间不重设attention为true
|
||||
if (!attention) {
|
||||
m_attentionDelayTimer->start();
|
||||
} else if (attention && m_attentionDelayTimer->isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
Q_ASSERT(wrapper);
|
||||
|
||||
if (attention) {
|
||||
setCurrentAttentionTray(wrapper);
|
||||
} else {
|
||||
if (m_currentAttentionTray != wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_controlWidget->expanded()) {
|
||||
m_currentAttentionTray = nullptr;
|
||||
} else {
|
||||
moveInAttionTray();
|
||||
m_currentAttentionTray = nullptr;
|
||||
requestResize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FashionTrayItem::setCurrentAttentionTray(FashionTrayWidgetWrapper *attentionWrapper)
|
||||
{
|
||||
if (!attentionWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_controlWidget->expanded()) {
|
||||
m_currentAttentionTray = attentionWrapper;
|
||||
} else {
|
||||
if (m_currentAttentionTray == attentionWrapper) {
|
||||
return;
|
||||
}
|
||||
moveInAttionTray();
|
||||
bool sizeChanged = !m_currentAttentionTray;
|
||||
m_currentAttentionTray = attentionWrapper;
|
||||
moveOutAttionTray();
|
||||
if (sizeChanged) {
|
||||
requestResize();
|
||||
}
|
||||
}
|
||||
|
||||
m_mainBoxLayout->setAlignment(m_currentAttentionTray, Qt::AlignCenter);
|
||||
}
|
||||
|
||||
void FashionTrayItem::requestResize()
|
||||
{
|
||||
// reset property "FashionTraySize" to notify dock resize
|
||||
// DockPluginsController will watch this property
|
||||
setProperty("FashionTraySize", sizeHint());
|
||||
}
|
||||
|
||||
void FashionTrayItem::moveOutAttionTray()
|
||||
{
|
||||
if (!m_currentAttentionTray) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_trayBoxLayout->removeWidget(m_currentAttentionTray);
|
||||
m_mainBoxLayout->insertWidget(m_mainBoxLayout->indexOf(m_rightSpliter), m_currentAttentionTray);
|
||||
m_currentAttentionTray->setVisible(true);
|
||||
}
|
||||
|
||||
void FashionTrayItem::moveInAttionTray()
|
||||
{
|
||||
if (!m_currentAttentionTray) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_mainBoxLayout->removeWidget(m_currentAttentionTray);
|
||||
m_trayBoxLayout->insertWidget(whereToInsert(m_currentAttentionTray), m_currentAttentionTray);
|
||||
m_currentAttentionTray->setVisible(false);
|
||||
m_currentAttentionTray->setAttention(false);
|
||||
}
|
||||
|
||||
void FashionTrayItem::switchAttionTray(FashionTrayWidgetWrapper *attentionWrapper)
|
||||
{
|
||||
if (!m_currentAttentionTray || !attentionWrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_mainBoxLayout->replaceWidget(m_currentAttentionTray, attentionWrapper);
|
||||
m_trayBoxLayout->removeWidget(attentionWrapper);
|
||||
m_trayBoxLayout->insertWidget(whereToInsert(m_currentAttentionTray), m_currentAttentionTray);
|
||||
|
||||
attentionWrapper->setVisible(true);
|
||||
m_currentAttentionTray->setVisible(m_controlWidget->expanded());
|
||||
|
||||
m_currentAttentionTray = attentionWrapper;
|
||||
}
|
||||
|
||||
void FashionTrayItem::refreshTraysVisible()
|
||||
{
|
||||
const bool expand = m_controlWidget->expanded();
|
||||
|
||||
if (m_currentAttentionTray) {
|
||||
if (expand) {
|
||||
m_mainBoxLayout->removeWidget(m_currentAttentionTray);
|
||||
m_trayBoxLayout->insertWidget(whereToInsert(m_currentAttentionTray), m_currentAttentionTray);
|
||||
}
|
||||
|
||||
m_currentAttentionTray = nullptr;
|
||||
}
|
||||
|
||||
for (auto wrapper : m_wrapperList) {
|
||||
wrapper->setVisible(expand);
|
||||
// reset all tray item attention state
|
||||
wrapper->setAttention(false);
|
||||
}
|
||||
|
||||
m_attentionDelayTimer->start();
|
||||
|
||||
requestResize();
|
||||
}
|
||||
|
||||
void FashionTrayItem::onItemDragStart()
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentDraggingTray = wrapper;
|
||||
}
|
||||
|
||||
void FashionTrayItem::onItemDragStop()
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
if (!wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_currentDraggingTray == wrapper) {
|
||||
m_currentDraggingTray = nullptr;
|
||||
} else {
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
saveCurrentOrderToConfig();
|
||||
}
|
||||
|
||||
void FashionTrayItem::onItemRequestSwapWithDragging()
|
||||
{
|
||||
FashionTrayWidgetWrapper *wrapper = static_cast<FashionTrayWidgetWrapper *>(sender());
|
||||
|
||||
if (!wrapper || !m_currentDraggingTray || wrapper == m_currentDraggingTray) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int indexOfDest = m_trayBoxLayout->indexOf(wrapper);
|
||||
const int indexOfDragging = m_trayBoxLayout->indexOf(m_currentDraggingTray);
|
||||
|
||||
m_trayBoxLayout->removeWidget(m_currentDraggingTray);
|
||||
m_trayBoxLayout->insertWidget(indexOfDest, m_currentDraggingTray);
|
||||
|
||||
m_wrapperList.insert(indexOfDest, m_wrapperList.takeAt(indexOfDragging));
|
||||
}
|
@ -268,3 +268,25 @@ void SystemTraysController::setSystemTrayItemSortKey(const QString &itemKey, con
|
||||
|
||||
inter->setSortKey(itemKey, order);
|
||||
}
|
||||
|
||||
const QVariant SystemTraysController::getValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &fallback)
|
||||
{
|
||||
auto inter = pluginInterAt(itemKey);
|
||||
|
||||
if (!inter) {
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
return getValue(inter, key, fallback);
|
||||
}
|
||||
|
||||
void SystemTraysController::saveValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &value)
|
||||
{
|
||||
auto inter = pluginInterAt(itemKey);
|
||||
|
||||
if (!inter) {
|
||||
return;
|
||||
}
|
||||
|
||||
saveValue(inter, key, value);
|
||||
}
|
||||
|
@ -46,11 +46,14 @@ public:
|
||||
void requestRefreshWindowVisible(PluginsItemInterface * const itemInter, const QString &itemKey) Q_DECL_OVERRIDE;
|
||||
void requestSetAppletVisible(PluginsItemInterface * const itemInter, const QString &itemKey, const bool visible) Q_DECL_OVERRIDE;
|
||||
void saveValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant &value) Q_DECL_OVERRIDE;
|
||||
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& failback = QVariant()) Q_DECL_OVERRIDE;
|
||||
const QVariant getValue(PluginsItemInterface *const itemInter, const QString &key, const QVariant& fallback = QVariant()) Q_DECL_OVERRIDE;
|
||||
|
||||
int systemTrayItemSortKey(const QString &itemKey);
|
||||
void setSystemTrayItemSortKey(const QString &itemKey, const int order);
|
||||
|
||||
const QVariant getValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant& fallback = QVariant());
|
||||
void saveValueSystemTrayItem(const QString &itemKey, const QString &key, const QVariant &value);
|
||||
|
||||
public slots:
|
||||
void startLoader();
|
||||
|
||||
|
@ -21,7 +21,8 @@
|
||||
*/
|
||||
|
||||
#include "trayplugin.h"
|
||||
#include "fashiontrayitem.h"
|
||||
#include "fashiontray/fashiontrayitem.h"
|
||||
#include "snitraywidget.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QWindow>
|
||||
@ -31,7 +32,6 @@
|
||||
#include "../widgets/tipswidget.h"
|
||||
#include "xcb/xcb_icccm.h"
|
||||
|
||||
#define FASHION_MODE_ITEM "fashion-mode-item"
|
||||
#define FASHION_MODE_TRAYS_SORTED "fashion-mode-trays-sorted"
|
||||
|
||||
#define SNI_WATCHER_SERVICE "org.kde.StatusNotifierWatcher"
|
||||
@ -124,12 +124,12 @@ void TrayPlugin::positionChanged(const Dock::Position position)
|
||||
return;
|
||||
}
|
||||
|
||||
m_fashionItem->setDockPostion(position);
|
||||
m_fashionItem->setDockPosition(position);
|
||||
}
|
||||
|
||||
QWidget *TrayPlugin::itemWidget(const QString &itemKey)
|
||||
{
|
||||
if (itemKey == FASHION_MODE_ITEM) {
|
||||
if (itemKey == FASHION_MODE_ITEM_KEY) {
|
||||
return m_fashionItem;
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ void TrayPlugin::setItemIsInContainer(const QString &itemKey, const bool contain
|
||||
|
||||
void TrayPlugin::refreshIcon(const QString &itemKey)
|
||||
{
|
||||
if (itemKey == FASHION_MODE_ITEM) {
|
||||
if (itemKey == FASHION_MODE_ITEM_KEY) {
|
||||
for (auto trayWidget : m_trayMap.values()) {
|
||||
if (trayWidget) {
|
||||
trayWidget->updateIcon();
|
||||
@ -231,13 +231,23 @@ bool TrayPlugin::traysSortedInFashionMode()
|
||||
return m_proxyInter->getValue(this, FASHION_MODE_TRAYS_SORTED, false).toBool();
|
||||
}
|
||||
|
||||
void TrayPlugin::saveValue(const QString &key, const QVariant &value)
|
||||
void TrayPlugin::saveValue(const QString &itemKey, const QString &key, const QVariant &value)
|
||||
{
|
||||
// 如果是系统托盘图标则调用内部插件的相应接口
|
||||
if (isSystemTrayItem(itemKey)) {
|
||||
return m_systemTraysController->saveValueSystemTrayItem(itemKey, key, value);
|
||||
}
|
||||
|
||||
m_proxyInter->saveValue(this, key, value);
|
||||
}
|
||||
|
||||
const QVariant TrayPlugin::getValue(const QString &key, const QVariant &fallback)
|
||||
const QVariant TrayPlugin::getValue(const QString &itemKey, const QString &key, const QVariant &fallback)
|
||||
{
|
||||
// 如果是系统托盘图标则调用内部插件的相应接口
|
||||
if (isSystemTrayItem(itemKey)) {
|
||||
return m_systemTraysController->getValueSystemTrayItem(itemKey, key, fallback);
|
||||
}
|
||||
|
||||
return m_proxyInter->getValue(this, key, fallback);
|
||||
}
|
||||
|
||||
@ -257,7 +267,7 @@ QString TrayPlugin::itemKeyOfTrayWidget(AbstractTrayWidget *trayWidget)
|
||||
QString itemKey;
|
||||
|
||||
if (displayMode() == Dock::DisplayMode::Fashion) {
|
||||
itemKey = FASHION_MODE_ITEM;
|
||||
itemKey = FASHION_MODE_ITEM_KEY;
|
||||
} else {
|
||||
itemKey = m_trayMap.key(trayWidget);
|
||||
}
|
||||
@ -317,7 +327,7 @@ void TrayPlugin::addTrayWidget(const QString &itemKey, AbstractTrayWidget *trayW
|
||||
if (displayMode() == Dock::Efficient) {
|
||||
m_proxyInter->itemAdded(this, itemKey);
|
||||
} else {
|
||||
m_proxyInter->itemAdded(this, FASHION_MODE_ITEM);
|
||||
m_proxyInter->itemAdded(this, FASHION_MODE_ITEM_KEY);
|
||||
m_fashionItem->trayWidgetAdded(itemKey, trayWidget);
|
||||
}
|
||||
|
||||
@ -420,14 +430,14 @@ void TrayPlugin::switchToMode(const Dock::DisplayMode mode)
|
||||
m_proxyInter->itemRemoved(this, itemKey);
|
||||
}
|
||||
if (m_trayMap.isEmpty()) {
|
||||
m_proxyInter->itemRemoved(this, FASHION_MODE_ITEM);
|
||||
m_proxyInter->itemRemoved(this, FASHION_MODE_ITEM_KEY);
|
||||
} else {
|
||||
m_fashionItem->setTrayWidgets(m_trayMap);
|
||||
m_proxyInter->itemAdded(this, FASHION_MODE_ITEM);
|
||||
m_proxyInter->itemAdded(this, FASHION_MODE_ITEM_KEY);
|
||||
}
|
||||
} else {
|
||||
m_fashionItem->clearTrayWidgets();
|
||||
m_proxyInter->itemRemoved(this, FASHION_MODE_ITEM);
|
||||
m_proxyInter->itemRemoved(this, FASHION_MODE_ITEM_KEY);
|
||||
for (auto itemKey : m_trayMap.keys()) {
|
||||
m_proxyInter->itemAdded(this, itemKey);
|
||||
}
|
||||
|
@ -62,8 +62,8 @@ public:
|
||||
|
||||
Dock::Position dockPosition() const;
|
||||
bool traysSortedInFashionMode();
|
||||
void saveValue(const QString &key, const QVariant &value);
|
||||
const QVariant getValue(const QString &key, const QVariant& fallback = QVariant());
|
||||
void saveValue(const QString &itemKey, const QString &key, const QVariant &value);
|
||||
const QVariant getValue(const QString &itemKey, const QString &key, const QVariant& fallback = QVariant());
|
||||
|
||||
private:
|
||||
void loadIndicator();
|
||||
|
Loading…
x
Reference in New Issue
Block a user