summaryrefslogtreecommitdiffstats
path: root/src/ui/tool/node.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/tool/node.cpp')
-rw-r--r--src/ui/tool/node.cpp184
1 files changed, 178 insertions, 6 deletions
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index 82eb697bd..8564f1f1a 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -13,7 +13,6 @@
#include <glib/gi18n.h>
#include <2geom/bezier-utils.h>
#include <2geom/transforms.h>
-
#include "display/sp-ctrlline.h"
#include "display/sp-canvas.h"
#include "display/sp-canvas-util.h"
@@ -29,6 +28,9 @@
#include "ui/tool/node.h"
#include "ui/tool/path-manipulator.h"
#include <gdk/gdkkeysyms.h>
+//BSpline
+#include <math.h>
+//BSpline End;
namespace {
@@ -135,7 +137,10 @@ void Handle::move(Geom::Point const &new_pos)
Node *node_away = _parent->nodeAwayFrom(this); // node in the opposite direction
Handle *towards = node_towards ? node_towards->handleAwayFrom(_parent) : NULL;
Handle *towards_second = node_towards ? node_towards->handleToward(_parent) : NULL;
-
+ //BSpline
+ Handle *h = NULL;
+ Handle *h2 = NULL;
+ //BSpline End
if (Geom::are_near(new_pos, _parent->position())) {
// The handle becomes degenerate.
// Adjust node type as necessary.
@@ -166,6 +171,30 @@ void Handle::move(Geom::Point const &new_pos)
}
}
setPosition(new_pos);
+ //BSpline
+ if(_pm().isBSpline){
+ h = this;
+ setPosition(_pm().BSplineHandleReposition(h));
+ _parent->bsplineWeight = _pm().BSplineHandlePosition(h);
+ //typedef ControlPointSelection::Set Set;
+ //Set &nodes = _parent->_selection.allPoints();
+ //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
+ // if((*i)->selected()){
+ // Node *n = static_cast<Node*>(*i);
+ // h = n->front();
+ // h2 = n->back();
+ // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight));
+ // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ //}
+ //}
+ //if(!_parent->selected()){
+ h = _parent->front();
+ h2 = _parent->back();
+ h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight));
+ h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ //}
+ }
+ //BSpline End
return;
}
@@ -177,6 +206,30 @@ void Handle::move(Geom::Point const &new_pos)
Geom::Point new_delta = (Geom::dot(delta, direction)
/ Geom::L2sq(direction)) * direction;
setRelativePos(new_delta);
+ //BSpline
+ if(_pm().isBSpline){
+ h = this;
+ setPosition(_pm().BSplineHandleReposition(h));
+ _parent->bsplineWeight = _pm().BSplineHandlePosition(h);
+ //typedef ControlPointSelection::Set Set;
+ //Set &nodes = _parent->_selection.allPoints();
+ //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
+ // if((*i)->selected()){
+ // Node *n = static_cast<Node*>(*i);
+ // h = n->front();
+ // h2 = n->back();
+ // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight));
+ // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ // }
+ //}
+ //if(!_parent->selected()){
+ h = _parent->front();
+ h2 = _parent->back();
+ h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight));
+ h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ //}
+ }
+ //BSpline End
return;
}
@@ -195,8 +248,31 @@ void Handle::move(Geom::Point const &new_pos)
break;
default: break;
}
-
setPosition(new_pos);
+ //BSpline
+ if(_pm().isBSpline){
+ h = this;
+ setPosition(_pm().BSplineHandleReposition(h));
+ _parent->bsplineWeight = _pm().BSplineHandlePosition(h);
+ //typedef ControlPointSelection::Set Set;
+ //Set &nodes = _parent->_selection.allPoints();
+ //for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
+ // if((*i)->selected()){
+ // Node *n = static_cast<Node*>(*i);
+ // h = n->front();
+ // h2 = n->back();
+ // h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight));
+ // h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ // }
+ //}
+ //if(!_parent->selected()){
+ h = _parent->front();
+ h2 = _parent->back();
+ h->setPosition(_pm().BSplineHandleReposition(h,_parent->bsplineWeight));
+ h2->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ //}
+ }
+ //BSpline End
}
void Handle::setPosition(Geom::Point const &p)
@@ -273,12 +349,33 @@ bool Handle::_eventHandler(SPEventContext *event_context, GdkEvent *event)
break;
default: break;
}
+ //BSpline
+ case GDK_2BUTTON_PRESS:
+ handle_2button_press();
+ break;
+ //BSpline End
default: break;
}
return ControlPoint::_eventHandler(event_context, event);
}
+//BSpline
+void Handle::handle_2button_press(){
+ if(_pm().isBSpline){
+ Handle *h = NULL;
+ Handle *h2 = NULL;
+ _parent->bsplineWeight = 0.0000;
+ h = this;
+ setPosition(_pm().BSplineHandleReposition(h,0.3334));
+ _parent->bsplineWeight = _pm().BSplineHandlePosition(h);
+ h2 = this->other();
+ this->other()->setPosition(_pm().BSplineHandleReposition(h2,_parent->bsplineWeight));
+ _pm().update();
+ }
+}
+//BSpline End
+
bool Handle::grabbed(GdkEventMotion *)
{
_saved_other_pos = other()->position();
@@ -289,6 +386,7 @@ bool Handle::grabbed(GdkEventMotion *)
void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
{
+
Geom::Point parent_pos = _parent->position();
Geom::Point origin = _last_drag_origin();
SnapManager &sm = _desktop->namedview->snap_manager;
@@ -326,10 +424,21 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
ctrl_constraint = Inkscape::Snapper::SnapConstraint(parent_pos, parent_pos - perp_pos);
}
new_pos = result;
+ //BSpline
+ if(_pm().isBSpline){
+ Handle *h = NULL;
+ _parent->bsplineWeight = 0.0000;
+ h = this;
+ setPosition(new_pos);
+ int steps = _pm().getSteps();
+ _parent->bsplineWeight = ceilf(_pm().BSplineHandlePosition(h)*steps)/steps;
+ new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight);
+ }
+ //BSpline End
}
std::vector<Inkscape::SnapCandidatePoint> unselected;
- if (snap) {
+ if (snap && ( (!held_control(*event) && _pm().isBSpline) || !_pm().isBSpline)) {
ControlPointSelection::Set &nodes = _parent->_selection.allPoints();
for (ControlPointSelection::Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
Node *n = static_cast<Node*>(*i);
@@ -355,6 +464,16 @@ void Handle::dragged(Geom::Point &new_pos, GdkEventMotion *event)
sm.freeSnapReturnByRef(new_pos, SNAPSOURCE_NODE_HANDLE);
}
sm.unSetup();
+ //BSpline
+ if(_pm().isBSpline){
+ Handle *h = NULL;
+ _parent->bsplineWeight = 0.0000;
+ h = this;
+ setPosition(new_pos);
+ _parent->bsplineWeight = _pm().BSplineHandlePosition(h);
+ new_pos=_pm().BSplineHandleReposition(h,_parent->bsplineWeight);
+ }
+ //BSpline End
}
@@ -385,6 +504,7 @@ void Handle::ungrabbed(GdkEventButton *event)
Geom::Point dist = _desktop->d2w(_parent->position()) - _desktop->d2w(position());
if (dist.length() <= drag_tolerance) {
move(_parent->position());
+ _parent->bsplineWeight = 0.0000;
}
}
@@ -514,6 +634,7 @@ Node::Node(NodeSharedData const &data, Geom::Point const &initial_pos) :
_type(NODE_CUSP),
_handles_shown(false)
{
+ this->bsplineWeight = 0.3334;
// NOTE we do not set type here, because the handles are still degenerate
}
@@ -553,13 +674,44 @@ void Node::move(Geom::Point const &new_pos)
// move handles when the node moves.
Geom::Point old_pos = position();
Geom::Point delta = new_pos - position();
+ //BSpline
+ double prevPos = 0.0000;
+ double nextPos = 0.0000;
+ Node *n = this;
+ Node * nextNode = n->nodeToward(n->front());
+ Node * prevNode = n->nodeToward(n->back());
+ if(_pm().isBSpline){
+ if(prevNode)
+ prevPos = _pm().BSplineHandlePosition(prevNode->front());
+ n->bsplineWeight = _pm().BSplineHandlePosition(n->front());
+ if(n->bsplineWeight == 0.0000)
+ n->bsplineWeight = _pm().BSplineHandlePosition(n->back());
+ if(nextNode)
+ nextPos = _pm().BSplineHandlePosition(nextNode->back());
+ }
+ //BSpline End
setPosition(new_pos);
+ //BSpline
+ if(_pm().isBSpline){
+ if(prevNode)
+ prevNode->front()->setPosition(_pm().BSplineHandleReposition(prevNode->front(),prevPos));
+ if(nextNode)
+ nextNode->back()->setPosition(_pm().BSplineHandleReposition(nextNode->back(),nextPos));
+ }
+ //BSpline End
_front.setPosition(_front.position() + delta);
_back.setPosition(_back.position() + delta);
-
+ //BSpline End
// if the node has a smooth handle after a line segment, it should be kept colinear
// with the segment
_fixNeighbors(old_pos, new_pos);
+ //BSpline
+ if(_pm().isBSpline){
+ Handle* front = &_front;
+ Handle* back = &_back;
+ _front.setPosition(_pm().BSplineHandleReposition(front,n->bsplineWeight));
+ _back.setPosition(_pm().BSplineHandleReposition(back,n->bsplineWeight));
+ }
}
void Node::transform(Geom::Affine const &m)
@@ -572,6 +724,11 @@ void Node::transform(Geom::Affine const &m)
/* Affine transforms keep handle invariants for smooth and symmetric nodes,
* but smooth nodes at ends of linear segments and auto nodes need special treatment */
_fixNeighbors(old_pos, position());
+ if(_pm().isBSpline){
+ _front.setPosition(_pm().BSplineHandleReposition(this->front(),this->bsplineWeight));
+ _back.setPosition(_pm().BSplineHandleReposition(this->back(),this->bsplineWeight));
+ _pm().BSplineNodeHandlesReposition(this);
+ }
}
Geom::Rect Node::bounds() const
@@ -675,7 +832,6 @@ void Node::setType(NodeType type, bool update_handles)
updateState(); // The size of the control might have changed
return;
}
-
// if update_handles is true, adjust handle positions to match the node type
// handle degenerate handles appropriately
if (update_handles) {
@@ -758,6 +914,16 @@ void Node::setType(NodeType type, bool update_handles)
break;
default: break;
}
+ //BSpline
+ if(_pm().isBSpline){
+ Handle* front = &_front;
+ Handle* back = &_back;
+ this->bsplineWeight = _pm().BSplineHandlePosition(front);
+ if(this->bsplineWeight !=0.0000) this->bsplineWeight = 0.3334;
+ _front.setPosition(_pm().BSplineHandleReposition(front,this->bsplineWeight));
+ _back.setPosition(_pm().BSplineHandleReposition(back,this->bsplineWeight));
+ }
+ //BSpline End
}
_type = type;
_setControlType(nodeTypeToCtrlType(_type));
@@ -1004,6 +1170,12 @@ void Node::_setState(State state)
case STATE_CLICKED:
mgr.setActive(_canvas_item, true);
mgr.setPrelight(_canvas_item, false);
+ //BSpline
+ if(_pm().isBSpline){
+ this->bsplineWeight = _pm().BSplineHandlePosition(this->back());
+ _pm().BSplineNodeHandlesReposition(this);
+ }
+ //BSpline End
break;
}
SelectableControlPoint::_setState(state);