Fix pressing multiple KeyAction modifiers at the same time (fix #778)

This commit is contained in:
David Capello 2015-08-25 13:29:19 -03:00
parent f71a0e2cc4
commit 0645a66521
11 changed files with 109 additions and 110 deletions

View File

@ -96,36 +96,8 @@ public:
->getCurrentQuicktool(currentTool); ->getCurrentQuicktool(currentTool);
} }
bool isCopySelectionKeyPressed() override { KeyAction getPressedKeyAction(KeyContext context) {
return isKeyActionPressed(KeyAction::CopySelection); return KeyboardShortcuts::instance()->getCurrentActionModifiers(context);
}
bool isSnapToGridKeyPressed() override {
return isKeyActionPressed(KeyAction::SnapToGrid);
}
bool isAngleSnapKeyPressed() override {
return isKeyActionPressed(KeyAction::AngleSnap);
}
bool isMaintainAspectRatioKeyPressed() override {
return isKeyActionPressed(KeyAction::MaintainAspectRatio);
}
bool isLockAxisKeyPressed() override {
return isKeyActionPressed(KeyAction::LockAxis);
}
bool isAddSelectionPressed() override {
return isKeyActionPressed(KeyAction::AddSelection);
}
bool isSubtractSelectionPressed() override {
return isKeyActionPressed(KeyAction::SubtractSelection);
}
bool isAutoSelectLayerPressed() override {
return isKeyActionPressed(KeyAction::AutoSelectLayer);
} }
protected: protected:
@ -173,13 +145,6 @@ private:
App::instance()->getMainWindow()->getPreviewEditor()->updateUsingEditor(editor); App::instance()->getMainWindow()->getPreviewEditor()->updateUsingEditor(editor);
} }
bool isKeyActionPressed(KeyAction action) {
if (Key* key = KeyboardShortcuts::instance()->action(action))
return key->isPressed();
else
return false;
}
}; };
class PreviewEditor : public Editor, class PreviewEditor : public Editor,

View File

@ -1068,11 +1068,9 @@ void Editor::updateQuicktool()
// Don't change quicktools if we are in a selection tool and using // Don't change quicktools if we are in a selection tool and using
// the selection modifiers. // the selection modifiers.
if (current_tool->getInk(0)->isSelection()) { if (current_tool->getInk(0)->isSelection() &&
if (m_customizationDelegate->isAddSelectionPressed() || int(m_customizationDelegate->getPressedKeyAction(KeyContext::Selection)) != 0)
m_customizationDelegate->isSubtractSelectionPressed()) return;
return;
}
tools::Tool* old_quicktool = m_quicktool; tools::Tool* old_quicktool = m_quicktool;
tools::Tool* new_quicktool = m_customizationDelegate->getQuickTool(current_tool); tools::Tool* new_quicktool = m_customizationDelegate->getQuickTool(current_tool);
@ -1123,9 +1121,13 @@ void Editor::updateContextBarFromModifiers()
tools::SelectionMode mode = Preferences::instance().selection.mode(); tools::SelectionMode mode = Preferences::instance().selection.mode();
if (m_customizationDelegate && m_customizationDelegate->isAddSelectionPressed()) KeyAction action = KeyAction::None;
if (m_customizationDelegate)
action = m_customizationDelegate->getPressedKeyAction(KeyContext::Selection);
if (int(action & KeyAction::AddSelection))
mode = tools::SelectionMode::ADD; mode = tools::SelectionMode::ADD;
else if (m_customizationDelegate && m_customizationDelegate->isSubtractSelectionPressed()) if (int(action & KeyAction::SubtractSelection))
mode = tools::SelectionMode::SUBTRACT; mode = tools::SelectionMode::SUBTRACT;
else if (m_secondaryButton) else if (m_secondaryButton)
mode = tools::SelectionMode::SUBTRACT; mode = tools::SelectionMode::SUBTRACT;
@ -1139,7 +1141,8 @@ void Editor::updateContextBarFromModifiers()
bool autoSelectLayer = Preferences::instance().editor.autoSelectLayer(); bool autoSelectLayer = Preferences::instance().editor.autoSelectLayer();
if (m_customizationDelegate && m_customizationDelegate->isAutoSelectLayerPressed()) if ((m_customizationDelegate) &&
int(m_customizationDelegate->getPressedKeyAction(KeyContext::MoveTool) & KeyAction::AutoSelectLayer))
autoSelectLayer = true; autoSelectLayer = true;
if (m_autoSelectLayer != autoSelectLayer) { if (m_autoSelectLayer != autoSelectLayer) {

View File

@ -9,6 +9,8 @@
#define APP_UI_EDITOR_CUSTOMIZATION_DELEGATE_H_INCLUDED #define APP_UI_EDITOR_CUSTOMIZATION_DELEGATE_H_INCLUDED
#pragma once #pragma once
#include "app/ui/keyboard_shortcuts.h"
namespace tools { namespace tools {
class Tool; class Tool;
} }
@ -26,31 +28,8 @@ namespace app {
// "currentTool" is the current tool selected in the toolbox. // "currentTool" is the current tool selected in the toolbox.
virtual tools::Tool* getQuickTool(tools::Tool* currentTool) = 0; virtual tools::Tool* getQuickTool(tools::Tool* currentTool) = 0;
// Returns true if the user wants to copy the selection instead of // Returns what action is pressed at this moment.
// to move it. virtual KeyAction getPressedKeyAction(KeyContext context) = 0;
virtual bool isCopySelectionKeyPressed() = 0;
// Returns true if the user wants to snap to grid when he's moving
// the selection.
virtual bool isSnapToGridKeyPressed() = 0;
// Returns true if the user wants to activate angle snap, so he can
// easily specify common angles (45, 90, 135, 180, etc.).
virtual bool isAngleSnapKeyPressed() = 0;
// Returns true if the user wants to maintain the aspect ratio when
// he is scaling the selection.
virtual bool isMaintainAspectRatioKeyPressed() = 0;
// Returns true if the user wants to lock the X or Y axis when he is
// dragging the selection.
virtual bool isLockAxisKeyPressed() = 0;
virtual bool isAddSelectionPressed() = 0;
virtual bool isSubtractSelectionPressed() = 0;
virtual bool isAutoSelectLayerPressed() = 0;
}; };
} // namespace app } // namespace app

View File

@ -129,7 +129,7 @@ bool MovingCelState::onMouseMove(Editor* editor, MouseMessage* msg)
gfx::Point newCursorPos = editor->screenToEditor(msg->position()); gfx::Point newCursorPos = editor->screenToEditor(msg->position());
gfx::Point delta = newCursorPos - m_mouseStart; gfx::Point delta = newCursorPos - m_mouseStart;
if (editor->getCustomizationDelegate()->isLockAxisKeyPressed()) { if (int(editor->getCustomizationDelegate()->getPressedKeyAction(KeyContext::MovingPixels) & KeyAction::LockAxis)) {
if (ABS(delta.x) < ABS(delta.y)) { if (ABS(delta.x) < ABS(delta.y)) {
delta.x = 0; delta.x = 0;
} }

View File

@ -263,7 +263,8 @@ bool MovingPixelsState::onMouseDown(Editor* editor, MouseMessage* msg)
msg->right())) { msg->right())) {
// In case that the user is pressing the copy-selection keyboard shortcut. // In case that the user is pressing the copy-selection keyboard shortcut.
EditorCustomizationDelegate* customization = editor->getCustomizationDelegate(); EditorCustomizationDelegate* customization = editor->getCustomizationDelegate();
if (customization && customization->isCopySelectionKeyPressed()) { if ((customization) &&
int(customization->getPressedKeyAction(KeyContext::MovingPixels) & KeyAction::CopySelection)) {
// Stamp the pixels to create the copy. // Stamp the pixels to create the copy.
m_pixelsMovement->stampImage(); m_pixelsMovement->stampImage();
} }
@ -315,17 +316,18 @@ bool MovingPixelsState::onMouseMove(Editor* editor, MouseMessage* msg)
// Get the customization for the pixels movement (snap to grid, angle snap, etc.). // Get the customization for the pixels movement (snap to grid, angle snap, etc.).
PixelsMovement::MoveModifier moveModifier = PixelsMovement::NormalMovement; PixelsMovement::MoveModifier moveModifier = PixelsMovement::NormalMovement;
KeyAction action = editor->getCustomizationDelegate()->getPressedKeyAction(KeyContext::MovingPixels);
if (editor->getCustomizationDelegate()->isSnapToGridKeyPressed()) if (int(action & KeyAction::SnapToGrid))
moveModifier |= PixelsMovement::SnapToGridMovement; moveModifier |= PixelsMovement::SnapToGridMovement;
if (editor->getCustomizationDelegate()->isAngleSnapKeyPressed()) if (int(action & KeyAction::AngleSnap))
moveModifier |= PixelsMovement::AngleSnapMovement; moveModifier |= PixelsMovement::AngleSnapMovement;
if (editor->getCustomizationDelegate()->isMaintainAspectRatioKeyPressed()) if (int(action & KeyAction::MaintainAspectRatio))
moveModifier |= PixelsMovement::MaintainAspectRatioMovement; moveModifier |= PixelsMovement::MaintainAspectRatioMovement;
if (editor->getCustomizationDelegate()->isLockAxisKeyPressed()) if (int(action & KeyAction::LockAxis))
moveModifier |= PixelsMovement::LockAxisMovement; moveModifier |= PixelsMovement::LockAxisMovement;
// Invalidate handles // Invalidate handles

View File

@ -252,6 +252,17 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
y2 += dy; y2 += dy;
updateBounds = true; updateBounds = true;
if ((moveModifier & LockAxisMovement) == LockAxisMovement) {
if (ABS(dx) < ABS(dy)) {
x1 -= dx;
x2 -= dx;
}
else {
y1 -= dy;
y2 -= dy;
}
}
if ((moveModifier & SnapToGridMovement) == SnapToGridMovement) { if ((moveModifier & SnapToGridMovement) == SnapToGridMovement) {
// Snap the x1,y1 point to the grid. // Snap the x1,y1 point to the grid.
gfx::Rect gridBounds = App::instance() gfx::Rect gridBounds = App::instance()
@ -268,16 +279,6 @@ void PixelsMovement::moveImage(const gfx::Point& pos, MoveModifier moveModifier)
x2 += gridOffset.x; x2 += gridOffset.x;
y2 += gridOffset.y; y2 += gridOffset.y;
} }
else if ((moveModifier & LockAxisMovement) == LockAxisMovement) {
if (ABS(dx) < ABS(dy)) {
x1 -= dx;
x2 -= dx;
}
else {
y1 -= dy;
y2 -= dy;
}
}
break; break;
case ScaleNWHandle: case ScaleNWHandle:

View File

@ -315,8 +315,8 @@ bool StandbyState::onSetCursor(Editor* editor, const gfx::Point& mouseScreenPos)
// Move pixels // Move pixels
if (editor->isInsideSelection()) { if (editor->isInsideSelection()) {
EditorCustomizationDelegate* customization = editor->getCustomizationDelegate(); EditorCustomizationDelegate* customization = editor->getCustomizationDelegate();
if ((customization) &&
if (customization && customization->isCopySelectionKeyPressed()) int(customization->getPressedKeyAction(KeyContext::MovingPixels) & KeyAction::CopySelection))
editor->showMouseCursor(kArrowPlusCursor); editor->showMouseCursor(kArrowPlusCursor);
else else
editor->showMouseCursor(kMoveCursor); editor->showMouseCursor(kMoveCursor);
@ -452,7 +452,8 @@ void StandbyState::transformSelection(Editor* editor, MouseMessage* msg, HandleT
"Transformation")); "Transformation"));
// If the Ctrl key is pressed start dragging a copy of the selection // If the Ctrl key is pressed start dragging a copy of the selection
if (customization && customization->isCopySelectionKeyPressed()) if ((customization) &&
int(customization->getPressedKeyAction(KeyContext::MovingPixels) & KeyAction::CopySelection))
pixelsMovement->copyMask(); pixelsMovement->copyMask();
else else
pixelsMovement->cutMask(); pixelsMovement->cutMask();

View File

@ -215,6 +215,15 @@ bool Key::isPressed() const
return false; return false;
} }
bool Key::isLooselyPressed() const
{
for (const Accelerator& accel : this->accels()) {
if (accel.isLooselyPressed())
return true;
}
return false;
}
bool Key::hasAccel(const ui::Accelerator& accel) const bool Key::hasAccel(const ui::Accelerator& accel) const
{ {
return accels().has(accel); return accels().has(accel);
@ -677,4 +686,19 @@ tools::Tool* KeyboardShortcuts::getCurrentQuicktool(tools::Tool* currentTool)
return NULL; return NULL;
} }
KeyAction KeyboardShortcuts::getCurrentActionModifiers(KeyContext context)
{
KeyAction flags = KeyAction::None;
for (Key* key : m_keys) {
if (key->type() == KeyType::Action &&
key->keycontext() == context &&
key->isLooselyPressed()) {
flags = static_cast<KeyAction>(int(flags) | int(key->action()));
}
}
return flags;
}
} // namespace app } // namespace app

View File

@ -50,20 +50,25 @@ namespace app {
Action, Action,
}; };
// TODO This should be called "KeyActionModifier" or something similar
enum class KeyAction { enum class KeyAction {
None, None = 0x00000000,
CopySelection, CopySelection = 0x00000001,
SnapToGrid, SnapToGrid = 0x00000002,
AngleSnap, AngleSnap = 0x00000004,
MaintainAspectRatio, MaintainAspectRatio = 0x00000008,
LockAxis, LockAxis = 0x00000010,
AddSelection, AddSelection = 0x00000020,
SubtractSelection, SubtractSelection = 0x00000040,
AutoSelectLayer, AutoSelectLayer = 0x00000080,
LeftMouseButton, LeftMouseButton = 0x00000100,
RightMouseButton RightMouseButton = 0x00000200,
}; };
inline KeyAction operator&(KeyAction a, KeyAction b) {
return KeyAction(int(a) & int(b));
}
class Key { class Key {
public: public:
Key(Command* command, const Params& params, KeyContext keyContext); Key(Command* command, const Params& params, KeyContext keyContext);
@ -81,6 +86,7 @@ namespace app {
void add(const ui::Accelerator& accel, KeySource source); void add(const ui::Accelerator& accel, KeySource source);
bool isPressed(ui::Message* msg) const; bool isPressed(ui::Message* msg) const;
bool isPressed() const; bool isPressed() const;
bool isLooselyPressed() const;
bool hasAccel(const ui::Accelerator& accel) const; bool hasAccel(const ui::Accelerator& accel) const;
void disableAccel(const ui::Accelerator& accel); void disableAccel(const ui::Accelerator& accel);
@ -147,6 +153,7 @@ namespace app {
KeyContext getCurrentKeyContext(); KeyContext getCurrentKeyContext();
bool getCommandFromKeyMessage(ui::Message* msg, Command** command, Params* params); bool getCommandFromKeyMessage(ui::Message* msg, Command** command, Params* params);
tools::Tool* getCurrentQuicktool(tools::Tool* currentTool); tools::Tool* getCurrentQuicktool(tools::Tool* currentTool);
KeyAction getCurrentActionModifiers(KeyContext context);
private: private:
KeyboardShortcuts(); KeyboardShortcuts();

View File

@ -27,8 +27,17 @@
namespace ui { namespace ui {
////////////////////////////////////////////////////////////////////// static KeyModifiers get_pressed_modifiers_from_she()
// Accelerator {
KeyModifiers mods = kKeyNoneModifier;
if (she::is_key_pressed(kKeyLShift) ) mods = KeyModifiers(int(mods) | int(kKeyShiftModifier));
if (she::is_key_pressed(kKeyRShift) ) mods = KeyModifiers(int(mods) | int(kKeyShiftModifier));
if (she::is_key_pressed(kKeyLControl)) mods = KeyModifiers(int(mods) | int(kKeyCtrlModifier));
if (she::is_key_pressed(kKeyRControl)) mods = KeyModifiers(int(mods) | int(kKeyCtrlModifier));
if (she::is_key_pressed(kKeyAlt) ) mods = KeyModifiers(int(mods) | int(kKeyAltModifier));
if (she::is_key_pressed(kKeyCommand) ) mods = KeyModifiers(int(mods) | int(kKeyCmdModifier));
return mods;
}
Accelerator::Accelerator() Accelerator::Accelerator()
: m_modifiers(kKeyNoneModifier) : m_modifiers(kKeyNoneModifier)
@ -434,19 +443,20 @@ bool Accelerator::isPressed(KeyModifiers modifiers, KeyScancode scancode, int un
bool Accelerator::isPressed() const bool Accelerator::isPressed() const
{ {
KeyModifiers modifiers = kKeyNoneModifier; KeyModifiers modifiers = get_pressed_modifiers_from_she();
if (she::is_key_pressed(kKeyLShift) ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyShiftModifier);
if (she::is_key_pressed(kKeyRShift) ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyShiftModifier);
if (she::is_key_pressed(kKeyLControl)) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyCtrlModifier);
if (she::is_key_pressed(kKeyRControl)) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyCtrlModifier);
if (she::is_key_pressed(kKeyAlt) ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyAltModifier);
if (she::is_key_pressed(kKeyCommand) ) modifiers = (KeyModifiers)((int)modifiers | (int)kKeyCmdModifier);
return ((m_scancode == 0 || she::is_key_pressed(m_scancode)) && return ((m_scancode == 0 || she::is_key_pressed(m_scancode)) &&
(m_modifiers == modifiers)); (m_modifiers == modifiers));
} }
bool Accelerator::isLooselyPressed() const
{
KeyModifiers modifiers = get_pressed_modifiers_from_she();
return ((m_scancode == 0 || she::is_key_pressed(m_scancode)) &&
(int(m_modifiers & modifiers) == m_modifiers));
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// Accelerators // Accelerators

View File

@ -26,8 +26,15 @@ namespace ui {
std::string toString() const; std::string toString() const;
bool isPressed(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar) const; bool isPressed(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar) const;
// Returns true if the key is pressed and only its modifiers are
// pressed.
bool isPressed() const; bool isPressed() const;
// Returns true if the key is pressed and the accelerator
// modifiers are pressed (other modifiers are allowed).
bool isLooselyPressed() const;
bool operator==(const Accelerator& other) const; bool operator==(const Accelerator& other) const;
bool operator!=(const Accelerator& other) const { bool operator!=(const Accelerator& other) const {
return !operator==(other); return !operator==(other);