mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 11:00:48 +03:00
Add snackbar
This commit is contained in:
parent
ebe36b5713
commit
ac525970b0
3 changed files with 237 additions and 18 deletions
|
@ -171,6 +171,7 @@ set(SRC_FILES
|
||||||
src/ui/FlatButton.cc
|
src/ui/FlatButton.cc
|
||||||
src/ui/OverlayModal.cc
|
src/ui/OverlayModal.cc
|
||||||
src/ui/ScrollBar.cc
|
src/ui/ScrollBar.cc
|
||||||
|
src/ui/SnackBar.cc
|
||||||
src/ui/RaisedButton.cc
|
src/ui/RaisedButton.cc
|
||||||
src/ui/Ripple.cc
|
src/ui/Ripple.cc
|
||||||
src/ui/RippleOverlay.cc
|
src/ui/RippleOverlay.cc
|
||||||
|
@ -249,6 +250,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
||||||
include/ui/FlatButton.h
|
include/ui/FlatButton.h
|
||||||
include/ui/OverlayWidget.h
|
include/ui/OverlayWidget.h
|
||||||
include/ui/ScrollBar.h
|
include/ui/ScrollBar.h
|
||||||
|
include/ui/SnackBar.h
|
||||||
include/ui/RaisedButton.h
|
include/ui/RaisedButton.h
|
||||||
include/ui/Ripple.h
|
include/ui/Ripple.h
|
||||||
include/ui/RippleOverlay.h
|
include/ui/RippleOverlay.h
|
||||||
|
@ -292,9 +294,6 @@ if (APPLE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (BUILD_TESTS)
|
if (BUILD_TESTS)
|
||||||
#
|
|
||||||
# Build tests.
|
|
||||||
#
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
find_package(GTest REQUIRED)
|
find_package(GTest REQUIRED)
|
||||||
|
@ -312,26 +311,23 @@ if (BUILD_TESTS)
|
||||||
add_test(MatrixEvents events_test)
|
add_test(MatrixEvents events_test)
|
||||||
add_test(MatrixEventCollection event_collection_test)
|
add_test(MatrixEventCollection event_collection_test)
|
||||||
add_test(MatrixMessageEvents message_events)
|
add_test(MatrixMessageEvents message_events)
|
||||||
else()
|
endif()
|
||||||
#
|
|
||||||
# Build the executable.
|
|
||||||
#
|
|
||||||
if(APPVEYOR_BUILD)
|
if(APPVEYOR_BUILD)
|
||||||
set (NHEKO_LIBS matrix_events Qt5::Widgets Qt5::Network lmdb)
|
set (NHEKO_LIBS matrix_events Qt5::Widgets Qt5::Network lmdb)
|
||||||
else()
|
else()
|
||||||
set (NHEKO_LIBS matrix_events Qt5::Widgets Qt5::Network ${LMDB_LIBRARY})
|
set (NHEKO_LIBS matrix_events Qt5::Widgets Qt5::Network ${LMDB_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set (NHEKO_DEPS ${OS_BUNDLE} ${SRC_FILES} ${UI_HEADERS} ${MOC_HEADERS} ${QRC} ${LANG_QRC} ${QM_SRC})
|
set (NHEKO_DEPS ${OS_BUNDLE} ${SRC_FILES} ${UI_HEADERS} ${MOC_HEADERS} ${QRC} ${LANG_QRC} ${QM_SRC})
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
add_executable (nheko ${NHEKO_DEPS})
|
add_executable (nheko ${NHEKO_DEPS})
|
||||||
target_link_libraries (nheko ${NHEKO_LIBS} Qt5::MacExtras)
|
target_link_libraries (nheko ${NHEKO_LIBS} Qt5::MacExtras)
|
||||||
elseif(WIN32)
|
elseif(WIN32)
|
||||||
add_executable (nheko ${ICON_FILE} ${NHEKO_DEPS})
|
add_executable (nheko ${ICON_FILE} ${NHEKO_DEPS})
|
||||||
target_link_libraries (nheko ${NTDLIB} ${NHEKO_LIBS} Qt5::WinMain)
|
target_link_libraries (nheko ${NTDLIB} ${NHEKO_LIBS} Qt5::WinMain)
|
||||||
else()
|
else()
|
||||||
add_executable (nheko ${NHEKO_DEPS})
|
add_executable (nheko ${NHEKO_DEPS})
|
||||||
target_link_libraries (nheko ${NHEKO_LIBS})
|
target_link_libraries (nheko ${NHEKO_LIBS})
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
80
include/ui/SnackBar.h
Normal file
80
include/ui/SnackBar.h
Normal file
|
@ -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();
|
||||||
|
}
|
143
src/ui/SnackBar.cc
Normal file
143
src/ui/SnackBar.cc
Normal file
|
@ -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 a new issue