Fix keyboard shortcuts with Shift+ key when pencil tool is active

This commit is contained in:
David Capello 2017-06-19 13:17:09 -03:00
parent 40136e5074
commit 7323f1d071
3 changed files with 47 additions and 7 deletions

View File

@ -39,14 +39,19 @@ namespace app {
using namespace ui; using namespace ui;
DrawingState::DrawingState(tools::ToolLoop* toolLoop, DrawingState::DrawingState(Editor* editor,
tools::ToolLoop* toolLoop,
const DrawingType type) const DrawingType type)
: m_type(type) : m_editor(editor)
, m_type(type)
, m_toolLoop(toolLoop) , m_toolLoop(toolLoop)
, m_toolLoopManager(new tools::ToolLoopManager(toolLoop)) , m_toolLoopManager(new tools::ToolLoopManager(toolLoop))
, m_mouseMoveReceived(false) , m_mouseMoveReceived(false)
, m_mousePressedReceived(false) , m_mousePressedReceived(false)
{ {
m_beforeCmdConn =
UIContext::instance()->BeforeCommandExecution.connect(
&DrawingState::onBeforeCommandExecution, this);
} }
DrawingState::~DrawingState() DrawingState::~DrawingState()
@ -92,6 +97,9 @@ bool DrawingState::onMouseDown(Editor* editor, MouseMessage* msg)
// Drawing loop // Drawing loop
ASSERT(m_toolLoopManager != NULL); ASSERT(m_toolLoopManager != NULL);
if (!editor->hasCapture())
editor->captureMouse();
m_mousePressedReceived = true; m_mousePressedReceived = true;
// Notify the mouse button down to the tool loop manager. // Notify the mouse button down to the tool loop manager.
@ -180,12 +188,15 @@ bool DrawingState::onKeyDown(Editor* editor, KeyMessage* msg)
if (KeyboardShortcuts::instance() if (KeyboardShortcuts::instance()
->getCommandFromKeyMessage(msg, &command, &params)) { ->getCommandFromKeyMessage(msg, &command, &params)) {
// We accept zoom commands. // We accept zoom commands.
if (command->id() == CommandId::Zoom) if (command->id() == CommandId::Zoom) {
UIContext::instance()->executeCommand(command, params); UIContext::instance()->executeCommand(command, params);
return true;
}
} }
// When we are drawing, we "eat" all pressed keys. // Return true when we cannot execute commands (true = the onKeyDown
return true; // event was used, so the key is not used to run a command).
return !canExecuteCommands();
} }
bool DrawingState::onKeyUp(Editor* editor, KeyMessage* msg) bool DrawingState::onKeyUp(Editor* editor, KeyMessage* msg)
@ -218,6 +229,25 @@ void DrawingState::onExposeSpritePixels(const gfx::Region& rgn)
m_toolLoop->validateDstImage(rgn); m_toolLoop->validateDstImage(rgn);
} }
bool DrawingState::canExecuteCommands()
{
// Returning true here means that the user can trigger commands with
// keyboard shortcuts. In our case we want to be able to use
// keyboard shortcuts only when the Shift key was pressed to run a
// command (e.g. Shift+N), not to draw a straight line from the
// pencil (freehand) tool.
return (m_type == DrawingType::LineFreehand &&
!m_mousePressedReceived);
}
void DrawingState::onBeforeCommandExecution(CommandExecutionEvent& cmd)
{
if (canExecuteCommands() && m_toolLoop) {
m_toolLoop->cancel();
destroyLoopIfCanceled(m_editor);
}
}
void DrawingState::destroyLoopIfCanceled(Editor* editor) void DrawingState::destroyLoopIfCanceled(Editor* editor)
{ {
// Cancel drawing loop // Cancel drawing loop

View File

@ -9,6 +9,7 @@
#pragma once #pragma once
#include "app/ui/editor/standby_state.h" #include "app/ui/editor/standby_state.h"
#include "obs/connection.h"
namespace app { namespace app {
namespace tools { namespace tools {
@ -17,9 +18,12 @@ namespace app {
class ToolLoopManager; class ToolLoopManager;
} }
class CommandExecutionEvent;
class DrawingState : public StandbyState { class DrawingState : public StandbyState {
public: public:
DrawingState(tools::ToolLoop* loop, DrawingState(Editor* editor,
tools::ToolLoop* loop,
const DrawingType type); const DrawingType type);
virtual ~DrawingState(); virtual ~DrawingState();
virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override; virtual bool onMouseDown(Editor* editor, ui::MouseMessage* msg) override;
@ -45,9 +49,12 @@ namespace app {
void notifyToolLoopModifiersChange(Editor* editor); void notifyToolLoopModifiersChange(Editor* editor);
private: private:
bool canExecuteCommands();
void onBeforeCommandExecution(CommandExecutionEvent& cmd);
void destroyLoopIfCanceled(Editor* editor); void destroyLoopIfCanceled(Editor* editor);
void destroyLoop(Editor* editor); void destroyLoop(Editor* editor);
Editor* m_editor;
DrawingType m_type; DrawingType m_type;
// The tool-loop. // The tool-loop.
@ -71,6 +78,8 @@ namespace app {
// Shift press is used to draw a line, but then released without a // Shift press is used to draw a line, but then released without a
// mouse click. // mouse click.
bool m_mousePressedReceived; bool m_mousePressedReceived;
obs::scoped_connection m_beforeCmdConn;
}; };
} // namespace app } // namespace app

View File

@ -596,7 +596,8 @@ DrawingState* StandbyState::startDrawingState(Editor* editor,
return nullptr; return nullptr;
EditorStatePtr newState( EditorStatePtr newState(
new DrawingState(toolLoop, new DrawingState(editor,
toolLoop,
drawingType)); drawingType));
editor->setState(newState); editor->setState(newState);