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:
David Capello 2015-08-12 10:15:39 -03:00
parent 045f11bf68
commit 72015c092a

View File

@ -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