From 9b730c2889c09eed0dea2ad22ab07d39ea454367 Mon Sep 17 00:00:00 2001 From: Le Tan Date: Sun, 12 Nov 2017 13:59:23 +0800 Subject: [PATCH] VToolBox: support Navigation mode --- src/vmainwindow.cpp | 1 + src/vsnippetlist.cpp | 11 ++++++ src/vsnippetlist.h | 3 ++ src/vtoolbox.cpp | 82 +++++++++++++++++++++++++++++++++++++++++--- src/vtoolbox.h | 10 +++++- 5 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/vmainwindow.cpp b/src/vmainwindow.cpp index b254ab7c..9878c036 100644 --- a/src/vmainwindow.cpp +++ b/src/vmainwindow.cpp @@ -112,6 +112,7 @@ void VMainWindow::registerCaptainAndNavigationTargets() m_captain->registerNavigationTarget(directoryTree); m_captain->registerNavigationTarget(m_fileList); m_captain->registerNavigationTarget(editArea); + m_captain->registerNavigationTarget(m_toolBox); m_captain->registerNavigationTarget(outline); m_captain->registerNavigationTarget(m_snippetList); diff --git a/src/vsnippetlist.cpp b/src/vsnippetlist.cpp index 171a1627..a2b49a7b 100644 --- a/src/vsnippetlist.cpp +++ b/src/vsnippetlist.cpp @@ -604,3 +604,14 @@ bool VSnippetList::deleteSnippetFile(const VSnippet &p_snippet, QString *p_errMs return true; } + +void VSnippetList::focusInEvent(QFocusEvent *p_event) +{ + QWidget::focusInEvent(p_event); + + if (m_snippets.isEmpty()) { + m_addBtn->setFocus(); + } else { + m_snippetList->setFocus(); + } +} diff --git a/src/vsnippetlist.h b/src/vsnippetlist.h index aef5463f..9bdbc1f8 100644 --- a/src/vsnippetlist.h +++ b/src/vsnippetlist.h @@ -14,6 +14,7 @@ class QListWidgetItem; class QLabel; class QAction; class QKeyEvent; +class QFocusEvent; class VSnippetList : public QWidget, public VNavigationMode @@ -29,6 +30,8 @@ public: protected: void keyPressEvent(QKeyEvent *p_event) Q_DECL_OVERRIDE; + void focusInEvent(QFocusEvent *p_event) Q_DECL_OVERRIDE; + private slots: void newSnippet(); diff --git a/src/vtoolbox.cpp b/src/vtoolbox.cpp index 6e424539..15e595a0 100644 --- a/src/vtoolbox.cpp +++ b/src/vtoolbox.cpp @@ -5,7 +5,12 @@ #include #include #include +#include +#include "vnote.h" +#include "utils/vutils.h" + +extern VNote *g_vnote; VToolBox::VToolBox(QWidget *p_parent) : QWidget(p_parent), @@ -64,10 +69,6 @@ int VToolBox::addItem(QWidget *p_widget, const QIcon &p_iconSet, const QString & void VToolBox::setCurrentIndex(int p_idx) { - if (m_currentIndex == p_idx) { - return; - } - if (p_idx < 0 || p_idx >= m_items.size()) { m_currentIndex = -1; } else { @@ -77,6 +78,24 @@ void VToolBox::setCurrentIndex(int p_idx) setCurrentButtonIndex(m_currentIndex); m_widgetLayout->setCurrentIndex(m_currentIndex); + + QWidget *widget = m_widgetLayout->widget(m_currentIndex); + if (widget) { + widget->setFocus(); + } +} + +void VToolBox::setCurrentWidget(QWidget *p_widget) +{ + int idx = -1; + for (int i = 0; i < m_items.size(); ++i) { + if (m_items[i].m_widget == p_widget) { + idx = i; + break; + } + } + + setCurrentIndex(idx); } void VToolBox::setCurrentButtonIndex(int p_idx) @@ -94,3 +113,58 @@ void VToolBox::setCurrentButtonIndex(int p_idx) m_items[p_idx].m_btn->setText(m_items[p_idx].m_text); } + +void VToolBox::showNavigation() +{ + clearNavigation(); + + if (!isVisible()) { + return; + } + + for (int i = 0; i < 26 && i < m_items.size(); ++i) { + const ItemInfo &item = m_items[i]; + + QChar key('a' + i); + m_keyMap[key] = item.m_widget; + + QString str = QString(m_majorKey) + key; + QLabel *label = new QLabel(str, this); + label->setStyleSheet(g_vnote->getNavigationLabelStyle(str)); + label->show(); + QRect rect = item.m_btn->geometry(); + // Display the label at the end to show the file name. + label->move(rect.x(), rect.y() + rect.height() / 2); + m_naviLabels.append(label); + } +} + +bool VToolBox::handleKeyNavigation(int p_key, bool &p_succeed) +{ + static bool secondKey = false; + bool ret = false; + p_succeed = false; + QChar keyChar = VUtils::keyToChar(p_key); + if (secondKey && !keyChar.isNull()) { + secondKey = false; + p_succeed = true; + ret = true; + auto it = m_keyMap.find(keyChar); + if (it != m_keyMap.end()) { + QWidget *widget = static_cast(it.value()); + setCurrentWidget(widget); + } + } else if (keyChar == m_majorKey) { + // Major key pressed. + // Need second key if m_keyMap is not empty. + if (m_keyMap.isEmpty()) { + p_succeed = true; + } else { + secondKey = true; + } + + ret = true; + } + + return ret; +} diff --git a/src/vtoolbox.h b/src/vtoolbox.h index 0b23a499..3eae72f8 100644 --- a/src/vtoolbox.h +++ b/src/vtoolbox.h @@ -6,11 +6,13 @@ #include #include +#include "vnavigationmode.h" + class QPushButton; class QStackedLayout; class QBoxLayout; -class VToolBox : public QWidget +class VToolBox : public QWidget, public VNavigationMode { Q_OBJECT public: @@ -20,6 +22,12 @@ public: void setCurrentIndex(int p_idx); + void setCurrentWidget(QWidget *p_widget); + + // Implementations for VNavigationMode. + void showNavigation() Q_DECL_OVERRIDE; + bool handleKeyNavigation(int p_key, bool &p_succeed) Q_DECL_OVERRIDE; + private: struct ItemInfo {