Remove .gitignore do nothing is ignored.
[synfig.git] / synfig-studio / trunk / src / gtkmm / duckmatic.cpp
index ac70cfd..0d88982 100644 (file)
@@ -254,9 +254,10 @@ Duckmatic::is_duck_group_selectable(const etl::handle<Duck>& x)const
                 !x->get_editable()))
                return false;
 
-       if(x->get_value_desc().parent_is_layer_param() && type & Duck::TYPE_POSITION)
+       synfigapp::ValueDesc value_desc(x->get_value_desc());
+       if(value_desc.parent_is_layer_param() && type & Duck::TYPE_POSITION)
        {
-               Layer::Handle layer(x->get_value_desc().get_layer());
+               Layer::Handle layer(value_desc.get_layer());
                String layer_name(layer->get_name());
 
                if (layer_name == "outline" || layer_name == "region" || layer_name == "plant" ||
@@ -267,6 +268,30 @@ Duckmatic::is_duck_group_selectable(const etl::handle<Duck>& x)const
                   !layer->get_param("children_lock").get(bool()))
                        return false;
        }
+       else if (value_desc.parent_is_value_node())
+       {
+               if (ValueNode_BLineCalcVertex::Handle::cast_dynamic(value_desc.get_value_node()))
+                       return false;
+               if (value_desc.parent_is_linkable_value_node())
+               {
+                       LinkableValueNode::Handle parent_value_node(value_desc.get_parent_value_node());
+                       if (ValueNode_Composite::Handle::cast_dynamic(parent_value_node))
+                       {
+                               if (parent_value_node->get_type() == ValueBase::TYPE_BLINEPOINT &&
+                                       ValueNode_BLineCalcVertex::Handle::cast_dynamic(
+                                               parent_value_node->get_link("point")))
+                                       return false;
+                       }
+                       else if (ValueNode_BLine::Handle::cast_dynamic(parent_value_node))
+                       {
+                               ValueNode_Composite::Handle composite(ValueNode_Composite::Handle::cast_dynamic(
+                                                                                                                 value_desc.get_value_node()));
+                               if (composite &&
+                                       ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))
+                                       return false;
+                       }
+               }
+       }
        return true;
 }
 
@@ -282,6 +307,14 @@ Duckmatic::select_all_ducks()
 }
 
 void
+Duckmatic::unselect_all_ducks()
+{
+       DuckMap::const_iterator iter;
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter)
+               unselect_duck(iter->second);
+}
+
+void
 Duckmatic::toggle_select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br)
 {
        Vector vmin, vmax;
@@ -366,8 +399,14 @@ Duckmatic::get_duck_list()const
 {
        DuckList ret;
        DuckMap::const_iterator iter;
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter) if (iter->second->get_type()&Duck::TYPE_POSITION) ret.push_back(iter->second);
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter) if (iter->second->get_type()&Duck::TYPE_VERTEX  ) ret.push_back(iter->second);
+       for(iter=duck_map.begin();iter!=duck_map.end();++iter) if (iter->second->get_type()&Duck::TYPE_TANGENT ) ret.push_back(iter->second);
        for(iter=duck_map.begin();iter!=duck_map.end();++iter)
-               ret.push_back(iter->second);
+               if (!(iter->second->get_type()&Duck::TYPE_POSITION) &&
+                       !(iter->second->get_type()&Duck::TYPE_VERTEX) &&
+                       !(iter->second->get_type()&Duck::TYPE_TANGENT))
+                       ret.push_back(iter->second);
        return ret;
 }
 
@@ -518,7 +557,13 @@ DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector
                {
                        duck->set_trans_point(positions[i]+vect);
 
-                       if (ValueNode_BLineCalcVertex::Handle bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node()))
+                       ValueNode_BLineCalcVertex::Handle bline_vertex;
+                       ValueNode_Composite::Handle composite;
+
+                       if ((bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node())) ||
+                               ((composite = ValueNode_Composite::Handle::cast_dynamic(duck->get_value_desc().get_value_node())) &&
+                                composite->get_type() == ValueBase::TYPE_BLINEPOINT &&
+                                (bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))))
                        {
                                synfig::Point closest_point = duck->get_point();
                                synfig::Real radius = 0.0;
@@ -544,68 +589,55 @@ DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector
        for (iter=selected_ducks.begin(); iter!=selected_ducks.end(); ++iter)
        {
                etl::handle<Duck> duck(*iter);
-               if ((duck->get_type() == Duck::TYPE_VERTEX || duck->get_type() == Duck::TYPE_POSITION) &&
-                       duck->get_value_desc().parent_is_value_node())
+               if (duck->get_type() == Duck::TYPE_VERTEX || duck->get_type() == Duck::TYPE_POSITION)
                {
-                       ValueNode_BLineCalcVertex::Handle bline_vertex(ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node()));
-                       if (bline_vertex)
-                       {
-                               ValueNode_Composite::Handle value_node_composite(ValueNode_Composite::Handle::cast_dynamic(duck->get_value_desc().get_parent_value_node()));
-                               if (value_node_composite &&
-                                       value_node_composite->get_type() == ValueBase::TYPE_BLINEPOINT)
-                               {
-                                       int t1_index(value_node_composite->get_link_index_from_name("t1"));
-                                       int t2_index(value_node_composite->get_link_index_from_name("t2"));
-                                       int width_index(value_node_composite->get_link_index_from_name("width"));
-                                       int vertex_amount_index(bline_vertex->get_link_index_from_name("amount"));
+                       ValueNode_BLineCalcVertex::Handle bline_vertex;
+                       ValueNode_Composite::Handle composite;
 
-                                       ValueNode::Handle t1_value_node(value_node_composite->get_link(t1_index));
-                                       ValueNode::Handle t2_value_node(value_node_composite->get_link(t2_index));
-                                       ValueNode::Handle width_value_node(value_node_composite->get_link(width_index));
-                                       ValueNode::Handle amount_value_node(bline_vertex->get_link(vertex_amount_index));
+                       if ((bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(duck->get_value_desc().get_value_node())) ||
+                               ((composite = ValueNode_Composite::Handle::cast_dynamic(duck->get_value_desc().get_value_node())) &&
+                                composite->get_type() == ValueBase::TYPE_BLINEPOINT &&
+                                (bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(composite->get_link("point")))))
+                       {
+                               synfig::Real radius = 0.0;
+                               ValueNode_BLine::Handle bline(ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline"))));
+                               Real amount = synfig::find_closest_point((*bline)(time), duck->get_point(), radius, bline->get_loop());
 
-                                       ValueNode_BLineCalcTangent::Handle bline_tangent_1(ValueNode_BLineCalcTangent::Handle::cast_dynamic(t1_value_node));
-                                       ValueNode_BLineCalcTangent::Handle bline_tangent_2(ValueNode_BLineCalcTangent::Handle::cast_dynamic(t2_value_node));
-                                       ValueNode_BLineCalcWidth::Handle bline_width(ValueNode_BLineCalcWidth::Handle::cast_dynamic(width_value_node));
+                               int vertex_amount_index(bline_vertex->get_link_index_from_name("amount"));
+                               ValueNode::Handle vertex_amount_value_node(bline_vertex->get_link(vertex_amount_index));
 
-                                       if (bline_tangent_1 || bline_tangent_2 || bline_width)
+                               DuckList::iterator iter;
+                               for (iter=duck_list.begin(); iter!=duck_list.end(); iter++)
+                               {
+                                       ValueNode::Handle duck_value_node((*iter)->get_value_desc().get_value_node());
+                                       if (ValueNode_BLineCalcTangent::Handle bline_tangent = ValueNode_BLineCalcTangent::Handle::cast_dynamic(duck_value_node))
                                        {
-                                               synfig::Real radius = 0.0;
-                                               ValueNode_BLine::Handle bline(ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline"))));
-                                               Real amount = synfig::find_closest_point((*bline)(time), duck->get_point(), radius, bline->get_loop());
-
-                                               // we need to update the position of the tangent ducks - but how do we find these ducks?
-                                               // this is a brute force search - but is there a better way to do it?
-                                               if (bline_tangent_1 &&
-                                                       bline_tangent_1->get_link(bline_tangent_1->get_link_index_from_name("amount")) == amount_value_node)
+                                               if (bline_tangent->get_link(bline_tangent->get_link_index_from_name("amount")) == vertex_amount_value_node)
                                                {
-                                                       Vector tangent = (*bline_tangent_1)(time, amount).get(Vector());
-                                                       DuckList::iterator iter;
-                                                       for (iter=duck_list.begin(); iter!=duck_list.end(); iter++)
-                                                               if ((*iter)->get_value_desc().get_value_node() == t1_value_node)
-                                                                       (*iter)->set_point(tangent);
-                                               }
-
-                                               if (bline_tangent_2 &&
-                                                       bline_tangent_2->get_link(bline_tangent_2->get_link_index_from_name("amount")) == amount_value_node)
-                                               {
-                                                       Vector tangent = (*bline_tangent_2)(time, amount).get(Vector());
-                                                       DuckList::iterator iter;
-                                                       for (iter=duck_list.begin(); iter!=duck_list.end(); iter++)
-                                                               if ((*iter)->get_value_desc().get_value_node() == t2_value_node)
-                                                                       (*iter)->set_point(tangent);
-                                               }
-
-                                               if (bline_width &&
-                                                       bline_width->get_link(bline_width->get_link_index_from_name("amount")) == amount_value_node)
-                                               {
-                                                       Real width = (*bline_width)(time, amount).get(Real());
-                                                       DuckList::iterator iter;
-                                                       for (iter=duck_list.begin(); iter!=duck_list.end(); iter++)
-                                                               if ((*iter)->get_value_desc().get_value_node() == width_value_node)
-                                                                       (*iter)->set_point(Point(width, 0));
+                                                       switch (bline_tangent->get_type())
+                                                       {
+                                                       case ValueBase::TYPE_ANGLE:
+                                                       {
+                                                               Angle angle((*bline_tangent)(time, amount).get(Angle()));
+                                                               (*iter)->set_point(Point(Angle::cos(angle).get(), Angle::sin(angle).get()));
+                                                               break;
+                                                       }
+                                                       case ValueBase::TYPE_REAL:
+                                                               (*iter)->set_point(Point((*bline_tangent)(time, amount).get(Real()), 0));
+                                                               break;
+                                                       case ValueBase::TYPE_VECTOR:
+                                                               (*iter)->set_point((*bline_tangent)(time, amount).get(Vector()));
+                                                               break;
+                                                       default:
+                                                               break;
+                                                       }
                                                }
                                        }
+                                       else if (ValueNode_BLineCalcWidth::Handle bline_width = ValueNode_BLineCalcWidth::Handle::cast_dynamic(duck_value_node))
+                                       {
+                                               if (bline_width->get_link(bline_width->get_link_index_from_name("amount")) == vertex_amount_value_node)
+                                                       (*iter)->set_point(Point((*bline_width)(time, amount).get(Real()), 0));
+                                       }
                                }
                        }
                }
@@ -849,21 +881,23 @@ Duckmatic::find_duck(synfig::Point point, synfig::Real radius, Duck::Type type)
        {
                const Duck::Handle& duck(iter->second);
 
-               if(duck->get_ignore())
+               if(duck->get_ignore() ||
+                  (duck->get_type() && !(type & duck->get_type())))
                        continue;
+
                Real dist((duck->get_trans_point()-point).mag_squared());
 
                if(duck->get_type()&Duck::TYPE_VERTEX)
                        dist*=1.0001;
+               else if(duck->get_type()&Duck::TYPE_TANGENT && duck->get_scalar()>0)
+                       dist*=1.00005;
                else if(duck->get_type()&Duck::TYPE_RADIUS)
                        dist*=0.9999;
 
-               if(dist<=closest && !( duck->get_type() && (!(type & duck->get_type())) ) )
+               if(dist<=closest)
                {
-                       {
-                               closest=dist;
-                               ret=duck;
-                       }
+                       closest=dist;
+                       ret=duck;
                }
        }
 
@@ -1526,6 +1560,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
                                                                                false),
                                                                        1.0f),
                                                                synfigapp::ValueDesc(value_node,i)));
+                                               duck->set_value_desc(synfigapp::ValueDesc(value_node,i));
 
                                                if(param_desc)
                                                {
@@ -1561,13 +1596,13 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
                                        {
                                                if(!param_desc->get_origin().empty())
                                                {
-                                                               synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
-                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
-                                                               duck->set_origin(last_duck());
+                                                       synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                                       add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                                       duck->set_origin(last_duck());
 /*
-                                                               ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
-                                                               if(value.same_type_as(synfig::Point()))
-                                                                       duck->set_origin(value.get(synfig::Point()));
+                                                       ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                                       if(value.same_type_as(synfig::Point()))
+                                                               duck->set_origin(value.get(synfig::Point()));
 */
                                                }
                                        }
@@ -1655,6 +1690,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
                                                                        false),
                                                                1.0f),
                                                        synfigapp::ValueDesc(value_node,i)));
+                                       duck->set_value_desc(synfigapp::ValueDesc(value_node,i));
 
                                        add_bezier(bezier);
                                        bezier=0;
@@ -1689,13 +1725,13 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
 //                                     add_duck(duck);
                                        if(param_desc)
                                        {
-                                                               synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
-                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
-                                                               duck->set_origin(last_duck());
+                                               synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                               duck->set_origin(last_duck());
 /*
-                                                               ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
-                                                               if(value.same_type_as(synfig::Point()))
-                                                                       duck->set_origin(value.get(synfig::Point()));
+                                               ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                               if(value.same_type_as(synfig::Point()))
+                                                       duck->set_origin(value.get(synfig::Point()));
 */
 //                                             if(!param_desc->get_origin().empty())
 //                                                     duck->set_origin(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()).get(synfig::Point()));
@@ -1711,6 +1747,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
                                                                        false),
                                                                1.0f),
                                                        synfigapp::ValueDesc(value_node,i)));
+                                       duck->set_value_desc(synfigapp::ValueDesc(value_node,i));
 
                                }
 
@@ -1778,6 +1815,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
                                                                false),
                                                        1.0f),
                                                synfigapp::ValueDesc(value_node,first)));
+                               duck->set_value_desc(synfigapp::ValueDesc(value_node,first));
 
                                add_bezier(bezier);
                                bezier=0;
@@ -1812,15 +1850,15 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle<Canva
                                                first_duck = duck;
                                        }
 
-                                       if(param_desc)
+                                       if(param_desc && !param_desc->get_origin().empty())
                                        {
-                                                               synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
-                                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
-                                                               duck->set_origin(last_duck());
+                                               synfigapp::ValueDesc value_desc_origin(value_desc.get_layer(),param_desc->get_origin());
+                                               add_to_ducks(value_desc_origin,canvas_view, transform_stack);
+                                               duck->set_origin(last_duck());
 /*
-                                                               ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
-                                                               if(value.same_type_as(synfig::Point()))
-                                                                       duck->set_origin(value.get(synfig::Point()));
+                                               ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()));
+                                               if(value.same_type_as(synfig::Point()))
+                                                       duck->set_origin(value.get(synfig::Point()));
 */
 //                                             if(!param_desc->get_origin().empty())
 //                                                     last_duck()->set_origin(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time()).get(synfig::Point()));