logic: Return to last scroll position in code view on undo

* fixed scrolling on undo
* refactored autoscrolling in code view
* save scroll position of user with MessageScrollCode
This commit is contained in:
Eberhard Graether
2016-01-29 13:08:30 +01:00
parent 427c94457b
commit ead0abfba2
20 changed files with 240 additions and 91 deletions
@@ -100,7 +100,7 @@ void CodeController::handleMessage(MessageActivateTokens* message)
if (message->isEdge)
{
view->showFirstActiveSnippet(activeTokenIds);
view->showFirstActiveSnippet(activeTokenIds, message->isLast());
}
if (message->keepContent())
@@ -202,6 +202,14 @@ void CodeController::handleMessage(MessageFocusOut* message)
getView()->defocusTokenIds();
}
void CodeController::handleMessage(MessageScrollCode* message)
{
if (!message->isFresh())
{
getView()->scrollToValue(message->value);
}
}
void CodeController::handleMessage(MessageShowErrors* message)
{
std::vector<std::string> errorMessages;
@@ -11,6 +11,7 @@
#include "utility/messaging/type/MessageFlushUpdates.h"
#include "utility/messaging/type/MessageFocusIn.h"
#include "utility/messaging/type/MessageFocusOut.h"
#include "utility/messaging/type/MessageScrollCode.h"
#include "utility/messaging/type/MessageShowErrors.h"
#include "utility/messaging/type/MessageShowScope.h"
#include "utility/types.h"
@@ -31,6 +32,7 @@ class CodeController
, public MessageListener<MessageFlushUpdates>
, public MessageListener<MessageFocusIn>
, public MessageListener<MessageFocusOut>
, public MessageListener<MessageScrollCode>
, public MessageListener<MessageShowErrors>
, public MessageListener<MessageShowScope>
{
@@ -47,6 +49,7 @@ private:
virtual void handleMessage(MessageFlushUpdates* message);
virtual void handleMessage(MessageFocusIn* message);
virtual void handleMessage(MessageFocusOut* message);
virtual void handleMessage(MessageScrollCode* message);
virtual void handleMessage(MessageShowErrors* message);
virtual void handleMessage(MessageShowScope* message);
@@ -188,6 +188,22 @@ void UndoRedoController::handleMessage(MessageRefresh* message)
}
}
void UndoRedoController::handleMessage(MessageScrollCode* message)
{
if (!m_lastCommand.message)
{
return;
}
if (m_lastCommand.subMessage && m_lastCommand.subMessage->getType() == message->getType())
{
static_cast<MessageScrollCode*>(m_lastCommand.subMessage.get())->value = message->value;
return;
}
m_lastCommand.subMessage = std::make_shared<MessageScrollCode>(*message);
}
void UndoRedoController::handleMessage(MessageSearch* message)
{
if (m_lastCommand.message && m_lastCommand.message->getType() == message->getType() &&
@@ -228,12 +244,19 @@ void UndoRedoController::replayCommands(bool removeLast)
{
m = m_undo[i].message;
m->undoRedoType = MessageBase::UNDOTYPE_IGNORE;
m->setIsLast(false);
m->dispatch();
i++;
}
m = m_undo.back().message;
std::shared_ptr<MessageBase> sm;
if (m_lastCommand.order == 0)
{
sm = m_undo.back().subMessage;
}
if (removeLast)
{
m_undo.pop_back();
@@ -244,12 +267,25 @@ void UndoRedoController::replayCommands(bool removeLast)
m->undoRedoType = MessageBase::UNDOTYPE_IGNORE;
}
m->setIsLast(!sm);
m->dispatch();
if (sm)
{
sm->undoRedoType = MessageBase::UNDOTYPE_IGNORE;
sm->setIsLast(true);
sm->dispatch();
}
}
}
void UndoRedoController::processCommand(const Command& command)
void UndoRedoController::processCommand(Command command)
{
if (command.order == 0 && command.message->keepContent())
{
command.order = 1;
}
switch (command.message->undoRedoType)
{
case MessageBase::UNDOTYPE_NORMAL:
@@ -17,6 +17,7 @@
#include "utility/messaging/type/MessageLoadProject.h"
#include "utility/messaging/type/MessageRedo.h"
#include "utility/messaging/type/MessageRefresh.h"
#include "utility/messaging/type/MessageScrollCode.h"
#include "utility/messaging/type/MessageSearch.h"
#include "utility/messaging/type/MessageShowScope.h"
#include "utility/messaging/type/MessageUndo.h"
@@ -41,6 +42,7 @@ class UndoRedoController
, public MessageListener<MessageLoadProject>
, public MessageListener<MessageRedo>
, public MessageListener<MessageRefresh>
, public MessageListener<MessageScrollCode>
, public MessageListener<MessageSearch>
, public MessageListener<MessageShowScope>
, public MessageListener<MessageUndo>
@@ -57,6 +59,7 @@ private:
Command(std::shared_ptr<MessageBase> message, size_t order);
std::shared_ptr<MessageBase> message;
std::shared_ptr<MessageBase> subMessage;
size_t order;
};
@@ -72,13 +75,14 @@ private:
virtual void handleMessage(MessageLoadProject* message);
virtual void handleMessage(MessageRedo* message);
virtual void handleMessage(MessageRefresh* message);
virtual void handleMessage(MessageScrollCode* message);
virtual void handleMessage(MessageSearch* message);
virtual void handleMessage(MessageShowScope* message);
virtual void handleMessage(MessageUndo* message);
void replayCommands(bool removeLast);
void processCommand(const Command& command);
void processCommand(Command command);
void processNormalCommand(const Command& command);
void processRedoCommand(const Command& command);
void processUndoCommand(const Command& command);
@@ -28,9 +28,8 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
const Id sourceId = m_storageAccess->getIdForNodeWithNameHierarchy(message->fromNameHierarchy);
const Id targetId = m_storageAccess->getIdForNodeWithNameHierarchy(message->toNameHierarchy);
m = std::make_shared<MessageActivateTokens>(m_storageAccess->getTokenIdsForAggregationEdge(sourceId, targetId));
m = std::make_shared<MessageActivateTokens>(message, m_storageAccess->getTokenIdsForAggregationEdge(sourceId, targetId));
m->isAggregation = true;
m->undoRedoType = message->undoRedoType;
}
else
{
@@ -43,10 +42,8 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
if (edgeId)
{
m = std::make_shared<MessageActivateTokens>(std::vector<Id>(1, edgeId));
m = std::make_shared<MessageActivateTokens>(message, std::vector<Id>(1, edgeId));
m->isEdge = true;
m->undoRedoType = message->undoRedoType;
m->setKeepContent(message->keepContent());
}
}
return m;
@@ -71,11 +68,7 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
return nullptr;
}
std::shared_ptr<MessageActivateTokens> m;
m = std::make_shared<MessageActivateTokens>(std::vector<Id>(1, fileId));
m->undoRedoType = message->undoRedoType;
m->setKeepContent(message->keepContent());
return m;
return std::make_shared<MessageActivateTokens>(message, std::vector<Id>(1, fileId));
}
std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(const MessageActivateNodes* message) const
@@ -101,20 +94,14 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
}
std::shared_ptr<MessageActivateTokens> m;
m = std::make_shared<MessageActivateTokens>(nodeIds);
m = std::make_shared<MessageActivateTokens>(message, nodeIds);
m->isFromSystem = message->isFromSystem;
m->undoRedoType = message->undoRedoType;
m->setKeepContent(message->keepContent());
return m;
}
std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(const MessageActivateTokenIds* message) const
{
std::shared_ptr<MessageActivateTokens> m;
m = std::make_shared<MessageActivateTokens>(message->tokenIds);
m->undoRedoType = message->undoRedoType;
m->setKeepContent(message->keepContent());
return m;
return std::make_shared<MessageActivateTokens>(message, message->tokenIds);
}
std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(const MessageSearch* message) const
@@ -144,13 +131,11 @@ std::shared_ptr<MessageActivateTokens> ActivationTranslator::translateMessage(co
std::vector<Id> tokenIds = m_storageAccess->getTokenIdsForMatches(matches);
tokenIds = m_storageAccess->getActiveTokenIdsForTokenIds(tokenIds);
std::shared_ptr<MessageActivateTokens> m;
m = std::make_shared<MessageActivateTokens>(tokenIds);
m->undoRedoType = message->undoRedoType;
m->setKeepContent(message->keepContent());
std::shared_ptr<MessageActivateTokens> m = std::make_shared<MessageActivateTokens>(message, tokenIds);
if (message->isFresh())
{
m->isFromSearch = true;
}
return m;
}