Merge branch 'master' into nikitakit_master
[synfig.git] / synfig-studio / src / gtkmm / canvasview.cpp
index 807a63e..f520ced 100644 (file)
@@ -8,6 +8,7 @@
 **     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
 **     Copyright (c) 2007, 2008 Chris Moore
 **     Copyright (c) 2009 Carlos López
+**     Copyright (c) 2009 Nikita Kitaev
 **
 **     This package is free software; you can redistribute it and/or
 **     modify it under the terms of the GNU General Public License as
@@ -35,6 +36,7 @@
 
 #include <ETL/clock>
 #include <sstream>
+#include <math.h>
 
 #include <gtkmm/paned.h>
 #include <gtkmm/scale.h>
@@ -52,6 +54,7 @@
 #include <synfig/valuenode_linear.h>
 #include <synfig/valuenode_timedswap.h>
 #include <synfig/valuenode_scale.h>
+#include <synfig/valuenode_range.h>
 #include <synfig/valuenode_dynamiclist.h>
 #include <synfig/valuenode_twotone.h>
 #include <synfig/valuenode_stripes.h>
@@ -717,8 +720,6 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
        toggling_snap_grid=false;
        toggling_onion_skin=false;
 
-       smach_.set_default_state(&state_normal);
-
        disp_audio = new Widget_Sound();
 
        //synfig::info("Canvasview: Entered constructor");
@@ -764,6 +765,8 @@ CanvasView::CanvasView(etl::loose_handle<Instance> instance,etl::handle<synfigap
 
        //set_transient_for(*App::toolbox);
 
+       smach_.set_default_state(&state_normal);
+
        //synfig::info("Canvasview: Before Signals");
        /*
  --    ** -- Signals -------------------------------------------------------------
@@ -2881,10 +2884,20 @@ CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDes
 
        if (ValueNode_BLineCalcVertex::Handle bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(value_desc.get_value_node()))
        {
-               ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link(bline_vertex->get_link_index_from_name("bline")));
+               ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link("bline"));
                Real radius = 0.0;
-               Real amount = synfig::find_closest_point((*bline)(get_time()), value, radius, bline->get_loop());
-               return canvas_interface()->change_value(synfigapp::ValueDesc(bline_vertex,bline_vertex->get_link_index_from_name("amount")), amount);
+               if (((*(bline_vertex->get_link("loop")))(get_time()).get(bool()))){
+                       Real amount_old((*(bline_vertex->get_link("amount")))(get_time()).get(Real()));
+                       Real amount_new = synfig::find_closest_point((*bline)(get_time()), value, radius, bline->get_loop());
+                       Real difference = fmod( fmod(amount_new - amount_old, 1.0) + 1.0 , 1.0);
+                                                       //fmod is called twice to avoid negative values
+                       if (difference > 0.5) difference=difference-1.0;
+                       return canvas_interface()->change_value(synfigapp::ValueDesc(bline_vertex,bline_vertex->get_link_index_from_name("amount")), amount_old+difference);
+
+               } else {
+                       Real amount = synfig::find_closest_point((*bline)(get_time()), value, radius, bline->get_loop());
+                       return canvas_interface()->change_value(synfigapp::ValueDesc(bline_vertex,bline_vertex->get_link_index_from_name("amount")), amount);
+               }
        }
 
        if (ValueNode_BLineCalcTangent::Handle bline_tangent = ValueNode_BLineCalcTangent::Handle::cast_dynamic(value_desc.get_value_node()))
@@ -2949,6 +2962,15 @@ CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDes
                        return false;
        }
 
+       if (ValueNode_Range::Handle range_value_node = ValueNode_Range::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               int link_index(range_value_node->get_link_index_from_name("link"));
+               return canvas_interface()->change_value(
+                       synfigapp::ValueDesc(range_value_node,link_index),
+                               range_value_node->get_inverse(get_time(), value)
+                               );
+       }
+
        switch(value_desc.get_value_type())
        {
        case ValueBase::TYPE_REAL:
@@ -2982,6 +3004,14 @@ CanvasView::on_duck_angle_changed(const synfig::Angle &rotation,const synfigapp:
                        return false;
 
        }
+       if (ValueNode_Range::Handle range_value_node = ValueNode_Range::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               int link_index(range_value_node->get_link_index_from_name("link"));
+               return canvas_interface()->change_value(
+                       synfigapp::ValueDesc(range_value_node,link_index),
+                               range_value_node->get_inverse(get_time(), rotation)
+                               );
+       }
        // \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);