2018-06-26 14:09:39 +02:00
|
|
|
#include "RippleEffectButton.hpp"
|
2017-04-12 17:46:44 +02:00
|
|
|
|
|
|
|
#include <QDebug>
|
|
|
|
#include <QPainter>
|
|
|
|
|
2018-06-28 20:03:04 +02:00
|
|
|
#include "singletons/Theme.hpp"
|
2017-12-19 02:23:17 +01:00
|
|
|
|
2017-04-14 17:52:22 +02:00
|
|
|
namespace chatterino {
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
RippleEffectButton::RippleEffectButton(BaseWidget *parent)
|
2017-06-26 16:41:20 +02:00
|
|
|
: BaseWidget(parent)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-08-06 21:17:03 +02:00
|
|
|
connect(&effectTimer_, &QTimer::timeout, this,
|
|
|
|
&RippleEffectButton::onMouseEffectTimeout);
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
this->effectTimer_.setInterval(20);
|
|
|
|
this->effectTimer_.start();
|
2018-06-06 13:35:06 +02:00
|
|
|
|
|
|
|
this->setMouseTracking(true);
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-12-19 02:23:17 +01:00
|
|
|
void RippleEffectButton::setMouseEffectColor(boost::optional<QColor> color)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-06-06 10:46:23 +02:00
|
|
|
this->mouseEffectColor_ = color;
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
void RippleEffectButton::setPixmap(const QPixmap &_pixmap)
|
2018-01-17 16:52:51 +01:00
|
|
|
{
|
2018-06-06 10:46:23 +02:00
|
|
|
this->pixmap_ = _pixmap;
|
2018-01-17 16:52:51 +01:00
|
|
|
this->update();
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
const QPixmap &RippleEffectButton::getPixmap() const
|
2018-01-17 16:52:51 +01:00
|
|
|
{
|
2018-06-06 10:46:23 +02:00
|
|
|
return this->pixmap_;
|
|
|
|
}
|
|
|
|
|
2018-07-04 13:13:21 +02:00
|
|
|
void RippleEffectButton::setDim(bool value)
|
2018-07-04 13:05:54 +02:00
|
|
|
{
|
|
|
|
this->dimPixmap_ = value;
|
|
|
|
|
|
|
|
this->update();
|
|
|
|
}
|
|
|
|
|
2018-07-04 13:13:21 +02:00
|
|
|
bool RippleEffectButton::getDim() const
|
2018-07-04 13:05:54 +02:00
|
|
|
{
|
|
|
|
return this->dimPixmap_;
|
|
|
|
}
|
|
|
|
|
2018-07-04 19:43:41 +02:00
|
|
|
void RippleEffectButton::setEnable(bool value)
|
|
|
|
{
|
|
|
|
this->enabled_ = value;
|
|
|
|
|
|
|
|
this->update();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool RippleEffectButton::getEnable() const
|
|
|
|
{
|
|
|
|
return this->enabled_;
|
|
|
|
}
|
|
|
|
|
2018-07-04 13:13:21 +02:00
|
|
|
qreal RippleEffectButton::getCurrentDimAmount() const
|
|
|
|
{
|
|
|
|
return this->dimPixmap_ && !this->mouseOver_ ? 0.7 : 1;
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
void RippleEffectButton::setBorderColor(const QColor &color)
|
|
|
|
{
|
|
|
|
this->borderColor_ = color;
|
2018-07-04 19:43:41 +02:00
|
|
|
|
|
|
|
this->update();
|
2018-06-06 10:46:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const QColor &RippleEffectButton::getBorderColor() const
|
|
|
|
{
|
|
|
|
return this->borderColor_;
|
2018-01-17 16:52:51 +01:00
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::paintEvent(QPaintEvent *)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2017-09-16 00:05:06 +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);
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
if (!this->pixmap_.isNull()) {
|
2018-07-04 19:43:41 +02:00
|
|
|
if (!this->mouseOver_ && this->dimPixmap_ && this->enabled_) {
|
2018-07-04 13:13:21 +02:00
|
|
|
painter.setOpacity(this->getCurrentDimAmount());
|
2018-07-04 13:05:54 +02:00
|
|
|
}
|
|
|
|
|
2018-01-17 16:52:51 +01:00
|
|
|
QRect rect = this->rect();
|
2018-06-06 10:46:23 +02:00
|
|
|
int s = int(6 * this->getScale());
|
2018-01-17 16:52:51 +01:00
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
rect.moveLeft(s);
|
|
|
|
rect.setRight(rect.right() - s - s);
|
|
|
|
rect.moveTop(s);
|
|
|
|
rect.setBottom(rect.bottom() - s - s);
|
|
|
|
|
|
|
|
painter.drawPixmap(rect, this->pixmap_);
|
2018-07-04 13:05:54 +02:00
|
|
|
|
|
|
|
painter.setOpacity(1);
|
2018-06-06 10:46:23 +02:00
|
|
|
}
|
2018-01-17 16:52:51 +01:00
|
|
|
|
2018-06-06 15:54:14 +02:00
|
|
|
this->fancyPaint(painter);
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
if (this->borderColor_.isValid()) {
|
|
|
|
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
|
|
painter.setPen(this->borderColor_);
|
|
|
|
painter.drawRect(0, 0, this->width() - 1, this->height() - 1);
|
2018-01-17 16:52:51 +01:00
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::fancyPaint(QPainter &painter)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-07-04 19:43:41 +02:00
|
|
|
if (!this->enabled_) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-01-24 15:08:22 +01:00
|
|
|
painter.setRenderHint(QPainter::HighQualityAntialiasing);
|
|
|
|
painter.setRenderHint(QPainter::Antialiasing);
|
2017-12-19 02:23:17 +01:00
|
|
|
QColor c;
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
if (this->mouseEffectColor_) {
|
|
|
|
c = this->mouseEffectColor_.get();
|
2017-12-19 02:23:17 +01:00
|
|
|
} else {
|
2018-08-06 21:17:03 +02:00
|
|
|
c = this->theme->isLightTheme() ? QColor(0, 0, 0)
|
|
|
|
: QColor(255, 255, 255);
|
2017-12-19 02:23:17 +01:00
|
|
|
}
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
if (this->hoverMultiplier_ > 0) {
|
2018-06-06 13:35:06 +02:00
|
|
|
QRadialGradient gradient(QPointF(mousePos_), this->width() / 2);
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2018-08-06 21:17:03 +02:00
|
|
|
gradient.setColorAt(0, QColor(c.red(), c.green(), c.blue(),
|
|
|
|
int(50 * this->hoverMultiplier_)));
|
|
|
|
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(),
|
|
|
|
int(40 * this->hoverMultiplier_)));
|
2017-04-12 17:46:44 +02:00
|
|
|
|
|
|
|
painter.fillRect(this->rect(), gradient);
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
for (auto effect : this->clickEffects_) {
|
2017-04-12 17:46:44 +02:00
|
|
|
QRadialGradient gradient(effect.position.x(), effect.position.y(),
|
2018-08-06 21:17:03 +02:00
|
|
|
effect.progress * qreal(width()) * 2,
|
|
|
|
effect.position.x(), effect.position.y());
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2018-08-06 21:17:03 +02:00
|
|
|
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)));
|
2018-06-06 10:46:23 +02:00
|
|
|
gradient.setColorAt(1, QColor(c.red(), c.green(), c.blue(), int(0)));
|
2017-04-12 17:46:44 +02:00
|
|
|
|
|
|
|
painter.fillRect(this->rect(), gradient);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::enterEvent(QEvent *)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-06-06 10:46:23 +02:00
|
|
|
this->mouseOver_ = true;
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::leaveEvent(QEvent *)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-06-06 10:46:23 +02:00
|
|
|
this->mouseOver_ = false;
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::mousePressEvent(QMouseEvent *event)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-07-04 19:43:41 +02:00
|
|
|
if (!this->enabled_) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
if (event->button() != Qt::LeftButton) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
this->clickEffects_.push_back(ClickEffect(event->pos()));
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
this->mouseDown_ = true;
|
2018-07-04 19:43:41 +02:00
|
|
|
|
|
|
|
emit this->leftMousePress();
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::mouseReleaseEvent(QMouseEvent *event)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-07-04 19:43:41 +02:00
|
|
|
if (!this->enabled_) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-04-12 17:46:44 +02:00
|
|
|
if (event->button() != Qt::LeftButton) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::mouseMoveEvent(QMouseEvent *event)
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
2018-07-04 19:43:41 +02:00
|
|
|
if (!this->enabled_) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
this->mousePos_ = event->pos();
|
2018-06-06 13:35:06 +02:00
|
|
|
|
|
|
|
this->update();
|
2017-04-12 17:46:44 +02:00
|
|
|
}
|
|
|
|
|
2017-09-21 17:34:41 +02:00
|
|
|
void RippleEffectButton::onMouseEffectTimeout()
|
2017-04-12 17:46:44 +02:00
|
|
|
{
|
|
|
|
bool performUpdate = false;
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
if (selected_) {
|
|
|
|
if (this->hoverMultiplier_ != 0) {
|
2018-08-06 21:17:03 +02:00
|
|
|
this->hoverMultiplier_ =
|
|
|
|
std::max(0.0, this->hoverMultiplier_ - 0.1);
|
2017-04-12 17:46:44 +02:00
|
|
|
performUpdate = true;
|
|
|
|
}
|
2018-06-06 10:46:23 +02:00
|
|
|
} else if (mouseOver_) {
|
|
|
|
if (this->hoverMultiplier_ != 1) {
|
2018-08-06 21:17:03 +02:00
|
|
|
this->hoverMultiplier_ =
|
|
|
|
std::min(1.0, this->hoverMultiplier_ + 0.5);
|
2017-04-12 17:46:44 +02:00
|
|
|
performUpdate = true;
|
|
|
|
}
|
|
|
|
} else {
|
2018-06-06 10:46:23 +02:00
|
|
|
if (this->hoverMultiplier_ != 0) {
|
2018-08-06 21:17:03 +02:00
|
|
|
this->hoverMultiplier_ =
|
|
|
|
std::max(0.0, this->hoverMultiplier_ - 0.3);
|
2017-04-12 17:46:44 +02:00
|
|
|
performUpdate = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-06 10:46:23 +02:00
|
|
|
if (this->clickEffects_.size() != 0) {
|
2017-04-12 17:46:44 +02:00
|
|
|
performUpdate = true;
|
|
|
|
|
2018-08-06 21:17:03 +02:00
|
|
|
for (auto it = this->clickEffects_.begin();
|
|
|
|
it != this->clickEffects_.end();) {
|
2018-06-06 13:35:06 +02:00
|
|
|
it->progress += mouseDown_ ? 0.02 : 0.07;
|
2017-04-12 17:46:44 +02:00
|
|
|
|
2018-06-06 13:35:06 +02:00
|
|
|
if (it->progress >= 1.0) {
|
2018-06-06 10:46:23 +02:00
|
|
|
it = this->clickEffects_.erase(it);
|
2017-04-12 17:46:44 +02:00
|
|
|
} else {
|
|
|
|
it++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (performUpdate) {
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
2017-06-07 10:09:24 +02:00
|
|
|
|
|
|
|
} // namespace chatterino
|