mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-30 13:20:28 +00:00
Add angle snap with Shift key to rotation.
This commit is contained in:
parent
9684672f5f
commit
a17d925847
@ -165,6 +165,14 @@
|
||||
<!-- When you drag-and-drop the selection, pressing this
|
||||
keyboard shortcut you can copy instead of move -->
|
||||
<key action="CopySelection" shortcut="Ctrl" />
|
||||
|
||||
<!-- When you move the selection, pressing this
|
||||
keyboard shortcut you can snap to grid -->
|
||||
<key action="SnapToGrid" shortcut="Shift" />
|
||||
|
||||
<!-- When you rotate the selection, pressing this
|
||||
keyboard shortcut you activate angle snap -->
|
||||
<key action="AngleSnap" shortcut="Shift" />
|
||||
</spriteeditor>
|
||||
|
||||
</keyboard>
|
||||
|
@ -128,6 +128,22 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSnapToGridKeyPressed() OVERRIDE {
|
||||
JAccel accel = get_accel_to_snap_to_grid();
|
||||
if (accel)
|
||||
return jaccel_check_from_key(accel);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAngleSnapKeyPressed() OVERRIDE {
|
||||
JAccel accel = get_accel_to_angle_snap();
|
||||
if (accel)
|
||||
return jaccel_check_from_key(accel);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class MiniEditor : public Editor
|
||||
|
@ -65,6 +65,8 @@
|
||||
#define MONITOR_TIMER_MSECS 100
|
||||
|
||||
#define SPRITEDITOR_ACTION_COPYSELECTION "CopySelection"
|
||||
#define SPRITEDITOR_ACTION_SNAPTOGRID "SnapToGrid"
|
||||
#define SPRITEDITOR_ACTION_ANGLESNAP "AngleSnap"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -939,6 +941,24 @@ JAccel get_accel_to_copy_selection()
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JAccel get_accel_to_snap_to_grid()
|
||||
{
|
||||
Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_SNAPTOGRID);
|
||||
if (shortcut)
|
||||
return shortcut->accel;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JAccel get_accel_to_angle_snap()
|
||||
{
|
||||
Shortcut* shortcut = get_keyboard_shortcut_for_spriteeditor(SPRITEDITOR_ACTION_ANGLESNAP);
|
||||
if (shortcut)
|
||||
return shortcut->accel;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tools::Tool* get_selected_quicktool(tools::Tool* currentTool)
|
||||
{
|
||||
if (currentTool && currentTool->getInk(0)->isSelection()) {
|
||||
|
@ -116,6 +116,8 @@ Command* get_command_from_key_message(Message* msg);
|
||||
JAccel get_accel_to_execute_command(const char* command, Params* params = NULL);
|
||||
JAccel get_accel_to_change_tool(tools::Tool* tool);
|
||||
JAccel get_accel_to_copy_selection();
|
||||
JAccel get_accel_to_snap_to_grid();
|
||||
JAccel get_accel_to_angle_snap();
|
||||
|
||||
tools::Tool* get_selected_quicktool(tools::Tool* currentTool);
|
||||
|
||||
|
@ -39,6 +39,14 @@ public:
|
||||
// Returns true if the user wants to copy the selection instead of
|
||||
// to move it.
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // WIDGETS_EDITOR_CUSTOMIZATION_DELEGATE_H_INCLUDED
|
||||
|
@ -187,8 +187,13 @@ bool MovingPixelsState::onMouseMove(Editor* editor, Message* msg)
|
||||
int x, y;
|
||||
editor->screenToEditor(msg->mouse.x, msg->mouse.y, &x, &y);
|
||||
|
||||
PixelsMovement::MoveModifier moveModifier = PixelsMovement::NormalMovement;
|
||||
|
||||
if (editor->getCustomizationDelegate()->isAngleSnapKeyPressed())
|
||||
moveModifier = PixelsMovement::AngleSnapMovement;
|
||||
|
||||
// Drag the image to that position
|
||||
gfx::Rect bounds = m_pixelsMovement->moveImage(x, y);
|
||||
gfx::Rect bounds = m_pixelsMovement->moveImage(x, y, moveModifier);
|
||||
|
||||
// If "bounds" is empty is because the cel was not moved
|
||||
if (!bounds.isEmpty()) {
|
||||
|
@ -148,7 +148,7 @@ void PixelsMovement::maskImage(const Image* image, int x, int y)
|
||||
update_screen_for_document(m_documentReader);
|
||||
}
|
||||
|
||||
gfx::Rect PixelsMovement::moveImage(int x, int y)
|
||||
gfx::Rect PixelsMovement::moveImage(int x, int y, MoveModifier moveModifier)
|
||||
{
|
||||
DocumentWriter documentWriter(m_documentReader);
|
||||
Image* image = documentWriter->getExtraCelImage();
|
||||
@ -241,6 +241,32 @@ gfx::Rect PixelsMovement::moveImage(int x, int y)
|
||||
- atan2((double)(-m_catchY + abs_initial_pivot.y),
|
||||
(double)(+m_catchX - abs_initial_pivot.x));
|
||||
|
||||
// Put the angle in -180 to 180 range.
|
||||
while (newAngle < -PI) newAngle += 2*PI;
|
||||
while (newAngle > PI) newAngle -= 2*PI;
|
||||
|
||||
// Is the "angle snap" is activated, we've to snap the angle
|
||||
// to common (pixel art) angles.
|
||||
if ((moveModifier & AngleSnapMovement) == AngleSnapMovement) {
|
||||
// TODO make this configurable
|
||||
static const double keyAngles[] = {
|
||||
0.0, 26.565, 45.0, 63.435, 90.0, 116.565, 135.0, 153.435, -180.0,
|
||||
180.0, -153.435, -135.0, -116, -90.0, -63.435, -45.0, -26.565
|
||||
};
|
||||
|
||||
double newAngleDegrees = 180.0 * newAngle / PI;
|
||||
|
||||
int closest = 0;
|
||||
int last = sizeof(keyAngles) / sizeof(keyAngles[0]) - 1;
|
||||
for (int i=0; i<=last; ++i) {
|
||||
if (std::fabs(newAngleDegrees-keyAngles[closest]) >
|
||||
std::fabs(newAngleDegrees-keyAngles[i]))
|
||||
closest = i;
|
||||
}
|
||||
|
||||
newAngle = PI * keyAngles[closest] / 180.0;
|
||||
}
|
||||
|
||||
m_currentData.angle(newAngle);
|
||||
}
|
||||
break;
|
||||
|
@ -36,6 +36,12 @@ class Sprite;
|
||||
class PixelsMovement
|
||||
{
|
||||
public:
|
||||
enum MoveModifier {
|
||||
NormalMovement = 1,
|
||||
SnapToGridMovement = 2,
|
||||
AngleSnapMovement = 4
|
||||
};
|
||||
|
||||
// The "moveThis" image specifies the chunk of pixels to be moved.
|
||||
// The "x" and "y" parameters specify the initial position of the image.
|
||||
PixelsMovement(Document* document, Sprite* sprite, const Image* moveThis, int x, int y, int opacity,
|
||||
@ -54,7 +60,7 @@ public:
|
||||
// Moves the image to the new position (relative to the start
|
||||
// position given in the ctor). Returns the rectangle that should be
|
||||
// redrawn.
|
||||
gfx::Rect moveImage(int x, int y);
|
||||
gfx::Rect moveImage(int x, int y, MoveModifier moveModifier);
|
||||
|
||||
void dropImageTemporarily();
|
||||
void dropImage();
|
||||
|
Loading…
x
Reference in New Issue
Block a user