From 41c5f156a236c5f2faa8e735ca5e33d35da72f72 Mon Sep 17 00:00:00 2001 From: Johannes Hilden Date: Sun, 15 Oct 2017 14:45:11 +0300 Subject: [PATCH] Implement fade effect for Auto Complete --- components/qtmaterialautocomplete.cpp | 17 ++++--- .../qtmaterialautocomplete_internal.cpp | 51 ++++++++++++++++--- components/qtmaterialautocomplete_internal.h | 15 ++++-- components/qtmaterialautocomplete_p.h | 2 +- 4 files changed, 63 insertions(+), 22 deletions(-) diff --git a/components/qtmaterialautocomplete.cpp b/components/qtmaterialautocomplete.cpp index ad0fa16..bb99706 100644 --- a/components/qtmaterialautocomplete.cpp +++ b/components/qtmaterialautocomplete.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "qtmaterialautocomplete_internal.h" #include "qtmaterialflatbutton.h" @@ -34,8 +35,8 @@ void QtMaterialAutoCompletePrivate::init() { Q_Q(QtMaterialAutoComplete); - stateMachine = new QtMaterialAutoCompleteStateMachine(q); menu = new QWidget; + stateMachine = new QtMaterialAutoCompleteStateMachine(menu); menuLayout = new QVBoxLayout; maxWidth = 0; @@ -46,7 +47,9 @@ void QtMaterialAutoCompletePrivate::init() effect->setColor(QColor(0, 0, 0, 50)); effect->setOffset(0, 3); - menu->setGraphicsEffect(effect); + // create a box with geometry identical to menu, and then apply effect to it + //menu->setGraphicsEffect(effect); + menu->setLayout(menuLayout); menu->setVisible(false); @@ -137,9 +140,9 @@ void QtMaterialAutoComplete::updateResults(QString text) } if (!results.count()) { - d->menu->hide(); - } else if (d->menu->isHidden()) { - d->menu->show(); + emit d->stateMachine->shouldClose(); + } else { + emit d->stateMachine->shouldOpen(); } d->menu->setFixedHeight(results.length()*50); @@ -178,9 +181,7 @@ bool QtMaterialAutoComplete::eventFilter(QObject *watched, QEvent *event) switch (event->type()) { case QEvent::MouseButtonPress: { - QTimer::singleShot(300, this, [=](){ - d->menu->hide(); - }); + emit d->stateMachine->shouldFade(); QtMaterialFlatButton *widget; if ((widget = static_cast(watched))) { QString text(widget->text()); diff --git a/components/qtmaterialautocomplete_internal.cpp b/components/qtmaterialautocomplete_internal.cpp index 23b3db7..a29f9d2 100644 --- a/components/qtmaterialautocomplete_internal.cpp +++ b/components/qtmaterialautocomplete_internal.cpp @@ -1,5 +1,8 @@ #include "qtmaterialautocomplete_internal.h" +#include #include +#include +#include /*! * \class QtMaterialAutoCompleteStateMachine @@ -9,25 +12,57 @@ /*! * \internal */ -QtMaterialAutoCompleteStateMachine::QtMaterialAutoCompleteStateMachine(QtMaterialAutoComplete *parent) - : QStateMachine(parent), - m_autoComplete(parent), +QtMaterialAutoCompleteStateMachine::QtMaterialAutoCompleteStateMachine(QWidget *menu) + : QStateMachine(menu), + m_menu(menu), m_closedState(new QState), m_openState(new QState), m_closingState(new QState) { - Q_ASSERT(parent); + Q_ASSERT(menu); addState(m_closedState); addState(m_openState); addState(m_closingState); setInitialState(m_closedState); - QEventTransition *transition; + QSignalTransition *transition; - //transition = new QEventTransition(parent, QEvent::HoverEnter); - //transition->setTargetState(m_focusState); - //m_blurState->addTransition(transition); + transition = new QSignalTransition(this, SIGNAL(shouldOpen())); + transition->setTargetState(m_openState); + m_closedState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(shouldClose())); + transition->setTargetState(m_closedState); + m_openState->addTransition(transition); + + transition = new QSignalTransition(this, SIGNAL(shouldFade())); + transition->setTargetState(m_closingState); + m_openState->addTransition(transition); + + m_closedState->assignProperty(menu, "visible", false); + m_openState->assignProperty(menu, "visible", true); + + QGraphicsOpacityEffect *effect = new QGraphicsOpacityEffect; + menu->setGraphicsEffect(effect); + + m_openState->assignProperty(effect, "opacity", 1); + m_closingState->assignProperty(effect, "opacity", 0); + m_closedState->assignProperty(effect, "opacity", 0); + + QPropertyAnimation *animation; + + animation = new QPropertyAnimation(effect, "opacity", this); + animation->setDuration(140); + addDefaultAnimation(animation); + + transition = new QSignalTransition(animation, SIGNAL(finished())); + transition->setTargetState(m_closedState); + m_closingState->addTransition(transition); + + QObject::connect(m_closedState, &QtMaterialAutoCompleteStateMachine::entered, [=](){ qDebug() << "Closed"; }); + QObject::connect(m_openState, &QtMaterialAutoCompleteStateMachine::entered, [=](){ qDebug() << "Opened"; }); + QObject::connect(m_closingState, &QtMaterialAutoCompleteStateMachine::entered, [=](){ qDebug() << "Closing"; }); } /*! diff --git a/components/qtmaterialautocomplete_internal.h b/components/qtmaterialautocomplete_internal.h index c395eb8..3eae5be 100644 --- a/components/qtmaterialautocomplete_internal.h +++ b/components/qtmaterialautocomplete_internal.h @@ -9,16 +9,21 @@ class QtMaterialAutoCompleteStateMachine : public QStateMachine Q_OBJECT public: - QtMaterialAutoCompleteStateMachine(QtMaterialAutoComplete *parent); + explicit QtMaterialAutoCompleteStateMachine(QWidget *menu); ~QtMaterialAutoCompleteStateMachine(); +signals: + void shouldOpen(); + void shouldClose(); + void shouldFade(); + private: Q_DISABLE_COPY(QtMaterialAutoCompleteStateMachine) - QtMaterialAutoComplete *const m_autoComplete; - QState *m_closedState; - QState *m_openState; - QState *m_closingState; + QWidget *const m_menu; + QState *m_closedState; + QState *m_openState; + QState *m_closingState; }; #endif // QTMATERIALAUTOCOMPLETESTATEMACHINE_H diff --git a/components/qtmaterialautocomplete_p.h b/components/qtmaterialautocomplete_p.h index 7d00776..8386bea 100644 --- a/components/qtmaterialautocomplete_p.h +++ b/components/qtmaterialautocomplete_p.h @@ -19,8 +19,8 @@ public: void init(); - QtMaterialAutoCompleteStateMachine *stateMachine; QWidget *menu; + QtMaterialAutoCompleteStateMachine *stateMachine; QVBoxLayout *menuLayout; QStringList dataSource; int maxWidth;