mirror-chatterino2/src/widgets/helper/rippleeffectbutton.cpp

177 lines
4.5 KiB
C++
Raw Normal View History

#include "rippleeffectbutton.hpp"
2017-04-12 17:46:44 +02:00
#include <QDebug>
#include <QPainter>
2017-12-31 00:50:07 +01:00
#include "singletons/thememanager.hpp"
2017-04-14 17:52:22 +02:00
namespace chatterino {
namespace widgets {
2017-04-12 17:46:44 +02:00
RippleEffectButton::RippleEffectButton(BaseWidget *parent)
: BaseWidget(parent)
2018-01-17 16:52:51 +01:00
, pixmap(nullptr)
2017-04-12 17:46:44 +02:00
{
connect(&effectTimer, &QTimer::timeout, this, &RippleEffectButton::onMouseEffectTimeout);
2017-04-12 17:46:44 +02:00
this->effectTimer.setInterval(20);
this->effectTimer.start();
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::setMouseEffectColor(boost::optional<QColor> color)
2017-04-12 17:46:44 +02:00
{
this->mouseEffectColor = color;
2017-04-12 17:46:44 +02:00
}
2018-01-17 16:52:51 +01:00
void RippleEffectButton::setPixmap(const QPixmap *_pixmap)
{
this->pixmap = const_cast<QPixmap *>(_pixmap);
this->update();
}
const QPixmap *RippleEffectButton::getPixmap() const
{
return this->pixmap;
}
void RippleEffectButton::paintEvent(QPaintEvent *)
2017-04-12 17:46:44 +02:00
{
QPainter painter(this);
2017-04-12 17:46:44 +02:00
2018-01-17 16:52:51 +01:00
painter.setRenderHint(QPainter::SmoothPixmapTransform);
this->fancyPaint(painter);
2018-01-17 16:52:51 +01:00
if (this->pixmap != nullptr) {
QRect rect = this->rect();
int xD = 6 * this->getDpiMultiplier();
rect.moveLeft(xD);
rect.setRight(rect.right() - xD - xD);
rect.moveTop(xD);
rect.setBottom(rect.bottom() - xD - xD);
painter.drawPixmap(rect, *this->pixmap);
}
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::fancyPaint(QPainter &painter)
2017-04-12 17:46:44 +02:00
{
2018-01-24 15:08:22 +01:00
painter.setRenderHint(QPainter::HighQualityAntialiasing);
painter.setRenderHint(QPainter::Antialiasing);
QColor c;
if (this->mouseEffectColor) {
c = this->mouseEffectColor.get();
} else {
2017-12-31 00:50:07 +01:00
c = this->themeManager.isLightTheme() ? QColor(0, 0, 0) : QColor(255, 255, 255);
}
2017-04-12 17:46:44 +02:00
if (this->hoverMultiplier > 0) {
QRadialGradient gradient(mousePos.x(), mousePos.y(), 50, mousePos.x(), mousePos.y());
2017-04-12 17:46:44 +02:00
2017-08-12 12:09:26 +02:00
gradient.setColorAt(
0, QColor(c.red(), c.green(), c.blue(), (int)(24 * this->hoverMultiplier)));
gradient.setColorAt(
1, QColor(c.red(), c.green(), c.blue(), (int)(12 * this->hoverMultiplier)));
2017-04-12 17:46:44 +02:00
painter.fillRect(this->rect(), gradient);
}
for (auto effect : this->clickEffects) {
2017-04-12 17:46:44 +02:00
QRadialGradient gradient(effect.position.x(), effect.position.y(),
effect.progress * (float)width() * 2, effect.position.x(),
effect.position.y());
gradient.setColorAt(
0, QColor(c.red(), c.green(), c.blue(), (int)((1 - effect.progress) * 95)));
gradient.setColorAt(
0.9999, QColor(c.red(), c.green(), c.blue(), (int)((1 - effect.progress) * 95)));
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(), (int)(0)));
painter.fillRect(this->rect(), gradient);
}
}
void RippleEffectButton::enterEvent(QEvent *)
2017-04-12 17:46:44 +02:00
{
this->mouseOver = true;
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::leaveEvent(QEvent *)
2017-04-12 17:46:44 +02:00
{
this->mouseOver = false;
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::mousePressEvent(QMouseEvent *event)
2017-04-12 17:46:44 +02:00
{
if (event->button() != Qt::LeftButton) {
return;
}
this->clickEffects.push_back(ClickEffect(event->pos()));
2017-04-12 17:46:44 +02:00
this->mouseDown = true;
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::mouseReleaseEvent(QMouseEvent *event)
2017-04-12 17:46:44 +02:00
{
if (event->button() != Qt::LeftButton) {
return;
}
this->mouseDown = false;
2017-09-15 17:23:49 +02:00
if (this->rect().contains(event->pos())) {
emit clicked();
}
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::mouseMoveEvent(QMouseEvent *event)
2017-04-12 17:46:44 +02:00
{
this->mousePos = event->pos();
2017-04-12 17:46:44 +02:00
}
void RippleEffectButton::onMouseEffectTimeout()
2017-04-12 17:46:44 +02:00
{
bool performUpdate = false;
if (selected) {
if (this->hoverMultiplier != 0) {
this->hoverMultiplier = std::max(0.0, this->hoverMultiplier - 0.1);
2017-04-12 17:46:44 +02:00
performUpdate = true;
}
} else if (mouseOver) {
if (this->hoverMultiplier != 1) {
this->hoverMultiplier = std::min(1.0, this->hoverMultiplier + 0.5);
2017-04-12 17:46:44 +02:00
performUpdate = true;
}
} else {
if (this->hoverMultiplier != 0) {
this->hoverMultiplier = std::max(0.0, this->hoverMultiplier - 0.3);
2017-04-12 17:46:44 +02:00
performUpdate = true;
}
}
if (this->clickEffects.size() != 0) {
2017-04-12 17:46:44 +02:00
performUpdate = true;
for (auto it = this->clickEffects.begin(); it != this->clickEffects.end();) {
(*it).progress += mouseDown ? 0.02 : 0.07;
2017-04-12 17:46:44 +02:00
if ((*it).progress >= 1.0) {
it = this->clickEffects.erase(it);
2017-04-12 17:46:44 +02:00
} else {
it++;
}
}
}
if (performUpdate) {
update();
}
}
} // namespace widgets
} // namespace chatterino