Navigate through choices using up,down keys

This change allows one to navigate through the choices using up and down arrow keys from keyboard
Enter/Return key can be pressed to select the current item
This commit is contained in:
Nikhil Tanwar 2023-08-19 12:21:41 +05:30 committed by Matthieu Gautier
parent 146705ba93
commit b3a0542ba7
8 changed files with 184 additions and 13 deletions

View File

@ -45,6 +45,7 @@ SOURCES += \
src/kiwixchoicebox.cpp \
src/kiwixconfirmbox.cpp \
src/kiwixlineedit.cpp \
src/kiwixlistwidget.cpp \
src/kiwixloader.cpp \
src/rownode.cpp \
src/suggestionlistworker.cpp \
@ -90,6 +91,7 @@ HEADERS += \
src/kiwixchoicebox.h \
src/kiwixconfirmbox.h \
src/kiwixlineedit.h \
src/kiwixlistwidget.h \
src/kiwixloader.h \
src/node.h \
src/rownode.h \

View File

@ -1,5 +1,4 @@
QListWidget::item {
color: #666666;
padding: 0;
padding-top: 6px;
padding-bottom: 6px;
@ -16,11 +15,6 @@ QListWidget::item::selected {
background-color: transparent;
}
QListWidget::item::hover {
color: white;
background-color: #4e63ad;
}
QLineEdit {
padding: 4px;
border: 0;

View File

@ -11,6 +11,7 @@
#include <QAbstractItemView>
#include <QScrollBar>
#include "kiwixlineedit.h"
#include "kiwixlistwidget.h"
KiwixChoiceBox::KiwixChoiceBox(QWidget *parent) :
QWidget(parent),
@ -28,7 +29,7 @@ KiwixChoiceBox::KiwixChoiceBox(QWidget *parent) :
choiceLabel = ui->choiceLabel;
choiceLabel->setText(gt("undefined"));
choiceSelector = new QListWidget(parent);
choiceSelector = new KiwixListWidget(parent);
choiceSelector->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
choiceSelector->setMaximumWidth(250);
choiceSelector->setMaximumHeight(200);
@ -110,6 +111,12 @@ void KiwixChoiceBox::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape) {
searcher->clearFocus();
} else if (event->key() == Qt::Key_Down) {
choiceSelector->moveDown();
} else if (event->key() == Qt::Key_Up) {
choiceSelector->moveUp();
} else if ((event->key() == Qt::Key_Enter) || (event->key() == Qt::Key_Return)) {
choiceSelector->selectCurrent();
}
}

View File

@ -14,6 +14,7 @@
class ChoiceItem;
class KiwixLineEdit;
class KiwixListWidget;
namespace Ui {
class kiwixchoicebox;
@ -43,7 +44,7 @@ private:
Ui::kiwixchoicebox *ui;
QLabel *choiceLabel;
QLineEdit *choiceSearch;
QListWidget *choiceSelector;
KiwixListWidget *choiceSelector;
FlowLayout *currentChoicesLayout;
KiwixLineEdit *searcher;
QStringList getCurrentSelected();

108
src/kiwixlistwidget.cpp Normal file
View File

@ -0,0 +1,108 @@
#include "kiwixlistwidget.h"
#include <QKeyEvent>
#include <QToolTip>
#include <QCursor>
#include <QDebug>
#include "kiwixapp.h"
#include "klistwidgetitem.h"
KiwixListWidget::KiwixListWidget(QWidget *parent)
: QListWidget(parent), currRow(0), m_visibleItems(count())
{
connect(this, &KiwixListWidget::currRowChanged, this, &KiwixListWidget::handleCurrRowChange);
setMouseTracking(true);
}
void KiwixListWidget::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
selectCurrent(item(m_mouseIndex));
}
}
void KiwixListWidget::mouseMoveEvent(QMouseEvent *event)
{
int oldRow = currRow;
m_mouseIndex = row(itemAt(event->pos()));
currRow = m_mouseIndex;
emit(currRowChanged(oldRow, currRow));
}
void KiwixListWidget::hideEvent(QHideEvent *event)
{
auto currItem = dynamic_cast<KListWidgetItem*>(item(currRow));
if (currItem)
currItem->disableHighlight();
QListWidget::hideEvent(event);
}
void KiwixListWidget::resizeEvent(QResizeEvent *e)
{
int oldRow = currRow;
for (auto i = 0; i < count(); i++) {
auto itemAtRow = item(i);
if (!itemAtRow->isHidden() && !itemAtRow->isSelected()) {
currRow = i;
break;
}
}
emit(currRowChanged(oldRow, currRow));
QListWidget::resizeEvent(e);
}
void KiwixListWidget::handleCurrRowChange(int oldRow, int newRow)
{
auto prevItem = dynamic_cast<KListWidgetItem*>(item(oldRow));
if (prevItem) {
prevItem->disableHighlight();
}
auto currItem = dynamic_cast<KListWidgetItem*>(item(newRow));
if (currItem) {
currItem->enableHighlight();
scrollToItem(currItem, QAbstractItemView::EnsureVisible);
}
emit(dataChanged(QModelIndex(), QModelIndex()));
}
void KiwixListWidget::moveUp()
{
if (selectedItems().size() == count())
return;
KListWidgetItem *currItem = dynamic_cast<KListWidgetItem*>(item(currRow));
int oldRow = currRow;
do {
currRow--;
if (currRow < 0) currRow = count() - 1;
currItem = dynamic_cast<KListWidgetItem*>(item(currRow));
} while (currItem->isSelected() || currItem->isHidden());
emit(currRowChanged(oldRow, currRow));
}
void KiwixListWidget::moveDown()
{
if (selectedItems().size() == count())
return;
KListWidgetItem *currItem = dynamic_cast<KListWidgetItem*>(item(currRow));
int oldRow = currRow;
do {
currRow++;
if (currRow == count()) currRow = 0;
currItem = dynamic_cast<KListWidgetItem*>(item(currRow));
} while (currItem->isSelected() || currItem->isHidden());
emit(currRowChanged(oldRow, currRow));
}
void KiwixListWidget::selectCurrent()
{
selectCurrent(item(currRow));
}
void KiwixListWidget::selectCurrent(QListWidgetItem *item)
{
auto currItem = dynamic_cast<KListWidgetItem*>(item);
if (currItem && !currItem->isSelected() && !currItem->isHidden()) {
currItem->disableHighlight();
currItem->setSelected(!currItem->isSelected());
emit(itemPressed(currItem));
}
}

36
src/kiwixlistwidget.h Normal file
View File

@ -0,0 +1,36 @@
#ifndef KIWIXLISTWIDGET_H
#define KIWIXLISTWIDGET_H
#include <QListWidget>
class KiwixListWidget : public QListWidget {
Q_OBJECT
public:
KiwixListWidget(QWidget *parent = nullptr);
void moveUp();
void moveDown();
void selectCurrent();
void selectCurrent(QListWidgetItem *item);
void setVisibleItems(int visibleItems) { m_visibleItems = visibleItems; }
int getVisibleItems() { return m_visibleItems; }
protected:
void hideEvent(QHideEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
signals:
void currRowChanged(int oldRow, int newRow);
private slots:
void handleCurrRowChange(int oldRow, int newRow);
private:
int currRow;
int m_visibleItems;
int m_mouseIndex;
};
#endif // KIWIXLISTWIDGET_H

View File

@ -6,16 +6,36 @@ KListWidgetItem::KListWidgetItem(QString text)
: QListWidgetItem (text)
{
setSizeHint(QSize(200, m_itemHeight));
setBackground(QColor("white"));
setForeground(QColor("#666666"));
}
void KListWidgetItem::disableHighlight()
{
isHighlighted = false;
}
void KListWidgetItem::enableHighlight()
{
isHighlighted = true;
}
QVariant KListWidgetItem::data(int role) const
{
QVariant v = QListWidgetItem::data(role);
if( isSelected() && role == Qt::FontRole )
{
QFont font = v.value<QFont>();
font.setBold( true );
v = QVariant::fromValue<QFont>( font );
if( isSelected()) {
if (role == Qt::FontRole) {
QFont font = v.value<QFont>();
font.setBold( true );
v = QVariant::fromValue<QFont>( font );
}
}
if (isHighlighted) {
if (role == Qt::BackgroundRole) {
v = QVariant::fromValue(QColor("#4e63ad"));
} else if (role == Qt::ForegroundRole) {
v = QVariant::fromValue(QColor("white"));
}
}
return v;
}

View File

@ -9,8 +9,11 @@ public:
KListWidgetItem(QString text);
QVariant data(int role) const;
static int getItemHeight() { return m_itemHeight; };
void disableHighlight();
void enableHighlight();
private:
static int m_itemHeight;
bool isHighlighted = false;
};
#endif // KLISTWIDGETITEM_H