Files
cbh/ElaWidgetTools/private/ElaSuggestBoxPrivate.cpp
2025-09-20 01:41:33 +08:00

140 lines
5.6 KiB
C++

#include "ElaSuggestBoxPrivate.h"
#include "ElaBaseListView.h"
#include "ElaLineEdit.h"
#include "ElaSuggestBox.h"
#include "ElaSuggestBoxSearchViewContainer.h"
#include "ElaSuggestModel.h"
#include <QLayout>
#include <QPropertyAnimation>
#include <QUuid>
ElaSuggestion::ElaSuggestion(QObject *parent) : QObject(parent) {
_pElaIcon = ElaIconType::None;
_pSuggestText = "";
_pSuggestKey = QUuid::createUuid().toString().remove("{").remove("}").remove("-");
_pSuggestData = QVariantMap();
}
ElaSuggestion::~ElaSuggestion() {}
ElaSuggestBoxPrivate::ElaSuggestBoxPrivate(QObject *parent) : QObject{parent} {}
ElaSuggestBoxPrivate::~ElaSuggestBoxPrivate() {}
void ElaSuggestBoxPrivate::onThemeModeChanged(ElaThemeType::ThemeMode themeMode) {
_themeMode = themeMode;
_searchEdit->removeAction(_themeMode == ElaThemeType::Light ? _darkSearchAction : _lightSearchAction);
_searchEdit->addAction(_themeMode == ElaThemeType::Light ? _lightSearchAction : _darkSearchAction, QLineEdit::TrailingPosition);
_searchEdit->update();
}
void ElaSuggestBoxPrivate::onSearchEditTextEdit(const QString &searchText) {
Q_Q(ElaSuggestBox);
if (searchText.isEmpty()) {
_startCloseAnimation();
return;
}
QVector<ElaSuggestion *> suggestionVector;
for (const auto &suggest : _suggestionVector) {
if (suggest->getSuggestText().contains(searchText, _pCaseSensitivity)) {
suggestionVector.append(suggest);
}
}
if (!suggestionVector.isEmpty()) {
_searchModel->setSearchSuggestion(suggestionVector);
int rowCount = suggestionVector.count();
if (rowCount > 4) {
rowCount = 4;
}
if (!_searchViewBaseWidget->isVisible()) {
q->raise();
_searchViewBaseWidget->show();
_searchViewBaseWidget->raise();
QPoint cyclePoint = _searchViewBaseWidget->mapFromGlobal(q->mapToGlobal(QPoint(-5, q->height())));
if (cyclePoint != QPoint(0, 0)) {
_searchViewBaseWidget->move(cyclePoint);
}
_startSizeAnimation(QSize(q->width() + 10, 0), QSize(q->width() + 10, 40 * rowCount + 16));
_searchView->move(_searchView->x(), -(40 * rowCount + 16));
} else {
_startSizeAnimation(_searchViewBaseWidget->size(), QSize(q->width() + 12, 40 * rowCount + 16));
}
_startExpandAnimation();
} else {
_startCloseAnimation();
}
}
void ElaSuggestBoxPrivate::onSearchViewClicked(const QModelIndex &index) {
Q_Q(ElaSuggestBox);
_searchEdit->clear();
_searchView->clearSelection();
if (!index.isValid()) {
return;
}
ElaSuggestion *suggest = _searchModel->getSearchSuggestion(index.row());
Q_EMIT q->suggestionClicked(suggest->getSuggestText(), suggest->getSuggestData());
_startCloseAnimation();
}
void ElaSuggestBoxPrivate::_startSizeAnimation(QSize oldSize, QSize newSize) {
if (_lastSize.isValid() && _lastSize == newSize) {
return;
}
_shadowLayout->removeWidget(_searchView);
QPropertyAnimation *expandAnimation = new QPropertyAnimation(_searchViewBaseWidget, "size");
connect(expandAnimation, &QPropertyAnimation::valueChanged, this, [=]() { _searchView->resize(_searchViewBaseWidget->size()); });
connect(expandAnimation, &QPropertyAnimation::finished, this, [=]() { _shadowLayout->addWidget(_searchView); });
expandAnimation->setDuration(300);
expandAnimation->setEasingCurve(QEasingCurve::InOutSine);
expandAnimation->setStartValue(oldSize);
expandAnimation->setEndValue(newSize);
expandAnimation->start(QAbstractAnimation::DeleteWhenStopped);
_lastSize = newSize;
}
void ElaSuggestBoxPrivate::_startExpandAnimation() {
if (!_isExpandAnimationFinished) {
return;
}
_isCloseAnimationFinished = true;
_isExpandAnimationFinished = false;
QPropertyAnimation *expandAnimation = new QPropertyAnimation(_searchView, "pos");
connect(expandAnimation, &QPropertyAnimation::finished, this, [=]() {
_isExpandAnimationFinished = true;
_searchView->clearSelection();
});
expandAnimation->setDuration(300);
expandAnimation->setEasingCurve(QEasingCurve::InOutSine);
expandAnimation->setStartValue(_searchView->pos());
expandAnimation->setEndValue(QPoint(8, 8));
expandAnimation->start(QAbstractAnimation::DeleteWhenStopped);
}
void ElaSuggestBoxPrivate::_startCloseAnimation() {
if (!_isCloseAnimationFinished) {
return;
}
_isExpandAnimationFinished = true;
_isCloseAnimationFinished = false;
QPropertyAnimation *baseWidgetsAnimation = new QPropertyAnimation(_searchViewBaseWidget, "size");
baseWidgetsAnimation->setDuration(300);
baseWidgetsAnimation->setEasingCurve(QEasingCurve::InOutSine);
baseWidgetsAnimation->setStartValue(_searchViewBaseWidget->size());
baseWidgetsAnimation->setEndValue(QSize(_searchViewBaseWidget->width(), 0));
baseWidgetsAnimation->start(QAbstractAnimation::DeleteWhenStopped);
QPropertyAnimation *closeAnimation = new QPropertyAnimation(_searchView, "pos");
connect(closeAnimation, &QPropertyAnimation::finished, this, [=]() {
_isCloseAnimationFinished = true;
_searchModel->clearSearchNode();
_searchViewBaseWidget->hide();
});
closeAnimation->setDuration(300);
closeAnimation->setEasingCurve(QEasingCurve::InOutSine);
closeAnimation->setStartValue(_searchView->pos());
closeAnimation->setEndValue(QPoint(_searchView->pos().x(), -_searchView->height()));
closeAnimation->start(QAbstractAnimation::DeleteWhenStopped);
_lastSize = baseWidgetsAnimation->endValue().toSize();
}