feat: animation of hold spliter

Change-Id: Ic15d015a03b95cf917039ebc3762b8984dbb146b
This commit is contained in:
listenerri 2018-12-29 17:55:19 +08:00
parent fea60742c5
commit 9dde0f6d30
Notes: gerrit 2018-12-29 18:04:17 +08:00
Verified+1: <jenkins@deepin.com>
Code-Review+2: listenerri <listenerri@gmail.com>
Submitted-by: listenerri <listenerri@gmail.com>
Submitted-at: Sat, 29 Dec 2018 18:04:16 +0800
Reviewed-on: https://cr.deepin.io/40998
Project: dde/dde-dock
Branch: refs/heads/dev/drag-and-hold-tray
8 changed files with 188 additions and 8 deletions

View File

@ -318,6 +318,8 @@ void AbstractContainer::onWrapperDragStart()
}
m_currentDraggingWrapper = wrapper;
Q_EMIT draggingStateChanged(wrapper, true);
}
void AbstractContainer::onWrapperDragStop()
@ -335,6 +337,8 @@ void AbstractContainer::onWrapperDragStop()
}
saveCurrentOrderToConfig();
Q_EMIT draggingStateChanged(wrapper, false);
}
void AbstractContainer::onWrapperRequestSwapWithDragging()

View File

@ -40,6 +40,7 @@ public:
Q_SIGNALS:
void attentionChanged(FashionTrayWidgetWrapper *wrapper, const bool attention);
void requestDraggingWrapper();
void draggingStateChanged(FashionTrayWidgetWrapper *wrapper, const bool dragging);
protected:
virtual int whereToInsert(FashionTrayWidgetWrapper *wrapper);

View File

@ -4,10 +4,8 @@
HoldContainer::HoldContainer(TrayPlugin *trayPlugin, QWidget *parent)
: AbstractContainer(trayPlugin, parent),
m_mainBoxLayout(new QBoxLayout(QBoxLayout::Direction::LeftToRight)),
m_holdSpliter(new QLabel)
m_holdSpliter(new SpliterAnimated(this))
{
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);
@ -58,6 +56,8 @@ void HoldContainer::setDockPosition(const Dock::Position pos)
m_mainBoxLayout->setDirection(QBoxLayout::Direction::TopToBottom);
}
m_holdSpliter->setDockPosition(pos);
AbstractContainer::setDockPosition(pos);
}
@ -93,16 +93,32 @@ QSize HoldContainer::totalSize() const
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_holdSpliter->setFixedSize(SpliterSize, mSize.height() * 0.3);
m_holdSpliterMiniSize = QSize(SpliterSize, mSize.height() * 0.3);
m_holdSpliterMaxSize = QSize(SpliterSize, mSize.height() * 0.5);
m_holdSpliter->setFixedSize(SpliterSize, mSize.height());
} else{
m_holdSpliter->setFixedSize(mSize.width() * 0.3, SpliterSize);
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);
}

View File

@ -2,6 +2,7 @@
#define HOLDCONTAINER_H
#include "abstractcontainer.h"
#include "spliteranimated.h"
class HoldContainer : public AbstractContainer
{
@ -17,12 +18,17 @@ public:
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;
QLabel *m_holdSpliter;
SpliterAnimated *m_holdSpliter;
QSize m_holdSpliterMiniSize;
QSize m_holdSpliterMaxSize;
};
#endif // HOLDCONTAINER_H

View 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();
}

View 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

View File

@ -78,9 +78,11 @@ FashionTrayItem::FashionTrayItem(TrayPlugin *trayPlugin, QWidget *parent)
connect(m_controlWidget, &FashionTrayControlWidget::expandChanged, this, &FashionTrayItem::onExpandChanged);
connect(m_normalContainer, &NormalContainer::attentionChanged, this, &FashionTrayItem::onWrapperAttentionChanged);
connect(m_attentionContainer, &NormalContainer::attentionChanged, this, &FashionTrayItem::onWrapperAttentionChanged);
connect(m_attentionContainer, &AttentionContainer::attentionChanged, this, &FashionTrayItem::onWrapperAttentionChanged);
connect(m_normalContainer, &NormalContainer::requestDraggingWrapper, this, &FashionTrayItem::onRequireDraggingWrapper);
connect(m_holdContainer, &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);
@ -442,3 +444,10 @@ void FashionTrayItem::onRequireDraggingWrapper()
container->addDraggingWrapper(draggingWrapper);
}
void FashionTrayItem::onContainerDraggingStateChanged(FashionTrayWidgetWrapper *wrapper, const bool dragging)
{
Q_UNUSED(wrapper);
m_holdContainer->setDragging(dragging);
}

View File

@ -79,6 +79,7 @@ private Q_SLOTS:
void requestResize();
void refreshHoldContainerPosition();
void onRequireDraggingWrapper();
void onContainerDraggingStateChanged(FashionTrayWidgetWrapper *wrapper, const bool dragging);
private:
QBoxLayout *m_mainBoxLayout;