Add snackbar

This commit is contained in:
Konstantinos Sideris 2017-10-08 16:49:56 +03:00
parent ebe36b5713
commit ac525970b0
3 changed files with 237 additions and 18 deletions

View File

@ -171,6 +171,7 @@ set(SRC_FILES
src/ui/FlatButton.cc
src/ui/OverlayModal.cc
src/ui/ScrollBar.cc
src/ui/SnackBar.cc
src/ui/RaisedButton.cc
src/ui/Ripple.cc
src/ui/RippleOverlay.cc
@ -249,6 +250,7 @@ qt5_wrap_cpp(MOC_HEADERS
include/ui/FlatButton.h
include/ui/OverlayWidget.h
include/ui/ScrollBar.h
include/ui/SnackBar.h
include/ui/RaisedButton.h
include/ui/Ripple.h
include/ui/RippleOverlay.h
@ -292,9 +294,6 @@ if (APPLE)
endif()
if (BUILD_TESTS)
#
# Build tests.
#
enable_testing()
find_package(GTest REQUIRED)
@ -312,26 +311,23 @@ if (BUILD_TESTS)
add_test(MatrixEvents events_test)
add_test(MatrixEventCollection event_collection_test)
add_test(MatrixMessageEvents message_events)
else()
#
# Build the executable.
#
endif()
if(APPVEYOR_BUILD)
set (NHEKO_LIBS matrix_events Qt5::Widgets Qt5::Network lmdb)
else()
set (NHEKO_LIBS matrix_events Qt5::Widgets Qt5::Network ${LMDB_LIBRARY})
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)
add_executable (nheko ${NHEKO_DEPS})
target_link_libraries (nheko ${NHEKO_LIBS} Qt5::MacExtras)
elseif(WIN32)
add_executable (nheko ${ICON_FILE} ${NHEKO_DEPS})
target_link_libraries (nheko ${NTDLIB} ${NHEKO_LIBS} Qt5::WinMain)
else()
add_executable (nheko ${NHEKO_DEPS})
target_link_libraries (nheko ${NHEKO_LIBS})
endif()
if(APPLE)
add_executable (nheko ${NHEKO_DEPS})
target_link_libraries (nheko ${NHEKO_LIBS} Qt5::MacExtras)
elseif(WIN32)
add_executable (nheko ${ICON_FILE} ${NHEKO_DEPS})
target_link_libraries (nheko ${NTDLIB} ${NHEKO_LIBS} Qt5::WinMain)
else()
add_executable (nheko ${NHEKO_DEPS})
target_link_libraries (nheko ${NHEKO_LIBS})
endif()

80
include/ui/SnackBar.h Normal file
View 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
View 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_);
}