add ripple
This commit is contained in:
parent
473999a5a8
commit
f3a4e06a1b
|
@ -1,15 +1,18 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QStylePainter>
|
#include <QStylePainter>
|
||||||
#include <QStyleOptionButton>
|
#include <QStyleOptionButton>
|
||||||
|
#include <QMouseEvent>
|
||||||
#include "flatbutton.h"
|
#include "flatbutton.h"
|
||||||
|
|
||||||
FlatButton::FlatButton(QWidget *parent)
|
FlatButton::FlatButton(QWidget *parent)
|
||||||
: QAbstractButton(parent)
|
: QAbstractButton(parent),
|
||||||
|
_overlay(new RippleOverlay(this))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatButton::FlatButton(const QString &text, QWidget *parent)
|
FlatButton::FlatButton(const QString &text, QWidget *parent)
|
||||||
: QAbstractButton(parent)
|
: QAbstractButton(parent),
|
||||||
|
_overlay(new RippleOverlay(this))
|
||||||
{
|
{
|
||||||
setText(text);
|
setText(text);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +21,13 @@ FlatButton::~FlatButton()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlatButton::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
|
|
||||||
|
updateOverlayGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
void FlatButton::paintEvent(QPaintEvent *event)
|
void FlatButton::paintEvent(QPaintEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
|
@ -45,6 +55,18 @@ void FlatButton::paintEvent(QPaintEvent *event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FlatButton::mousePressEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
_overlay->addRipple(event->pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlatButton::mouseReleaseEvent(QMouseEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
|
|
||||||
|
emit clicked();
|
||||||
|
}
|
||||||
|
|
||||||
void FlatButton::enterEvent(QEvent *event)
|
void FlatButton::enterEvent(QEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event)
|
Q_UNUSED(event)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define FLATBUTTON_H
|
#define FLATBUTTON_H
|
||||||
|
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
|
#include "rippleoverlay.h"
|
||||||
|
|
||||||
class FlatButton : public QAbstractButton
|
class FlatButton : public QAbstractButton
|
||||||
{
|
{
|
||||||
|
@ -13,9 +14,17 @@ public:
|
||||||
~FlatButton();
|
~FlatButton();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
|
||||||
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;
|
||||||
void enterEvent(QEvent *event) Q_DECL_OVERRIDE;
|
void enterEvent(QEvent *event) Q_DECL_OVERRIDE;
|
||||||
void leaveEvent(QEvent *event) Q_DECL_OVERRIDE;
|
void leaveEvent(QEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline void updateOverlayGeometry() { _overlay->setGeometry(rect()); }
|
||||||
|
|
||||||
|
RippleOverlay *const _overlay;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FLATBUTTON_H
|
#endif // FLATBUTTON_H
|
||||||
|
|
|
@ -27,7 +27,9 @@ SOURCES += main.cpp\
|
||||||
tab.cpp \
|
tab.cpp \
|
||||||
tabs.cpp \
|
tabs.cpp \
|
||||||
textfield.cpp \
|
textfield.cpp \
|
||||||
table.cpp
|
table.cpp \
|
||||||
|
ripple.cpp \
|
||||||
|
rippleoverlay.cpp
|
||||||
|
|
||||||
HEADERS += mainwindow.h \
|
HEADERS += mainwindow.h \
|
||||||
style.h \
|
style.h \
|
||||||
|
@ -43,4 +45,6 @@ HEADERS += mainwindow.h \
|
||||||
tab.h \
|
tab.h \
|
||||||
tabs.h \
|
tabs.h \
|
||||||
textfield.h \
|
textfield.h \
|
||||||
table.h
|
table.h \
|
||||||
|
ripple.h \
|
||||||
|
rippleoverlay.h
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include "ripple.h"
|
||||||
|
|
||||||
|
Ripple::Ripple(const QPoint ¢er, QObject *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
_radiusAnimation(animate("radius")),
|
||||||
|
_opacityAnimation(animate("opacity")),
|
||||||
|
_radius(0),
|
||||||
|
_opacity(0),
|
||||||
|
_center(center)
|
||||||
|
{
|
||||||
|
connect(&_group, SIGNAL(finished()), this, SIGNAL(finished()));
|
||||||
|
|
||||||
|
setOpacityStartValue(0.5);
|
||||||
|
setOpacityEndValue(0);
|
||||||
|
setRadiusStartValue(0);
|
||||||
|
setRadiusEndValue(300);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ripple::~Ripple()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QPropertyAnimation *Ripple::animate(const QByteArray &property)
|
||||||
|
{
|
||||||
|
QPropertyAnimation *animation = new QPropertyAnimation;
|
||||||
|
animation->setPropertyName(property);
|
||||||
|
animation->setEasingCurve(QEasingCurve::OutCubic);
|
||||||
|
animation->setTargetObject(this);
|
||||||
|
animation->setDuration(700);
|
||||||
|
_group.addAnimation(animation);
|
||||||
|
return animation;
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
#ifndef RIPPLE_H
|
||||||
|
#define RIPPLE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QPoint>
|
||||||
|
#include <QParallelAnimationGroup>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
|
||||||
|
class Ripple : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(qreal radius WRITE setRadius READ radius)
|
||||||
|
Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Ripple(const QPoint ¢er, QObject *parent = 0);
|
||||||
|
~Ripple();
|
||||||
|
|
||||||
|
inline void setRadius(qreal radius) { _radius = radius; emit valueChanged(); }
|
||||||
|
inline qreal radius() const { return _radius; }
|
||||||
|
|
||||||
|
inline void setOpacity(qreal opacity) { _opacity = opacity; emit valueChanged(); }
|
||||||
|
inline qreal opacity() const { return _opacity; }
|
||||||
|
|
||||||
|
inline const QPoint ¢er() const { return _center; }
|
||||||
|
|
||||||
|
inline void setDuration(int duration)
|
||||||
|
{
|
||||||
|
_radiusAnimation->setDuration(duration);
|
||||||
|
_opacityAnimation->setDuration(duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setOpacityStartValue(qreal value) { _opacityAnimation->setStartValue(value); }
|
||||||
|
inline void setOpacityEndValue(qreal value) { _opacityAnimation->setEndValue(value); }
|
||||||
|
inline void setRadiusStartValue(qreal value) { _radiusAnimation->setStartValue(value); }
|
||||||
|
inline void setRadiusEndValue(qreal value) { _radiusAnimation->setEndValue(value); }
|
||||||
|
|
||||||
|
inline void startAnimation() { _group.start(); }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void valueChanged();
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QPropertyAnimation *animate(const QByteArray &property);
|
||||||
|
|
||||||
|
QParallelAnimationGroup _group;
|
||||||
|
QPropertyAnimation *const _radiusAnimation;
|
||||||
|
QPropertyAnimation *const _opacityAnimation;
|
||||||
|
qreal _radius;
|
||||||
|
qreal _opacity;
|
||||||
|
QPoint _center;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RIPPLE_H
|
|
@ -0,0 +1,57 @@
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QPainter>
|
||||||
|
#include "rippleoverlay.h"
|
||||||
|
#include "ripple.h"
|
||||||
|
|
||||||
|
RippleOverlay::RippleOverlay(QWidget *parent)
|
||||||
|
: QWidget(parent)
|
||||||
|
{
|
||||||
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
|
setAttribute(Qt::WA_NoSystemBackground);
|
||||||
|
}
|
||||||
|
|
||||||
|
RippleOverlay::~RippleOverlay()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void RippleOverlay::addRipple(const QPoint &position, qreal radius)
|
||||||
|
{
|
||||||
|
Ripple *ripple = new Ripple(position);
|
||||||
|
ripple->setRadiusEndValue(radius);
|
||||||
|
ripples.push_back(ripple);
|
||||||
|
connect(ripple, SIGNAL(valueChanged()), this, SLOT(update()));
|
||||||
|
connect(ripple, SIGNAL(finished()), this, SLOT(deleteRipple()));
|
||||||
|
ripple->startAnimation();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RippleOverlay::paintEvent(QPaintEvent *event)
|
||||||
|
{
|
||||||
|
Q_UNUSED(event)
|
||||||
|
|
||||||
|
QPainter painter(this);
|
||||||
|
painter.setRenderHint(QPainter::Antialiasing);
|
||||||
|
|
||||||
|
QBrush brush;
|
||||||
|
brush.setColor(Qt::black);
|
||||||
|
brush.setStyle(Qt::SolidPattern);
|
||||||
|
painter.setBrush(brush);
|
||||||
|
|
||||||
|
QList<Ripple *>::const_iterator i;
|
||||||
|
for (i = ripples.begin(); i != ripples.end(); ++i)
|
||||||
|
{
|
||||||
|
const Ripple *ripple = *i;
|
||||||
|
const qreal radius = ripple->radius();
|
||||||
|
const QPointF ¢er = ripple->center();
|
||||||
|
painter.setOpacity(ripple->opacity());
|
||||||
|
painter.drawEllipse(center, radius, radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RippleOverlay::deleteRipple()
|
||||||
|
{
|
||||||
|
if (ripples.isEmpty()) {
|
||||||
|
qWarning() << "RippleOverlay::deleteRipple was called when no active ripple.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ripples.takeFirst()->deleteLater();
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#ifndef RIPPLEOVERLAY_H
|
||||||
|
#define RIPPLEOVERLAY_H
|
||||||
|
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class Ripple;
|
||||||
|
|
||||||
|
class RippleOverlay : public QWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit RippleOverlay(QWidget *parent = 0);
|
||||||
|
~RippleOverlay();
|
||||||
|
|
||||||
|
void addRipple(const QPoint &position, qreal radius = 300);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void deleteRipple();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<Ripple *> ripples;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // RIPPLEOVERLAY_H
|
Loading…
Reference in New Issue