Add a member to check if the value node is invertible
authorCarlos Lopez <carlos@pcnuevo.(none)>
Mon, 6 Jul 2009 23:49:30 +0000 (01:49 +0200)
committerCarlos Lopez <carlos@pcnuevo.(none)>
Mon, 13 Jul 2009 18:17:02 +0000 (20:17 +0200)
and a member to calculate the inverse. Code in studio
is more independent on core modifications.

synfig-core/trunk/src/synfig/valuenode_scale.cpp
synfig-core/trunk/src/synfig/valuenode_scale.h
synfig-studio/trunk/src/gtkmm/canvasview.cpp

index 25b3822..b272d7d 100644 (file)
@@ -142,20 +142,49 @@ synfig::ValueNode_Scale::operator()(Time t)const
 }
 
 synfig::ValueBase
-synfig::ValueNode_Scale::operator()(Time t, const synfig::Point &target_value)const
+synfig::ValueNode_Scale::get_inverse(Time t, const synfig::Vector &target_value) const
 {
        Real scalar_value((*scalar)(t).get(Real()));
        if(scalar_value==0)
-               return (*value_node)(t).get(value_node->get_type());
-       switch (get_type())
-       case ValueBase::TYPE_REAL:
-               return target_value.mag() / scalar_value;
-       case ValueBase::TYPE_ANGLE:
-               return Angle::tan(target_value[1] / scalar_value ,target_value[0] / scalar_value);
-       default:
-               return target_value / scalar_value;
+                       throw runtime_error(strprintf("ValueNode_Scale: %s",_("Attempting to get the inverse of a non invertible Valuenode")));
+       else
+               {
+                       switch (get_type())
+                       {
+                               case ValueBase::TYPE_REAL:
+                                       return target_value.mag() / scalar_value;
+                               case ValueBase::TYPE_ANGLE:
+                                       return Angle::tan(target_value[1] / scalar_value ,target_value[0] / scalar_value);
+                               default:
+                                       return target_value / scalar_value;
+                       }
+               }
+       return ValueBase();
 }
 
+synfig::ValueBase
+synfig::ValueNode_Scale::get_inverse(Time t, const synfig::Angle &target_value) const
+{
+       Real scalar_value((*scalar)(t).get(Real()));
+       if(scalar_value==0)
+                       throw runtime_error(strprintf("ValueNode_Scale: %s",_("Attempting to get the inverse of a non invertible Valuenode")));
+       else
+               {
+                       switch (get_type())
+                       {
+                                       default:
+                                       return (*value_node)(t).get(Angle()) + target_value / scalar_value;
+                       }
+               }
+       return ValueBase();
+}
+
+bool
+synfig::ValueNode_Scale::is_invertible(Time t) const
+{
+       Real scalar_value((*scalar)(t).get(Real()));
+       return (!scalar_value==0);
+}
 
 bool
 ValueNode_Scale::set_link_vfunc(int i,ValueNode::Handle value)
index a11f6e0..fba1aa0 100644 (file)
@@ -65,7 +65,10 @@ public:
        virtual ValueBase operator()(Time t)const;
 
        //! Returns the modified Link to match the target value at time t
-       virtual ValueBase operator()(Time t, const synfig::Point &target_value) const;
+       ValueBase get_inverse(Time t, const synfig::Vector &target_value) const;
+       ValueBase get_inverse(Time t, const synfig::Angle &target_value) const;
+
+       bool is_invertible(Time t)const;
 
        virtual String get_name()const;
 
index 50789a9..a76b1a0 100644 (file)
@@ -2890,7 +2890,13 @@ CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDes
        if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node()))
        {
                int link_index(scale_value_node->get_link_index_from_name("link"));
-               return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index), scale_value_node(t, value));
+               if(scale_value_node->is_invertible(get_time()))
+                       return canvas_interface()->change_value(
+                               synfigapp::ValueDesc(scale_value_node,link_index),
+                                       scale_value_node->get_inverse(get_time(), value)
+                                       );
+               else
+                       return false;
        }
 
        switch(value_desc.get_value_type())
@@ -2914,6 +2920,18 @@ CanvasView::on_duck_angle_changed(const synfig::Angle &rotation,const synfigapp:
                return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,offset_index), old_offset + rotation);
        }
 
+       if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               int link_index(scale_value_node->get_link_index_from_name("link"));
+               if(scale_value_node->is_invertible(get_time()))
+                       return canvas_interface()->change_value(
+                               synfigapp::ValueDesc(scale_value_node,link_index),
+                                       scale_value_node->get_inverse(get_time(), rotation)
+                                       );
+               else
+                       return false;
+
+       }
        // \todo will this really always be the case?
        assert(value_desc.get_value_type() == ValueBase::TYPE_ANGLE);
        return canvas_interface()->change_value(value_desc, value_desc.get_value(get_time()).get(Angle()) + rotation);