From 4ee6a54d41a4aa53820f3a7fe50ff0d53b3e9ad2 Mon Sep 17 00:00:00 2001 From: albertony <12441419+albertony@users.noreply.github.com> Date: Thu, 21 Jan 2021 16:42:30 +0100 Subject: [PATCH] Enable use of keyboard to modify screens --- ...gui-keyboard-enabled-screen-layout.feature | 1 + src/gui/src/ScreenSetupModel.cpp | 2 +- src/gui/src/ScreenSetupView.cpp | 78 +++++++++++++++++-- src/gui/src/ScreenSetupView.h | 4 + 4 files changed, 78 insertions(+), 7 deletions(-) create mode 100644 doc/newsfragments/gui-keyboard-enabled-screen-layout.feature diff --git a/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature b/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature new file mode 100644 index 0000000000..5ca3019e89 --- /dev/null +++ b/doc/newsfragments/gui-keyboard-enabled-screen-layout.feature @@ -0,0 +1 @@ +Made it possible to use keyboard instead of mouse to modify screen layout. \ No newline at end of file diff --git a/src/gui/src/ScreenSetupModel.cpp b/src/gui/src/ScreenSetupModel.cpp index eed9865c63..405ba22740 100644 --- a/src/gui/src/ScreenSetupModel.cpp +++ b/src/gui/src/ScreenSetupModel.cpp @@ -71,7 +71,7 @@ Qt::ItemFlags ScreenSetupModel::flags(const QModelIndex& index) const if (!screen(index).isNull()) return Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; - return Qt::ItemIsDropEnabled; + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; } Qt::DropActions ScreenSetupModel::supportedDropActions() const diff --git a/src/gui/src/ScreenSetupView.cpp b/src/gui/src/ScreenSetupView.cpp index 5bc796d06a..15795092c6 100644 --- a/src/gui/src/ScreenSetupView.cpp +++ b/src/gui/src/ScreenSetupView.cpp @@ -30,6 +30,7 @@ ScreenSetupView::ScreenSetupView(QWidget* parent) : setDropIndicatorShown(true); setDragDropMode(DragDrop); setSelectionMode(SingleSelection); + setTabKeyNavigation(false); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); @@ -65,18 +66,83 @@ void ScreenSetupView::resizeEvent(QResizeEvent* event) event->ignore(); } +void ScreenSetupView::enter(const QModelIndex& index) +{ + if (!index.isValid()) + return; + Screen& screen = model()->screen(index); + if (screen.isNull()) + screen = Screen(tr("Unnamed")); + ScreenSettingsDialog dlg(this, &screen); + dlg.exec(); +} + +void ScreenSetupView::remove(const QModelIndex& index) +{ + if (!index.isValid()) + return; + Screen& screen = model()->screen(index); + if (!screen.isNull()) { + screen = Screen(); + emit dataChanged(index, index); + } +} + +void ScreenSetupView::keyPressEvent(QKeyEvent* event) +{ + if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Delete) + { + QModelIndexList indexes = selectedIndexes(); + if (indexes.count() == 1 && indexes[0].isValid()) + { + if (event->key() == Qt::Key_Return) + enter(indexes[0]); + else if (event->key() == Qt::Key_Delete) + remove(indexes[0]); + } + // Do not let base handle the event, at least not for return key because it + // results in next esc/return key in the opened Screen Settings dialog not + // only closing that but also the parent Server Configuration dialog. + } + else if ((event->modifiers() & Qt::ControlModifier) + && (event->key() == Qt::Key_Left || event->key() == Qt::Key_Right + || event->key() == Qt::Key_Up || event->key() == Qt::Key_Down)) + { + QModelIndexList indexes = selectedIndexes(); + if (indexes.count() == 1 && indexes[0].isValid()) + { + const QModelIndex& fromIndex = indexes[0]; + QModelIndex toIndex; + + if (event->key() == Qt::Key_Left) + toIndex = fromIndex.sibling(fromIndex.row(), fromIndex.column() - 1); + else if (event->key() == Qt::Key_Right) + toIndex = fromIndex.sibling(fromIndex.row(), fromIndex.column() + 1); + else if (event->key() == Qt::Key_Up) + toIndex = fromIndex.sibling(fromIndex.row() - 1, fromIndex.column()); + else if (event->key() == Qt::Key_Down) + toIndex = fromIndex.sibling(fromIndex.row() + 1, fromIndex.column()); + + if (toIndex.isValid() && fromIndex != toIndex) + std::swap(model()->screen(fromIndex), model()->screen(toIndex)); + } + // In this case let base also handle the event, because it will proceed moving + // the selection to target, update the view according to model changes etc. + QTableView::keyPressEvent(event); + } + else + { + QTableView::keyPressEvent(event); + } +} + void ScreenSetupView::mouseDoubleClickEvent(QMouseEvent* event) { if (event->buttons() & Qt::LeftButton) { int col = columnAt(event->pos().x()); int row = rowAt(event->pos().y()); - - if (!model()->screen(col, row).isNull()) - { - ScreenSettingsDialog dlg(this, &model()->screen(col, row)); - dlg.exec(); - } + enter(model()->createIndex(row, col)); } else event->ignore(); diff --git a/src/gui/src/ScreenSetupView.h b/src/gui/src/ScreenSetupView.h index d1067b81bd..55981c784c 100644 --- a/src/gui/src/ScreenSetupView.h +++ b/src/gui/src/ScreenSetupView.h @@ -44,6 +44,7 @@ class ScreenSetupView : public QTableView protected: void mouseDoubleClickEvent(QMouseEvent*) override; + void keyPressEvent(QKeyEvent*) override; void setTableSize(); void resizeEvent(QResizeEvent*) override; void dragEnterEvent(QDragEnterEvent* event) override; @@ -51,6 +52,9 @@ class ScreenSetupView : public QTableView void startDrag(Qt::DropActions supportedActions) override; QStyleOptionViewItem viewOptions() const override; void scrollTo(const QModelIndex&, ScrollHint) override {} + private: + void enter(const QModelIndex&); + void remove(const QModelIndex&); }; #endif