123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- #include "qtmaterialautocomplete.h"
- #include "qtmaterialautocomplete_p.h"
- #include <QtWidgets/QGraphicsDropShadowEffect>
- #include <QtWidgets/QVBoxLayout>
- #include <QEvent>
- #include <QTimer>
- #include <QPainter>
- #include <QDebug>
- #include "qtmaterialautocomplete_internal.h"
- #include "qtmaterialflatbutton.h"
- /*!
- * \class QtMaterialAutoCompletePrivate
- * \internal
- */
- /*!
- * \internal
- */
- QtMaterialAutoCompletePrivate::QtMaterialAutoCompletePrivate(QtMaterialAutoComplete *q)
- : QtMaterialTextFieldPrivate(q)
- {
- }
- /*!
- * \internal
- */
- QtMaterialAutoCompletePrivate::~QtMaterialAutoCompletePrivate()
- {
- }
- /*!
- * \internal
- */
- void QtMaterialAutoCompletePrivate::init()
- {
- Q_Q(QtMaterialAutoComplete);
- menu = new QWidget;
- frame = new QWidget;
- stateMachine = new QtMaterialAutoCompleteStateMachine(menu);
- menuLayout = new QVBoxLayout;
- maxWidth = 0;
- menu->setParent(q->parentWidget());
- frame->setParent(q->parentWidget());
- menu->installEventFilter(q);
- frame->installEventFilter(q);
- QGraphicsDropShadowEffect *effect = new QGraphicsDropShadowEffect;
- effect->setBlurRadius(11);
- effect->setColor(QColor(0, 0, 0, 50));
- effect->setOffset(0, 3);
- frame->setGraphicsEffect(effect);
- frame->setVisible(false);
- menu->setLayout(menuLayout);
- menu->setVisible(false);
- menuLayout->setContentsMargins(0, 0, 0, 0);
- menuLayout->setSpacing(0);
- QObject::connect(q, SIGNAL(textEdited(QString)), q, SLOT(updateResults(QString)));
- stateMachine->start();
- }
- /*!
- * \class QtMaterialAutoComplete
- */
- QtMaterialAutoComplete::QtMaterialAutoComplete(QWidget *parent)
- : QtMaterialTextField(*new QtMaterialAutoCompletePrivate(this), parent)
- {
- d_func()->init();
- }
- QtMaterialAutoComplete::~QtMaterialAutoComplete()
- {
- }
- void QtMaterialAutoComplete::setDataSource(const QStringList &data)
- {
- Q_D(QtMaterialAutoComplete);
- d->dataSource = data;
- update();
- }
- void QtMaterialAutoComplete::updateResults(QString text)
- {
- Q_D(QtMaterialAutoComplete);
- QStringList results;
- QString trimmed(text.trimmed());
- if (!trimmed.isEmpty()) {
- QString lookup(trimmed.toLower());
- QStringList::iterator i;
- for (i = d->dataSource.begin(); i != d->dataSource.end(); ++i) {
- if (i->toLower().indexOf(lookup) != -1) {
- results.push_back(*i);
- }
- }
- }
- const int diff = results.length() - d->menuLayout->count();
- QFont font("Roboto", 12, QFont::Normal);
- if (diff > 0) {
- for (int c = 0; c < diff; c++) {
- QtMaterialFlatButton *item = new QtMaterialFlatButton;
- item->setFont(font);
- item->setTextAlignment(Qt::AlignLeft);
- item->setCornerRadius(0);
- item->setHaloVisible(false);
- item->setFixedHeight(50);
- item->setOverlayStyle(Material::TintedOverlay);
- d->menuLayout->addWidget(item);
- item->installEventFilter(this);
- }
- } else if (diff < 0) {
- for (int c = 0; c < -diff; c++) {
- QWidget *widget = d->menuLayout->itemAt(0)->widget();
- if (widget) {
- d->menuLayout->removeWidget(widget);
- delete widget;
- }
- }
- }
- QFontMetrics *fm = new QFontMetrics(font);
- d->maxWidth = 0;
- for (int i = 0; i < results.count(); ++i) {
- QWidget *widget = d->menuLayout->itemAt(i)->widget();
- QtMaterialFlatButton *item;
- if ((item = static_cast<QtMaterialFlatButton *>(widget))) {
- QString text = results.at(i);
- QRect rect = fm->boundingRect(text);
- d->maxWidth = qMax(d->maxWidth, rect.width());
- item->setText(text);
- }
- }
- if (!results.count()) {
- emit d->stateMachine->shouldClose();
- } else {
- emit d->stateMachine->shouldOpen();
- }
- d->menu->setFixedHeight(results.length()*50);
- d->menu->setFixedWidth(qMax(d->maxWidth + 24, width()));
- d->menu->update();
- }
- bool QtMaterialAutoComplete::QtMaterialAutoComplete::event(QEvent *event)
- {
- Q_D(QtMaterialAutoComplete);
- switch (event->type())
- {
- case QEvent::Move:
- case QEvent::Resize: {
- d->menu->move(pos() + QPoint(0, height() + 6));
- break;
- }
- case QEvent::ParentChange: {
- QWidget *widget = static_cast<QWidget *>(parent());
- if (widget) {
- d->menu->setParent(widget);
- d->frame->setParent(widget);
- }
- break;
- }
- default:
- break;
- }
- return QtMaterialTextField::event(event);
- }
- bool QtMaterialAutoComplete::eventFilter(QObject *watched, QEvent *event)
- {
- Q_D(QtMaterialAutoComplete);
- if (d->frame == watched)
- {
- switch (event->type())
- {
- case QEvent::Paint: {
- QPainter painter(d->frame);
- painter.fillRect(d->frame->rect(), Qt::white);
- break;
- }
- default:
- break;
- }
- }
- else if (d->menu == watched)
- {
- switch (event->type())
- {
- case QEvent::Resize:
- case QEvent::Move: {
- d->frame->setGeometry(d->menu->geometry());
- break;
- }
- case QEvent::Show: {
- d->frame->show();
- d->menu->raise();
- break;
- }
- case QEvent::Hide: {
- d->frame->hide();
- break;
- }
- default:
- break;
- }
- }
- else
- {
- switch (event->type())
- {
- case QEvent::MouseButtonPress: {
- emit d->stateMachine->shouldFade();
- QtMaterialFlatButton *widget;
- if ((widget = static_cast<QtMaterialFlatButton *>(watched))) {
- QString text(widget->text());
- setText(text);
- emit itemSelected(text);
- }
- break;
- }
- default:
- break;
- }
- }
- return QtMaterialTextField::eventFilter(watched, event);
- }
|