Accept 1932525: Patch "Improved GUI for the sound file selection dialog" from David...
[synfig.git] / synfig-studio / trunk / src / gtkmm / canvasview.cpp
index 31d3153..0501e09 100644 (file)
 #include <synfig/valuenode_dynamiclist.h>
 #include <synfig/valuenode_twotone.h>
 #include <synfig/valuenode_stripes.h>
+#include <synfig/valuenode_blinecalctangent.h>
+#include <synfig/valuenode_blinecalcvertex.h>
+#include <synfig/valuenode_blinecalcwidth.h>
+#include <synfig/valuenode_bline.h>
 #include <synfig/layer.h>
 
 #include <synfigapp/uimanager.h>
@@ -2004,6 +2008,7 @@ static bool _close_instance(etl::handle<Instance> instance)
 bool
 CanvasView::close_instance()
 {
+#ifdef SINGLE_THREADED
        if (get_work_area()->get_updating())
        {
                get_work_area()->stop_updating(true); // stop and mark as cancelled
@@ -2014,6 +2019,7 @@ CanvasView::close_instance()
                        250);
        }
        else
+#endif
                Glib::signal_timeout().connect(
                        sigc::bind(sigc::ptr_fun(_close_instance),
                                           (etl::handle<Instance>)get_instance()),
@@ -2157,10 +2163,10 @@ CanvasView::on_layer_toggle(synfig::Layer::Handle layer)
 }
 
 void
-CanvasView::popup_param_menu(synfigapp::ValueDesc value_desc, float location)
+CanvasView::popup_param_menu(synfigapp::ValueDesc value_desc, float location, bool bezier)
 {
        parammenu.items().clear();
-       get_instance()->make_param_menu(&parammenu,get_canvas(),value_desc,location);
+       get_instance()->make_param_menu(&parammenu,get_canvas(),value_desc,location,bezier);
 
        parammenu.popup(3,gtk_get_current_event_time());
 }
@@ -2418,6 +2424,7 @@ CanvasView::time_zoom_in()
        time_window_adjustment().set_page_size(time_window_adjustment().get_page_size()*0.75);
        if (time_window_adjustment().get_page_size() < min_page_size)
                time_window_adjustment().set_page_size(min_page_size);
+       time_window_adjustment().set_page_increment(time_window_adjustment().get_page_size());
        time_window_adjustment().changed();
 
        refresh_time_window();
@@ -2432,6 +2439,7 @@ CanvasView::time_zoom_out()
        time_window_adjustment().set_page_size(time_window_adjustment().get_page_size()/0.75);
        if (time_window_adjustment().get_page_size() > length)
                time_window_adjustment().set_page_size(length);
+       time_window_adjustment().set_page_increment(time_window_adjustment().get_page_size());
        time_window_adjustment().changed();
 
        refresh_time_window();
@@ -2579,25 +2587,90 @@ CanvasView::duck_change_param(const synfig::Point &value,synfig::Layer::Handle l
 bool
 CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc)
 {
+       if (ValueNode_BLineCalcWidth::Handle bline_width = ValueNode_BLineCalcWidth::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               Real old_width((*bline_width)(get_time()).get(Real()));
+               Real new_width(value.mag());
+               int scale_index(bline_width->get_link_index_from_name("scale"));
+               Real scale((*(bline_width->get_link(scale_index)))(get_time()).get(Real()));
+               return canvas_interface()->change_value(synfigapp::ValueDesc(bline_width,scale_index), new_width * scale / old_width);
+       }
+
+       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")));
+               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 (ValueNode_BLineCalcTangent::Handle bline_tangent = ValueNode_BLineCalcTangent::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               switch(value_desc.get_value_type())
+               {
+               case ValueBase::TYPE_REAL:
+               {
+                       Real old_length = (*bline_tangent)(get_time()).get(Real());
+                       Real new_length = value.mag();
+                       int scale_index(bline_tangent->get_link_index_from_name("scale"));
+                       int fixed_length_index(bline_tangent->get_link_index_from_name("fixed_length"));
+                       Real scale((*(bline_tangent->get_link(scale_index)))(get_time()).get(Real()));
+                       bool fixed_length((*(bline_tangent->get_link(fixed_length_index)))(get_time()).get(bool()));
+                       if (fixed_length)
+                               return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,scale_index), new_length);
+                       if (old_length == 0)
+                               return true;
+                       return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,scale_index), new_length * scale / old_length);
+               }
+
+               case ValueBase::TYPE_ANGLE:
+                       assert(0);                      // doesn't happen?
+                       break;
+
+               case ValueBase::TYPE_VECTOR:
+                       Vector old_tangent = (*bline_tangent)(get_time()).get(Vector());
+                       Angle old_angle = old_tangent.angle();
+                       Real old_length = old_tangent.mag();
+                       Angle new_angle = value.angle();
+                       Real new_length = value.mag();
+                       int offset_index(bline_tangent->get_link_index_from_name("offset"));
+                       int scale_index(bline_tangent->get_link_index_from_name("scale"));
+                       int fixed_length_index(bline_tangent->get_link_index_from_name("fixed_length"));
+                       Angle old_offset((*(bline_tangent->get_link(offset_index)))(get_time()).get(Angle()));
+                       Real scale((*(bline_tangent->get_link(scale_index)))(get_time()).get(Real()));
+                       bool fixed_length((*(bline_tangent->get_link(fixed_length_index)))(get_time()).get(bool()));
+                       if (fixed_length)
+                       {
+                               if (!(canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,scale_index), new_length)))
+                                       return false;
+                       }
+                       else if (old_length != 0 && !(canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,scale_index), new_length * scale / old_length)))
+                               return false;
+                       return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,offset_index), old_offset + new_angle - old_angle);
+               }
+       }
+
        switch(value_desc.get_value_type())
        {
        case ValueBase::TYPE_REAL:
                return canvas_interface()->change_value(value_desc,value.mag());
-               break;
        case ValueBase::TYPE_ANGLE:
                return canvas_interface()->change_value(value_desc,Angle::tan(value[1],value[0]));
-               break;
        default:
                return canvas_interface()->change_value(value_desc,value);
-               break;
        }
-
-       return true;
 }
 
 bool
 CanvasView::on_duck_angle_changed(const synfig::Angle &rotation,const synfigapp::ValueDesc& value_desc)
 {
+       if (ValueNode_BLineCalcTangent::Handle bline_tangent = ValueNode_BLineCalcTangent::Handle::cast_dynamic(value_desc.get_value_node()))
+       {
+               int offset_index(bline_tangent->get_link_index_from_name("offset"));
+               Angle old_offset((*(bline_tangent->get_link(offset_index)))(get_time()).get(Angle()));
+               return canvas_interface()->change_value(synfigapp::ValueDesc(bline_tangent,offset_index), old_offset + 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);