Skip to content

Commit

Permalink
Add overlayMode property to QtMaterialDrawer
Browse files Browse the repository at this point in the history
  • Loading branch information
laserpants committed Oct 7, 2017
1 parent fc1fb1e commit 3a7d7a1
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 61 deletions.
80 changes: 48 additions & 32 deletions components/qtmaterialdrawer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "qtmaterialdrawer_p.h"
#include <QPainter>
#include <QEvent>
#include <QDebug>
#include <QMouseEvent>
#include <QtWidgets/QApplication>
#include <QtWidgets/QLayout>
Expand Down Expand Up @@ -36,17 +37,25 @@ void QtMaterialDrawerPrivate::init()
{
Q_Q(QtMaterialDrawer);

stateMachine = new QtMaterialDrawerStateMachine(q);
widget = new QtMaterialDrawerWidget;
stateMachine = new QtMaterialDrawerStateMachine(widget, q);
window = new QWidget;
width = 250;
clickToClose = false;
autoRaise = true;
closed = true;
overlay = false;

QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(window);

q->setLayout(layout);
q->setFixedWidth(width+16);
widget->setLayout(layout);
widget->setFixedWidth(width+16);

widget->setParent(q);

q->setAttribute(Qt::WA_TransparentForMouseEvents);
q->setAttribute(Qt::WA_NoSystemBackground);

stateMachine->start();
QCoreApplication::processEvents();
Expand All @@ -73,7 +82,7 @@ void QtMaterialDrawer::setDrawerWidth(int width)

d->width = width;
d->stateMachine->updatePropertyAssignments();
setFixedWidth(width+16);
d->widget->setFixedWidth(width+16);
}

int QtMaterialDrawer::drawerWidth() const
Expand Down Expand Up @@ -125,22 +134,43 @@ bool QtMaterialDrawer::autoRaise() const
return d->autoRaise;
}

void QtMaterialDrawer::setOverlayMode(bool value)
{
Q_D(QtMaterialDrawer);

d->overlay = value;
}

bool QtMaterialDrawer::overlayMode() const
{
Q_D(const QtMaterialDrawer);

return d->overlay;
}

void QtMaterialDrawer::openDrawer()
{
Q_D(QtMaterialDrawer);

emit d->stateMachine->enterOpenedState();
emit d->stateMachine->signalOpen();

if (d->autoRaise) {
raise();
}
if (d->overlay) {
setAttribute(Qt::WA_TransparentForMouseEvents, false);
setAttribute(Qt::WA_NoSystemBackground, false);
}
}

void QtMaterialDrawer::closeDrawer()
{
Q_D(QtMaterialDrawer);

emit d->stateMachine->enterClosedState();
emit d->stateMachine->signalClose();

setAttribute(Qt::WA_TransparentForMouseEvents);
setAttribute(Qt::WA_NoSystemBackground);
}

bool QtMaterialDrawer::eventFilter(QObject *obj, QEvent *event)
Expand All @@ -152,17 +182,18 @@ bool QtMaterialDrawer::eventFilter(QObject *obj, QEvent *event)
case QEvent::MouseButtonPress: {
QMouseEvent *mouseEvent;
if ((mouseEvent = static_cast<QMouseEvent *>(event))) {
if (!geometry().contains(mouseEvent->pos()) && d->clickToClose) {
const bool canClose = d->clickToClose || d->overlay;
if (!d->widget->geometry().contains(mouseEvent->pos()) && canClose) {
closeDrawer();
}
}
break;
}
case QEvent::Move:
case QEvent::Resize: {
QLayout *lyut = layout();
if (lyut && 16 != lyut->contentsMargins().right()) {
lyut->setContentsMargins(0, 0, 16, 0);
QLayout *lout = d->widget->layout();
if (lout && 16 != lout->contentsMargins().right()) {
lout->setContentsMargins(0, 0, 16, 0);
}
}
default:
Expand All @@ -175,28 +206,13 @@ void QtMaterialDrawer::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)

QPainter painter(this);

QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
painter.setBrush(brush);
painter.setPen(Qt::NoPen);

painter.drawRect(rect().adjusted(0, 0, -16, 0));

QLinearGradient gradient(QPointF(width()-16, 0), QPointF(width(), 0));
gradient.setColorAt(0, QColor(0, 0, 0, 80));
gradient.setColorAt(0.5, QColor(0, 0, 0, 20));
gradient.setColorAt(1, QColor(0, 0, 0, 0));
painter.setBrush(QBrush(gradient));

painter.drawRect(width()-16, 0, 16, height());
}
Q_D(QtMaterialDrawer);

QRect QtMaterialDrawer::overlayGeometry() const
{
Q_D(const QtMaterialDrawer);
if (!d->overlay || d->stateMachine->isInClosedState()) {
return;
}

return QtMaterialOverlayWidget::overlayGeometry().translated(d->stateMachine->offset(), 0);
QPainter painter(this);
painter.setOpacity(d->stateMachine->opacity());
painter.fillRect(rect(), Qt::SolidPattern);
}
5 changes: 3 additions & 2 deletions components/qtmaterialdrawer.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ class QtMaterialDrawer : public QtMaterialOverlayWidget
void setAutoRaise(bool state);
bool autoRaise() const;

void setOverlayMode(bool value);
bool overlayMode() const;

public slots:
void openDrawer();
void closeDrawer();
Expand All @@ -34,8 +37,6 @@ public slots:
bool eventFilter(QObject *obj, QEvent *event) Q_DECL_OVERRIDE;
void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;

QRect overlayGeometry() const Q_DECL_OVERRIDE;

const QScopedPointer<QtMaterialDrawerPrivate> d_ptr;

private:
Expand Down
142 changes: 125 additions & 17 deletions components/qtmaterialdrawer_internal.cpp
Original file line number Diff line number Diff line change
@@ -1,61 +1,169 @@
#include "qtmaterialdrawer_internal.h"
#include <QState>
#include <QPainter>
#include <QtWidgets/QLayout>
#include <QSignalTransition>
#include <QPropertyAnimation>
#include "qtmaterialdrawer.h"

QtMaterialDrawerStateMachine::QtMaterialDrawerStateMachine(QtMaterialDrawer *drawer)
: QStateMachine(drawer),
/*!
* \class QtMaterialDrawerStateMachine
* \internal
*/

QtMaterialDrawerStateMachine::QtMaterialDrawerStateMachine(QtMaterialDrawerWidget *drawer, QtMaterialDrawer *parent)
: QStateMachine(parent),
m_drawer(drawer),
m_openState(new QState),
m_main(parent),
m_openingState(new QState),
m_openedState(new QState),
m_closingState(new QState),
m_closedState(new QState),
m_offset(0)
m_opacity(0)
{
addState(m_openState);
addState(m_openingState);
addState(m_openedState);
addState(m_closingState);
addState(m_closedState);

setInitialState(m_closedState);

QSignalTransition *transition;
QPropertyAnimation *animation;

transition = new QSignalTransition(this, SIGNAL(enterOpenedState()));
transition->setTargetState(m_openState);
transition = new QSignalTransition(this, SIGNAL(signalOpen()));
transition->setTargetState(m_openingState);
m_closedState->addTransition(transition);

animation = new QPropertyAnimation(this, "offset", this);
animation = new QPropertyAnimation(drawer, "offset", this);
animation->setDuration(220);
animation->setEasingCurve(QEasingCurve::OutCirc);
transition->addAnimation(animation);

transition = new QSignalTransition(this, SIGNAL(enterClosedState()));
animation = new QPropertyAnimation(this, "opacity", this);
animation->setDuration(220);
transition->addAnimation(animation);

transition = new QSignalTransition(animation, SIGNAL(finished()));
transition->setTargetState(m_openedState);
m_openingState->addTransition(transition);

transition = new QSignalTransition(this, SIGNAL(signalClose()));
transition->setTargetState(m_closingState);
m_openingState->addTransition(transition);

animation = new QPropertyAnimation(this, "opacity", this);
animation->setDuration(220);
transition->addAnimation(animation);

animation = new QPropertyAnimation(drawer, "offset", this);
animation->setDuration(220);
animation->setEasingCurve(QEasingCurve::InCirc);
transition->addAnimation(animation);

transition = new QSignalTransition(animation, SIGNAL(finished()));
transition->setTargetState(m_closedState);
m_openState->addTransition(transition);
m_closingState->addTransition(transition);

transition = new QSignalTransition(this, SIGNAL(signalClose()));
transition->setTargetState(m_closingState);
m_openedState->addTransition(transition);

animation = new QPropertyAnimation(this, "offset", this);
animation = new QPropertyAnimation(drawer, "offset", this);
animation->setDuration(220);
animation->setEasingCurve(QEasingCurve::InCirc);
transition->addAnimation(animation);

animation = new QPropertyAnimation(this, "opacity", this);
animation->setDuration(220);
transition->addAnimation(animation);

transition = new QSignalTransition(animation, SIGNAL(finished()));
transition->setTargetState(m_closedState);
m_closingState->addTransition(transition);

updatePropertyAssignments();
}

QtMaterialDrawerStateMachine::~QtMaterialDrawerStateMachine()
{
}

void QtMaterialDrawerStateMachine::setOffset(int offset)
void QtMaterialDrawerStateMachine::setOpacity(qreal opacity)
{
m_opacity = opacity;
m_main->update();
}

bool QtMaterialDrawerStateMachine::isInClosedState() const
{
return m_closedState->active();
}

void QtMaterialDrawerStateMachine::updatePropertyAssignments()
{
const qreal closedOffset = -(m_drawer->width()+32);

m_closingState->assignProperty(m_drawer, "offset", closedOffset);
m_closedState->assignProperty(m_drawer, "offset", closedOffset);

m_closingState->assignProperty(this, "opacity", 0);
m_closedState->assignProperty(this, "opacity", 0);

m_openingState->assignProperty(m_drawer, "offset", 0);
m_openingState->assignProperty(this, "opacity", 0.4);
}

/*!
* \class QtMaterialDrawerWidget
* \internal
*/

QtMaterialDrawerWidget::QtMaterialDrawerWidget(QWidget *parent)
: QtMaterialOverlayWidget(parent),
m_offset(0)
{
}

QtMaterialDrawerWidget::~QtMaterialDrawerWidget()
{
}

void QtMaterialDrawerWidget::setOffset(int offset)
{
m_offset = offset;

QWidget *widget = m_drawer->parentWidget();
QWidget *widget = parentWidget();
if (widget) {
m_drawer->setGeometry(widget->rect().translated(offset, 0));
setGeometry(widget->rect().translated(offset, 0));
}
update();
}

void QtMaterialDrawerStateMachine::updatePropertyAssignments()
void QtMaterialDrawerWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)

QPainter painter(this);

QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::white);
painter.setBrush(brush);
painter.setPen(Qt::NoPen);

painter.drawRect(rect().adjusted(0, 0, -16, 0));

QLinearGradient gradient(QPointF(width()-16, 0), QPointF(width(), 0));
gradient.setColorAt(0, QColor(0, 0, 0, 80));
gradient.setColorAt(0.5, QColor(0, 0, 0, 20));
gradient.setColorAt(1, QColor(0, 0, 0, 0));
painter.setBrush(QBrush(gradient));

painter.drawRect(width()-16, 0, 16, height());
}

QRect QtMaterialDrawerWidget::overlayGeometry() const
{
m_closedState->assignProperty(this, "offset", -(m_drawer->width()+32));
m_openState->assignProperty(this, "offset", 0);
return QtMaterialOverlayWidget::overlayGeometry().translated(m_offset, 0);
}
Loading

0 comments on commit 3a7d7a1

Please sign in to comment.