ui: Keyboard controls (#935)

* switch focus between views with Tab
* move focus within views with WASD/HJKL/Arrows
* move focus between graph edges by holding Shift
* move focus between code references by holding Shift
* removed graph panning with WASD and moved zooming to Alt + W/S
* removed graph navigation by pressing starting character in graph view lists
* changed local reference and custom trail shortcuts
* updated Keyboard Shortcuts window
* use common back and forward shortcuts and YZ & Shift + YZ
* fix macOS issue where widgets don't get proper focus after creating a new tab
* don't use shared_ptr in QtMainView

fixes #486, #327, #214, #210
This commit is contained in:
Eberhard Gräther
2020-03-02 14:48:03 +01:00
committed by GitHub
parent f4b37f9763
commit b0616778f3
98 changed files with 4204 additions and 863 deletions
+93 -13
View File
@@ -7,8 +7,8 @@
#include <QGraphicsSceneEvent>
#include <QPen>
#include "GraphFocusHandler.h"
#include "MessageCodeShowDefinition.h"
#include "MessageGraphNodeExpand.h"
#include "MessageGraphNodeHide.h"
#include "MessageGraphNodeMove.h"
#include "QtDeviceScaledPixmap.h"
@@ -40,7 +40,26 @@ void QtGraphNode::hideNode()
this->hide();
}
QtGraphNode::QtGraphNode()
QtGraphNode* QtGraphNode::findNodeRecursive(const std::list<QtGraphNode*>& nodes, Id tokenId)
{
for (QtGraphNode* node: nodes)
{
if (node->getTokenId() == tokenId)
{
return node;
}
QtGraphNode* result = findNodeRecursive(node->getSubNodes(), tokenId);
if (result != nullptr)
{
return result;
}
}
return nullptr;
}
QtGraphNode::QtGraphNode(GraphFocusHandler* focusHandler): m_focusHandler(focusHandler)
{
this->setPen(QPen(Qt::transparent));
this->setCursor(Qt::PointingHandCursor);
@@ -208,6 +227,11 @@ bool QtGraphNode::hasActiveChild() const
return false;
}
bool QtGraphNode::isFocusable() const
{
return m_isInteractive && (isDataNode() || isGroupNode() || isBundleNode());
}
std::wstring QtGraphNode::getName() const
{
return m_text->text().toStdWString();
@@ -234,28 +258,84 @@ void QtGraphNode::hoverEnter()
}
}
bool QtGraphNode::getIsFocused() const
{
return m_isFocused;
}
void QtGraphNode::setIsFocused(bool focused)
{
if (m_isFocused != focused)
{
m_isFocused = focused;
if (focused)
{
coFocusIn();
}
else
{
coFocusOut();
}
}
}
void QtGraphNode::focusIn()
{
m_isHovering = true;
if (m_isInteractive && m_focusHandler)
{
m_focusHandler->focusNode(this);
}
else
{
coFocusIn();
}
}
void QtGraphNode::focusOut()
{
if (m_isInteractive && m_focusHandler)
{
m_focusHandler->defocusNode(this);
}
else
{
coFocusOut();
}
}
void QtGraphNode::coFocusIn()
{
if (m_isCoFocused)
{
return;
}
m_isCoFocused = true;
forEachEdge([](QtGraphEdge* edge) {
if (edge->isTrailEdge())
{
edge->focusIn();
edge->coFocusIn();
}
});
updateStyle();
}
void QtGraphNode::focusOut()
void QtGraphNode::coFocusOut()
{
m_isHovering = false;
if (!m_isCoFocused)
{
return;
}
m_isCoFocused = false;
forEachEdge([](QtGraphEdge* edge) {
if (edge->isTrailEdge())
{
edge->focusOut();
edge->coFocusOut();
}
});
@@ -390,23 +470,23 @@ void QtGraphNode::onHide()
}
}
void QtGraphNode::onCollapseExpand()
Id QtGraphNode::onCollapseExpand()
{
for (auto subNode: getSubNodes())
{
if (subNode->isExpandToggleNode())
{
MessageGraphNodeExpand(
getTokenId(), !dynamic_cast<QtGraphNodeExpandToggle*>(subNode)->isExpanded())
.dispatch();
return;
subNode->onClick();
return getTokenId();
}
}
if (getParent())
{
getParent()->onCollapseExpand();
return getParent()->onCollapseExpand();
}
return 0;
}
void QtGraphNode::onShowDefinition(bool inIDE)