mirror of https://github.com/Nheko-Reborn/nheko
parent
ebe36b5713
commit
ac525970b0
@ -0,0 +1,80 @@ |
|||||||
|
#pragma once |
||||||
|
|
||||||
|
#include <QCoreApplication> |
||||||
|
#include <QPaintEvent> |
||||||
|
#include <QStateMachine> |
||||||
|
#include <QTimer> |
||||||
|
|
||||||
|
#include "OverlayWidget.h" |
||||||
|
|
||||||
|
enum class SnackBarPosition { |
||||||
|
Bottom, |
||||||
|
Top, |
||||||
|
}; |
||||||
|
|
||||||
|
class SnackBar : public OverlayWidget |
||||||
|
{ |
||||||
|
Q_OBJECT |
||||||
|
|
||||||
|
public: |
||||||
|
explicit SnackBar(QWidget *parent); |
||||||
|
~SnackBar(); |
||||||
|
|
||||||
|
inline void setBackgroundColor(const QColor &color); |
||||||
|
inline void setTextColor(const QColor &color); |
||||||
|
inline void setPosition(SnackBarPosition pos); |
||||||
|
|
||||||
|
public slots: |
||||||
|
void showMessage(const QString &msg); |
||||||
|
|
||||||
|
protected: |
||||||
|
void paintEvent(QPaintEvent *event) override; |
||||||
|
void mousePressEvent(QMouseEvent *event) override; |
||||||
|
|
||||||
|
private slots: |
||||||
|
void onTimeout(); |
||||||
|
void hideMessage(); |
||||||
|
|
||||||
|
private: |
||||||
|
void stopTimers(); |
||||||
|
void start(); |
||||||
|
|
||||||
|
QColor bgColor_; |
||||||
|
QColor textColor_; |
||||||
|
|
||||||
|
qreal bgOpacity_; |
||||||
|
qreal offset_; |
||||||
|
|
||||||
|
QList<QString> messages_; |
||||||
|
|
||||||
|
QTimer *showTimer_; |
||||||
|
QTimer *hideTimer_; |
||||||
|
|
||||||
|
int duration_; |
||||||
|
int boxWidth_; |
||||||
|
int boxHeight_; |
||||||
|
int boxPadding_; |
||||||
|
|
||||||
|
SnackBarPosition position_; |
||||||
|
}; |
||||||
|
|
||||||
|
inline void |
||||||
|
SnackBar::setPosition(SnackBarPosition pos) |
||||||
|
{ |
||||||
|
position_ = pos; |
||||||
|
update(); |
||||||
|
} |
||||||
|
|
||||||
|
inline void |
||||||
|
SnackBar::setBackgroundColor(const QColor &color) |
||||||
|
{ |
||||||
|
bgColor_ = color; |
||||||
|
update(); |
||||||
|
} |
||||||
|
|
||||||
|
inline void |
||||||
|
SnackBar::setTextColor(const QColor &color) |
||||||
|
{ |
||||||
|
textColor_ = color; |
||||||
|
update(); |
||||||
|
} |
@ -0,0 +1,143 @@ |
|||||||
|
#include <QDebug> |
||||||
|
#include <QPainter> |
||||||
|
|
||||||
|
#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", 14, QFont::Medium); |
||||||
|
setFont(font); |
||||||
|
|
||||||
|
showTimer_ = new QTimer(); |
||||||
|
hideTimer_ = new QTimer(); |
||||||
|
hideTimer_->setSingleShot(true); |
||||||
|
|
||||||
|
connect(showTimer_, SIGNAL(timeout()), this, SLOT(onTimeout())); |
||||||
|
connect(hideTimer_, SIGNAL(timeout()), this, SLOT(hideMessage())); |
||||||
|
} |
||||||
|
|
||||||
|
SnackBar::~SnackBar() |
||||||
|
{ |
||||||
|
stopTimers(); |
||||||
|
|
||||||
|
delete showTimer_; |
||||||
|
delete hideTimer_; |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
SnackBar::start() |
||||||
|
{ |
||||||
|
show(); |
||||||
|
raise(); |
||||||
|
|
||||||
|
showTimer_->start(10); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
SnackBar::hideMessage() |
||||||
|
{ |
||||||
|
stopTimers(); |
||||||
|
hide(); |
||||||
|
|
||||||
|
// Moving on to the next message.
|
||||||
|
messages_.removeFirst(); |
||||||
|
|
||||||
|
// Reseting the starting position of the widget.
|
||||||
|
offset_ = STARTING_OFFSET; |
||||||
|
|
||||||
|
if (!messages_.isEmpty()) |
||||||
|
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::onTimeout() |
||||||
|
{ |
||||||
|
offset_ -= 0.5; |
||||||
|
|
||||||
|
if (offset_ <= 0.0) { |
||||||
|
showTimer_->stop(); |
||||||
|
hideTimer_->start(duration_); |
||||||
|
} |
||||||
|
|
||||||
|
update(); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
SnackBar::mousePressEvent(QMouseEvent *) |
||||||
|
{ |
||||||
|
hideMessage(); |
||||||
|
} |
||||||
|
|
||||||
|
void |
||||||
|
SnackBar::paintEvent(QPaintEvent *event) |
||||||
|
{ |
||||||
|
Q_UNUSED(event) |
||||||
|
|
||||||
|
if (messages_.isEmpty()) |
||||||
|
return; |
||||||
|
|
||||||
|
auto message_ = messages_.first(); |
||||||
|
|
||||||
|
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_); |
||||||
|
} |
Loading…
Reference in new issue