mirror of
https://github.com/aseprite/aseprite.git
synced 2024-10-03 21:46:20 +00:00
Add logic to displace points in PointByPointController
In this change we've added a new MoveOrirginCapability class to share the Space bar logic to move all points in several controllers (TwoPointsController, PointByPointController, and FourPointsController). Related to #741
This commit is contained in:
parent
045f11bf68
commit
72015c092a
@ -14,66 +14,16 @@ namespace tools {
|
|||||||
|
|
||||||
using namespace gfx;
|
using namespace gfx;
|
||||||
|
|
||||||
// Controls clicks for tools like pencil
|
// Shared logic between controllers that can move/displace all points
|
||||||
class FreehandController : public Controller {
|
// using the space bar.
|
||||||
public:
|
class MoveOriginCapability : public Controller {
|
||||||
bool isFreehand() { return true; }
|
|
||||||
|
|
||||||
void pressButton(Points& points, const Point& point)
|
|
||||||
{
|
|
||||||
points.push_back(point);
|
|
||||||
}
|
|
||||||
bool releaseButton(Points& points, const Point& point)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void movement(ToolLoop* loop, Points& points, const Point& point)
|
|
||||||
{
|
|
||||||
points.push_back(point);
|
|
||||||
}
|
|
||||||
void getPointsToInterwine(const Points& input, Points& output)
|
|
||||||
{
|
|
||||||
if (input.size() == 1) {
|
|
||||||
output.push_back(input[0]);
|
|
||||||
}
|
|
||||||
else if (input.size() >= 2) {
|
|
||||||
output.push_back(input[input.size()-2]);
|
|
||||||
output.push_back(input[input.size()-1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void getStatusBarText(const Points& points, std::string& text)
|
|
||||||
{
|
|
||||||
ASSERT(!points.empty());
|
|
||||||
if (points.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
char buf[1024];
|
|
||||||
sprintf(buf, "Start %3d %3d End %3d %3d",
|
|
||||||
points[0].x, points[0].y,
|
|
||||||
points[points.size()-1].x,
|
|
||||||
points[points.size()-1].y);
|
|
||||||
text = buf;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Controls clicks for tools like line
|
|
||||||
class TwoPointsController : public Controller {
|
|
||||||
public:
|
public:
|
||||||
void prepareController(ui::KeyModifiers modifiers) override {
|
void prepareController(ui::KeyModifiers modifiers) override {
|
||||||
m_squareAspect = (modifiers & ui::kKeyShiftModifier) ? true: false;
|
|
||||||
m_fromCenter = (modifiers & ui::kKeyCtrlModifier) ? true: false;
|
|
||||||
m_movingOrigin = false;
|
m_movingOrigin = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pressButton(Points& points, const Point& point) override {
|
void pressButton(Points& points, const Point& point) override {
|
||||||
m_first = m_last = point;
|
m_last = point;
|
||||||
|
|
||||||
points.push_back(point);
|
|
||||||
points.push_back(point);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool releaseButton(Points& points, const Point& point) override {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pressKey(ui::KeyScancode key) override {
|
bool pressKey(ui::KeyScancode key) override {
|
||||||
@ -86,21 +36,132 @@ public:
|
|||||||
return processKey(key, false);
|
return processKey(key, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void movement(ToolLoop* loop, Points& points, const Point& point) {
|
protected:
|
||||||
ASSERT(points.size() >= 2);
|
bool isMovingOrigin(Points& points, const Point& point) {
|
||||||
if (points.size() < 2)
|
bool used = false;
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_movingOrigin) {
|
if (m_movingOrigin) {
|
||||||
Point delta = (point - m_last);
|
Point delta = (point - m_last);
|
||||||
for (auto& p : points)
|
for (auto& p : points)
|
||||||
p += delta;
|
p += delta;
|
||||||
m_first += delta;
|
|
||||||
m_last = point;
|
onMoveOrigin(delta);
|
||||||
return;
|
used = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_last = point;
|
m_last = point;
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void onMoveOrigin(const Point& delta) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool processKey(ui::KeyScancode key, bool state) {
|
||||||
|
if (key == ui::kKeySpace) {
|
||||||
|
m_movingOrigin = state;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flag used to know if the space bar is pressed, i.e., we have
|
||||||
|
// displace all points.
|
||||||
|
bool m_movingOrigin;
|
||||||
|
|
||||||
|
// Last known mouse position used to calculate delta values (dx, dy)
|
||||||
|
// with the new mouse position to displace all points.
|
||||||
|
Point m_last;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Controls clicks for tools like pencil
|
||||||
|
class FreehandController : public Controller {
|
||||||
|
public:
|
||||||
|
bool isFreehand() { return true; }
|
||||||
|
|
||||||
|
void pressButton(Points& points, const Point& point) override {
|
||||||
|
points.push_back(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool releaseButton(Points& points, const Point& point) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
||||||
|
points.push_back(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getPointsToInterwine(const Points& input, Points& output) override {
|
||||||
|
if (input.size() == 1) {
|
||||||
|
output.push_back(input[0]);
|
||||||
|
}
|
||||||
|
else if (input.size() >= 2) {
|
||||||
|
output.push_back(input[input.size()-2]);
|
||||||
|
output.push_back(input[input.size()-1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getStatusBarText(const Points& points, std::string& text) override {
|
||||||
|
ASSERT(!points.empty());
|
||||||
|
if (points.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
char buf[1024];
|
||||||
|
sprintf(buf, "Start %3d %3d End %3d %3d",
|
||||||
|
points[0].x, points[0].y,
|
||||||
|
points[points.size()-1].x,
|
||||||
|
points[points.size()-1].y);
|
||||||
|
text = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// Controls clicks for tools like line
|
||||||
|
class TwoPointsController : public MoveOriginCapability {
|
||||||
|
public:
|
||||||
|
void prepareController(ui::KeyModifiers modifiers) override {
|
||||||
|
MoveOriginCapability::prepareController(modifiers);
|
||||||
|
|
||||||
|
m_squareAspect = (modifiers & ui::kKeyShiftModifier) ? true: false;
|
||||||
|
m_fromCenter = (modifiers & ui::kKeyCtrlModifier) ? true: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pressButton(Points& points, const Point& point) override {
|
||||||
|
MoveOriginCapability::pressButton(points, point);
|
||||||
|
|
||||||
|
m_first = point;
|
||||||
|
|
||||||
|
points.push_back(point);
|
||||||
|
points.push_back(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool releaseButton(Points& points, const Point& point) override {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pressKey(ui::KeyScancode key) override {
|
||||||
|
if (MoveOriginCapability::pressKey(key))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return processKey(key, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool releaseKey(ui::KeyScancode key) override {
|
||||||
|
if (MoveOriginCapability::releaseKey(key))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return processKey(key, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
||||||
|
ASSERT(points.size() >= 2);
|
||||||
|
if (points.size() < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (MoveOriginCapability::isMovingOrigin(points, point))
|
||||||
|
return;
|
||||||
|
|
||||||
points[1] = point;
|
points[1] = point;
|
||||||
|
|
||||||
if (m_squareAspect) {
|
if (m_squareAspect) {
|
||||||
@ -199,6 +260,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void onMoveOrigin(const Point& delta) override {
|
||||||
|
m_first += delta;
|
||||||
|
}
|
||||||
|
|
||||||
bool processKey(ui::KeyScancode key, bool state) {
|
bool processKey(ui::KeyScancode key, bool state) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case ui::kKeyLShift:
|
case ui::kKeyLShift:
|
||||||
@ -209,29 +274,27 @@ private:
|
|||||||
case ui::kKeyRControl:
|
case ui::kKeyRControl:
|
||||||
m_fromCenter = state;
|
m_fromCenter = state;
|
||||||
return true;
|
return true;
|
||||||
case ui::kKeySpace:
|
|
||||||
m_movingOrigin = state;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Point m_first, m_last;
|
Point m_first;
|
||||||
bool m_squareAspect;
|
bool m_squareAspect;
|
||||||
bool m_fromCenter;
|
bool m_fromCenter;
|
||||||
bool m_movingOrigin;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Controls clicks for tools like polygon
|
// Controls clicks for tools like polygon
|
||||||
class PointByPointController : public Controller {
|
class PointByPointController : public MoveOriginCapability {
|
||||||
public:
|
public:
|
||||||
void pressButton(Points& points, const Point& point)
|
|
||||||
{
|
void pressButton(Points& points, const Point& point) override {
|
||||||
|
MoveOriginCapability::pressButton(points, point);
|
||||||
|
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
}
|
}
|
||||||
bool releaseButton(Points& points, const Point& point)
|
|
||||||
{
|
bool releaseButton(Points& points, const Point& point) override {
|
||||||
ASSERT(!points.empty());
|
ASSERT(!points.empty());
|
||||||
if (points.empty())
|
if (points.empty())
|
||||||
return false;
|
return false;
|
||||||
@ -242,20 +305,23 @@ public:
|
|||||||
else
|
else
|
||||||
return true; // Continue adding points
|
return true; // Continue adding points
|
||||||
}
|
}
|
||||||
void movement(ToolLoop* loop, Points& points, const Point& point)
|
|
||||||
{
|
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
||||||
ASSERT(!points.empty());
|
ASSERT(!points.empty());
|
||||||
if (points.empty())
|
if (points.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (MoveOriginCapability::isMovingOrigin(points, point))
|
||||||
|
return;
|
||||||
|
|
||||||
points[points.size()-1] = point;
|
points[points.size()-1] = point;
|
||||||
}
|
}
|
||||||
void getPointsToInterwine(const Points& input, Points& output)
|
|
||||||
{
|
void getPointsToInterwine(const Points& input, Points& output) override {
|
||||||
output = input;
|
output = input;
|
||||||
}
|
}
|
||||||
void getStatusBarText(const Points& points, std::string& text)
|
|
||||||
{
|
void getStatusBarText(const Points& points, std::string& text) override {
|
||||||
ASSERT(!points.empty());
|
ASSERT(!points.empty());
|
||||||
if (points.empty())
|
if (points.empty())
|
||||||
return;
|
return;
|
||||||
@ -267,6 +333,7 @@ public:
|
|||||||
points[points.size()-1].y);
|
points[points.size()-1].y);
|
||||||
text = buf;
|
text = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class OnePointController : public Controller {
|
class OnePointController : public Controller {
|
||||||
@ -275,25 +342,24 @@ public:
|
|||||||
bool canSnapToGrid() { return false; }
|
bool canSnapToGrid() { return false; }
|
||||||
bool isOnePoint() { return true; }
|
bool isOnePoint() { return true; }
|
||||||
|
|
||||||
void pressButton(Points& points, const Point& point)
|
void pressButton(Points& points, const Point& point) override {
|
||||||
{
|
|
||||||
if (points.size() == 0)
|
if (points.size() == 0)
|
||||||
points.push_back(point);
|
points.push_back(point);
|
||||||
}
|
}
|
||||||
bool releaseButton(Points& points, const Point& point)
|
|
||||||
{
|
bool releaseButton(Points& points, const Point& point) override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void movement(ToolLoop* loop, Points& points, const Point& point)
|
|
||||||
{
|
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
void getPointsToInterwine(const Points& input, Points& output)
|
|
||||||
{
|
void getPointsToInterwine(const Points& input, Points& output) override {
|
||||||
output = input;
|
output = input;
|
||||||
}
|
}
|
||||||
void getStatusBarText(const Points& points, std::string& text)
|
|
||||||
{
|
void getStatusBarText(const Points& points, std::string& text) override {
|
||||||
ASSERT(!points.empty());
|
ASSERT(!points.empty());
|
||||||
if (points.empty())
|
if (points.empty())
|
||||||
return;
|
return;
|
||||||
@ -302,16 +368,14 @@ public:
|
|||||||
sprintf(buf, "Pos %3d %3d", points[0].x, points[0].y);
|
sprintf(buf, "Pos %3d %3d", points[0].x, points[0].y);
|
||||||
text = buf;
|
text = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FourPointsController : public Controller {
|
class FourPointsController : public MoveOriginCapability {
|
||||||
public:
|
public:
|
||||||
void prepareController(ui::KeyModifiers modifiers) override {
|
|
||||||
m_movingOrigin = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pressButton(Points& points, const Point& point) override {
|
void pressButton(Points& points, const Point& point) override {
|
||||||
m_last = point;
|
MoveOriginCapability::pressButton(points, point);
|
||||||
|
|
||||||
if (points.size() == 0) {
|
if (points.size() == 0) {
|
||||||
points.resize(4, point);
|
points.resize(4, point);
|
||||||
@ -326,24 +390,9 @@ public:
|
|||||||
return m_clickCounter < 4;
|
return m_clickCounter < 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pressKey(ui::KeyScancode key) override {
|
|
||||||
return processKey(key, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool releaseKey(ui::KeyScancode key) override {
|
|
||||||
return processKey(key, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
||||||
if (m_movingOrigin) {
|
if (MoveOriginCapability::isMovingOrigin(points, point))
|
||||||
Point delta = (point - m_last);
|
|
||||||
for (auto& p : points)
|
|
||||||
p += delta;
|
|
||||||
m_last = point;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_last = point;
|
|
||||||
|
|
||||||
switch (m_clickCounter) {
|
switch (m_clickCounter) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -381,18 +430,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool processKey(ui::KeyScancode key, bool state) {
|
|
||||||
switch (key) {
|
|
||||||
case ui::kKeySpace:
|
|
||||||
m_movingOrigin = state;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int m_clickCounter;
|
int m_clickCounter;
|
||||||
bool m_movingOrigin;
|
|
||||||
Point m_last;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace tools
|
} // namespace tools
|
||||||
|
Loading…
Reference in New Issue
Block a user