Fix right-to-left layout in SearchBar

Use QLineEdit::addAction() to place a button inside the widget.
It will automatically positioned on the left, or on the right, depending
on the current language.

Fixes: #594
This commit is contained in:
Alexander Sashnov 2022-04-19 22:12:04 +07:00 committed by Kelson
parent adad44aced
commit f2157f1335
3 changed files with 32 additions and 43 deletions

View File

@ -32,23 +32,14 @@ QToolButton {
SearchBar { SearchBar {
background-color: white; background-color: white;
padding: 2px 2px 2px 40px; padding: 2px;
max-height: 38px; max-height: 38px;
margin: 2px 5px;
color: #666; color: #666;
font-size: 16px; font-size: 16px;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 3px; border-radius: 3px;
} }
SearchBar > QPushButton {
margin: 8px 0px 8px 12px;
padding: 0;
border: 0 solid #fff;
background-color: white;
height: 32px;
width: 32px;
}
TopWidget QToolButton:pressed, TopWidget QToolButton:pressed,
TopWidget QToolButton::hover { TopWidget QToolButton::hover {

View File

@ -2,37 +2,29 @@
#include <QCompleter> #include <QCompleter>
#include <QFocusEvent> #include <QFocusEvent>
#include <QCursor>
#include "kiwixapp.h" #include "kiwixapp.h"
#include "suggestionlistworker.h" #include "suggestionlistworker.h"
SearchButton::SearchButton(QWidget *parent) :
QPushButton(parent),
m_searchMode(true)
{
setFlat(true);
setIcon(QIcon(":/icons/search.svg"));
connect(this, &QPushButton::clicked, this, &SearchButton::on_buttonClicked);
}
void SearchButton::set_searchMode(bool searchMode)
void SearchBar::set_searchMode(bool searchMode)
{ {
m_searchMode = searchMode; m_searchMode = searchMode;
if (m_searchMode) { if (m_searchMode) {
setIcon(QIcon(":/icons/search.svg")); m_action->setIcon(QIcon(":/icons/search.svg"));
setIconSize(QSize(27, 27));
} else { } else {
auto kiwixApp = KiwixApp::instance(); auto kiwixApp = KiwixApp::instance();
if (kiwixApp->isCurrentArticleBookmarked()) { if (kiwixApp->isCurrentArticleBookmarked()) {
setIcon(QIcon(":/icons/reading-list-active.svg")); m_action->setIcon(QIcon(":/icons/reading-list-active.svg"));
} else { } else {
setIcon(QIcon(":/icons/reading-list.svg")); m_action->setIcon(QIcon(":/icons/reading-list.svg"));
} }
setIconSize(QSize(25, 25));
} }
} }
void SearchButton::on_buttonClicked() void SearchBar::on_action_triggered()
{ {
if (m_searchMode) if (m_searchMode)
return; return;
@ -60,7 +52,7 @@ void SearchButton::on_buttonClicked()
SearchBar::SearchBar(QWidget *parent) : SearchBar::SearchBar(QWidget *parent) :
QLineEdit(parent), QLineEdit(parent),
m_completer(&m_completionModel, this), m_completer(&m_completionModel, this),
m_button(this) m_action(new QAction(this))
{ {
mp_typingTimer = new QTimer(this); mp_typingTimer = new QTimer(this);
mp_typingTimer->setSingleShot(true); mp_typingTimer->setSingleShot(true);
@ -71,6 +63,11 @@ SearchBar::SearchBar(QWidget *parent) :
m_completer.setMaxVisibleItems(16); m_completer.setMaxVisibleItems(16);
setCompleter(&m_completer); setCompleter(&m_completer);
connect(m_action, &QAction::triggered,
this, &SearchBar::on_action_triggered);
addAction(m_action, QLineEdit::LeadingPosition);
set_searchMode(true);
QFile styleFile(":/css/popup.css"); QFile styleFile(":/css/popup.css");
styleFile.open(QIODevice::ReadOnly); styleFile.open(QIODevice::ReadOnly);
auto byteContent = styleFile.readAll(); auto byteContent = styleFile.readAll();
@ -121,30 +118,41 @@ void SearchBar::on_currentTitleChanged(const QString& title)
} else { } else {
setText(""); setText("");
} }
m_button.set_searchMode(title.isEmpty()); set_searchMode(title.isEmpty());
m_title = title; m_title = title;
} }
void SearchBar::focusInEvent( QFocusEvent* event) void SearchBar::focusInEvent( QFocusEvent* event)
{ {
if (event->reason() == Qt::MouseFocusReason) {
if (QApplication::widgetAt(QCursor::pos()) != this) {
// drop focus, mouse clicked on one of inner widget (m_action)
clearFocus();
return;
}
}
setReadOnly(false); setReadOnly(false);
if (event->reason() == Qt::MouseFocusReason && text() == m_title) { if (event->reason() == Qt::MouseFocusReason && text() == m_title) {
clear(); clear();
} }
if (event->reason() == Qt::ActiveWindowFocusReason || if (event->reason() == Qt::ActiveWindowFocusReason ||
event->reason() == Qt::MouseFocusReason) { event->reason() == Qt::MouseFocusReason) {
/* need to connect every time because QLineEdit::focusOutEvent does:
* QObject::disconnect(d->control->completer(), 0, this, 0);
*/
connect(&m_completer, QOverload<const QModelIndex &>::of(&QCompleter::activated), connect(&m_completer, QOverload<const QModelIndex &>::of(&QCompleter::activated),
this, QOverload<const QModelIndex &>::of(&SearchBar::openCompletion)); this, QOverload<const QModelIndex &>::of(&SearchBar::openCompletion));
} }
QLineEdit::focusInEvent(event); QLineEdit::focusInEvent(event);
m_button.set_searchMode(true); set_searchMode(true);
} }
void SearchBar::focusOutEvent(QFocusEvent* event) void SearchBar::focusOutEvent(QFocusEvent* event)
{ {
setReadOnly(true); setReadOnly(true);
if (event->reason() == Qt::MouseFocusReason && text().isEmpty()) { if (event->reason() == Qt::MouseFocusReason && text().isEmpty()) {
m_button.set_searchMode(false); set_searchMode(false);
setText(m_title); setText(m_title);
} }
deselect(); deselect();

View File

@ -5,23 +5,10 @@
#include <QStringListModel> #include <QStringListModel>
#include <QCompleter> #include <QCompleter>
#include <QIcon> #include <QIcon>
#include <QPushButton>
#include <QUrl> #include <QUrl>
#include <QTimer> #include <QTimer>
#include <QThread> #include <QThread>
class SearchButton : public QPushButton {
Q_OBJECT
public:
SearchButton(QWidget *parent = nullptr);
public slots:
void set_searchMode(bool searchMode);
void on_buttonClicked();
protected:
bool m_searchMode;
};
class SearchBar : public QLineEdit class SearchBar : public QLineEdit
{ {
@ -41,17 +28,20 @@ private:
QStringListModel m_completionModel; QStringListModel m_completionModel;
QCompleter m_completer; QCompleter m_completer;
QVector<QUrl> m_urlList; QVector<QUrl> m_urlList;
SearchButton m_button; QAction *m_action;
QString m_title; QString m_title;
QString m_searchbarInput; QString m_searchbarInput;
bool m_returnPressed = false; bool m_returnPressed = false;
QTimer* mp_typingTimer; QTimer* mp_typingTimer;
int m_token; int m_token;
void set_searchMode(bool searchMode);
bool m_searchMode;
private slots: private slots:
void updateCompletion(); void updateCompletion();
void openCompletion(const QModelIndex& index); void openCompletion(const QModelIndex& index);
void openCompletion(const QString& text, int index); void openCompletion(const QString& text, int index);
void on_action_triggered();
}; };
#endif // SEARCHBAR_H #endif // SEARCHBAR_H