X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Fsrc%2Fsynfigapp%2Factions%2Fvaluedescset.cpp;h=90264c8d63c19da88646cdee5aafae3acd728dca;hb=20e89d9a399f110a44b9d641723c17e0fc164a17;hp=e3959ce06662ada48836dd444cb90d61e745227d;hpb=a095981e18cc37a8ecc7cd237cc22b9c10329264;p=synfig.git diff --git a/synfig-studio/src/synfigapp/actions/valuedescset.cpp b/synfig-studio/src/synfigapp/actions/valuedescset.cpp index e3959ce..90264c8 100644 --- a/synfig-studio/src/synfigapp/actions/valuedescset.cpp +++ b/synfig-studio/src/synfigapp/actions/valuedescset.cpp @@ -37,9 +37,15 @@ #include "valuedescset.h" #include +#include +#include +#include +#include #include #include +#include #include +#include #include #include @@ -156,7 +162,8 @@ Action::ValueDescSet::prepare() // tangent. if( value_desc.parent_is_value_node() && value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT && - (value_desc.get_index()==4 || value_desc.get_index()==5) && + (value_desc.get_name()=="t1" || value_desc.get_name()=="t2") && + //(value_desc.get_index()==4 || value_desc.get_index()==5) && (*value_desc.get_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false) { { @@ -168,7 +175,8 @@ Action::ValueDescSet::prepare() Vector t2((*parent_value_node->get_link("t2"))(time)); } - if (value_desc.get_index()==4) { + //if (value_desc.get_index()==4) { + if (value_desc.get_name()=="t1") { ValueNode_Composite::Handle parent_value_node; parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node()); @@ -183,7 +191,7 @@ Action::ValueDescSet::prepare() action->set_param("canvas_interface",get_canvas_interface()); action->set_param("time",time); action->set_param("new_value",value); - action->set_param("value_desc",ValueDesc(parent_value_node,5)); + action->set_param("value_desc",ValueDesc(parent_value_node, parent_value_node->get_link_index_from_name("t2"))); if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY); @@ -300,7 +308,7 @@ Action::ValueDescSet::prepare() case ValueBase::TYPE_VECTOR: { Angle old_angle = (*(ValueNode_RadialComposite::Handle::cast_dynamic( - value_desc.get_value_node())->get_link_vfunc(1)))(time).get(Angle()); + value_desc.get_value_node())->get_link("theta")))(time).get(Angle()); Vector vect(value.get(Vector())); components[0]=vect.mag(); Angle change = Angle(Angle::tan(vect[1],vect[0])) - old_angle; @@ -345,6 +353,263 @@ Action::ValueDescSet::prepare() return; } + // Perform reverse manipulations + + // If we are a scale value node, then edit the link + // such that it will scale to our target value + if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) + { + if(! scale_value_node->is_invertible(time)) + { + synfig::warning(_("Attempt to edit scale ValueNode with a scale factor of zero.")); + return; + } + + ValueBase new_value; + + if (value.get_type() == ValueBase::TYPE_ANGLE) + new_value = scale_value_node->get_inverse(time, value.get(Angle())); + else if (value.get_type() == ValueBase::TYPE_REAL) + throw Error(_("Inverse manipulation of real scale values not implemented in core.")); + else + new_value = scale_value_node->get_inverse(time, value.get(Vector())); + + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",new_value); + action->set_param("value_desc",ValueDesc(scale_value_node, scale_value_node->get_link_index_from_name("link"))); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + return; + } + + // Range: disallow values outside the range + if (ValueNode_Range::Handle range_value_node = ValueNode_Range::Handle::cast_dynamic(value_desc.get_value_node())) + { + ValueBase new_value; + + if (value.get_type() == ValueBase::TYPE_ANGLE) + new_value = range_value_node->get_inverse(time, value.get(Angle())); + else if (value.get_type() == ValueBase::TYPE_REAL) + throw Error(_("Inverse manipulation of real range values not implemented in core.")); + else + new_value = range_value_node->get_inverse(time, value.get(Vector())); + + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",new_value); + action->set_param("value_desc",ValueDesc(range_value_node,range_value_node->get_link_index_from_name("link"))); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + return; + } + + // BlineCalcWidth: modify the scale value node + // so that the target width is achieved + if (ValueNode_BLineCalcWidth::Handle bline_width = ValueNode_BLineCalcWidth::Handle::cast_dynamic(value_desc.get_value_node())) + { + Real old_width((*bline_width)(time).get(Real())); + Real scale((*(bline_width->get_link("scale")))(time).get(Real())); + + ValueBase new_width(value.get(Real()) * scale / old_width); + + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",new_width); + action->set_param("value_desc",ValueDesc(bline_width, bline_width->get_link_index_from_name("scale"))); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + return; + } + + // BLineCalcVertex: snap the point to the nearest + // allowed position. + 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")); + Real radius = 0.0; + ValueBase new_amount; + if (((*(bline_vertex->get_link("loop")))(time).get(bool()))){ + // The bline is looped. Animation may require an amount parameter + // outside the range of 0-1, so make sure that the amount does + // not change drastically. + Real amount_old((*(bline_vertex->get_link("amount")))(time).get(Real())); + Real amount_new = synfig::find_closest_point((*bline)(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; + + new_amount = amount_old+difference; + } else { + new_amount = synfig::find_closest_point((*bline)(time), value, radius, bline->get_loop()); + } + + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",new_amount); + action->set_param("value_desc",ValueDesc(bline_vertex, bline_vertex->get_link_index_from_name("amount"))); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + return; + } + + + // BLineCalcTangent: adjust scale and offset + // to achieve the desired tangent + if (ValueNode_BLineCalcTangent::Handle bline_tangent = ValueNode_BLineCalcTangent::Handle::cast_dynamic(value_desc.get_value_node())) + { + ValueBase new_scale; + ValueDesc scale_value_desc(bline_tangent,bline_tangent->get_link_index_from_name("scale")); + ValueDesc offset_value_desc(bline_tangent,bline_tangent->get_link_index_from_name("offset")); + + switch(value_desc.get_value_type()) + { + case ValueBase::TYPE_REAL: + { + Real old_length = (*bline_tangent)(time).get(Real()); + Real new_length = value.get(Vector()).mag(); + Real scale((*(bline_tangent->get_link("scale")))(time).get(Real())); + bool fixed_length((*(bline_tangent->get_link("fixed_length")))(time).get(bool())); + + if (fixed_length) + { + new_scale = new_length; + break; + } + if (old_length == 0) + return; + new_scale = new_length * scale / old_length; + } + + case ValueBase::TYPE_VECTOR: + { + Vector old_tangent = (*bline_tangent)(time).get(Vector()); + Angle old_angle = old_tangent.angle(); + Real old_length = old_tangent.mag(); + Angle new_angle = value.get(Vector()).angle(); + Real new_length = value.get(Vector()).mag(); + Angle old_offset((*(bline_tangent->get_link("offset")))(time).get(Angle())); + Real scale((*(bline_tangent->get_link("scale")))(time).get(Real())); + bool fixed_length((*(bline_tangent->get_link("fixed_length")))(time).get(bool())); + if (fixed_length) + { + new_scale = new_length; + break; + } + if (old_length != 0) + { + new_scale = new_length * scale / old_length; + + + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value", ValueBase(old_offset + new_angle - old_angle)); + action->set_param("value_desc",offset_value_desc); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + } + } + break; + + case ValueBase::TYPE_ANGLE: + { + Angle old_angle = (*bline_tangent)(time).get(Angle()); + Angle new_angle = value.get(Vector()).angle(); + Angle old_offset((*(bline_tangent->get_link("offset")))(time).get(Angle())); + + + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value", ValueBase(old_offset + new_angle - old_angle)); + action->set_param("value_desc",offset_value_desc); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + return; + } + + default: + break; + } + + if (new_scale) + { + Action::Handle action(Action::create("ValueDescSet")); + + if(!action) + throw Error(_("Unable to find action ValueDescSet (bug)")); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",new_scale); + action->set_param("value_desc",scale_value_desc); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + } + return; + } + + // end reverse manipulations + + + // If we are merging the tangents of a BLinePoint, // we must also set the second tangent for things // to interpolate properly @@ -370,8 +635,8 @@ Action::ValueDescSet::prepare() action->set_param("canvas",get_canvas()); action->set_param("canvas_interface",get_canvas_interface()); action->set_param("time",time); - action->set_param("new_value",(*parent_value_node->get_link(4))(time)); - action->set_param("value_desc",ValueDesc(parent_value_node,5)); + action->set_param("new_value",(*parent_value_node->get_link("t1"))(time)); + action->set_param("value_desc",ValueDesc(parent_value_node,parent_value_node->get_link_index_from_name("t2"))); if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY); @@ -396,7 +661,7 @@ Action::ValueDescSet::prepare() action->set_param("canvas_interface",get_canvas_interface()); action->set_param("time",time); action->set_param("new_value",average); - action->set_param("value_desc",ValueDesc(parent_value_node,4)); + action->set_param("value_desc",ValueDesc(parent_value_node,parent_value_node->get_link_index_from_name("t1"))); if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY); @@ -414,7 +679,7 @@ Action::ValueDescSet::prepare() action->set_param("canvas_interface",get_canvas_interface()); action->set_param("time",time); action->set_param("new_value",average); - action->set_param("value_desc",ValueDesc(parent_value_node,5)); + action->set_param("value_desc",ValueDesc(parent_value_node,parent_value_node->get_link_index_from_name("t2"))); if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY); @@ -444,9 +709,17 @@ Action::ValueDescSet::prepare() } */ - + ValueBase local_value; + local_value.set_static(false); + if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())) + { + if(value_desc.is_value_node()) + local_value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value(); + else + local_value=value_desc.get_value(); + } // If we are in animate editing mode - if(get_edit_mode()&MODE_ANIMATE) + if(get_edit_mode()&MODE_ANIMATE && !local_value.get_static()) { ValueNode_Animated::Handle& value_node(value_node_animated); @@ -525,7 +798,8 @@ Action::ValueDescSet::prepare() if(ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())) { Action::Handle action(ValueNodeConstSet::create()); - + synfig::ValueNode_Const::Handle localvaluenode(ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())); + value.set_static(localvaluenode->get_static()); action->set_param("canvas",get_canvas()); action->set_param("canvas_interface",get_canvas_interface()); action->set_param("value_node",value_desc.get_value_node()); @@ -547,7 +821,8 @@ Action::ValueDescSet::prepare() if(value_desc.parent_is_layer_param() && !value_desc.is_value_node()) { Action::Handle layer_param_set(LayerParamSet::create()); - + synfig::ValueBase localvalue(value_desc.get_value()); + value.set_static(local_value.get_static()); layer_param_set->set_param("canvas",get_canvas()); layer_param_set->set_param("canvas_interface",get_canvas_interface()); layer_param_set->set_param("layer",value_desc.get_layer());