nheko/src/ui/SnackBar.cpp

136 lines
3.0 KiB
C++
Raw Normal View History

2021-03-05 00:35:15 +01:00
// SPDX-FileCopyrightText: 2021 Nheko Contributors
//
// SPDX-License-Identifier: GPL-3.0-or-later
2017-10-08 15:49:56 +02:00
#include <QPainter>
#include "SnackBar.h"
2018-07-25 22:07:56 +02:00
constexpr int STARTING_OFFSET = 1;
constexpr int BOX_PADDING = 10;
constexpr double MIN_WIDTH = 400.0;
constexpr double MIN_WIDTH_PERCENTAGE = 0.3;
2017-10-08 15:49:56 +02:00
SnackBar::SnackBar(QWidget *parent)
: OverlayWidget(parent)
2021-03-05 14:04:11 +01:00
, offset_anim(this, "offset", this)
2017-10-08 15:49:56 +02:00
{
2021-09-18 00:22:33 +02:00
QFont font;
font.setPointSizeF(font.pointSizeF() * 1.2);
font.setWeight(50);
setFont(font);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
boxHeight_ = QFontMetrics(font).height() * 2;
offset_ = STARTING_OFFSET;
position_ = SnackBarPosition::Top;
2018-07-25 22:07:56 +02:00
2021-09-18 00:22:33 +02:00
hideTimer_.setSingleShot(true);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
offset_anim.setStartValue(1.0);
offset_anim.setEndValue(0.0);
offset_anim.setDuration(100);
offset_anim.setEasingCurve(QEasingCurve::OutCubic);
2021-03-05 14:04:11 +01:00
2021-09-18 00:22:33 +02:00
connect(this, &SnackBar::offsetChanged, this, [this]() mutable { repaint(); });
connect(
&offset_anim, &QPropertyAnimation::finished, this, [this]() { hideTimer_.start(10000); });
2018-03-16 16:56:45 +01:00
2021-09-18 00:22:33 +02:00
connect(&hideTimer_, SIGNAL(timeout()), this, SLOT(hideMessage()));
2021-09-18 00:22:33 +02:00
hide();
2017-10-08 15:49:56 +02:00
}
void
SnackBar::start()
{
2021-09-18 00:22:33 +02:00
if (messages_.empty())
return;
2021-09-18 00:22:33 +02:00
show();
raise();
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
offset_anim.start();
2017-10-08 15:49:56 +02:00
}
void
SnackBar::hideMessage()
{
2021-09-18 00:22:33 +02:00
stopTimers();
hide();
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
if (!messages_.empty())
// Moving on to the next message.
messages_.pop_front();
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
// Resetting the starting position of the widget.
offset_ = STARTING_OFFSET;
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
if (!messages_.empty())
start();
2017-10-08 15:49:56 +02:00
}
void
SnackBar::stopTimers()
{
2021-09-18 00:22:33 +02:00
hideTimer_.stop();
2017-10-08 15:49:56 +02:00
}
void
SnackBar::showMessage(const QString &msg)
{
2021-09-18 00:22:33 +02:00
messages_.push_back(msg);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
// There is already an active message.
if (isVisible())
return;
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
start();
2017-10-08 15:49:56 +02:00
}
void
SnackBar::mousePressEvent(QMouseEvent *)
{
2021-09-18 00:22:33 +02:00
hideMessage();
2017-10-08 15:49:56 +02:00
}
void
SnackBar::paintEvent(QPaintEvent *event)
{
2021-09-18 00:22:33 +02:00
Q_UNUSED(event)
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
if (messages_.empty())
return;
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
auto message_ = messages_.front();
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(bgColor_);
p.setBrush(brush);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
QRect r(0, 0, std::max(MIN_WIDTH, width() * MIN_WIDTH_PERCENTAGE), boxHeight_);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
p.setPen(Qt::white);
QRect br = p.boundingRect(r, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
p.setPen(Qt::NoPen);
r = br.united(r).adjusted(-BOX_PADDING, -BOX_PADDING, BOX_PADDING, BOX_PADDING);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
const qreal s = 1 - offset_;
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
if (position_ == SnackBarPosition::Bottom)
p.translate((width() - (r.width() - 2 * BOX_PADDING)) / 2,
height() - BOX_PADDING - s * (r.height()));
else
p.translate((width() - (r.width() - 2 * BOX_PADDING)) / 2,
s * (r.height()) - 2 * BOX_PADDING);
2017-10-08 15:49:56 +02:00
2021-09-18 00:22:33 +02:00
br.moveCenter(r.center());
p.drawRoundedRect(r.adjusted(0, 0, 0, 4), 4, 4);
p.setPen(textColor_);
p.drawText(br, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_);
2017-10-08 15:49:56 +02:00
}