From 56cb620d6fc7c03a5ca465def34a9ff16d60eb8b Mon Sep 17 00:00:00 2001 From: johanneshilden Date: Sat, 30 Sep 2017 02:15:08 +0300 Subject: [PATCH] Add Dialog files --- components/components.pro | 9 +- components/qtmaterialdialog.cpp | 166 +++++++++++++++++++++++ components/qtmaterialdialog.h | 35 +++++ components/qtmaterialdialog_internal.cpp | 127 +++++++++++++++++ components/qtmaterialdialog_internal.h | 79 +++++++++++ components/qtmaterialdialog_p.h | 30 ++++ 6 files changed, 444 insertions(+), 2 deletions(-) create mode 100644 components/qtmaterialdialog.cpp create mode 100644 components/qtmaterialdialog.h create mode 100644 components/qtmaterialdialog_internal.cpp create mode 100644 components/qtmaterialdialog_internal.h create mode 100644 components/qtmaterialdialog_p.h diff --git a/components/components.pro b/components/components.pro index 2eb9daa..83ffe78 100644 --- a/components/components.pro +++ b/components/components.pro @@ -33,7 +33,9 @@ SOURCES = \ qtmaterialtabs_internal.cpp \ qtmaterialtabs.cpp \ qtmaterialscrollbar_internal.cpp \ - qtmaterialscrollbar.cpp + qtmaterialscrollbar.cpp \ + qtmaterialdialog_internal.cpp \ + qtmaterialdialog.cpp HEADERS = \ qtmaterialavatar_p.h \ qtmaterialavatar.h \ @@ -87,6 +89,9 @@ HEADERS = \ qtmaterialtabs.h \ qtmaterialscrollbar_internal.h \ qtmaterialscrollbar_p.h \ - qtmaterialscrollbar.h + qtmaterialscrollbar.h \ + qtmaterialdialog_internal.h \ + qtmaterialdialog_p.h \ + qtmaterialdialog.h RESOURCES += \ resources.qrc diff --git a/components/qtmaterialdialog.cpp b/components/qtmaterialdialog.cpp new file mode 100644 index 0000000..f572402 --- /dev/null +++ b/components/qtmaterialdialog.cpp @@ -0,0 +1,166 @@ +#include "xx/qtmaterialdialog.h" +#include "xx/qtmaterialdialog_p.h" +#include +#include +#include +#include +#include +#include +#include +#include "xx/qtmaterialdialog_internal.h" +#include "xxlib/qtmaterialstatetransition.h" + +/*! + * \class QtMaterialDialogPrivate + * \internal + */ + +QtMaterialDialogPrivate::QtMaterialDialogPrivate(QtMaterialDialog *q) + : q_ptr(q) +{ +} + +QtMaterialDialogPrivate::~QtMaterialDialogPrivate() +{ +} + +void QtMaterialDialogPrivate::init() +{ + Q_Q(QtMaterialDialog); + + dialogWindow = new QtMaterialDialogWindow(q); + proxyStack = new QStackedLayout; + stateMachine = new QStateMachine(q); + proxy = new QtMaterialDialogProxy(dialogWindow, proxyStack, q); + + QVBoxLayout *layout = new QVBoxLayout; + q->setLayout(layout); + + QWidget *widget = new QWidget; + widget->setLayout(proxyStack); + widget->setMinimumWidth(400); + + QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect; + effect->setColor(QColor(0, 0, 0, 200)); + effect->setBlurRadius(64); + effect->setOffset(0, 13); + widget->setGraphicsEffect(effect); + + layout->addWidget(widget); + layout->setAlignment(widget, Qt::AlignCenter); + + proxyStack->addWidget(dialogWindow); + proxyStack->addWidget(proxy); + proxyStack->setCurrentIndex(1); + + q->setAttribute(Qt::WA_TransparentForMouseEvents); + + QState *hiddenState = new QState; + QState *visibleState = new QState; + + stateMachine->addState(hiddenState); + stateMachine->addState(visibleState); + stateMachine->setInitialState(hiddenState); + + QtMaterialStateTransition *transition; + + transition = new QtMaterialStateTransition(DialogShowTransition); + transition->setTargetState(visibleState); + hiddenState->addTransition(transition); + + transition = new QtMaterialStateTransition(DialogHideTransition); + transition->setTargetState(hiddenState); + visibleState->addTransition(transition); + + visibleState->assignProperty(proxy, "opacity", 1); + visibleState->assignProperty(effect, "color", QColor(0, 0, 0, 200)); + visibleState->assignProperty(dialogWindow, "offset", 0); + hiddenState->assignProperty(proxy, "opacity", 0); + hiddenState->assignProperty(effect, "color", QColor(0, 0, 0, 0)); + hiddenState->assignProperty(dialogWindow, "offset", 200); + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(proxy, "opacity", q); + animation->setDuration(280); + stateMachine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(effect, "color", q); + animation->setDuration(280); + stateMachine->addDefaultAnimation(animation); + + animation = new QPropertyAnimation(dialogWindow, "offset", q); + animation->setDuration(280); + animation->setEasingCurve(QEasingCurve::OutCirc); + stateMachine->addDefaultAnimation(animation); + + QObject::connect(visibleState, SIGNAL(propertiesAssigned()), + proxy, SLOT(makeOpaque())); + QObject::connect(hiddenState, SIGNAL(propertiesAssigned()), + proxy, SLOT(makeTransparent())); + + stateMachine->start(); + QCoreApplication::processEvents(); +} + +/*! + * \class QtMaterialDialog + */ + +QtMaterialDialog::QtMaterialDialog(QWidget *parent) + : QtMaterialOverlayWidget(parent), + d_ptr(new QtMaterialDialogPrivate(this)) +{ + d_func()->init(); +} + +QtMaterialDialog::~QtMaterialDialog() +{ +} + +QLayout *QtMaterialDialog::windowLayout() const +{ + Q_D(const QtMaterialDialog); + + return d->dialogWindow->layout(); +} + +void QtMaterialDialog::setWindowLayout(QLayout *layout) +{ + Q_D(QtMaterialDialog); + + d->dialogWindow->setLayout(layout); +} + +void QtMaterialDialog::showDialog() +{ + Q_D(QtMaterialDialog); + + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(DialogShowTransition)); +} + +void QtMaterialDialog::hideDialog() +{ + Q_D(QtMaterialDialog); + + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(DialogHideTransition)); + setAttribute(Qt::WA_TransparentForMouseEvents); + d->proxyStack->setCurrentIndex(1); +} + +void QtMaterialDialog::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + Q_D(QtMaterialDialog); + + QPainter painter(this); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(Qt::black); + painter.setBrush(brush); + painter.setPen(Qt::NoPen); + painter.setOpacity(d->proxy->opacity()/2.4); + painter.drawRect(rect()); +} diff --git a/components/qtmaterialdialog.h b/components/qtmaterialdialog.h new file mode 100644 index 0000000..3cf8f2a --- /dev/null +++ b/components/qtmaterialdialog.h @@ -0,0 +1,35 @@ +#ifndef QTMATERIALDIALOG_H +#define QTMATERIALDIALOG_H + +#include +#include "xxlib/qtmaterialoverlaywidget.h" + +class QLayout; +class QtMaterialDialogPrivate; + +class QtMaterialDialog : public QtMaterialOverlayWidget +{ + Q_OBJECT + +public: + explicit QtMaterialDialog(QWidget *parent = 0); + ~QtMaterialDialog(); + + QLayout *windowLayout() const; + void setWindowLayout(QLayout *layout); + +protected slots: + void showDialog(); + void hideDialog(); + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + + const QScopedPointer d_ptr; + +private: + Q_DISABLE_COPY(QtMaterialDialog) + Q_DECLARE_PRIVATE(QtMaterialDialog) +}; + +#endif // QTMATERIALDIALOG_H diff --git a/components/qtmaterialdialog_internal.cpp b/components/qtmaterialdialog_internal.cpp new file mode 100644 index 0000000..ba1e40d --- /dev/null +++ b/components/qtmaterialdialog_internal.cpp @@ -0,0 +1,127 @@ +#include "xx/qtmaterialdialog_internal.h" +#include +#include +#include +#include +#include "xx/qtmaterialdialog.h" + +/*! + * \class QtMaterialDialogProxy + * \internal + */ + +QtMaterialDialogProxy::QtMaterialDialogProxy( + QtMaterialDialogWindow *source, + QStackedLayout *layout, + QtMaterialDialog *dialog, + QWidget *parent) + : QWidget(parent), + m_source(source), + m_layout(layout), + m_dialog(dialog), + m_opacity(0), + m_mode(Transparent) +{ +} + +QtMaterialDialogProxy::~QtMaterialDialogProxy() +{ +} + +void QtMaterialDialogProxy::setOpacity(qreal opacity) +{ + m_opacity = opacity; + m_mode = SemiTransparent; + update(); + m_dialog->update(); +} + + +void QtMaterialDialogProxy::makeOpaque() +{ + m_dialog->setAttribute(Qt::WA_TransparentForMouseEvents, false); + m_layout->setCurrentIndex(0); + m_opacity = 1.0; + m_mode = Opaque; + update(); +} + +void QtMaterialDialogProxy::makeTransparent() +{ + m_opacity = 0.0; + m_mode = Transparent; + update(); +} + +QSize QtMaterialDialogProxy::sizeHint() const +{ + return m_source->sizeHint(); +} + +bool QtMaterialDialogProxy::event(QEvent *event) +{ + const QEvent::Type type = event->type(); + + if (QEvent::Move == type || QEvent::Resize == type) { + m_source->setGeometry(geometry()); + } + return QWidget::event(event); +} + +void QtMaterialDialogProxy::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + + if (Transparent == m_mode) { + return; + } else if (Opaque != m_mode) { + painter.setOpacity(m_opacity); + } + QPixmap pm = m_source->grab(m_source->rect()); + painter.drawPixmap(0, 0, pm); +} + +/*! + * \class QtMaterialDialogWindow + * \internal + */ + +QtMaterialDialogWindow::QtMaterialDialogWindow( + QtMaterialDialog *dialog, + QWidget *parent) + : QWidget(parent), + m_dialog(dialog) +{ +} + +QtMaterialDialogWindow::~QtMaterialDialogWindow() +{ +} + +void QtMaterialDialogWindow::setOffset(int offset) +{ + QMargins margins = m_dialog->layout()->contentsMargins(); + margins.setBottom(offset); + m_dialog->layout()->setContentsMargins(margins); +} + +int QtMaterialDialogWindow::offset() const +{ + return m_dialog->layout()->contentsMargins().bottom(); +} + +void QtMaterialDialogWindow::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event) + + QPainter painter(this); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(Qt::white); + painter.setPen(Qt::NoPen); + painter.setBrush(brush); + painter.drawRect(rect()); +} diff --git a/components/qtmaterialdialog_internal.h b/components/qtmaterialdialog_internal.h new file mode 100644 index 0000000..903c026 --- /dev/null +++ b/components/qtmaterialdialog_internal.h @@ -0,0 +1,79 @@ +#ifndef QTMATERIALDIALOG_INTERNAL_H +#define QTMATERIALDIALOG_INTERNAL_H + +#include + +class QStackedLayout; +class QtMaterialDialog; +class QtMaterialDialogWindow; + +class QtMaterialDialogProxy : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(qreal opacity WRITE setOpacity READ opacity) + + enum TransparencyMode { + Transparent, + SemiTransparent, + Opaque, + }; + +public: + QtMaterialDialogProxy(QtMaterialDialogWindow *source, + QStackedLayout *layout, + QtMaterialDialog *dialog, + QWidget *parent = 0); + ~QtMaterialDialogProxy(); + + void setOpacity(qreal opacity); + inline qreal opacity() const; + +protected slots: + void makeOpaque(); + void makeTransparent(); + + QSize sizeHint() const Q_DECL_OVERRIDE; + +protected: + bool event(QEvent *event) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialDialogProxy) + + QtMaterialDialogWindow *const m_source; + QStackedLayout *const m_layout; + QtMaterialDialog *const m_dialog; + qreal m_opacity; + TransparencyMode m_mode; +}; + +inline qreal QtMaterialDialogProxy::opacity() const +{ + return m_opacity; +} + +class QtMaterialDialogWindow : public QWidget +{ + Q_OBJECT + + Q_PROPERTY(int offset WRITE setOffset READ offset) + +public: + explicit QtMaterialDialogWindow(QtMaterialDialog *dialog, QWidget *parent = 0); + ~QtMaterialDialogWindow(); + + void setOffset(int offset); + int offset() const; + +protected: + void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; + +private: + Q_DISABLE_COPY(QtMaterialDialogWindow) + + QtMaterialDialog *const m_dialog; +}; + +#endif // QTMATERIALDIALOG_INTERNAL_H diff --git a/components/qtmaterialdialog_p.h b/components/qtmaterialdialog_p.h new file mode 100644 index 0000000..b10088e --- /dev/null +++ b/components/qtmaterialdialog_p.h @@ -0,0 +1,30 @@ +#ifndef QTMATERIALDIALOG_P_H +#define QTMATERIALDIALOG_P_H + +#include + +class QStateMachine; +class QtMaterialDialog; +class QStackedLayout; +class QtMaterialDialogWindow; +class QtMaterialDialogProxy; + +class QtMaterialDialogPrivate +{ + Q_DISABLE_COPY(QtMaterialDialogPrivate) + Q_DECLARE_PUBLIC(QtMaterialDialog) + +public: + QtMaterialDialogPrivate(QtMaterialDialog *q); + ~QtMaterialDialogPrivate(); + + void init(); + + QtMaterialDialog *const q_ptr; + QtMaterialDialogWindow *dialogWindow; + QStackedLayout *proxyStack; + QStateMachine *stateMachine; + QtMaterialDialogProxy *proxy; +}; + +#endif // QTMATERIALDIALOG_P_H