summary refs log tree commit diff
path: root/src/ui/SnackBar.cpp
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-17 16:37:25 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-17 16:37:25 +0300
commit0e814da91c8e041897a4c3f7e6e9234bbc7c6f7a (patch)
tree21f655d30630fe77ba48d07e4b357e2b6c6a5730 /src/ui/SnackBar.cpp
parentMerge pull request #372 from bebehei/notification (diff)
downloadnheko-0e814da91c8e041897a4c3f7e6e9234bbc7c6f7a.tar.xz
Move all files under src/
Diffstat (limited to 'src/ui/SnackBar.cpp')
-rw-r--r--src/ui/SnackBar.cpp141
1 files changed, 141 insertions, 0 deletions
diff --git a/src/ui/SnackBar.cpp b/src/ui/SnackBar.cpp
new file mode 100644

index 00000000..43a4c85d --- /dev/null +++ b/src/ui/SnackBar.cpp
@@ -0,0 +1,141 @@ +#include <QDebug> +#include <QPainter> + +#include <tweeny/tweeny.h> + +#include "SnackBar.h" + +constexpr int STARTING_OFFSET = 1; + +SnackBar::SnackBar(QWidget *parent) + : OverlayWidget(parent) +{ + bgOpacity_ = 0.9; + duration_ = 6000; + boxWidth_ = 400; + boxHeight_ = 40; + boxPadding_ = 10; + textColor_ = QColor("white"); + bgColor_ = QColor("#333"); + offset_ = STARTING_OFFSET; + position_ = SnackBarPosition::Top; + + QFont font("Open Sans"); + font.setPixelSize(14); + font.setWeight(50); + setFont(font); + + hideTimer_.setSingleShot(true); + + auto offset_anim = tweeny::from(1.0f).to(0.0f).during(100).via(tweeny::easing::cubicOut); + connect(&showTimer_, &QTimer::timeout, this, [this, offset_anim]() mutable { + if (offset_anim.progress() < 1.0f) { + offset_ = offset_anim.step(0.07f); + update(); + } else { + showTimer_.stop(); + hideTimer_.start(duration_); + offset_anim.seek(0.0f); + } + }); + + connect(&hideTimer_, SIGNAL(timeout()), this, SLOT(hideMessage())); + + hide(); +} + +void +SnackBar::start() +{ + if (messages_.empty()) + return; + + show(); + raise(); + + showTimer_.start(10); +} + +void +SnackBar::hideMessage() +{ + stopTimers(); + hide(); + + if (!messages_.empty()) + // Moving on to the next message. + messages_.pop_front(); + + // Reseting the starting position of the widget. + offset_ = STARTING_OFFSET; + + if (!messages_.empty()) + start(); +} + +void +SnackBar::stopTimers() +{ + showTimer_.stop(); + hideTimer_.stop(); +} + +void +SnackBar::showMessage(const QString &msg) +{ + messages_.push_back(msg); + + // There is already an active message. + if (isVisible()) + return; + + start(); +} + +void +SnackBar::mousePressEvent(QMouseEvent *) +{ + hideMessage(); +} + +void +SnackBar::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + if (messages_.empty()) + return; + + auto message_ = messages_.front(); + + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(bgColor_); + p.setBrush(brush); + p.setOpacity(bgOpacity_); + + QRect r(0, 0, boxWidth_, boxHeight_); + + p.setPen(Qt::white); + QRect br = p.boundingRect(r, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_); + + p.setPen(Qt::NoPen); + r = br.united(r).adjusted(-boxPadding_, -boxPadding_, boxPadding_, boxPadding_); + + const qreal s = 1 - offset_; + + if (position_ == SnackBarPosition::Bottom) + p.translate((width() - (r.width() - 2 * boxPadding_)) / 2, + height() - boxPadding_ - s * (r.height())); + else + p.translate((width() - (r.width() - 2 * boxPadding_)) / 2, + s * (r.height()) - 2 * boxPadding_); + + br.moveCenter(r.center()); + p.drawRoundedRect(r.adjusted(0, 0, 0, 3), 3, 3); + p.setPen(textColor_); + p.drawText(br, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message_); +}