Skip to content

Commit

Permalink
sync: from linuxdeepin/dtkwidget
Browse files Browse the repository at this point in the history
Synchronize source files from linuxdeepin/dtkwidget.

Source-pull-request: linuxdeepin/dtkwidget#589
  • Loading branch information
deepin-ci-robot committed Jul 23, 2024
1 parent c8b8148 commit 8c43d1b
Show file tree
Hide file tree
Showing 8 changed files with 312 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/DWidget/DIndeterminateProgressbar
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "dindeterminateprogressbar.h"
26 changes: 26 additions & 0 deletions include/widgets/dindeterminateprogressbar.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2019 - 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#ifndef DINDETERMINATEPROGRESSBAR_H
#define DINDETERMINATEPROGRESSBAR_H

#include <DObject>
#include <QWidget>

class DIndeterminateProgressbarPrivate;
class DIndeterminateProgressbar : public QWidget, public DTK_CORE_NAMESPACE::DObject
{
Q_OBJECT
public:
explicit DIndeterminateProgressbar(QWidget *parent = nullptr);

protected:
void paintEvent(QPaintEvent *e) override;
void resizeEvent(QResizeEvent *e) override;

private:
D_DECLARE_PRIVATE(DIndeterminateProgressbar)
};

#endif // DINDETERMINATEPROGRESSBAR_H
13 changes: 12 additions & 1 deletion include/widgets/dprogressbar.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2019 - 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

Expand All @@ -8,16 +8,27 @@
#include <dtkwidget_global.h>
#include <DObject>
#include <QProgressBar>
#include <QResizeEvent>
#include <QPaintEvent>

class QPropertyAnimation;
DWIDGET_BEGIN_NAMESPACE

class DProgressBarPrivate;
class DProgressBar : public QProgressBar, public DCORE_NAMESPACE::DObject
{
public:
explicit DProgressBar(QWidget *parent = nullptr);

QSize sizeHint() const override;
QSize minimumSizeHint() const override;

protected:
void resizeEvent(QResizeEvent *e) override;
void paintEvent(QPaintEvent *e) override;

private:
D_DECLARE_PRIVATE(DProgressBar)
};

DWIDGET_END_NAMESPACE
Expand Down
133 changes: 133 additions & 0 deletions src/widgets/dindeterminateprogressbar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// SPDX-FileCopyrightText: 2019 - 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#include "private/dindeterminateprogressbar_p.h"

#include <DStyle>

#include <QPainter>
#include <QTimer>
#include <QPropertyAnimation>
#include <QDebug>
#include <QPainterPath>

const int SPOT_WIDGET_WIDTH = 200;

DIndeterminateProgressbarPrivate::DIndeterminateProgressbarPrivate(DIndeterminateProgressbar *qq)
: DObjectPrivate(qq)
, m_sliderWidget(new QWidget(qq))
, m_timer(new QTimer(qq))
, m_leftToRight(true)
, m_spotWidget(new QWidget(qq))
, m_animation(new QPropertyAnimation(m_spotWidget, "pos", qq))
{
}

DIndeterminateProgressbar::DIndeterminateProgressbar(QWidget *parent)
: QWidget(parent)
, DObject(*new DIndeterminateProgressbarPrivate(this))
{
D_D(DIndeterminateProgressbar);
d->m_spotWidget->setFixedSize(SPOT_WIDGET_WIDTH, height());
d->m_spotWidget->move(-SPOT_WIDGET_WIDTH, 0);

d->m_sliderWidget->setFixedWidth(150);
d->m_sliderWidget->move(0, 0);

d->m_timer->setInterval(10);
static int step = 0;
connect(d->m_timer, &QTimer::timeout, this, [this, d]() {
if (d->m_sliderWidget->geometry().right() >= rect().right()) {
d->m_leftToRight = false;
}

if (d->m_sliderWidget->geometry().left() <= rect().left()) {
d->m_leftToRight = true;
}

d->m_leftToRight ? step += 2 : step -= 2;
d->m_sliderWidget->move(step, 0);
});
d->m_timer->start();
}

void DIndeterminateProgressbar::resizeEvent(QResizeEvent *e)
{
D_D(DIndeterminateProgressbar);
d->m_sliderWidget->setFixedHeight(height());
d->m_spotWidget->setFixedSize(SPOT_WIDGET_WIDTH, height());

d->m_animation->setStartValue(QPoint(-SPOT_WIDGET_WIDTH, 0));
d->m_animation->setEndValue(QPoint(rect().right(), 0));
d->m_animation->setDuration(3000);
d->m_animation->setEasingCurve(QEasingCurve::InQuad);
d->m_animation->start();
connect(d->m_animation, &QPropertyAnimation::finished, this, [d]() {
d->m_animation->start();
});
QWidget::resizeEvent(e);
}

void DIndeterminateProgressbar::paintEvent(QPaintEvent *e)
{
D_D(DIndeterminateProgressbar);
QWidget::paintEvent(e);
QPainter p(this);

p.setRenderHint(QPainter::Antialiasing);
int radius;
this->height() <= DTK_WIDGET_NAMESPACE::DStyle::pixelMetric(style(), DTK_WIDGET_NAMESPACE::DStyle::PM_FrameRadius) * 2
? radius = height() / 2
: radius = DTK_WIDGET_NAMESPACE::DStyle::pixelMetric(style(), DTK_WIDGET_NAMESPACE::DStyle::PM_FrameRadius);

p.setBrush(QColor(0, 0, 0, int(0.1 * 255)));
p.setPen(Qt::NoPen);

p.drawRoundedRect(rect(), radius, radius);

QPen pen;
pen.setWidth(2);
pen.setColor(QColor(0, 0, 0, int(0.2 * 255)));
p.setBrush(Qt::NoBrush);
p.setPen(pen);
p.drawRoundedRect(rect().marginsRemoved(QMargins(1, 1, 1, 1)), radius, radius);

p.setPen(Qt::NoPen);
p.setBrush(palette().highlight().color());
p.drawRoundedRect(d->m_sliderWidget->geometry(), radius, radius);

pen.setColor(QColor(0, 0, 0, int(0.3 * 255)));
p.setBrush(Qt::NoBrush);
p.setPen(pen);
p.drawRoundedRect(d->m_sliderWidget->geometry().marginsRemoved(QMargins(1, 1, 1, 1)), radius, radius);

if (d->m_sliderWidget->width() < d->m_spotWidget->width() / 2)
return;

QPointF pointStart(d->m_spotWidget->geometry().left(), d->m_spotWidget->geometry().center().y());
QPointF pointEnd(d->m_spotWidget->geometry().right(), d->m_spotWidget->geometry().center().y());

QColor shadowColor(0, 0, 0, int(0.15 * 255));
QColor spotColor(255, 255, 255, int(0.5 * 255));
QColor highLightColor(palette().highlight().color());

QLinearGradient linear(pointStart, pointEnd);
linear.setColorAt(0, highLightColor);
linear.setColorAt(0.35, shadowColor);
linear.setColorAt(0.5, spotColor);
linear.setColorAt(0.65, shadowColor);
linear.setColorAt(1, highLightColor);
linear.setSpread(QGradient::PadSpread);
linear.setInterpolationMode(QLinearGradient::InterpolationMode::ColorInterpolation);

p.setBrush(linear);
p.setPen(Qt::NoPen);

QPainterPath clipPath;
clipPath.addRoundedRect(d->m_sliderWidget->geometry(), radius, radius);
p.setClipPath(clipPath);
p.setClipping(true);
p.drawRoundedRect(d->m_spotWidget->geometry().marginsRemoved(QMargins(2, 2, 2, 2)), radius, radius);
p.setClipping(false);
}
87 changes: 83 additions & 4 deletions src/widgets/dprogressbar.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
// SPDX-FileCopyrightText: 2019 - 2022 UnionTech Software Technology Co., Ltd.
// SPDX-FileCopyrightText: 2019 - 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#include "dprogressbar.h"
#include "private/dprogressbar_p.h"

#include <DStyle>

#include <QStyle>
#include <QStyleOptionProgressBar>
#include <QPropertyAnimation>
#include <QDebug>
#include <QTimer>
#include <QPainter>
#include <QPainterPath>

const int SPOT_WIDGET_WIDTH = 200;

DWIDGET_BEGIN_NAMESPACE

DProgressBarPrivate::DProgressBarPrivate(DProgressBar *qq)
: DObjectPrivate(qq)
, m_spotWidget(new QWidget(qq))
, m_animation(new QPropertyAnimation(m_spotWidget, "pos", qq))
{
}
/*!
@~english
@class Dtk::Widget::DProgressBar
Expand All @@ -23,8 +38,11 @@ DWIDGET_BEGIN_NAMESPACE
*/
DProgressBar::DProgressBar(QWidget *parent)
: QProgressBar(parent)
, DObject(*new DProgressBarPrivate(this))
{

D_D(DProgressBar);
d->m_spotWidget->setFixedSize(SPOT_WIDGET_WIDTH, height());
d->m_spotWidget->move(-SPOT_WIDGET_WIDTH, 0);
}

/*!
Expand Down Expand Up @@ -57,4 +75,65 @@ QSize DProgressBar::minimumSizeHint() const
return sizeHint();
}

void DProgressBar::resizeEvent(QResizeEvent *e)
{
D_D(DProgressBar);
d->m_spotWidget->setFixedSize(SPOT_WIDGET_WIDTH, height());

d->m_animation->setStartValue(QPoint(-SPOT_WIDGET_WIDTH, 0));
d->m_animation->setEndValue(QPoint(rect().right(), 0));
d->m_animation->setDuration(2000);
d->m_animation->setEasingCurve(QEasingCurve::InQuad);
d->m_animation->start();
connect(d->m_animation, &QPropertyAnimation::finished, this, [this, d]() {
// 动画之间需要间隔1s
QTimer::singleShot(1000, this, [this, d]() {
d->m_animation->start();
});
});
QProgressBar::resizeEvent(e);
}

void DProgressBar::paintEvent(QPaintEvent *e)
{
D_D(DProgressBar);
QProgressBar::paintEvent(e);

QPainter p(this);

if (rect().right() * (qreal(value()) / qreal(maximum())) < d->m_spotWidget->width() / 2)
return;

int radius;
this->height() <= DStyle::pixelMetric(style(), DStyle::PM_FrameRadius) * 2
? radius = height() / 2
: radius = DStyle::pixelMetric(style(), DStyle::PM_FrameRadius);

QPointF pointStart(d->m_spotWidget->geometry().left(), d->m_spotWidget->geometry().center().y());
QPointF pointEnd(d->m_spotWidget->geometry().right(), d->m_spotWidget->geometry().center().y());

QColor shadowColor(0, 0, 0, int(0.15 * 255));
QColor spotColor(255, 255, 255, int(0.5 * 255));
QColor highLightColor(palette().highlight().color());

QLinearGradient linear(pointStart, pointEnd);
linear.setColorAt(0, highLightColor);
linear.setColorAt(0.35, shadowColor);
linear.setColorAt(0.5, spotColor);
linear.setColorAt(0.65, shadowColor);
linear.setColorAt(1, highLightColor);
linear.setSpread(QGradient::PadSpread);
linear.setInterpolationMode(QLinearGradient::InterpolationMode::ColorInterpolation);

p.setBrush(linear);
p.setPen(Qt::NoPen);
int progressWidth = int(rect().right() * (qreal(value()) / qreal(maximum())));

QPainterPath clipPath;
clipPath.addRoundedRect(QRect(rect().x(), rect().y(), progressWidth, rect().height()), radius, radius);
p.setClipPath(clipPath);
p.setClipping(true);
p.drawRoundedRect(d->m_spotWidget->geometry().marginsRemoved(QMargins(2, 2, 2, 2)), radius, radius);
p.setClipping(false);
}
DWIDGET_END_NAMESPACE
2 changes: 1 addition & 1 deletion src/widgets/dtitlebar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ void DTitlebarPrivate::setIconVisible(bool visible)
return;

if (visible) {
if (auto spacerItem = dynamic_cast<QSpacerItem *>(leftLayout->takeAt(0)))
if (dynamic_cast<QSpacerItem *>(leftLayout->itemAt(0)))
delete leftLayout->takeAt(0);

leftLayout->insertSpacing(0, 10);
Expand Down
29 changes: 29 additions & 0 deletions src/widgets/private/dindeterminateprogressbar_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: 2017 - 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#ifndef DINDETERMINATEPROGRESSBAR_P_H
#define DINDETERMINATEPROGRESSBAR_P_H

#include <DObjectPrivate>
#include <DIndeterminateProgressbar>

#include <QTimer>

class QPropertyAnimation;
class DIndeterminateProgressbarPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate
{
public:
DIndeterminateProgressbarPrivate(DIndeterminateProgressbar *qq);

Check warning on line 17 in src/widgets/private/dindeterminateprogressbar_p.h

View workflow job for this annotation

GitHub Actions / cppcheck

Class 'DIndeterminateProgressbarPrivate' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.

QWidget *m_sliderWidget;
QTimer *m_timer;
bool m_leftToRight;
QWidget *m_spotWidget;
QPropertyAnimation *m_animation;

Check warning on line 23 in src/widgets/private/dindeterminateprogressbar_p.h

View workflow job for this annotation

GitHub Actions / cppcheck

The class 'DIndeterminateProgressbarPrivate' is unsafe, wrong usage can cause memory/resource leaks for 'DIndeterminateProgressbarPrivate::m_animation'. This can for instance be fixed by adding proper cleanup in the destructor.

private:
D_DECLARE_PUBLIC(DIndeterminateProgressbar)
};

#endif // DINDETERMINATEPROGRESSBAR_P_H
27 changes: 27 additions & 0 deletions src/widgets/private/dprogressbar_p.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-FileCopyrightText: 2019 - 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later

#ifndef DPROGRESSBAR_P_H
#define DPROGRESSBAR_P_H

#include "dprogressbar.h"
#include <DObjectPrivate>

DWIDGET_BEGIN_NAMESPACE

class DProgressBarPrivate : public DTK_CORE_NAMESPACE::DObjectPrivate
{
public:
DProgressBarPrivate(DProgressBar *qq);

Check warning on line 16 in src/widgets/private/dprogressbar_p.h

View workflow job for this annotation

GitHub Actions / cppcheck

Class 'DProgressBarPrivate' has a constructor with 1 argument that is not explicit. Such constructors should in general be explicit for type safety reasons. Using the explicit keyword in the constructor means some mistakes when using the class can be avoided.

QWidget *m_spotWidget;
QPropertyAnimation *m_animation;

private:
D_DECLARE_PUBLIC(DProgressBar)
};

DWIDGET_END_NAMESPACE

#endif // DPROGRESSBAR_P_H

0 comments on commit 8c43d1b

Please sign in to comment.