mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-29 19:20:09 +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;
|
||||
|
||||
// Controls clicks for tools like pencil
|
||||
class FreehandController : public Controller {
|
||||
public:
|
||||
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 {
|
||||
// Shared logic between controllers that can move/displace all points
|
||||
// using the space bar.
|
||||
class MoveOriginCapability : public Controller {
|
||||
public:
|
||||
void prepareController(ui::KeyModifiers modifiers) override {
|
||||
m_squareAspect = (modifiers & ui::kKeyShiftModifier) ? true: false;
|
||||
m_fromCenter = (modifiers & ui::kKeyCtrlModifier) ? true: false;
|
||||
m_movingOrigin = false;
|
||||
}
|
||||
|
||||
void pressButton(Points& points, const Point& point) override {
|
||||
m_first = m_last = point;
|
||||
|
||||
points.push_back(point);
|
||||
points.push_back(point);
|
||||
}
|
||||
|
||||
bool releaseButton(Points& points, const Point& point) override {
|
||||
return false;
|
||||
m_last = point;
|
||||
}
|
||||
|
||||
bool pressKey(ui::KeyScancode key) override {
|
||||
@ -86,21 +36,132 @@ public:
|
||||
return processKey(key, false);
|
||||
}
|
||||
|
||||
void movement(ToolLoop* loop, Points& points, const Point& point) {
|
||||
ASSERT(points.size() >= 2);
|
||||
if (points.size() < 2)
|
||||
return;
|
||||
protected:
|
||||
bool isMovingOrigin(Points& points, const Point& point) {
|
||||
bool used = false;
|
||||
|
||||
if (m_movingOrigin) {
|
||||
Point delta = (point - m_last);
|
||||
for (auto& p : points)
|
||||
p += delta;
|
||||
m_first += delta;
|
||||
m_last = point;
|
||||
return;
|
||||
|
||||
onMoveOrigin(delta);
|
||||
used = true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (m_squareAspect) {
|
||||
@ -199,6 +260,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void onMoveOrigin(const Point& delta) override {
|
||||
m_first += delta;
|
||||
}
|
||||
|
||||
bool processKey(ui::KeyScancode key, bool state) {
|
||||
switch (key) {
|
||||
case ui::kKeyLShift:
|
||||
@ -209,29 +274,27 @@ private:
|
||||
case ui::kKeyRControl:
|
||||
m_fromCenter = state;
|
||||
return true;
|
||||
case ui::kKeySpace:
|
||||
m_movingOrigin = state;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Point m_first, m_last;
|
||||
Point m_first;
|
||||
bool m_squareAspect;
|
||||
bool m_fromCenter;
|
||||
bool m_movingOrigin;
|
||||
};
|
||||
|
||||
// Controls clicks for tools like polygon
|
||||
class PointByPointController : public Controller {
|
||||
class PointByPointController : public MoveOriginCapability {
|
||||
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);
|
||||
}
|
||||
bool releaseButton(Points& points, const Point& point)
|
||||
{
|
||||
|
||||
bool releaseButton(Points& points, const Point& point) override {
|
||||
ASSERT(!points.empty());
|
||||
if (points.empty())
|
||||
return false;
|
||||
@ -242,20 +305,23 @@ public:
|
||||
else
|
||||
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());
|
||||
if (points.empty())
|
||||
return;
|
||||
|
||||
if (MoveOriginCapability::isMovingOrigin(points, point))
|
||||
return;
|
||||
|
||||
points[points.size()-1] = point;
|
||||
}
|
||||
void getPointsToInterwine(const Points& input, Points& output)
|
||||
{
|
||||
|
||||
void getPointsToInterwine(const Points& input, Points& output) override {
|
||||
output = input;
|
||||
}
|
||||
void getStatusBarText(const Points& points, std::string& text)
|
||||
{
|
||||
|
||||
void getStatusBarText(const Points& points, std::string& text) override {
|
||||
ASSERT(!points.empty());
|
||||
if (points.empty())
|
||||
return;
|
||||
@ -267,6 +333,7 @@ public:
|
||||
points[points.size()-1].y);
|
||||
text = buf;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class OnePointController : public Controller {
|
||||
@ -275,25 +342,24 @@ public:
|
||||
bool canSnapToGrid() { return false; }
|
||||
bool isOnePoint() { return true; }
|
||||
|
||||
void pressButton(Points& points, const Point& point)
|
||||
{
|
||||
void pressButton(Points& points, const Point& point) override {
|
||||
if (points.size() == 0)
|
||||
points.push_back(point);
|
||||
}
|
||||
bool releaseButton(Points& points, const Point& point)
|
||||
{
|
||||
|
||||
bool releaseButton(Points& points, const Point& point) override {
|
||||
return false;
|
||||
}
|
||||
void movement(ToolLoop* loop, Points& points, const Point& point)
|
||||
{
|
||||
|
||||
void movement(ToolLoop* loop, Points& points, const Point& point) override {
|
||||
// Do nothing
|
||||
}
|
||||
void getPointsToInterwine(const Points& input, Points& output)
|
||||
{
|
||||
|
||||
void getPointsToInterwine(const Points& input, Points& output) override {
|
||||
output = input;
|
||||
}
|
||||
void getStatusBarText(const Points& points, std::string& text)
|
||||
{
|
||||
|
||||
void getStatusBarText(const Points& points, std::string& text) override {
|
||||
ASSERT(!points.empty());
|
||||
if (points.empty())
|
||||
return;
|
||||
@ -302,16 +368,14 @@ public:
|
||||
sprintf(buf, "Pos %3d %3d", points[0].x, points[0].y);
|
||||
text = buf;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class FourPointsController : public Controller {
|
||||
class FourPointsController : public MoveOriginCapability {
|
||||
public:
|
||||
void prepareController(ui::KeyModifiers modifiers) override {
|
||||
m_movingOrigin = false;
|
||||
}
|
||||
|
||||
void pressButton(Points& points, const Point& point) override {
|
||||
m_last = point;
|
||||
MoveOriginCapability::pressButton(points, point);
|
||||
|
||||
if (points.size() == 0) {
|
||||
points.resize(4, point);
|
||||
@ -326,24 +390,9 @@ public:
|
||||
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 {
|
||||
if (m_movingOrigin) {
|
||||
Point delta = (point - m_last);
|
||||
for (auto& p : points)
|
||||
p += delta;
|
||||
m_last = point;
|
||||
if (MoveOriginCapability::isMovingOrigin(points, point))
|
||||
return;
|
||||
}
|
||||
|
||||
m_last = point;
|
||||
|
||||
switch (m_clickCounter) {
|
||||
case 0:
|
||||
@ -381,18 +430,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool processKey(ui::KeyScancode key, bool state) {
|
||||
switch (key) {
|
||||
case ui::kKeySpace:
|
||||
m_movingOrigin = state;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int m_clickCounter;
|
||||
bool m_movingOrigin;
|
||||
Point m_last;
|
||||
};
|
||||
|
||||
} // namespace tools
|
||||
|
Loading…
x
Reference in New Issue
Block a user