ui: bidirectional hovering

hovering for graphview and codeview via messaging, hovering in one view will "hover" the equivalent in the other view
This commit is contained in:
Andreas Stallinger
2015-05-12 13:55:23 +02:00
parent 97345cc72f
commit a41c0e1b85
25 changed files with 302 additions and 10 deletions
+34 -6
View File
@@ -8,6 +8,8 @@
#include "utility/messaging/type/MessageActivateTokenLocation.h"
#include "utility/messaging/type/MessageShowFile.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "data/location/TokenLocation.h"
#include "data/location/TokenLocationFile.h"
@@ -47,7 +49,8 @@ QtCodeArea::QtCodeArea(
, m_parent(parent)
, m_maximizeButton(nullptr)
, m_startLineNumber(startLineNumber)
, m_hoveredAnnotation(nullptr)
, m_focusedTokenId(0)
, m_isFocused(false)
, m_digits(0)
{
setObjectName("code_area");
@@ -193,7 +196,12 @@ void QtCodeArea::leaveEvent(QEvent* event)
m_maximizeButton->setEnabled(false);
}
m_hoveredAnnotation = nullptr;
if(m_isFocused)
{
MessageFocusOut(m_focusedTokenId).dispatch();
}
m_isFocused = false;
annotateText();
}
@@ -227,11 +235,19 @@ void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
if (annotation && annotation->isScope)
{
annotation = nullptr;
MessageFocusOut(m_focusedTokenId).dispatch();
}
if (annotation != m_hoveredAnnotation)
if (annotation && annotation->tokenId != m_focusedTokenId)
{
m_hoveredAnnotation = annotation;
if(m_isFocused)
{
MessageFocusOut(m_focusedTokenId).dispatch();
}
m_focusedTokenId = annotation->tokenId;
m_isFocused = true;
MessageFocusIn(m_focusedTokenId).dispatch();
const std::vector<std::string>& errorMessages = m_parent->getErrorMessages();
@@ -362,11 +378,11 @@ void QtCodeArea::annotateText()
{
bool isActive = std::find(ids.begin(), ids.end(), annotation.tokenId) != ids.end();
if (&annotation == m_hoveredAnnotation && errorMessages.size())
if (annotation.tokenId == m_focusedTokenId && errorMessages.size())
{
color = Colori(255, 0, 0, 128);
}
else if (&annotation == m_hoveredAnnotation)
else if(annotation.tokenId == m_focusedTokenId)
{
color = ApplicationSettings::getInstance()->getCodeActiveLinkColor();
}
@@ -436,3 +452,15 @@ int QtCodeArea::endTextEditPosition() const
return position - 1;
}
void QtCodeArea::focusToken(Id tokenId)
{
m_focusedTokenId = tokenId;
annotateText();
}
void QtCodeArea::defocusToken()
{
m_focusedTokenId = -1;
annotateText();
}
+5
View File
@@ -57,6 +57,9 @@ public:
void update();
void focusToken(Id tokenId);
void defocusToken();
protected:
virtual void resizeEvent(QResizeEvent *event);
virtual void showEvent(QShowEvent* event);
@@ -103,6 +106,8 @@ private:
std::vector<Annotation> m_annotations;
const Annotation* m_hoveredAnnotation;
Id m_focusedTokenId;
bool m_isFocused;
int m_digits;
};
+16
View File
@@ -102,3 +102,19 @@ void QtCodeFile::clickedTitle()
{
MessageShowFile(m_filePath.absoluteStr(), 0, 0).dispatch();
}
void QtCodeFile::focusToken(Id tokenId)
{
for (std::shared_ptr<QtCodeSnippet> snippet : m_snippets)
{
snippet->focusToken(tokenId);
}
}
void QtCodeFile::defocusToken()
{
for (std::shared_ptr<QtCodeSnippet> snippet : m_snippets)
{
snippet->defocusToken();
}
}
+2
View File
@@ -37,6 +37,8 @@ public:
);
void update();
void focusToken(Id tokenId);
void defocusToken();
private slots:
void clickedTitle();
+16
View File
@@ -110,3 +110,19 @@ void QtCodeFileList::updateFiles()
file->update();
}
}
void QtCodeFileList::focusToken(Id tokenId)
{
for (std::shared_ptr<QtCodeFile> file: m_files)
{
file->focusToken(tokenId);
}
}
void QtCodeFileList::defocusToken()
{
for (std::shared_ptr<QtCodeFile> file: m_files)
{
file->defocusToken();
}
}
+3
View File
@@ -40,6 +40,9 @@ public:
bool getShowMaximizeButton() const;
void setShowMaximizeButton(bool show);
void focusToken(Id tokenId);
void defocusToken();
private:
void updateFiles();
+10
View File
@@ -57,3 +57,13 @@ void QtCodeSnippet::update()
{
m_codeArea->update();
}
void QtCodeSnippet::focusToken(Id tokenId)
{
m_codeArea->focusToken(tokenId);
}
void QtCodeSnippet::defocusToken()
{
m_codeArea->defocusToken();
}
+3
View File
@@ -33,6 +33,9 @@ public:
void updateLineNumberAreaWidthForDigits(int digits);
void update();
void focusToken(Id tokenId);
void defocusToken();
private:
QtCodeFile* m_parent; // need this?
QPushButton* m_title;
+22
View File
@@ -12,6 +12,8 @@ QtCodeView::QtCodeView(ViewLayout* viewLayout)
, m_refreshViewFunctor(std::bind(&QtCodeView::doRefreshView, this))
, m_showCodeSnippetsFunctor(std::bind(&QtCodeView::doShowCodeSnippets, this, std::placeholders::_1))
, m_showCodeFileFunctor(std::bind(&QtCodeView::doShowCodeFile, this, std::placeholders::_1))
, m_focusTokenFunctor(std::bind(&QtCodeView::doFocusToken, this, std::placeholders::_1))
, m_defocusTokenFunctor(std::bind(&QtCodeView::doDefocusToken, this))
{
m_widget = new QtCodeFileList();
setStyleSheet(m_widget);
@@ -137,3 +139,23 @@ void QtCodeView::clearClosedWindows()
}
}
}
void QtCodeView::focusToken(const Id tokenId)
{
m_focusTokenFunctor(tokenId);
}
void QtCodeView::defocusToken()
{
m_defocusTokenFunctor();
}
void QtCodeView::doFocusToken(const Id tokenId)
{
m_widget->focusToken(tokenId);
}
void QtCodeView::doDefocusToken()
{
m_widget->defocusToken();
}
+7
View File
@@ -30,10 +30,15 @@ public:
virtual void showCodeSnippets(const std::vector<CodeSnippetParams>& snippets);
virtual void showCodeFile(const CodeSnippetParams& params);
virtual void focusToken(const Id tokenId);
virtual void defocusToken();
private:
void doRefreshView();
void doShowCodeSnippets(const std::vector<CodeSnippetParams>& snippets);
void doShowCodeFile(const CodeSnippetParams& params);
void doFocusToken(const Id tokenId);
void doDefocusToken();
std::shared_ptr<QtCodeFileList> createQtCodeFileList() const;
@@ -43,6 +48,8 @@ private:
QtThreadedFunctor<> m_refreshViewFunctor;
QtThreadedFunctor<const std::vector<CodeSnippetParams>&> m_showCodeSnippetsFunctor;
QtThreadedFunctor<const CodeSnippetParams&> m_showCodeFileFunctor;
QtThreadedFunctor<const Id&> m_focusTokenFunctor;
QtThreadedFunctor<> m_defocusTokenFunctor;
QtCodeFileList* m_widget;
std::vector<std::shared_ptr<QtCodeFileList>> m_windows;
+49
View File
@@ -25,6 +25,9 @@ QtGraphView::QtGraphView(ViewLayout* viewLayout)
std::bind(&QtGraphView::doRebuildGraph, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3))
, m_clearFunctor(std::bind(&QtGraphView::doClear, this))
, m_resizeFunctor(std::bind(&QtGraphView::doResize, this))
, m_focusInFunctor(std::bind(&QtGraphView::doFocusIn, this, std::placeholders::_1))
, m_focusOutFunctor(std::bind(&QtGraphView::doFocusOut, this, std::placeholders::_1))
{
}
@@ -494,3 +497,49 @@ void QtGraphView::createTransition()
connect(m_transition.get(), SIGNAL(finished()), this, SLOT(finishedTransition()));
m_transition->start();
}
void QtGraphView::focusToken(Id tokenId)
{
m_focusInFunctor(tokenId);
}
void QtGraphView::doFocusIn(Id tokenId)
{
std::shared_ptr<QtGraphNode> node = findNodeRecursive(m_oldNodes, tokenId);
if(node)
{
node->focusIn();
return;
}
for(std::shared_ptr<QtGraphEdge> edge : m_oldEdges)
{
if(edge->getData()->getId() == tokenId)
{
edge->focusIn();
return;
}
}
}
void QtGraphView::defocusToken(Id tokenId)
{
m_focusOutFunctor(tokenId);
}
void QtGraphView::doFocusOut(Id tokenId)
{
std::shared_ptr<QtGraphNode> node = findNodeRecursive(m_oldNodes, tokenId);
if(node)
{
node->focusOut();
return;
}
for(std::shared_ptr<QtGraphEdge> edge : m_oldEdges)
{
if(edge->getData()->getId() == tokenId)
{
edge->focusOut();
return;
}
}
}
+7
View File
@@ -35,6 +35,9 @@ public:
virtual void rebuildGraph(std::shared_ptr<Graph> graph, const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
virtual void clear();
virtual void focusToken(Id tokenId);
virtual void defocusToken(Id tokenId);
virtual void resizeView();
virtual Vec2i getViewSize() const;
@@ -50,6 +53,8 @@ private:
void doRebuildGraph(std::shared_ptr<Graph> graph, const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges);
void doClear();
void doResize();
void doFocusIn(Id tokenId);
void doFocusOut(Id tokeId);
std::shared_ptr<QtGraphNode> findNodeRecursive(const std::list<std::shared_ptr<QtGraphNode>>& nodes, Id tokenId);
@@ -72,6 +77,8 @@ private:
QtThreadedFunctor<std::shared_ptr<Graph>, const std::vector<DummyNode>&, const std::vector<DummyEdge>&> m_rebuildGraphFunctor;
QtThreadedFunctor<void> m_clearFunctor;
QtThreadedFunctor<void> m_resizeFunctor;
QtThreadedFunctor<Id> m_focusInFunctor;
QtThreadedFunctor<Id> m_focusOutFunctor;
std::shared_ptr<Graph> m_graph;
std::shared_ptr<Graph> m_oldGraph;
+14 -2
View File
@@ -5,6 +5,8 @@
#include <QPen>
#include "utility/messaging/type/MessageActivateTokens.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "component/view/graphElements/GraphNode.h"
#include "component/view/GraphViewStyle.h"
@@ -137,13 +139,23 @@ void QtGraphEdge::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
}
void QtGraphEdge::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
MessageFocusIn(getData()->getId()).dispatch();
}
void QtGraphEdge::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
MessageFocusOut(getData()->getId()).dispatch();
}
void QtGraphEdge::focusIn()
{
bool isActive = m_isActive;
this->setIsActive(true);
m_isActive = isActive;
}
void QtGraphEdge::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
void QtGraphEdge::focusOut()
{
this->setIsActive(m_isActive);
}
}
@@ -33,6 +33,9 @@ public:
void onClick();
void focusIn();
void focusOut();
protected:
virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
virtual void mouseMoveEvent(QGraphicsSceneMouseEvent* event);
+19 -1
View File
@@ -6,6 +6,8 @@
#include "utility/messaging/type/MessageActivateTokens.h"
#include "utility/messaging/type/MessageGraphNodeMove.h"
#include "utility/messaging/type/MessageFocusIn.h";
#include "utility/messaging/type/MessageFocusOut.h";
#include "qt/graphics/QtRoundedRectItem.h"
#include "qt/utility/QtDeviceScaledPixmap.h"
@@ -332,12 +334,28 @@ void QtGraphNode::mouseReleaseEvent(QGraphicsSceneMouseEvent* event)
}
void QtGraphNode::hoverEnterEvent(QGraphicsSceneHoverEvent* event)
{
if(m_data)
{
MessageFocusIn(m_data->getId()).dispatch();
}
}
void QtGraphNode::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
{
if(m_data)
{
MessageFocusOut(m_data->getId()).dispatch();
}
}
void QtGraphNode::focusIn()
{
m_isHovering = true;
updateStyle();
}
void QtGraphNode::hoverLeaveEvent(QGraphicsSceneHoverEvent* event)
void QtGraphNode::focusOut()
{
m_isHovering = false;
updateStyle();
@@ -6,6 +6,7 @@
#include "component/view/graphElements/GraphNode.h"
#include "component/view/GraphViewStyle.h"
#include "utility/messaging/MessageListener.h"
class QtGraphEdge;
class QtRoundedRectItem;
@@ -76,6 +77,9 @@ public:
virtual void onClick();
void hoverEnter();
void focusIn();
void focusOut();
virtual void updateStyle();
protected:
+2
View File
@@ -253,6 +253,8 @@ add_files(
utility/messaging/type/MessageAutoRefreshChanged.h
utility/messaging/type/MessageFind.h
utility/messaging/type/MessageFinishedParsing.h
utility/messaging/type/MessageFocusIn.h
utility/messaging/type/MessageFocusOut.h
utility/messaging/type/MessageGraphNodeExpand.h
utility/messaging/type/MessageGraphNodeMove.h
utility/messaging/type/MessageInterruptTasks.h
@@ -70,6 +70,16 @@ void CodeController::handleMessage(MessageFinishedParsing* message)
}
}
void CodeController::handleMessage(MessageFocusIn* message)
{
getView()->focusToken(message->tokenId);
}
void CodeController::handleMessage(MessageFocusOut* message)
{
getView()->defocusToken();
}
void CodeController::handleMessage(MessageRefresh* message)
{
getView()->refreshView();
@@ -183,7 +193,7 @@ std::vector<CodeView::CodeSnippetParams> CodeController::getSnippetsForFile(std:
std::shared_ptr<TokenLocationFile> tempFile = m_storageAccess->getTokenLocationsForLinesInFile(file->getFilePath().str(), params.startLineNumber, params.endLineNumber);
TokenLocationLine* firstUsedLine = nullptr;
for (rsize_t i = params.startLineNumber; i <= params.endLineNumber, firstUsedLine == nullptr; i++)
for (size_t i = params.startLineNumber; i <= params.endLineNumber, firstUsedLine == nullptr; i++)
{
firstUsedLine = tempFile->findTokenLocationLineByNumber(i);
}
@@ -11,6 +11,8 @@
#include "utility/messaging/type/MessageActivateTokenLocation.h"
#include "utility/messaging/type/MessageActivateTokens.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "utility/messaging/type/MessageRefresh.h"
#include "utility/messaging/type/MessageShowFile.h"
#include "utility/types.h"
@@ -23,6 +25,8 @@ class CodeController
, public MessageListener<MessageActivateTokenLocation>
, public MessageListener<MessageActivateTokens>
, public MessageListener<MessageFinishedParsing>
, public MessageListener<MessageFocusIn>
, public MessageListener<MessageFocusOut>
, public MessageListener<MessageRefresh>
, public MessageListener<MessageShowFile>
{
@@ -36,6 +40,8 @@ private:
virtual void handleMessage(MessageActivateTokenLocation* message);
virtual void handleMessage(MessageActivateTokens* message);
virtual void handleMessage(MessageFinishedParsing* message);
virtual void handleMessage(MessageFocusIn* message);
virtual void handleMessage(MessageFocusOut* message);
virtual void handleMessage(MessageRefresh* message);
virtual void handleMessage(MessageShowFile* message);
@@ -51,6 +51,18 @@ void GraphController::handleMessage(MessageFinishedParsing* message)
getView()->clear();
}
#include <iostream>
void GraphController::handleMessage(MessageFocusIn* message)
{
getView()->focusToken(message->tokenId);
}
void GraphController::handleMessage(MessageFocusOut *message)
{
getView()->defocusToken(message->tokenId);
}
void GraphController::handleMessage(MessageGraphNodeExpand* message)
{
DummyNode* node = findDummyNodeRecursive(m_dummyNodes, message->tokenId);
@@ -6,6 +6,8 @@
#include "utility/messaging/MessageListener.h"
#include "utility/messaging/type/MessageActivateTokens.h"
#include "utility/messaging/type/MessageFinishedParsing.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "utility/messaging/type/MessageGraphNodeExpand.h"
#include "utility/messaging/type/MessageGraphNodeMove.h"
@@ -24,6 +26,8 @@ class GraphController
: public Controller
, public MessageListener<MessageActivateTokens>
, public MessageListener<MessageFinishedParsing>
, public MessageListener<MessageFocusIn>
, public MessageListener<MessageFocusOut>
, public MessageListener<MessageGraphNodeExpand>
, public MessageListener<MessageGraphNodeMove>
{
@@ -34,6 +38,8 @@ public:
private:
virtual void handleMessage(MessageActivateTokens* message);
virtual void handleMessage(MessageFinishedParsing* message);
virtual void handleMessage(MessageFocusIn* message);
virtual void handleMessage(MessageFocusOut* message);
virtual void handleMessage(MessageGraphNodeExpand* message);
virtual void handleMessage(MessageGraphNodeMove* message);
+3
View File
@@ -43,6 +43,9 @@ public:
virtual void showCodeSnippets(const std::vector<CodeSnippetParams>& snippets) = 0;
virtual void showCodeFile(const CodeSnippetParams& params) = 0;
virtual void focusToken(const Id tokenId) = 0;
virtual void defocusToken() = 0;
private:
CodeController* getController();
};
+2
View File
@@ -24,6 +24,8 @@ public:
virtual void rebuildGraph(
std::shared_ptr<Graph> graph, const std::vector<DummyNode>& nodes, const std::vector<DummyEdge>& edges) = 0;
virtual void clear() = 0;
virtual void focusToken(Id tokenId) = 0;
virtual void defocusToken(Id tokenId) = 0;
virtual void resizeView() = 0;
@@ -0,0 +1,23 @@
#ifndef MESSAGE_FOCUS_IN_H
#define MESSAGE_FOCUS_IN_H
#include "utility/messaging/Message.h"
#include "utility/types.h"
class MessageFocusIn : public Message<MessageFocusIn>
{
public:
MessageFocusIn(Id tokenId)
: tokenId(tokenId)
{
}
static const std::string getStaticType()
{
return "MessageFocusIn";
}
const Id tokenId;
};
#endif //MESSAGE_FOCUS_IN_H
@@ -0,0 +1,23 @@
#ifndef MESSAGE_FOCUS_OUT_H
#define MESSAGE_FOCUS_OUT_H
#include "utility/messaging/Message.h"
#include "utility/types.h"
class MessageFocusOut : public Message<MessageFocusOut>
{
public:
MessageFocusOut(Id tokenId)
: tokenId(tokenId)
{
}
static const std::string getStaticType()
{
return "MessageHoverLeave";
}
const Id tokenId;
};
#endif //MESSAGE_FOCUS_OUT_H