diff --git a/mainwindow.cpp b/mainwindow.cpp index e5a74c0..bbce67b 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -245,6 +245,12 @@ MainWindow::MainWindow(QWidget *parent) connect(btn, SIGNAL(pressed()), this, SLOT(hello())); + btn = new QPushButton; + btn->setText("Show instant Snackbar"); + layout->addWidget(btn); + + connect(btn, SIGNAL(pressed()), this, SLOT(hello2())); + { im->addMenuItem("C"); @@ -1063,5 +1069,18 @@ void MainWindow::hello() static int n = 0; ++n; //snackbar->addMessage(QString("Hello from the Snackbar (%1)").arg(n)); - snackbar2->addMessage(QString("Hello from the Snackbar (%1)").arg(n)); + //snackbar2->addMessage(QString("Hello from the Snackbar (%1)").arg(n)); + //snackbar2->setBoxWidth(80); + + snackbar2->addMessage(QString( + "License shall mean the terms and conditions for use, reproduction," + "and distribution as defined by Sections 1 through 9 of this document." + )); +} + +void MainWindow::hello2() +{ + snackbar2->addInstantMessage(QString( + "and distribution as defined by Sections 1 through 9 of this document." + )); } diff --git a/mainwindow.h b/mainwindow.h index b2990f3..bcbb6df 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -28,6 +28,7 @@ protected slots: void button3Pressed(); void button4Pressed(); void hello(); + void hello2(); private: void _initMenu() const; diff --git a/qt-material-widgets.pro b/qt-material-widgets.pro index b85e40f..15588d7 100644 --- a/qt-material-widgets.pro +++ b/qt-material-widgets.pro @@ -135,7 +135,8 @@ SOURCES += main.cpp\ xx/qtmaterialtoggle_internal.cpp \ yy/togglesettingseditor.cpp \ xx/qtmaterialsnackbar.cpp \ - xx/qtmaterialsnackbar_internal.cpp + xx/qtmaterialsnackbar_internal.cpp \ + xxlib/qtmaterialstatetransition.cpp HEADERS += mainwindow.h \ components/appbar.h \ @@ -308,7 +309,9 @@ HEADERS += mainwindow.h \ yy/togglesettingseditor.h \ xx/qtmaterialsnackbar.h \ xx/qtmaterialsnackbar_p.h \ - xx/qtmaterialsnackbar_internal.h + xx/qtmaterialsnackbar_internal.h \ + xxlib/qtmaterialstatetransitionevent.h \ + xxlib/qtmaterialstatetransition.h RESOURCES += \ resources.qrc diff --git a/xx/qtmaterialcollapsiblemenu.cpp b/xx/qtmaterialcollapsiblemenu.cpp index 198bd73..eeef39e 100644 --- a/xx/qtmaterialcollapsiblemenu.cpp +++ b/xx/qtmaterialcollapsiblemenu.cpp @@ -7,6 +7,7 @@ #include "xx/qtmaterialmenuitem.h" #include "xx/qtmaterialscrollbar.h" #include "xxlib/qtmaterialstyle.h" +#include "xxlib/qtmaterialstatetransitionevent.h" /*! * \class QtMaterialCollapsibleMenuPrivate @@ -197,7 +198,7 @@ void QtMaterialCollapsibleMenu::collapse() Q_D(QtMaterialCollapsibleMenu); d->proxyStack->setCurrentIndex(1); - emit d->proxy->collapse(); + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(CollapsibleMenuCollapse)); emit aboutToCollapse(); } @@ -206,7 +207,7 @@ void QtMaterialCollapsibleMenu::expand() Q_D(QtMaterialCollapsibleMenu); d->proxyStack->setCurrentIndex(1); - emit d->proxy->expand(); + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(CollapsibleMenuExpand)); emit aboutToExpand(); } diff --git a/xx/qtmaterialcollapsiblemenu_internal.cpp b/xx/qtmaterialcollapsiblemenu_internal.cpp index 91a2c5e..49dc5ff 100644 --- a/xx/qtmaterialcollapsiblemenu_internal.cpp +++ b/xx/qtmaterialcollapsiblemenu_internal.cpp @@ -1,9 +1,9 @@ #include "xx/qtmaterialcollapsiblemenu_internal.h" -#include #include #include #include #include "xx/qtmaterialcollapsiblemenu.h" +#include "xxlib/qtmaterialstatetransition.h" /*! * \class QtMaterialCollapsibleMenuStateMachine @@ -29,9 +29,9 @@ QtMaterialCollapsibleMenuStateMachine::QtMaterialCollapsibleMenuStateMachine( addState(m_collapsedState); setInitialState(m_collapsedState); - QSignalTransition *transition; + QtMaterialStateTransition *transition; - transition = new QSignalTransition(m_proxy, SIGNAL(expand())); + transition = new QtMaterialStateTransition(CollapsibleMenuExpand); transition->setTargetState(m_expandedState); m_collapsedState->addTransition(transition); @@ -47,7 +47,7 @@ QtMaterialCollapsibleMenuStateMachine::QtMaterialCollapsibleMenuStateMachine( m_expandYAnimation->setEasingCurve(QEasingCurve::OutElastic); transition->addAnimation(m_expandYAnimation); - transition = new QSignalTransition(m_proxy, SIGNAL(collapse())); + transition = new QtMaterialStateTransition(CollapsibleMenuCollapse); transition->setTargetState(m_collapsedState); m_expandedState->addTransition(transition); diff --git a/xx/qtmaterialcollapsiblemenu_internal.h b/xx/qtmaterialcollapsiblemenu_internal.h index 67ac624..0ee6876 100644 --- a/xx/qtmaterialcollapsiblemenu_internal.h +++ b/xx/qtmaterialcollapsiblemenu_internal.h @@ -94,9 +94,9 @@ public: inline void setOpacity(qreal opacity); inline qreal opacity() const; -signals: - void expand(); - void collapse(); +//signals: +// void expand(); +// void collapse(); protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; diff --git a/xx/qtmaterialflatbutton.cpp b/xx/qtmaterialflatbutton.cpp index 10e9a02..666a4e7 100644 --- a/xx/qtmaterialflatbutton.cpp +++ b/xx/qtmaterialflatbutton.cpp @@ -405,7 +405,6 @@ void QtMaterialFlatButton::setCheckable(bool value) Q_D(QtMaterialFlatButton); d->stateMachine->updateCheckedStatus(); - d->stateMachine->setCheckedOverlayProgress(0); QPushButton::setCheckable(value); } diff --git a/xx/qtmaterialflatbutton_internal.cpp b/xx/qtmaterialflatbutton_internal.cpp index fb03ec4..5b8ce5e 100644 --- a/xx/qtmaterialflatbutton_internal.cpp +++ b/xx/qtmaterialflatbutton_internal.cpp @@ -1,10 +1,10 @@ #include "xx/qtmaterialflatbutton_internal.h" #include -#include #include #include #include #include "xx/qtmaterialflatbutton.h" +#include "xxlib/qtmaterialstatetransition.h" /*! * \class QtMaterialFlatButtonStateMachine @@ -42,10 +42,10 @@ QtMaterialFlatButtonStateMachine::QtMaterialFlatButtonStateMachine(QtMaterialFla m_checkableState->setInitialState(parent->isChecked() ? m_checkedState : m_uncheckedState); - QSignalTransition *transition; + QtMaterialStateTransition *transition; QPropertyAnimation *animation; - transition = new QSignalTransition(this, SIGNAL(buttonChecked())); + transition = new QtMaterialStateTransition(FlatButtonCheckedTransition); transition->setTargetState(m_checkedState); m_uncheckedState->addTransition(transition); @@ -53,7 +53,7 @@ QtMaterialFlatButtonStateMachine::QtMaterialFlatButtonStateMachine(QtMaterialFla animation->setDuration(200); transition->addAnimation(animation); - transition = new QSignalTransition(this, SIGNAL(buttonUnchecked())); + transition = new QtMaterialStateTransition(FlatButtonUncheckedTransition); transition->setTargetState(m_uncheckedState); m_checkedState->addTransition(transition); @@ -69,7 +69,11 @@ QtMaterialFlatButtonStateMachine::QtMaterialFlatButtonStateMachine(QtMaterialFla addTransition(m_button, QEvent::Leave, m_hoveredFocusedState, m_neutralFocusedState); addTransition(m_button, QEvent::FocusIn, m_hoveredState, m_hoveredFocusedState); addTransition(m_button, QEvent::FocusOut, m_hoveredFocusedState, m_hoveredState); - addTransition(this, SIGNAL(buttonPressed()), m_hoveredState, m_pressedState); + + transition = new QtMaterialStateTransition(FlatButtonPressedTransition); + transition->setTargetState(m_pressedState); + m_hoveredState->addTransition(transition); + addTransition(m_button, QEvent::Leave, m_pressedState, m_neutralFocusedState); addTransition(m_button, QEvent::FocusOut, m_pressedState, m_hoveredState); @@ -111,9 +115,9 @@ void QtMaterialFlatButtonStateMachine::setOverlayOpacity(qreal opacity) m_button->update(); } -void QtMaterialFlatButtonStateMachine::setCheckedOverlayProgress(qreal opacity) +void QtMaterialFlatButtonStateMachine::setCheckedOverlayProgress(qreal progress) { - m_checkedOverlayProgress = opacity; + m_checkedOverlayProgress = progress; m_button->update(); } @@ -175,9 +179,9 @@ void QtMaterialFlatButtonStateMachine::updateCheckedStatus() if (m_wasChecked != checked) { m_wasChecked = checked; if (checked) { - emit buttonChecked(); + postEvent(new QtMaterialStateTransitionEvent(FlatButtonCheckedTransition)); } else { - emit buttonUnchecked(); + postEvent(new QtMaterialStateTransitionEvent(FlatButtonUncheckedTransition)); } } } @@ -188,21 +192,13 @@ bool QtMaterialFlatButtonStateMachine::eventFilter(QObject *watched, if (QEvent::FocusIn == event->type()) { QFocusEvent *focusEvent = static_cast(event); if (focusEvent && Qt::MouseFocusReason == focusEvent->reason()) { - emit buttonPressed(); + postEvent(new QtMaterialStateTransitionEvent(FlatButtonPressedTransition)); return true; } } return QStateMachine::eventFilter(watched, event); } -void QtMaterialFlatButtonStateMachine::addTransition(QObject *object, - const char *signal, - QState *fromState, - QState *toState) -{ - addTransition(new QSignalTransition(object, signal), fromState, toState); -} - void QtMaterialFlatButtonStateMachine::addTransition(QObject *object, QEvent::Type eventType, QState *fromState, diff --git a/xx/qtmaterialflatbutton_internal.h b/xx/qtmaterialflatbutton_internal.h index 82449cd..ff93972 100644 --- a/xx/qtmaterialflatbutton_internal.h +++ b/xx/qtmaterialflatbutton_internal.h @@ -24,7 +24,7 @@ public: void setOverlayOpacity(qreal opacity); inline qreal overlayOpacity() const; - void setCheckedOverlayProgress(qreal opacity); + void setCheckedOverlayProgress(qreal progress); inline qreal checkedOverlayProgress() const; void setHaloOpacity(qreal opacity); @@ -51,7 +51,6 @@ protected: private: Q_DISABLE_COPY(QtMaterialFlatButtonStateMachine) - void addTransition(QObject *object, const char *signal, QState *fromState, QState *toState); void addTransition(QObject *object, QEvent::Type eventType, QState *fromState, QState *toState); void addTransition(QAbstractTransition *transition, QState *fromState, QState *toState); diff --git a/xx/qtmaterialslider.cpp b/xx/qtmaterialslider.cpp index b249675..660ad18 100644 --- a/xx/qtmaterialslider.cpp +++ b/xx/qtmaterialslider.cpp @@ -4,6 +4,7 @@ #include #include "xx/qtmaterialslider_internal.h" #include "xxlib/qtmaterialstyle.h" +#include "xxlib/qtmaterialstatetransitionevent.h" /*! * \class QtMaterialSliderPrivate @@ -108,9 +109,9 @@ void QtMaterialSliderPrivate::setHovered(bool status) if (!q->hasFocus()) { if (status) { - emit stateMachine->noFocusMouseEnter(); + stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderNoFocusMouseEnter)); } else { - emit stateMachine->noFocusMouseLeave(); + stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderNoFocusMouseLeave)); } } @@ -254,12 +255,12 @@ void QtMaterialSlider::sliderChange(SliderChange change) { if (minimum() == value()) { triggerAction(SliderToMinimum); - emit d->stateMachine->changedToMinimum(); + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderChangedToMinimum)); } else if (maximum() == value()) { triggerAction(SliderToMaximum); } if (minimum() == d->oldValue) { - emit d->stateMachine->changedFromMinimum(); + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SliderChangedFromMinimum)); } d->oldValue = value(); } diff --git a/xx/qtmaterialslider_internal.cpp b/xx/qtmaterialslider_internal.cpp index 6b0437e..b932491 100644 --- a/xx/qtmaterialslider_internal.cpp +++ b/xx/qtmaterialslider_internal.cpp @@ -7,6 +7,7 @@ #include #include "xx/qtmaterialslider.h" #include "xxlib/qtmaterialstyle.h" +#include "xxlib/qtmaterialstatetransition.h" /*! * \class QtMaterialSliderStateMachine @@ -49,18 +50,19 @@ QtMaterialSliderStateMachine::QtMaterialSliderStateMachine( m_slidingState->assignProperty(thumb, "diameter", 17); QAbstractTransition *transition; + QtMaterialStateTransition *customTransition; QPropertyAnimation *animation; // Show halo on mouse enter - transition = new QSignalTransition(this, SIGNAL(noFocusMouseEnter())); - transition->setTargetState(m_focusState); + customTransition = new QtMaterialStateTransition(SliderNoFocusMouseEnter); + customTransition->setTargetState(m_focusState); animation = new QPropertyAnimation(thumb, "haloSize", this); animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - transition->addAnimation(new QPropertyAnimation(track, "fillColor", this)); - m_inactiveState->addTransition(transition); + customTransition->addAnimation(animation); + customTransition->addAnimation(new QPropertyAnimation(track, "fillColor", this)); + m_inactiveState->addTransition(customTransition); // Show halo on focus in @@ -86,14 +88,14 @@ QtMaterialSliderStateMachine::QtMaterialSliderStateMachine( // Hide halo on mouse leave, except if widget has focus - transition = new QSignalTransition(this, SIGNAL(noFocusMouseLeave())); - transition->setTargetState(m_inactiveState); + customTransition = new QtMaterialStateTransition(SliderNoFocusMouseLeave); + customTransition->setTargetState(m_inactiveState); animation = new QPropertyAnimation(thumb, "haloSize", this); animation->setEasingCurve(QEasingCurve::InOutSine); - transition->addAnimation(animation); - transition->addAnimation(new QPropertyAnimation(track, "fillColor", this)); - m_focusState->addTransition(transition); + customTransition->addAnimation(animation); + customTransition->addAnimation(new QPropertyAnimation(track, "fillColor", this)); + m_focusState->addTransition(customTransition); // Pulse in @@ -150,47 +152,47 @@ QtMaterialSliderStateMachine::QtMaterialSliderStateMachine( m_sndState->setInitialState(m_minState); - transition = new QSignalTransition(this, SIGNAL(changedFromMinimum())); - transition->setTargetState(m_normalState); + customTransition = new QtMaterialStateTransition(SliderChangedFromMinimum); + customTransition->setTargetState(m_normalState); animation = new QPropertyAnimation(thumb, "fillColor", this); animation->setDuration(200); - transition->addAnimation(animation); + customTransition->addAnimation(animation); animation = new QPropertyAnimation(thumb, "haloColor", this); animation->setDuration(300); - transition->addAnimation(animation); + customTransition->addAnimation(animation); animation = new QPropertyAnimation(thumb, "borderColor", this); animation->setDuration(200); - transition->addAnimation(animation); + customTransition->addAnimation(animation); animation = new QPropertyAnimation(thumb, "borderWidth", this); animation->setDuration(200); - transition->addAnimation(animation); + customTransition->addAnimation(animation); - m_minState->addTransition(transition); + m_minState->addTransition(customTransition); - transition = new QSignalTransition(this, SIGNAL(changedToMinimum())); - transition->setTargetState(m_minState); + customTransition = new QtMaterialStateTransition(SliderChangedToMinimum); + customTransition->setTargetState(m_minState); animation = new QPropertyAnimation(thumb, "fillColor", this); animation->setDuration(200); - transition->addAnimation(animation); + customTransition->addAnimation(animation); animation = new QPropertyAnimation(thumb, "haloColor", this); animation->setDuration(300); - transition->addAnimation(animation); + customTransition->addAnimation(animation); animation = new QPropertyAnimation(thumb, "borderColor", this); animation->setDuration(200); - transition->addAnimation(animation); + customTransition->addAnimation(animation); animation = new QPropertyAnimation(thumb, "borderWidth", this); animation->setDuration(200); - transition->addAnimation(animation); + customTransition->addAnimation(animation); - m_normalState->addTransition(transition); + m_normalState->addTransition(customTransition); setupProperties(); } diff --git a/xx/qtmaterialslider_internal.h b/xx/qtmaterialslider_internal.h index 4c6272c..930f601 100644 --- a/xx/qtmaterialslider_internal.h +++ b/xx/qtmaterialslider_internal.h @@ -20,11 +20,11 @@ public: void setupProperties(); -signals: - void changedToMinimum(); - void changedFromMinimum(); - void noFocusMouseEnter(); - void noFocusMouseLeave(); +//signals: +// void changedToMinimum(); +// void changedFromMinimum(); +// void noFocusMouseEnter(); +// void noFocusMouseLeave(); private: Q_DISABLE_COPY(QtMaterialSliderStateMachine) diff --git a/xx/qtmaterialsnackbar.cpp b/xx/qtmaterialsnackbar.cpp index 1cfc08e..a45902c 100644 --- a/xx/qtmaterialsnackbar.cpp +++ b/xx/qtmaterialsnackbar.cpp @@ -2,8 +2,11 @@ #include "xx/qtmaterialsnackbar_p.h" #include #include +#include #include "xx/qtmaterialsnackbar_internal.h" #include "xxlib/qtmaterialstyle.h" +#include "xxlib/qtmaterialstatetransition.h" +#include /*! * \class QtMaterialSnackbarPrivate @@ -24,12 +27,19 @@ void QtMaterialSnackbarPrivate::init() Q_Q(QtMaterialSnackbar); stateMachine = new QtMaterialSnackbarStateMachine(q); + bgOpacity = 0.9; duration = 3000; boxWidth = 300; + clickDismiss = false; useThemeColors = true; q->setAttribute(Qt::WA_TransparentForMouseEvents); + QFontDatabase db; + QFont font(db.font("Roboto", "Medium", 10)); + font.setCapitalization(QFont::AllUppercase); + q->setFont(font); + stateMachine->start(); QCoreApplication::processEvents(); } @@ -101,6 +111,21 @@ QColor QtMaterialSnackbar::backgroundColor() const } } +void QtMaterialSnackbar::setBackgroundOpacity(qreal opacity) +{ + Q_D(QtMaterialSnackbar); + + d->bgOpacity = opacity; + update(); +} + +qreal QtMaterialSnackbar::backgroundOpacity() const +{ + Q_D(const QtMaterialSnackbar); + + return d->bgOpacity; +} + void QtMaterialSnackbar::setTextColor(const QColor &color) { Q_D(QtMaterialSnackbar); @@ -149,22 +174,94 @@ int QtMaterialSnackbar::boxWidth() const return d->boxWidth; } +void QtMaterialSnackbar::setClickToDismissMode(bool value) +{ + Q_D(QtMaterialSnackbar); + + d->clickDismiss = value; +} + +bool QtMaterialSnackbar::clickToDismissMode() const +{ + Q_D(const QtMaterialSnackbar); + + return d->clickDismiss; +} + void QtMaterialSnackbar::addMessage(const QString &message) { + Q_D(QtMaterialSnackbar); + + d->messages.push_back(message); + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SnackbarShowTransition)); } void QtMaterialSnackbar::addInstantMessage(const QString &message) { + Q_D(QtMaterialSnackbar); + + if (d->messages.isEmpty()) { + d->messages.push_back(message); + } else { + d->messages.insert(1, message); + } + + d->stateMachine->progress(); +} + +void QtMaterialSnackbar::dequeue() +{ + Q_D(QtMaterialSnackbar); + + if (d->messages.isEmpty()) { + return; + } + + d->messages.removeFirst(); + + if (!d->messages.isEmpty()) { + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SnackbarNextTransition)); + } else { + d->stateMachine->postEvent(new QtMaterialStateTransitionEvent(SnackbarWaitTransition)); + } } void QtMaterialSnackbar::paintEvent(QPaintEvent *event) { Q_UNUSED(event) - QPainter painter(this); + Q_D(QtMaterialSnackbar); - QPen p; - p.setWidth(3); - p.setColor(Qt::red); - painter.setPen(p); + if (d->messages.isEmpty()) { + return; + } + + QString message = d->messages.first(); + + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + QBrush brush; + brush.setStyle(Qt::SolidPattern); + brush.setColor(backgroundColor()); + painter.setBrush(brush); + painter.setOpacity(d->bgOpacity); + + QRect r(0, 0, d->boxWidth, 40); + + painter.setPen(Qt::white); + QRect br = painter.boundingRect(r, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message); + + painter.setPen(Qt::NoPen); + r = br.united(r).adjusted(-10, -10, 10, 20); + + const qreal s = 1-d->stateMachine->offset(); + + painter.translate((width()-(r.width()-20))/2, + height()+10-s*(r.height())); + + br.moveCenter(r.center()); + painter.drawRoundedRect(r.adjusted(0, 0, 0, 3), 3, 3); + painter.setPen(textColor()); + painter.drawText(br, Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, message); } diff --git a/xx/qtmaterialsnackbar.h b/xx/qtmaterialsnackbar.h index 097f02c..8631891 100644 --- a/xx/qtmaterialsnackbar.h +++ b/xx/qtmaterialsnackbar.h @@ -22,6 +22,9 @@ public: void setBackgroundColor(const QColor &color); QColor backgroundColor() const; + void setBackgroundOpacity(qreal opacity); + qreal backgroundOpacity() const; + void setTextColor(const QColor &color); QColor textColor() const; @@ -31,10 +34,16 @@ public: void setBoxWidth(int width); int boxWidth() const; + void setClickToDismissMode(bool value); + bool clickToDismissMode() const; + public slots: void addMessage(const QString &message); void addInstantMessage(const QString &message); +protected slots: + void dequeue(); + protected: void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; diff --git a/xx/qtmaterialsnackbar_internal.cpp b/xx/qtmaterialsnackbar_internal.cpp index 14b7385..3c7ef12 100644 --- a/xx/qtmaterialsnackbar_internal.cpp +++ b/xx/qtmaterialsnackbar_internal.cpp @@ -1,5 +1,8 @@ #include "xx/qtmaterialsnackbar_internal.h" +#include #include "xx/qtmaterialsnackbar.h" +#include "xxlib/qtmaterialstatetransition.h" +#include QtMaterialSnackbarStateMachine::QtMaterialSnackbarStateMachine(QtMaterialSnackbar *parent) : QStateMachine(parent), @@ -17,19 +20,80 @@ QtMaterialSnackbarStateMachine::QtMaterialSnackbarStateMachine(QtMaterialSnackba setInitialState(hiddenState); - QSignalTransition *transition; + QtMaterialStateTransition *transition; - // + transition = new QtMaterialStateTransition(SnackbarShowTransition); + transition->setTargetState(visibleState); + hiddenState->addTransition(transition); - // + transition = new QtMaterialStateTransition(SnackbarHideTransition); + transition->setTargetState(visibleState); + hiddenState->addTransition(transition); + + transition = new QtMaterialStateTransition(SnackbarHideTransition); + transition->setTargetState(finalState); + visibleState->addTransition(transition); + + transition = new QtMaterialStateTransition(SnackbarWaitTransition); + transition->setTargetState(hiddenState); + finalState->addTransition(transition); + + transition = new QtMaterialStateTransition(SnackbarNextTransition); + transition->setTargetState(visibleState); + finalState->addTransition(transition); + + connect(visibleState, SIGNAL(propertiesAssigned()), + this, SLOT(snackbarShown())); + connect(finalState, SIGNAL(propertiesAssigned()), + m_snackbar, SLOT(dequeue())); + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(this, "offset", this); + animation->setEasingCurve(QEasingCurve::OutCubic); + animation->setDuration(400); + addDefaultAnimation(animation); + + hiddenState->assignProperty(this, "offset", 1); + visibleState->assignProperty(this, "offset", 0); + finalState->assignProperty(this, "offset", 1); + + connect(&m_timer, SIGNAL(timeout()), this, SLOT(progress())); + + m_snackbar->installEventFilter(this); } QtMaterialSnackbarStateMachine::~QtMaterialSnackbarStateMachine() { } +bool QtMaterialSnackbarStateMachine::eventFilter(QObject *watched, QEvent *event) +{ + if (QEvent::MouseButtonPress == event->type() && m_snackbar->clickToDismissMode()) { + progress(); + } + return QStateMachine::eventFilter(watched, event); +} + void QtMaterialSnackbarStateMachine::setOffset(qreal offset) { m_offset = offset; m_snackbar->update(); } + +void QtMaterialSnackbarStateMachine::progress() +{ + m_timer.stop(); + postEvent(new QtMaterialStateTransitionEvent(SnackbarHideTransition)); + if (m_snackbar->clickToDismissMode()) { + m_snackbar->setAttribute(Qt::WA_TransparentForMouseEvents, true); + } +} + +void QtMaterialSnackbarStateMachine::snackbarShown() +{ + m_timer.start(m_snackbar->autoHideDuration()); + if (m_snackbar->clickToDismissMode()) { + m_snackbar->setAttribute(Qt::WA_TransparentForMouseEvents, false); + } +} diff --git a/xx/qtmaterialsnackbar_internal.h b/xx/qtmaterialsnackbar_internal.h index d4931cf..117a8e5 100644 --- a/xx/qtmaterialsnackbar_internal.h +++ b/xx/qtmaterialsnackbar_internal.h @@ -19,6 +19,15 @@ public: void setOffset(qreal offset); inline qreal offset() const; +public slots: + void progress(); + +protected slots: + void snackbarShown(); + +protected: + bool eventFilter(QObject *watched, QEvent *event) Q_DECL_OVERRIDE; + private: Q_DISABLE_COPY(QtMaterialSnackbarStateMachine) diff --git a/xx/qtmaterialsnackbar_p.h b/xx/qtmaterialsnackbar_p.h index c5d7451..39501fd 100644 --- a/xx/qtmaterialsnackbar_p.h +++ b/xx/qtmaterialsnackbar_p.h @@ -22,9 +22,11 @@ public: QtMaterialSnackbarStateMachine *stateMachine; QColor backgroundColor; QColor textColor; + qreal bgOpacity; QList messages; int duration; int boxWidth; + bool clickDismiss; bool useThemeColors; }; diff --git a/xxlib/qtmaterialstatetransition.cpp b/xxlib/qtmaterialstatetransition.cpp new file mode 100644 index 0000000..0d525d6 --- /dev/null +++ b/xxlib/qtmaterialstatetransition.cpp @@ -0,0 +1,19 @@ +#include "xxlib/qtmaterialstatetransition.h" + +QtMaterialStateTransition::QtMaterialStateTransition(QtMaterialStateTransitionType type) + : m_type(type) +{ +} + +bool QtMaterialStateTransition::eventTest(QEvent *event) +{ + if (event->type() != QEvent::Type(QEvent::User + 1)) { + return false; + } + QtMaterialStateTransitionEvent *transition = static_cast(event); + return (m_type == transition->type); +} + +void QtMaterialStateTransition::onTransition(QEvent *) +{ +} diff --git a/xxlib/qtmaterialstatetransition.h b/xxlib/qtmaterialstatetransition.h new file mode 100644 index 0000000..4b7c447 --- /dev/null +++ b/xxlib/qtmaterialstatetransition.h @@ -0,0 +1,22 @@ +#ifndef QTMATERIALSTATETRANSITION_H +#define QTMATERIALSTATETRANSITION_H + +#include +#include "xxlib/qtmaterialstatetransitionevent.h" + +class QtMaterialStateTransition : public QAbstractTransition +{ + Q_OBJECT + +public: + QtMaterialStateTransition(QtMaterialStateTransitionType type); + +protected: + virtual bool eventTest(QEvent *event); + virtual void onTransition(QEvent *); + +private: + QtMaterialStateTransitionType m_type; +}; + +#endif // QTMATERIALSTATETRANSITION_H diff --git a/xxlib/qtmaterialstatetransitionevent.h b/xxlib/qtmaterialstatetransitionevent.h new file mode 100644 index 0000000..f985cc3 --- /dev/null +++ b/xxlib/qtmaterialstatetransitionevent.h @@ -0,0 +1,39 @@ +#ifndef QTMATERIALSTATETRANSITIONEVENT_H +#define QTMATERIALSTATETRANSITIONEVENT_H + +#include + +enum QtMaterialStateTransitionType { + // Snackbar + SnackbarShowTransition = 1, + SnackbarHideTransition, + SnackbarWaitTransition, + SnackbarNextTransition, + // FlatButton + FlatButtonPressedTransition, + FlatButtonCheckedTransition, + FlatButtonUncheckedTransition, + // CollapsibleMenu + CollapsibleMenuExpand, + CollapsibleMenuCollapse, + // Slider + SliderChangedToMinimum, + SliderChangedFromMinimum, + SliderNoFocusMouseEnter, + SliderNoFocusMouseLeave, + + MaxTransitionType = 65535 +}; + +struct QtMaterialStateTransitionEvent : public QEvent +{ + QtMaterialStateTransitionEvent(QtMaterialStateTransitionType type) + : QEvent(QEvent::Type(QEvent::User + 1)), + type(type) + { + } + + QtMaterialStateTransitionType type; +}; + +#endif // QTMATERIALSTATETRANSITIONEVENT_H