Implement fade effect for Auto Complete

This commit is contained in:
Johannes Hilden 2017-10-15 14:45:11 +03:00
parent 5aefcce24d
commit 41c5f156a2
4 changed files with 63 additions and 22 deletions

View File

@ -4,6 +4,7 @@
#include <QtWidgets/QVBoxLayout> #include <QtWidgets/QVBoxLayout>
#include <QEvent> #include <QEvent>
#include <QTimer> #include <QTimer>
#include <QDebug>
#include "qtmaterialautocomplete_internal.h" #include "qtmaterialautocomplete_internal.h"
#include "qtmaterialflatbutton.h" #include "qtmaterialflatbutton.h"
@ -34,8 +35,8 @@ void QtMaterialAutoCompletePrivate::init()
{ {
Q_Q(QtMaterialAutoComplete); Q_Q(QtMaterialAutoComplete);
stateMachine = new QtMaterialAutoCompleteStateMachine(q);
menu = new QWidget; menu = new QWidget;
stateMachine = new QtMaterialAutoCompleteStateMachine(menu);
menuLayout = new QVBoxLayout; menuLayout = new QVBoxLayout;
maxWidth = 0; maxWidth = 0;
@ -46,7 +47,9 @@ void QtMaterialAutoCompletePrivate::init()
effect->setColor(QColor(0, 0, 0, 50)); effect->setColor(QColor(0, 0, 0, 50));
effect->setOffset(0, 3); 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->setLayout(menuLayout);
menu->setVisible(false); menu->setVisible(false);
@ -137,9 +140,9 @@ void QtMaterialAutoComplete::updateResults(QString text)
} }
if (!results.count()) { if (!results.count()) {
d->menu->hide(); emit d->stateMachine->shouldClose();
} else if (d->menu->isHidden()) { } else {
d->menu->show(); emit d->stateMachine->shouldOpen();
} }
d->menu->setFixedHeight(results.length()*50); d->menu->setFixedHeight(results.length()*50);
@ -178,9 +181,7 @@ bool QtMaterialAutoComplete::eventFilter(QObject *watched, QEvent *event)
switch (event->type()) switch (event->type())
{ {
case QEvent::MouseButtonPress: { case QEvent::MouseButtonPress: {
QTimer::singleShot(300, this, [=](){ emit d->stateMachine->shouldFade();
d->menu->hide();
});
QtMaterialFlatButton *widget; QtMaterialFlatButton *widget;
if ((widget = static_cast<QtMaterialFlatButton *>(watched))) { if ((widget = static_cast<QtMaterialFlatButton *>(watched))) {
QString text(widget->text()); QString text(widget->text());

View File

@ -1,5 +1,8 @@
#include "qtmaterialautocomplete_internal.h" #include "qtmaterialautocomplete_internal.h"
#include <QSignalTransition>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QtWidgets/QGraphicsOpacityEffect>
#include <QDebug>
/*! /*!
* \class QtMaterialAutoCompleteStateMachine * \class QtMaterialAutoCompleteStateMachine
@ -9,25 +12,57 @@
/*! /*!
* \internal * \internal
*/ */
QtMaterialAutoCompleteStateMachine::QtMaterialAutoCompleteStateMachine(QtMaterialAutoComplete *parent) QtMaterialAutoCompleteStateMachine::QtMaterialAutoCompleteStateMachine(QWidget *menu)
: QStateMachine(parent), : QStateMachine(menu),
m_autoComplete(parent), m_menu(menu),
m_closedState(new QState), m_closedState(new QState),
m_openState(new QState), m_openState(new QState),
m_closingState(new QState) m_closingState(new QState)
{ {
Q_ASSERT(parent); Q_ASSERT(menu);
addState(m_closedState); addState(m_closedState);
addState(m_openState); addState(m_openState);
addState(m_closingState); addState(m_closingState);
setInitialState(m_closedState); setInitialState(m_closedState);
QEventTransition *transition; QSignalTransition *transition;
//transition = new QEventTransition(parent, QEvent::HoverEnter); transition = new QSignalTransition(this, SIGNAL(shouldOpen()));
//transition->setTargetState(m_focusState); transition->setTargetState(m_openState);
//m_blurState->addTransition(transition); 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"; });
} }
/*! /*!

View File

@ -9,16 +9,21 @@ class QtMaterialAutoCompleteStateMachine : public QStateMachine
Q_OBJECT Q_OBJECT
public: public:
QtMaterialAutoCompleteStateMachine(QtMaterialAutoComplete *parent); explicit QtMaterialAutoCompleteStateMachine(QWidget *menu);
~QtMaterialAutoCompleteStateMachine(); ~QtMaterialAutoCompleteStateMachine();
signals:
void shouldOpen();
void shouldClose();
void shouldFade();
private: private:
Q_DISABLE_COPY(QtMaterialAutoCompleteStateMachine) Q_DISABLE_COPY(QtMaterialAutoCompleteStateMachine)
QtMaterialAutoComplete *const m_autoComplete; QWidget *const m_menu;
QState *m_closedState; QState *m_closedState;
QState *m_openState; QState *m_openState;
QState *m_closingState; QState *m_closingState;
}; };
#endif // QTMATERIALAUTOCOMPLETESTATEMACHINE_H #endif // QTMATERIALAUTOCOMPLETESTATEMACHINE_H

View File

@ -19,8 +19,8 @@ public:
void init(); void init();
QtMaterialAutoCompleteStateMachine *stateMachine;
QWidget *menu; QWidget *menu;
QtMaterialAutoCompleteStateMachine *stateMachine;
QVBoxLayout *menuLayout; QVBoxLayout *menuLayout;
QStringList dataSource; QStringList dataSource;
int maxWidth; int maxWidth;