summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorroot <root@jtx.marker.es>2013-03-11 23:48:05 +0000
committerroot <root@jtx.marker.es>2013-03-11 23:48:05 +0000
commitb2981a3b8f54bccfa45c76f57b38c9c93808d2fc (patch)
tree59eae63d752f70b5ad26acc2852f82ebbb9f1563 /src
parentMerge from trunk (diff)
downloadinkscape-b2981a3b8f54bccfa45c76f57b38c9c93808d2fc.tar.gz
inkscape-b2981a3b8f54bccfa45c76f57b38c9c93808d2fc.zip
~sub fix, double click to reset default handles and control to 10% step
(bzr r11950.1.51)
Diffstat (limited to 'src')
-rw-r--r--src/draw-context.cpp6
-rw-r--r--src/live_effects/lpe-bspline.cpp135
-rw-r--r--src/live_effects/lpe-bspline.h5
-rw-r--r--src/pen-context.cpp50
-rw-r--r--src/pencil-context.cpp4
-rw-r--r--src/ui/tool/multi-path-manipulator.cpp4
-rw-r--r--src/ui/tool/node.cpp68
-rw-r--r--src/ui/tool/node.h3
8 files changed, 248 insertions, 27 deletions
diff --git a/src/draw-context.cpp b/src/draw-context.cpp
index dcd0fc7ec..356853e09 100644
--- a/src/draw-context.cpp
+++ b/src/draw-context.cpp
@@ -291,6 +291,7 @@ static void spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item
Effect::createAndApply(SPIRO, dc->desktop->doc(), item);
}
//BSpline
+ //Añadimos el modo BSpline a los efectos en espera
if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) {
Effect::createAndApply(BSPLINE, dc->desktop->doc(), item);
}
@@ -562,6 +563,8 @@ void spdc_concat_colors_and_flush(SPDrawContext *dc, gboolean forceclosed)
c->unref();
dc->sa->curve->closepath_current();
//BSpline
+ //Si la curva tiene un LPE del tipo BSpline ejecutamos spdc_flush_white
+ //pasándole la curva de inicio necesaria
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 ||
prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
@@ -696,6 +699,9 @@ SPDrawAnchor *spdc_test_inside(SPDrawContext *dc, Geom::Point p)
}
//BSpline
+ //Modificamos la curva del "anchor" final para que sea igual que la curva de inicio.
+ //Esta curva fue modificada al continuar la curva y necesitamos que sea igual que la curva en
+ //la que cerramos el trazado.
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
if((prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 ||
prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) &&
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index d91f7297e..fcca38e4c 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -11,7 +11,7 @@
#include <2geom/affine.h>
#include <2geom/bezier-curve.h>
#include "helper/geom-curves.h"
-
+#include <glibmm/i18n.h>
// For handling un-continuous paths:
#include "message-stack.h"
#include "inkscape.h"
@@ -21,8 +21,11 @@ namespace Inkscape {
namespace LivePathEffect {
LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) :
- Effect(lpeobject)
+ Effect(lpeobject),unify_weights(_("Unify weights:"),
+ _("Percent of the with for all poinrs"), "unify_weights", &wr, this, 33.)
{
+ registerParameter( dynamic_cast<Parameter *>(&unify_weights) );
+ unify_weights.param_set_range(0, 100.);
}
LPEBSpline::~LPEBSpline()
@@ -205,6 +208,134 @@ LPEBSpline::doEffect(SPCurve * curve)
}
}
+std::vector<Geom::Path>
+LPEBSpline::doEffect_path (std::vector<Geom::Path> const &path_in)
+{
+ Geom::PathVector const original_pathv = path_in;
+ SPCurve *curve = new SPCurve();
+ //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el penúltimo
+ for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
+ //Si está vacío...
+ if (path_it->empty())
+ continue;
+ //Itreadores
+
+ Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
+ Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
+ //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán
+ //los puntos clave para los manejadores.
+ //Esto hace que la curva BSpline no pierda su condición aunque se trasladen
+ //dichos manejadores
+ SPCurve *nCurve = new SPCurve();
+ Geom::Point previousNode(0,0);
+ Geom::Point node(0,0);
+ Geom::Point pointAt0(0,0);
+ Geom::Point pointAt1(0,0);
+ Geom::Point pointAt2(0,0);
+ Geom::Point pointAt3(0,0);
+ double pos1 = 0;
+ double pos2 = 0;
+ Geom::Point nextPointAt1(0,0);
+ Geom::Point nextPointAt2(0,0);
+ Geom::Point nextPointAt3(0,0);
+ Geom::D2< Geom::SBasis > SBasisIn;
+ Geom::D2< Geom::SBasis > SBasisOut;
+ Geom::D2< Geom::SBasis > SBasisHelper;
+ Geom::CubicBezier const *cubic = NULL;
+ if (path_it->closed()) {
+ // if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength.
+ const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment.
+ if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
+ // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors...
+ // the closing line segment has zero-length. So stop before that one!
+ curve_endit = path_it->end_open();
+ }
+ }
+ //Si la curva está cerrada calculamos el punto donde
+ //deveria estar el nodo BSpline de cierre/inicio de la curva
+ //en posible caso de que se cierre con una linea recta creando un nodo BSPline
+
+ //Recorremos todos los segmentos menos el último
+ while ( curve_it2 != curve_endit )
+ {
+ //previousPointAt3 = pointAt3;
+ //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida
+ SPCurve * in = new SPCurve();
+ in->moveto(curve_it1->initialPoint());
+ in->lineto(curve_it1->finalPoint());
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if(cubic){
+ SBasisIn = in->first_segment()->toSBasis();
+ pointAt0 = in->first_segment()->initialPoint();
+ pos1 = unify_weights/100;
+ pos2 = 1-unify_weights/100;
+ pointAt1 = SBasisIn.valueAt(pos1);
+ pointAt2 = SBasisIn.valueAt(pos2);
+ pointAt3 = in->first_segment()->finalPoint();
+ }else{
+ pointAt0 = in->first_segment()->initialPoint();
+ pointAt1 = in->first_segment()->initialPoint();
+ pointAt2 = in->first_segment()->finalPoint();
+ pointAt3 = in->first_segment()->finalPoint();
+ }
+ in->reset();
+ delete in;
+ //Y hacemos lo propio con el path de salida
+ //nextPointAt0 = curveOut.valueAt(0);
+ SPCurve * out = new SPCurve();
+ out->moveto(curve_it2->initialPoint());
+ out->lineto(curve_it2->finalPoint());
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
+ if(cubic){
+ SBasisOut = out->first_segment()->toSBasis();
+ pos1 = unify_weights/100;
+ pos2 = 1-unify_weights/100;
+ nextPointAt1 = SBasisOut.valueAt(pos1);
+ nextPointAt2 = SBasisOut.valueAt(pos2);
+ nextPointAt3 = (*cubic)[3];
+ }else{
+ nextPointAt1 = out->first_segment()->initialPoint();
+ nextPointAt2 = out->first_segment()->finalPoint();
+ nextPointAt3 = out->first_segment()->finalPoint();
+ }
+ out->reset();
+ delete out;
+ //Y este hará de final de curva
+ SPCurve *curveHelper = new SPCurve();
+ curveHelper->moveto(pointAt0);
+ curveHelper->curveto(pointAt1, pointAt2, pointAt3);
+ //añadimos la curva generada a la curva pricipal
+ nCurve->append_continuous(curveHelper, 0.0625);
+ curveHelper->reset();
+ delete curveHelper;
+ //aumentamos los valores para el siguiente paso en el bucle
+ ++curve_it1;
+ ++curve_it2;
+ }
+ //Aberiguamos la ultima parte de la curva correspondiente al último segmento
+ SPCurve *curveHelper = new SPCurve();
+ curveHelper->moveto(node);
+ //Si está cerrada la curva, la cerramos sobre el valor guardado previamente
+ //Si no finalizamos en el punto final
+ Geom::Point startNode(0,0);
+ startNode = path_it->begin()->initialPoint();
+ curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
+ nCurve->append_continuous(curveHelper, 0.0625);
+ nCurve->move_endpoints(startNode,nextPointAt3);
+ curveHelper->reset();
+ delete curveHelper;
+ //y cerramos la curva
+ if (path_it->closed()) {
+ nCurve->closepath_current();
+ }
+ curve->append(nCurve,false);
+ nCurve->reset();
+ delete nCurve;
+ }
+ return curve->get_pathvector();
+}
+
}; //namespace LivePathEffect
}; /* namespace Inkscape */
diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h
index d983a7654..27c79f040 100644
--- a/src/live_effects/lpe-bspline.h
+++ b/src/live_effects/lpe-bspline.h
@@ -8,7 +8,7 @@
*/
#include "live_effects/effect.h"
-
+#include "live_effects/parameter/parameter.h"
namespace Inkscape {
namespace LivePathEffect {
@@ -18,11 +18,14 @@ public:
LPEBSpline(LivePathEffectObject *lpeobject);
virtual ~LPEBSpline();
+ virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & input_path);
+
virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; }
virtual void doEffect(SPCurve * curve);
private:
+ ScalarParam unify_weights;
LPEBSpline(const LPEBSpline&);
LPEBSpline& operator=(const LPEBSpline&);
};
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 6232c5e59..79e4cbabf 100644
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
@@ -45,7 +45,7 @@
#include "tools-switch.h"
#include "ui/control-manager.h"
//BSpline
-//Incluimos
+//Incluimos los archivos necesarios para las BSpline y Spiro
#define INKSCAPE_LPE_SPIRO_C
#include "live_effects/lpe-spiro.h"
@@ -86,23 +86,27 @@ static void spdc_pen_set_initial_point(SPPenContext *pc, Geom::Point const p);
*BSpline
*Added functions
*/
-
-/*
- *Sobrecarga la función "sp_pen_context_set_polyline_mode"
- *Le da valor a la nueva propiedad "pc->spiro" que como se auto define indica si estamos en modo spiro
- *En el futuro se la dará a "pc->bspline"
-*/
+//Añade los modos spiro y bspline
static void sp_pen_context_set_mode(SPPenContext *const pc, guint mode);
//Esta función cambia los colores rojo,verde y azul haciendolos transparentes o no en función de si se usa spiro
static void bspline_spiro_color(SPPenContext *const pc);
+//Crea un nodo en modo bspline o spiro
static void bspline_spiro(SPPenContext *const pc,bool shift);
+//Crea un nodo de modo spiro o bspline
static void bspline_spiro_on(SPPenContext *const pc);
+//Crea un nodo de tipo CUSP
static void bspline_spiro_off(SPPenContext *const pc);
+//Continua una curva existente en modo bspline o spiro
static void bspline_spiro_start_anchor(SPPenContext *const pc,bool shift);
+//Continua una curva exsitente con el nodo de union en modo bspline o spiro
static void bspline_spiro_start_anchor_on(SPPenContext *const pc);
+//Continua una curva existente con el nodo de union en modo CUSP
static void bspline_spiro_start_anchor_off(SPPenContext *const pc);
+//Modifica la "red_curve" cuando se detecta movimiento
static void bspline_spiro_motion(SPPenContext *const pc,bool shift);
+//Cierra la curva con el último nodo en modo bspline o spiro
static void bspline_spiro_end_anchor_on(SPPenContext *const pc);
+//Cierra la curva con el último nodo en modo CUSP
static void bspline_spiro_end_anchor_off(SPPenContext *const pc);
//Unimos todas las curvas en juego y llamamos a la función doEffect.
static void bspline_spiro_build(SPPenContext *const pc);
@@ -224,7 +228,7 @@ void sp_pen_context_set_polyline_mode(SPPenContext *const pc) {
pc->polylines_only = (mode == 3 || mode == 4);
pc->polylines_paraxial = (mode == 4);
//BSpline
- //we call the function which defines the Spiro modes and the B-spline in the future
+ //we call the function which defines the Spiro modes and the BSpline
//todo: merge to one function only
sp_pen_context_set_mode(pc, mode);
//BSpline End
@@ -232,7 +236,7 @@ void sp_pen_context_set_polyline_mode(SPPenContext *const pc) {
//BSpline
/*
-*.Set the mode of draw now spiro, and later b-splines
+*.Set the mode of draw spiro, and bsplines
*/
void sp_pen_context_set_mode(SPPenContext *const pc, guint mode) {
pc->spiro = (mode == 1);
@@ -461,7 +465,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
//Test whether we hit any anchor.
SPDrawAnchor * const anchor = spdc_test_inside(pc, event_w);
//with this we avoid creating a new point over the existing one
- if((pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){
+ if(!bevent.button == 3 && (pc->spiro || pc->bspline) && pc->npoints > 0 && pc->p[0] == pc->p[3]){
return FALSE;
}
//BSpline end
@@ -529,9 +533,9 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
// Set start anchor
pc->sa = anchor;
//BSpline
+ //Continuamos una curva existente
if(anchor){
- if(pc->bspline || pc->spiro)
- bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK));
+ bspline_spiro_start_anchor(pc,(bevent.state & GDK_SHIFT_MASK));
}
//BSpline End
if (anchor && !sp_pen_context_has_waiting_LPE(pc)) {
@@ -585,8 +589,7 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
}
}
//BSpline
- //Esto evita arrastrar los manejadores ya que el punto se crea
- //al soltar el botón del ratón.
+ //Evitamos la creación de un punto de control para que se cree el nodo en el evento de soltar
pc->state = (pc->spiro || pc->bspline || pc->polylines_only) ? SP_PEN_CONTEXT_POINT : SP_PEN_CONTEXT_CONTROL;
//BSpline End
ret = TRUE;
@@ -778,6 +781,7 @@ static gint pen_handle_motion_notify(SPPenContext *const pc, GdkEventMotion cons
break;
}
//BSpline
+ //Lanzamos la función "bspline_spiro_motion" al moverse el ratón o cuando se para.
if ( Geom::LInfty( event_w - pen_drag_origin_w ) > tolerance || mevent.time == 0) {
bspline_spiro_motion(pc,(mevent.state & GDK_SHIFT_MASK));
pen_drag_origin_w = event_w;
@@ -809,6 +813,7 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con
// Test whether we hit any anchor.
SPDrawAnchor *anchor = spdc_test_inside(pc, event_w);
//BSpline
+ //with this we avoid creating a new point over the existing one
if(pc->spiro || pc->bspline){
//Si intentamos crear un nodo en el mismo sitio que el origen, paramos.
if(pc->npoints > 0 && pc->p[0] == pc->p[3]){
@@ -827,6 +832,7 @@ static gint pen_handle_button_release(SPPenContext *const pc, GdkEventButton con
}
pc->sa = anchor;
//BSpline
+ //continuamos una curva existente
if (anchor) {
if(pc->bspline || pc->spiro){
bspline_spiro_start_anchor(pc,(revent.state & GDK_SHIFT_MASK));
@@ -982,6 +988,7 @@ static void pen_redraw_all (SPPenContext *const pc)
// handles
//BSpline
+ //Ocultamos los tiradores en modo BSpline y spiro
if (pc->p[0] != pc->p[1] && !pc->spiro && !pc->bspline) {
//BSpline End
SP_CTRL(pc->c1)->moveto(pc->p[1]);
@@ -997,6 +1004,7 @@ static void pen_redraw_all (SPPenContext *const pc)
if (last_seg) {
Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const *>( last_seg );
//BSpline
+ //Ocultamos los tiradores en modo BSpline y spiro
if ( cubic &&
(*cubic)[2] != pc->p[0] && !pc->spiro && !pc->bspline )
{
@@ -1017,6 +1025,7 @@ static void pen_redraw_all (SPPenContext *const pc)
//sino al final de esta
//BSpline
+ //Lanzamos solamente el redibujado
bspline_spiro_build(pc);
//BSpline End
}
@@ -1056,8 +1065,7 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc)
//BSpline
Geom::CubicBezier const * cubic;
pc->p[1] = pc->red_curve->last_segment()->initialPoint() + (1./3)* (Geom::Point)(pc->red_curve->last_segment()->finalPoint() - pc->red_curve->last_segment()->initialPoint());
- //Para formar una curva necesitamos un nodo symm en el "lastpoint"
- //de esta manera modificamos el final de la "curva_verde" para que sea symm con el pricipio de la "red_curve"
+ //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos
if(pc->spiro||pc->bspline){
if(!pc->green_curve->is_empty()){
Geom::Point A(0,0);
@@ -1095,6 +1103,7 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc)
pc->green_curve->append_continuous(previous, 0.0625);
}
}
+ //Si el último nodo es una union con otra curva
if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){
bspline_spiro_start_anchor(pc, false);
}
@@ -1107,9 +1116,11 @@ static void pen_lastpoint_tocurve (SPPenContext *const pc)
static void pen_lastpoint_toline (SPPenContext *const pc)
{
//BSpline
- //Si no es bspline
+ //Evitamos que si la "red_curve" tiene solo dos puntos -recta- no se pare aqui.
if (pc->npoints != 5 && !pc->bspline)
return;
+
+ //Modificamos el último segmento de la curva verde para que forme el tipo de nodo que deseamos
if(pc->spiro || pc->bspline){
if(!pc->green_curve->is_empty()){
Geom::Point A(0,0);
@@ -1141,6 +1152,7 @@ static void pen_lastpoint_toline (SPPenContext *const pc)
pc->green_curve->append_continuous(previous, 0.0625);
}
}
+ //Si el último nodo es una union con otra curva
if(pc->green_curve->is_empty() && pc->sa && !pc->sa->curve->is_empty()){
bspline_spiro_start_anchor(pc, true);
}
@@ -1329,6 +1341,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event)
} else {
pc->p[1] = pc->p[0];
}
+ //Asignamos el valor a un tercio de distancia del último segmento.
if(pc->bspline){
pc->p[1] = pc->p[0] + (1./3)*(pc->p[3] - pc->p[0]);
}
@@ -1339,6 +1352,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event)
pc->npoints = 2;
//BSpline
+ //Eliminamos el último segmento de la curva verde
if( pc->green_curve->get_segment_count() == 1){
pc->npoints = 5;
if (pc->green_bpaths) {
@@ -1350,6 +1364,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event)
}else{
pc->green_curve->backspace();
}
+ //Asignamos el valor de pc->p[1] a el opuesto de el ultimo segmento de la línea verde
if(pc->spiro){
cubic = dynamic_cast<Geom::CubicBezier const *>(pc->green_curve->last_segment());
if ( cubic ) {
@@ -1366,6 +1381,7 @@ static gint pen_handle_key_press(SPPenContext *const pc, GdkEvent *event)
spdc_pen_set_subsequent_point(pc, pt, true);
pen_last_paraxial_dir = !pen_last_paraxial_dir;
//BSpline
+ //Redibujamos
bspline_spiro_build(pc);
//BSpline End
ret = TRUE;
diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp
index 1ece4528a..37df2588a 100644
--- a/src/pencil-context.cpp
+++ b/src/pencil-context.cpp
@@ -757,7 +757,8 @@ interpolate(SPPencilContext *pc)
guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0);
//BSpline End
for (int c = 0; c < n_segs; c++) {
- //BSpline
+ //BSpline
+ //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc
if(mode == 2){
Geom::Point BP = b[4*c+0] + (1./3)*(b[4*c+3] - b[4*c+0]);
Geom::Point CP = b[4*c+3] + (1./3)*(b[4*c+0] - b[4*c+3]);
@@ -907,6 +908,7 @@ fit_and_split(SPPencilContext *pc)
pc->red_curve->reset();
pc->red_curve->moveto(b[0]);
//BSpline
+ //Si el modo es BSpline modificamos para que el trazado cree los nodos adhoc
Inkscape::Preferences *prefs = Inkscape::Preferences::get();
guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0);
if(mode == 2){
diff --git a/src/ui/tool/multi-path-manipulator.cpp b/src/ui/tool/multi-path-manipulator.cpp
index c9e35e5b2..2ef8c1766 100644
--- a/src/ui/tool/multi-path-manipulator.cpp
+++ b/src/ui/tool/multi-path-manipulator.cpp
@@ -296,6 +296,7 @@ void MultiPathManipulator::invertSelectionInSubpaths()
invokeForAll(&PathManipulator::invertSelectionInSubpaths);
}
+
void MultiPathManipulator::setNodeType(NodeType type)
{
if (_selection.empty()) return;
@@ -307,7 +308,7 @@ void MultiPathManipulator::setNodeType(NodeType type)
Node *node = dynamic_cast<Node*>(*i);
if (node) {
retract_handles &= (node->type() == NODE_CUSP);
- node->setType(type);
+ node->setType(type,true);
}
}
@@ -324,6 +325,7 @@ void MultiPathManipulator::setNodeType(NodeType type)
_done(retract_handles ? _("Retract handles") : _("Change node type"));
}
+
void MultiPathManipulator::setSegmentType(SegmentType type)
{
if (_selection.empty()) return;
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index e7d62d619..bee2cc477 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -29,6 +29,9 @@
#include "ui/tool/node.h"
#include "ui/tool/path-manipulator.h"
#include <gdk/gdkkeysyms.h>
+//BSpline
+#include <math.h>
+//BSpline End;
namespace {
@@ -146,10 +149,11 @@ void Handle::move(Geom::Point const &new_pos)
Set &nodes = _parent->_selection.allPoints();
for (Set::iterator i = nodes.begin(); i != nodes.end(); ++i) {
Node *n = static_cast<Node*>(*i);
- _parent->_selection.erase(n);
- }
- //if(!_parent->selected())
- _parent->_selection.insert(_parent);
+ if(n != _parent)
+ _parent->_selection.erase(n);
+ }
+ if(!_parent->selected())
+ _parent->_selection.insert(_parent);
}
//BSpline End
@@ -307,12 +311,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;
+ double pos = 0;
+ h = this;
+ setPosition(_pm().BSplineHandleReposition(h,0.3334));
+ pos = _pm().BSplineHandlePosition(h);
+ h2 = this->other();
+ this->other()->setPosition(_pm().BSplineHandleReposition(h2,pos));
+ _pm().update();
+ }
+}
+//BSpline End
+
bool Handle::grabbed(GdkEventMotion *)
{
_saved_other_pos = other()->position();
@@ -360,6 +385,16 @@ 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;
+ double pos = 0;
+ h = this;
+ setPosition(new_pos);
+ pos = ceilf(_pm().BSplineHandlePosition(h)*10)/10;
+ new_pos=_pm().BSplineHandleReposition(h,pos);
+ }
+ //BSpline End
}
std::vector<Inkscape::SnapCandidatePoint> unselected;
@@ -728,7 +763,7 @@ void Node::updateHandles()
_front._handleControlStyling();
_back._handleControlStyling();
}
-
+
void Node::setType(NodeType type, bool update_handles)
{
@@ -738,6 +773,27 @@ void Node::setType(NodeType type, bool update_handles)
return;
}
+ //BSpline
+ if(_pm().isBSpline()){
+ if (isEndNode()) return;
+ Handle* front = &_front;
+ Handle* back = &_back;
+ double pos = 0.3334;
+ switch (type) {
+ case NODE_CUSP:
+ if(update_handles)
+ pos = 0;
+ else
+ pos = _pm().BSplineHandlePosition(front);;
+ break;
+ default: break;
+ }
+ type = NODE_CUSP;
+ _front.setPosition(_pm().BSplineHandleReposition(front,pos));
+ _back.setPosition(_pm().BSplineHandleReposition(back,pos));
+ }
+ //BSpline End
+
// if update_handles is true, adjust handle positions to match the node type
// handle degenerate handles appropriately
if (update_handles) {
@@ -821,7 +877,9 @@ void Node::setType(NodeType type, bool update_handles)
default: break;
}
}
+
_type = type;
+
_setControlType(nodeTypeToCtrlType(_type));
updateState();
}
diff --git a/src/ui/tool/node.h b/src/ui/tool/node.h
index 591dd8532..e74698b1a 100644
--- a/src/ui/tool/node.h
+++ b/src/ui/tool/node.h
@@ -107,6 +107,9 @@ protected:
Handle(NodeSharedData const &data, Geom::Point const &initial_pos, Node *parent);
virtual bool _eventHandler(SPEventContext *event_context, GdkEvent *event);
+ //Bspline
+ virtual void handle_2button_press();
+ //BSpline End
virtual void dragged(Geom::Point &new_pos, GdkEventMotion *event);
virtual bool grabbed(GdkEventMotion *event);
virtual void ungrabbed(GdkEventButton *event);