Index: synfig-studio/src/gtkmm/duckmatic.cpp =================================================================== --- synfig-studio/src/gtkmm/duckmatic.cpp (revision 1877) +++ synfig-studio/src/gtkmm/duckmatic.cpp (working copy) @@ -1568,6 +1568,7 @@ synfigapp::ValueDesc(value_node,i))); duck->set_value_desc(synfigapp::ValueDesc(value_node,i)); + bezier->parent_bline_id = value_node->get_guid(); add_bezier(bezier); bezier=0; } @@ -1693,6 +1694,7 @@ synfigapp::ValueDesc(value_node,first))); duck->set_value_desc(synfigapp::ValueDesc(value_node,first)); + bezier->parent_bline_id = value_node->get_guid(); add_bezier(bezier); bezier=0; } Index: synfig-studio/src/gtkmm/canvasview.cpp =================================================================== --- synfig-studio/src/gtkmm/canvasview.cpp (revision 1877) +++ synfig-studio/src/gtkmm/canvasview.cpp (working copy) @@ -53,6 +53,10 @@ #include #include #include +#include +#include +#include +#include #include #include @@ -2581,6 +2585,79 @@ bool CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc) { + if( ValueNode_BLineCalcVertex::Handle bline_vertex = + ValueNode_BLineCalcVertex::Handle::cast_dynamic(value_desc.get_value_node()) + ) + { + WorkArea* w_area = get_work_area(); + float bezier_pos; + float radius( ( abs( w_area->get_pw() ) + abs( w_area->get_ph() ) ) * 4 ); + Real d,step; + float time = 0; + float best_time = 0; + int best_index = 0; + + if(radius==0)radius=10000000; + Real closest(10000000); + + int i = 0; + for(std::list >::const_iterator iter=w_area->bezier_list().begin();iter!=w_area->bezier_list().end();++iter) + { + if((*iter)->parent_bline_id != bline_vertex->get_link(0)->get_guid()) + continue; + + i++; + + bezier curve; + + curve[0] = (*iter)->p1->get_trans_point(); + curve[1] = (*iter)->c1->get_trans_point(); + curve[2] = (*iter)->c2->get_trans_point(); + curve[3] = (*iter)->p2->get_trans_point(); + curve.sync(); + + #if 0 + // I don't know why this doesn't work + time=curve.find_closest(pos,6); + d=((curve(time)-pos).mag_squared()); + + #else + //set the step size based on the size of the picture + d = (curve[1] - curve[0]).mag() + (curve[2]-curve[1]).mag() + (curve[3]-curve[2]).mag(); + + step = d/(2*radius); //want to make the distance between lines happy + + step = max(step,0.01); //100 samples should be plenty + step = min(step,0.1); //10 is minimum + + d = find_closest(curve,value,step,&closest,&time); + #endif + + if(d < closest) + { + closest = d; + best_time = time; + best_index = i; + } + + } + + if(closest < radius*radius) + { + ValueNode_DynamicList::Handle bline_value_node(ValueNode_DynamicList::Handle::cast_dynamic(bline_vertex->get_link(0))); + bool loop(bline_value_node->get_loop()); + int loop_adjust(loop ? 0 : -1); + const std::vector bline((*bline_value_node)(time)); + int size = bline.size(); + Real amount = (best_index + best_time + loop_adjust) / (size + loop_adjust); + + return canvas_interface()->change_value(synfigapp::ValueDesc(bline_vertex,2), amount); + } + else + return true; + + } + switch(value_desc.get_value_type()) { case ValueBase::TYPE_REAL: Index: synfig-studio/src/gtkmm/duckmatic.h =================================================================== --- synfig-studio/src/gtkmm/duckmatic.h (revision 1877) +++ synfig-studio/src/gtkmm/duckmatic.h (working copy) @@ -425,6 +425,8 @@ bool is_valid()const { return p1 && p2 && c1 && c2; } sigc::signal &signal_user_click(int i=0) { assert(i>=0); assert(i<5); return signal_user_click_[i]; } + + synfig::GUID parent_bline_id; }; // END of struct Duckmatic::Bezier /*! \struct Duckmatic::Stroke Index: synfig-studio/src/synfigapp/instance.cpp =================================================================== --- synfig-studio/src/synfigapp/instance.cpp (revision 1877) +++ synfig-studio/src/synfigapp/instance.cpp (working copy) @@ -38,6 +38,7 @@ #include #include #include +#include #include #include "general.h" @@ -67,6 +68,7 @@ || ValueNode_Composite::Handle::cast_dynamic(value_node) || ValueNode_RadialComposite::Handle::cast_dynamic(value_node) || ValueNode_Reference::Handle::cast_dynamic(value_node) + || ValueNode_BLineCalcVertex::Handle::cast_dynamic(value_node) ) return true; return false;