ui: fixed flickering of search autocompletions popup

This commit is contained in:
Eberhard Graether
2016-06-29 22:15:00 +02:00
parent cba0cfad65
commit b5d9d20bc9
5 changed files with 39 additions and 38 deletions
+14 -20
View File
@@ -120,7 +120,11 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt
float charWidth = option.fontMetrics.width( float charWidth = option.fontMetrics.width(
"----------------------------------------------------------------------------------------------------" "----------------------------------------------------------------------------------------------------"
) / 100.0f; "----------------------------------------------------------------------------------------------------"
"----------------------------------------------------------------------------------------------------"
"----------------------------------------------------------------------------------------------------"
"----------------------------------------------------------------------------------------------------"
) / 500.0f;
painter->drawText(option.rect.adjusted(charWidth + 2, -1, 0, 0), Qt::AlignLeft, name); painter->drawText(option.rect.adjusted(charWidth + 2, -1, 0, 0), Qt::AlignLeft, name);
QString highlightName(name.size(), ' '); QString highlightName(name.size(), ' ');
@@ -173,11 +177,11 @@ void QtAutocompletionDelegate::paint(QPainter* painter, const QStyleOptionViewIt
painter->restore(); painter->restore();
} }
QSize QtAutocompletionDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const QSize QtAutocompletionDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
{ {
QString name = index.data().toString(); QString name = index.data().toString();
QString type = index.sibling(index.row(), index.column() + 1).data().toString(); QString type = index.sibling(index.row(), index.column() + 1).data().toString();
return QSize( option.fontMetrics.width(name+type)+5, option.fontMetrics.height()); return QSize(option.fontMetrics.width(name + type) + 5, option.fontMetrics.height());
} }
QtAutocompletionList::QtAutocompletionList(QWidget* parent) QtAutocompletionList::QtAutocompletionList(QWidget* parent)
@@ -196,44 +200,34 @@ QtAutocompletionList::QtAutocompletionList(QWidget* parent)
setPopup(list); setPopup(list);
setCaseSensitivity(Qt::CaseInsensitive); setCaseSensitivity(Qt::CaseInsensitive);
// setCompletionMode(QCompleter::UnfilteredPopupCompletion); setCompletionMode(QCompleter::UnfilteredPopupCompletion);
setModelSorting(QCompleter::UnsortedModel);
setCompletionPrefix("");
setMaxVisibleItems(20);
} }
QtAutocompletionList::~QtAutocompletionList() QtAutocompletionList::~QtAutocompletionList()
{ {
} }
void QtAutocompletionList::completeAt(const QPoint& pos, const std::vector<SearchMatch>& autocompletionList) void QtAutocompletionList::completeAt(const QPoint& pos, const std::vector<SearchMatch>& autocompletionList)
{ {
m_model->setMatchList(autocompletionList); m_model->setMatchList(autocompletionList);
QSize minSize(400, 253);
QListView* list = dynamic_cast<QListView*>(popup()); QListView* list = dynamic_cast<QListView*>(popup());
if (!autocompletionList.size()) if (!autocompletionList.size())
{ {
list->hide(); list->hide();
return; return;
} }
setCompletionPrefix("");
const QModelIndex& index = completionModel()->index(0, 0);
list->setCurrentIndex(index);
QRect rect = list->visualRect(index);
minSize.setHeight(std::min(minSize.height(), m_model->rowCount(index) * rect.height() + 16));
list->setMinimumSize(minSize);
list->verticalScrollBar()->setValue(list->verticalScrollBar()->minimum());
disconnect(); // must be done because of a bug where signals are no longer received by QtSmartSearchBox disconnect(); // must be done because of a bug where signals are no longer received by QtSmartSearchBox
connect(this, SIGNAL(highlighted(const QModelIndex&)), this, SLOT(onHighlighted(const QModelIndex&)), Qt::DirectConnection); connect(this, SIGNAL(highlighted(const QModelIndex&)), this, SLOT(onHighlighted(const QModelIndex&)), Qt::DirectConnection);
connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(onActivated(const QModelIndex&)), Qt::DirectConnection); connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(onActivated(const QModelIndex&)), Qt::DirectConnection);
QWidget* textBox = dynamic_cast<QWidget*>(parent()); complete(QRect(pos.x(), pos.y(), std::max(dynamic_cast<QWidget*>(parent())->width(), 400), 1));
complete(QRect(pos.x(), pos.y(), textBox->width(), 1));
list->setCurrentIndex(completionModel()->index(0, 0));
} }
const SearchMatch* QtAutocompletionList::getSearchMatchAt(int idx) const const SearchMatch* QtAutocompletionList::getSearchMatchAt(int idx) const
@@ -42,7 +42,7 @@ public:
virtual ~QtAutocompletionDelegate(); virtual ~QtAutocompletionDelegate();
virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
virtual QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
}; };
+1 -6
View File
@@ -1,6 +1,5 @@
#include "qt/element/QtSearchBar.h" #include "qt/element/QtSearchBar.h"
#include <QCompleter>
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPushButton> #include <QPushButton>
@@ -89,11 +88,7 @@ void QtSearchBar::setAutocompletionList(const std::vector<SearchMatch>& autocomp
QAbstractItemView* QtSearchBar::getCompleterPopup() QAbstractItemView* QtSearchBar::getCompleterPopup()
{ {
if (m_searchBox->completer()) return m_searchBox->getCompleter()->popup();
{
return m_searchBox->completer()->popup();
}
return nullptr;
} }
void QtSearchBar::refreshStyle() void QtSearchBar::refreshStyle()
+19 -11
View File
@@ -15,7 +15,6 @@
#include "utility/utilityString.h" #include "utility/utilityString.h"
#include "component/view/GraphViewStyle.h" #include "component/view/GraphViewStyle.h"
#include "qt/element/QtAutocompletionList.h"
#include "settings/ColorScheme.h" #include "settings/ColorScheme.h"
QtSearchElement::QtSearchElement(const QString& text, QWidget* parent) QtSearchElement::QtSearchElement(const QString& text, QWidget* parent)
@@ -69,8 +68,8 @@ QtSmartSearchBox::QtSmartSearchBox(QWidget* parent)
connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(onTextEdited(const QString&))); connect(this, SIGNAL(textEdited(const QString&)), this, SLOT(onTextEdited(const QString&)));
connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&))); connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
QCompleter* completer = new QtAutocompletionList(this); m_completer = new QtAutocompletionList(this);
setCompleter(completer); m_completer->setWidget(this);
updatePlaceholder(); updatePlaceholder();
} }
@@ -79,13 +78,18 @@ QtSmartSearchBox::~QtSmartSearchBox()
{ {
} }
QCompleter* QtSmartSearchBox::getCompleter() const
{
return m_completer;
}
void QtSmartSearchBox::setAutocompletionList(const std::vector<SearchMatch>& autocompletionList) void QtSmartSearchBox::setAutocompletionList(const std::vector<SearchMatch>& autocompletionList)
{ {
// Save the cursor position, because after activating the completer the cursor gets set to the end position. // Save the cursor position, because after activating the completer the cursor gets set to the end position.
int cursor = cursorPosition(); int cursor = cursorPosition();
QtAutocompletionList* completer = dynamic_cast<QtAutocompletionList*>(this->completer()); QtAutocompletionList* completer = m_completer;
completer->completeAt(QPoint(textMargins().left() + 3, height() + 3), autocompletionList); completer->completeAt(QPoint(textMargins().left() + 3, height() + 5), autocompletionList);
setCursorPosition(cursor); setCursorPosition(cursor);
@@ -138,7 +142,7 @@ bool QtSmartSearchBox::event(QEvent *event)
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
if (keyEvent->key() == Qt::Key_Tab) if (keyEvent->key() == Qt::Key_Tab)
{ {
if (completer()->popup()->isVisible()) if (m_completer->popup()->isVisible())
{ {
addMatchAndUpdate(m_highlightedMatch); addMatchAndUpdate(m_highlightedMatch);
} }
@@ -170,7 +174,7 @@ void QtSmartSearchBox::keyPressEvent(QKeyEvent* event)
fullTextSearch(); fullTextSearch();
return; return;
} }
else if (!completer()->popup()->isVisible()) else if (!m_completer->popup()->isVisible())
{ {
search(); search();
} }
@@ -244,7 +248,7 @@ void QtSmartSearchBox::keyPressEvent(QKeyEvent* event)
} }
else if (cursorPosition() == text().size() && !event->isAutoRepeat()) else if (cursorPosition() == text().size() && !event->isAutoRepeat())
{ {
if (completer()->popup()->isVisible()) if (m_completer->popup()->isVisible())
{ {
addMatchAndUpdate(m_highlightedMatch); addMatchAndUpdate(m_highlightedMatch);
} }
@@ -445,6 +449,10 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
{ {
requestAutoCompletions(); requestAutoCompletions();
} }
else
{
hideAutoCompletions();
}
} }
void QtSmartSearchBox::onTextChanged(const QString& text) void QtSmartSearchBox::onTextChanged(const QString& text)
@@ -549,9 +557,9 @@ void QtSmartSearchBox::addMatch(const SearchMatch& match)
const SearchMatch* matchPtr = &match; const SearchMatch* matchPtr = &match;
if (completer()->popup()->isVisible()) if (m_completer->popup()->isVisible())
{ {
const SearchMatch* mPtr = dynamic_cast<QtAutocompletionList*>(completer())->getSearchMatchAt(0); const SearchMatch* mPtr = m_completer->getSearchMatchAt(0);
if (mPtr && utility::equalsCaseInsensitive(match.getFullName(), mPtr->getFullName())) if (mPtr && utility::equalsCaseInsensitive(match.getFullName(), mPtr->getFullName()))
{ {
matchPtr = mPtr; matchPtr = mPtr;
@@ -862,7 +870,7 @@ void QtSmartSearchBox::requestAutoCompletions() const
void QtSmartSearchBox::hideAutoCompletions() void QtSmartSearchBox::hideAutoCompletions()
{ {
completer()->popup()->hide(); m_completer->popup()->hide();
} }
std::deque<SearchMatch> QtSmartSearchBox::getMatchesForInput(const std::string& text) const std::deque<SearchMatch> QtSmartSearchBox::getMatchesForInput(const std::string& text) const
@@ -8,6 +8,7 @@
#include <QPushButton> #include <QPushButton>
#include "data/search/SearchMatch.h" #include "data/search/SearchMatch.h"
#include "qt/element/QtAutocompletionList.h"
class QtSearchElement class QtSearchElement
: public QPushButton : public QPushButton
@@ -38,6 +39,8 @@ public:
QtSmartSearchBox(QWidget* parent); QtSmartSearchBox(QWidget* parent);
virtual ~QtSmartSearchBox(); virtual ~QtSmartSearchBox();
QCompleter* getCompleter() const;
void setAutocompletionList(const std::vector<SearchMatch>& autocompletionList); void setAutocompletionList(const std::vector<SearchMatch>& autocompletionList);
void setMatches(const std::vector<SearchMatch>& matches); void setMatches(const std::vector<SearchMatch>& matches);
void setFocus(); void setFocus();
@@ -109,6 +112,7 @@ private:
int m_mouseX; int m_mouseX;
QWidget* m_highlightRect; QWidget* m_highlightRect;
QtAutocompletionList* m_completer;
}; };
#endif // QT_SMART_SEARCH_BOX_H #endif // QT_SMART_SEARCH_BOX_H