Place the completion popup under the search widget

This commit is contained in:
Konstantinos Sideris 2017-08-20 21:13:00 +03:00
parent 2644e4acca
commit c6ec20fa40
2 changed files with 74 additions and 27 deletions

View file

@ -17,6 +17,7 @@
#pragma once #pragma once
#include <QAbstractItemView>
#include <QFrame> #include <QFrame>
#include <QKeyEvent> #include <QKeyEvent>
#include <QVBoxLayout> #include <QVBoxLayout>
@ -29,8 +30,14 @@ class RoomSearchInput : public TextField
public: public:
explicit RoomSearchInput(QWidget *parent = nullptr); explicit RoomSearchInput(QWidget *parent = nullptr);
signals:
void selectNextCompletion();
void selectPreviousCompletion();
void hiding();
protected: protected:
void keyPressEvent(QKeyEvent *event) override; void keyPressEvent(QKeyEvent *event) override;
void hideEvent(QHideEvent *event) override;
bool focusNextPrevChild(bool next) override; bool focusNextPrevChild(bool next) override;
}; };
@ -51,8 +58,12 @@ protected:
void showEvent(QShowEvent *event) override; void showEvent(QShowEvent *event) override;
private: private:
// Current highlighted selection from the completer.
int selection_ = -1;
QVBoxLayout *topLayout_; QVBoxLayout *topLayout_;
RoomSearchInput *roomSearch_; RoomSearchInput *roomSearch_;
QCompleter *completer_;
QMap<QString, QString> rooms_; QMap<QString, QString> rooms_;
}; };

View file

@ -15,7 +15,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <QAbstractItemView>
#include <QCompleter> #include <QCompleter>
#include <QDebug> #include <QDebug>
#include <QStringListModel> #include <QStringListModel>
@ -39,17 +38,12 @@ RoomSearchInput::focusNextPrevChild(bool next)
void void
RoomSearchInput::keyPressEvent(QKeyEvent *event) RoomSearchInput::keyPressEvent(QKeyEvent *event)
{ {
if (event->key() == Qt::Key_Tab) { if (event->key() == Qt::Key_Tab || event->key() == Qt::Key_Down) {
auto completer = this->completer(); emit selectNextCompletion();
event->accept();
if (completer) { return;
// Enable the current item if its valid. } else if (event->key() == Qt::Key_Up) {
completer->popup()->setCurrentIndex(completer->currentIndex()); emit selectPreviousCompletion();
if (!completer->setCurrentRow(completer->currentRow() + 1))
completer->setCurrentRow(0);
}
event->accept(); event->accept();
return; return;
} }
@ -57,11 +51,18 @@ RoomSearchInput::keyPressEvent(QKeyEvent *event)
TextField::keyPressEvent(event); TextField::keyPressEvent(event);
} }
void
RoomSearchInput::hideEvent(QHideEvent *event)
{
emit hiding();
TextField::hideEvent(event);
}
QuickSwitcher::QuickSwitcher(QWidget *parent) QuickSwitcher::QuickSwitcher(QWidget *parent)
: QFrame(parent) : QFrame(parent)
{ {
setMaximumWidth(400); setMaximumWidth(450);
setStyleSheet("background-color: #f9f9f9"); setStyleSheet("background-color: white");
QFont font; QFont font;
font.setPixelSize(20); font.setPixelSize(20);
@ -70,17 +71,56 @@ QuickSwitcher::QuickSwitcher(QWidget *parent)
roomSearch_->setFont(font); roomSearch_->setFont(font);
roomSearch_->setPlaceholderText(tr("Find a room...")); roomSearch_->setPlaceholderText(tr("Find a room..."));
QStringList wordList; completer_ = new QCompleter();
QCompleter *completer = new QCompleter(wordList, this); completer_->setCaseSensitivity(Qt::CaseInsensitive);
completer->setCaseSensitivity(Qt::CaseInsensitive); completer_->setCompletionMode(QCompleter::PopupCompletion);
completer_->setWidget(this);
roomSearch_->setCompleter(completer);
topLayout_ = new QVBoxLayout(this); topLayout_ = new QVBoxLayout(this);
topLayout_->setMargin(20);
topLayout_->setSpacing(0);
topLayout_->addWidget(roomSearch_); topLayout_->addWidget(roomSearch_);
connect(completer_, SIGNAL(highlighted(QString)), roomSearch_, SLOT(setText(QString)));
connect(roomSearch_, &QLineEdit::textEdited, this, [=](const QString &prefix) {
if (prefix.isEmpty()) {
completer_->popup()->hide();
selection_ = -1;
return;
}
if (prefix != completer_->completionPrefix()) {
completer_->setCompletionPrefix(prefix);
selection_ = -1;
}
completer_->popup()->setWindowFlags(completer_->popup()->windowFlags() | Qt::ToolTip |
Qt::NoDropShadowWindowHint);
completer_->popup()->setAttribute(Qt::WA_ShowWithoutActivating);
completer_->complete();
});
connect(roomSearch_, &RoomSearchInput::selectNextCompletion, this, [=]() {
selection_ += 1;
if (!completer_->setCurrentRow(selection_)) {
selection_ = 0;
completer_->setCurrentRow(selection_);
}
completer_->popup()->setCurrentIndex(completer_->currentIndex());
});
connect(roomSearch_, &RoomSearchInput::selectPreviousCompletion, this, [=]() {
selection_ -= 1;
if (!completer_->setCurrentRow(selection_)) {
selection_ = completer_->completionCount() - 1;
completer_->setCurrentRow(selection_);
}
completer_->popup()->setCurrentIndex(completer_->currentIndex());
});
connect(roomSearch_, &RoomSearchInput::hiding, this, [=]() { completer_->popup()->hide(); });
connect(roomSearch_, &QLineEdit::returnPressed, this, [=]() { connect(roomSearch_, &QLineEdit::returnPressed, this, [=]() {
emit closing(); emit closing();
emit roomSelected(rooms_[this->roomSearch_->text().trimmed()]); emit roomSelected(rooms_[this->roomSearch_->text().trimmed()]);
@ -93,13 +133,9 @@ void
QuickSwitcher::setRoomList(const QMap<QString, QString> &rooms) QuickSwitcher::setRoomList(const QMap<QString, QString> &rooms)
{ {
rooms_ = rooms; rooms_ = rooms;
QStringList items = rooms.keys();
QStringList search_items = rooms.keys(); completer_->setModel(new QStringListModel(items));
if (!roomSearch_->completer())
return;
roomSearch_->completer()->setModel(new QStringListModel(search_items));
} }
void void