Reverse manipulations for Scale Convert – Part 2

The solution came when I looked at the end of CanvasView::on_duck_changed() function:

bool
CanvasView::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc)
{
	//Handling other convert types (LinkToBline)
	if (ValueNode_BLineCalcWidth::Handle bline_width = ValueNode_BLineCalcWidth::Handle::cast_dynamic(value_desc.get_value_node()))
	{
		...
	}

	...

	//Handling Scale Convert
	if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node()))
	{
		//Our code
		int scalar_index(scale_value_node->get_link_index_from_name("scalar"));
		Real scalar((*(scale_value_node->get_link(scalar_index)))(get_time()).get(Real()));
		if (scalar == 0.0)
		{
			return false;
		}
		else
		{
			int link_index(scale_value_node->get_link_index_from_name("link"));
			return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index), value / scalar);
		}
	}

	//Interesting part:
	switch(value_desc.get_value_type())
	{
	case ValueBase::TYPE_REAL:
		return canvas_interface()->change_value(value_desc,value.mag());
	case ValueBase::TYPE_ANGLE:
		return canvas_interface()->change_value(value_desc,Angle::tan(value[1],value[0]));
	default:
		return canvas_interface()->change_value(value_desc,value);
	}
}

Last lines of CanvasView::on_duck_changed() processing the case when the duck is not affected by any convert type – just passing value to the value_desc. Value variable is a Vector type, because it resides on the 2D plane – screen. But changed value node is not always a vector. It could be an Angle or Radius. For those cases value is converted to angle via Angle::tan() and value.mag() functions. “Mag” stays for “magnitude” for sure.

K, so the problem in our code is

return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index), value / scalar);

line, because even if we have Scale Convert attached to Radius duck  it is passes Vector value to it. Which is no good of course. Let’s fix it by repacing with this:

switch(value_desc.get_value_type())
{
	case ValueBase::TYPE_REAL:
		return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index),value.mag() / scalar);
	case ValueBase::TYPE_ANGLE:
		return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index),Angle::tan(value[1] / scalar ,value[0] / scalar));
	default:
		return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index), value / scalar);
}

Now, depending on duck type (value_desc.get_value_type()) we converting value to Radius or Angle if needed. Now  reverse manipulations for Radius works.

Unfortunately not for Angle. It produces strange message:

Set Layer Parameter (Rotate):Amount: Direct manipulation of this ValueNode type is not yet supported

This is differs from Radius case. When I tried to manipulate Radius without proper support in code we made today, it haven’t produced any message. I’ll dig that further.

Anyway, current patch status is:

diff --git a/synfig-studio/trunk/src/gtkmm/canvasview.cpp b/synfig-studio/trunk/src/gtkmm/canvasview.cpp
index 3154ae4..9b02a5b 100644
--- a/synfig-studio/trunk/src/gtkmm/canvasview.cpp
+++ b/synfig-studio/trunk/src/gtkmm/canvasview.cpp
@@ -2684,6 +2684,29 @@ 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 scalar_index(scale_value_node->get_link_index_from_name("scalar"));
+		Real scalar((*(scale_value_node->get_link(scalar_index)))(get_time()).get(Real()));
+		if (scalar == 0.0)
+		{
+			return false;
+		}
+		else
+		{
+			int link_index(scale_value_node->get_link_index_from_name("link"));
+			switch(value_desc.get_value_type())
+			{
+			case ValueBase::TYPE_REAL:
+				return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index),value.mag() / scalar);
+			case ValueBase::TYPE_ANGLE:
+				return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index),Angle::tan(value[1] / scalar ,value[0] / scalar));
+			default:
+				return canvas_interface()->change_value(synfigapp::ValueDesc(scale_value_node,link_index), value / scalar);
+			}
+		}
+	}
+
 	switch(value_desc.get_value_type())
 	{
 	case ValueBase::TYPE_REAL:
diff --git a/synfig-studio/trunk/src/synfigapp/instance.cpp b/synfig-studio/trunk/src/synfigapp/instance.cpp
index 020d337..c3c542b 100644
--- a/synfig-studio/trunk/src/synfigapp/instance.cpp
+++ b/synfig-studio/trunk/src/synfigapp/instance.cpp
@@ -42,6 +42,7 @@
 #include <synfig/valuenode_blinecalctangent.h>
 #include <synfig/valuenode_blinecalcvertex.h>
 #include <synfig/valuenode_blinecalcwidth.h>
+#include <synfig/valuenode_scale.h>
 #include <map>

 #include "general.h"
@@ -74,6 +75,7 @@ synfigapp::is_editable(synfig::ValueNode::Handle value_node)
 		|| ValueNode_BLineCalcVertex::Handle::cast_dynamic(value_node)
 		|| ValueNode_BLineCalcTangent::Handle::cast_dynamic(value_node)
 		|| ValueNode_BLineCalcWidth::Handle::cast_dynamic(value_node)
+		|| ValueNode_Scale::Handle::cast_dynamic(value_node)
 	)
 		return true;
 	return false;
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: