diff options
| author | root <root@jtx.marker.es> | 2013-03-11 23:48:05 +0000 |
|---|---|---|
| committer | root <root@jtx.marker.es> | 2013-03-11 23:48:05 +0000 |
| commit | b2981a3b8f54bccfa45c76f57b38c9c93808d2fc (patch) | |
| tree | 59eae63d752f70b5ad26acc2852f82ebbb9f1563 /src | |
| parent | Merge from trunk (diff) | |
| download | inkscape-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.cpp | 6 | ||||
| -rw-r--r-- | src/live_effects/lpe-bspline.cpp | 135 | ||||
| -rw-r--r-- | src/live_effects/lpe-bspline.h | 5 | ||||
| -rw-r--r-- | src/pen-context.cpp | 50 | ||||
| -rw-r--r-- | src/pencil-context.cpp | 4 | ||||
| -rw-r--r-- | src/ui/tool/multi-path-manipulator.cpp | 4 | ||||
| -rw-r--r-- | src/ui/tool/node.cpp | 68 | ||||
| -rw-r--r-- | src/ui/tool/node.h | 3 |
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); |
