X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftags%2Fstable%2Fsynfig-studio%2Fsrc%2Fsynfigapp%2Factions%2Fvaluedescset.cpp;fp=synfig-studio%2Ftags%2Fstable%2Fsynfig-studio%2Fsrc%2Fsynfigapp%2Factions%2Fvaluedescset.cpp;h=60f4d75601f21879fa6797a84f89d5d43b41c296;hb=de3db2ba507930dcffd69a876223272eefa6720f;hp=0000000000000000000000000000000000000000;hpb=dbc06d6abaf17178dcbd0a6f68832edc7ba2771d;p=synfig.git diff --git a/synfig-studio/tags/stable/synfig-studio/src/synfigapp/actions/valuedescset.cpp b/synfig-studio/tags/stable/synfig-studio/src/synfigapp/actions/valuedescset.cpp new file mode 100644 index 0000000..60f4d75 --- /dev/null +++ b/synfig-studio/tags/stable/synfig-studio/src/synfigapp/actions/valuedescset.cpp @@ -0,0 +1,533 @@ +/* === S Y N F I G ========================================================= */ +/*! \file valuedescset.cpp +** \brief Template File +** +** $Id: valuedescset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $ +** +** \legal +** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** +** This package is free software; you can redistribute it and/or +** modify it under the terms of the GNU General Public License as +** published by the Free Software Foundation; either version 2 of +** the License, or (at your option) any later version. +** +** This package is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +** General Public License for more details. +** \endlegal +*/ +/* ========================================================================= */ + +/* === H E A D E R S ======================================================= */ + +#ifdef USING_PCH +# include "pch.h" +#else +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "layerparamset.h" +#include "valuenodeconstset.h" +#include "valuedescconnect.h" +#include "waypointsetsmart.h" + +#include "valuedescset.h" +#include +#include +#include +#include +#include + +#endif + +using namespace std; +using namespace etl; +using namespace synfig; +using namespace synfigapp; +using namespace Action; + +/* === M A C R O S ========================================================= */ +#define ACTION_INIT2(class) \ + Action::Base* class::create() { return new class(); } \ + synfig::String class::get_name()const { return name__; } + +ACTION_INIT2(Action::ValueDescSet); +ACTION_SET_NAME(Action::ValueDescSet,"value_desc_set"); +ACTION_SET_LOCAL_NAME(Action::ValueDescSet,"Set ValueDesc"); +ACTION_SET_TASK(Action::ValueDescSet,"set"); +ACTION_SET_CATEGORY(Action::ValueDescSet,Action::CATEGORY_VALUEDESC); +ACTION_SET_PRIORITY(Action::ValueDescSet,0); +ACTION_SET_VERSION(Action::ValueDescSet,"0.0"); +ACTION_SET_CVS_ID(Action::ValueDescSet,"$Id: valuedescset.cpp,v 1.1.1.1 2005/01/07 03:34:37 darco Exp $"); + +/* === G L O B A L S ======================================================= */ + +/* === P R O C E D U R E S ================================================= */ + +/* === M E T H O D S ======================================================= */ + +Action::ValueDescSet::ValueDescSet(): + time(0) +{ +} + +synfig::String +Action::ValueDescSet::get_local_name()const +{ + String name("ValueDesc"); + + if(!value_desc) + { + } + else if(value_desc.parent_is_layer_param()) + { + if(value_desc.get_layer()->get_description().empty()) + name=value_desc.get_layer()->get_local_name(); + else + name=value_desc.get_layer()->get_description(); + name+="->"+value_desc.get_param_name(); + } + else if(value_desc.parent_is_value_node()) + { + synfig::LinkableValueNode::Handle value_node(synfig::LinkableValueNode::Handle::cast_reinterpret(value_desc.get_parent_value_node())); + name=value_node->link_local_name(value_desc.get_index()); + + synfig::Node* node; + for(node=value_node.get();!node->parent_set.empty() && !dynamic_cast(node);node=*node->parent_set.begin()); + Layer::Handle parent_layer(dynamic_cast(node)); + if(parent_layer) + { + if(parent_layer->get_description().empty()) + name=parent_layer->get_local_name()+"=>"+name; + else + name=parent_layer->get_description()+"=>"+name; + } + } + + return strprintf(_("Set %s"),name.c_str()); +} + +Action::ParamVocab +Action::ValueDescSet::get_param_vocab() +{ + ParamVocab ret(Action::CanvasSpecific::get_param_vocab()); + + ret.push_back(ParamDesc("value_desc",Param::TYPE_VALUEDESC) + .set_local_name(_("ValueDesc")) + ); + + ret.push_back(ParamDesc("new_value",Param::TYPE_VALUE) + .set_local_name(_("ValueBase")) + ); + + ret.push_back(ParamDesc("time",Param::TYPE_TIME) + .set_local_name(_("Time")) + .set_optional() + ); + + return ret; +} + +bool +Action::ValueDescSet::is_canidate(const ParamList &x) +{ + return canidate_check(get_param_vocab(),x); +} + +bool +Action::ValueDescSet::set_param(const synfig::String& name, const Action::Param ¶m) +{ + if(name=="value_desc" && param.get_type()==Param::TYPE_VALUEDESC) + { + value_desc=param.get_value_desc(); + + return true; + } + + if(name=="new_value" && param.get_type()==Param::TYPE_VALUE) + { + value=param.get_value(); + + return true; + } + + if(name=="time" && param.get_type()==Param::TYPE_TIME) + { + time=param.get_time(); + + return true; + } + + return Action::CanvasSpecific::set_param(name,param); +} + +bool +Action::ValueDescSet::is_ready()const +{ + if(!value_desc || !value.is_valid()) + return false; + return Action::CanvasSpecific::is_ready(); +} + +void +Action::ValueDescSet::prepare() +{ + clear(); + + // If our tangents are merged, and + // our first tangent is being manipulated, + // then we also need to adjust the other + // 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_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false + ) + { + DEBUGPOINT(); + ValueNode_Composite::Handle parent_value_node; + parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node()); + + assert(parent_value_node); + + Action::Handle action(Action::create("value_desc_set")); + + if(!action) + throw Error(_("Unable to find action value_desc_set (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",value); + action->set_param("value_desc",ValueDesc(parent_value_node,5)); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + } + + // If we are a reference value node, then + // we need to distribute the changes to the + // referenced value node + if(value_desc.is_value_node() && ValueNode_Reference::Handle::cast_dynamic(value_desc.get_value_node())) + { + ValueDesc reference_value_desc(ValueNode_Reference::Handle::cast_dynamic(value_desc.get_value_node()),0); + + Action::Handle action(Action::create("value_desc_set")); + + if(!action) + throw Error(_("Unable to find action value_desc_set (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",value); + action->set_param("value_desc",reference_value_desc); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + + return; + } + + // If we are a composite value node, then + // we need to distribute the changes to the + // individual parts + if(value_desc.is_value_node() && ValueNode_Composite::Handle::cast_dynamic(value_desc.get_value_node())) + { + ValueBase components[6]; + int n_components(0); + switch(value.get_type()) + { + case ValueBase::TYPE_VECTOR: + components[0]=value.get(Vector())[0]; + components[1]=value.get(Vector())[1]; + n_components=2; + break; + case ValueBase::TYPE_COLOR: + components[0]=value.get(Color()).get_r(); + components[1]=value.get(Color()).get_g(); + components[2]=value.get(Color()).get_b(); + components[3]=value.get(Color()).get_a(); + n_components=4; + break; + case ValueBase::TYPE_SEGMENT: + components[0]=value.get(Segment()).p1; + components[1]=value.get(Segment()).t1; + components[2]=value.get(Segment()).p2; + components[3]=value.get(Segment()).t2; + n_components=4; + break; + case ValueBase::TYPE_BLINEPOINT: + { + BLinePoint bline_point(value); + components[0]=bline_point.get_vertex(); + components[1]=bline_point.get_width(); + components[2]=bline_point.get_origin(); + components[3]=bline_point.get_split_tangent_flag(); + components[4]=bline_point.get_tangent1(); + components[5]=bline_point.get_tangent2(); + n_components=6; + break; + } + default: + throw Error("Bad type for composite (%s)",ValueBase::type_name(value.get_type()).c_str()); + break; + } + + for(int i=0;iset_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",components[i]); + action->set_param("value_desc",component_value_desc); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + } + + return; + } + + + // If we are a RADIAL composite value node, then + // we need to distribute the changes to the + // individual parts + if(value_desc.is_value_node() && ValueNode_RadialComposite::Handle::cast_dynamic(value_desc.get_value_node())) + { + ValueBase components[6]; + int n_components(0); + switch(value.get_type()) + { + case ValueBase::TYPE_VECTOR: + { + Vector vect(value.get(Vector())); + components[0]=vect.mag(); + components[1]=Angle(Angle::tan(vect[1],vect[0])); + n_components=2; + } + break; + case ValueBase::TYPE_COLOR: + components[0]=value.get(Color()).get_y(); + components[1]=value.get(Color()).get_s(); + components[2]=value.get(Color()).get_hue(); + components[3]=value.get(Color()).get_a(); + n_components=4; + break; + default: + throw Error("Bad type for radial composite (%s)",ValueBase::type_name(value.get_type()).c_str()); + break; + } + for(int i=0;iset_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("time",time); + action->set_param("new_value",components[i]); + action->set_param("value_desc",component_value_desc); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + } + + return; + } + + // If we are merging the tangents of a BLinePoint, + // we must also set the second tangent for things + // to interpolate properly + if( value_desc.parent_is_value_node() + && value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT + && value_desc.get_index()==3 +// && value.get(bool())==false // Actually, we want to do this any time the split flag is tweaked with + ) + { + ValueNode_Composite::Handle parent_value_node; + parent_value_node=parent_value_node.cast_dynamic(value_desc.get_parent_value_node()); + + assert(parent_value_node); + + Action::Handle action(Action::create("value_desc_set")); + + if(!action) + throw Error(_("Unable to find action value_desc_set (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",(*parent_value_node->get_link(4))(time)); + action->set_param("value_desc",ValueDesc(parent_value_node,5)); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action(action); + } + +/* DEBUGPOINT(); + if( value_desc.parent_is_value_node()) + { + DEBUGPOINT(); + if(value_desc.get_parent_value_node()->get_type()==ValueBase::TYPE_BLINEPOINT) + { + DEBUGPOINT(); + if(value_desc.get_index()==4) + { + DEBUGPOINT(); + if((*value_desc.get_parent_value_node())(time).get(BLinePoint()).get_split_tangent_flag()==false) + { + DEBUGPOINT(); + } + } + } + } +*/ + + + // If we are in animate editing mode + if(get_edit_mode()&MODE_ANIMATE) + { + + ValueNode_Animated::Handle& value_node(value_node_animated); + + // If this value isn't a ValueNode_Animated, but + // it is somewhat constant, then go ahead and convert + // it to a ValueNode_Animated. + if(!value_desc.is_value_node() || ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())) + { + ValueBase value; + if(value_desc.is_value_node()) + value=ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())->get_value(); + else + value=value_desc.get_value(); + + if(!value_node)value_node=ValueNode_Animated::create(value,time); + //if(!value_node)value_node=ValueNode_Animated::create(value.get_type()); + + Action::Handle action; + + if(!value_desc.is_value_node()) + { + action=(ValueDescConnect::create()); + action->set_param("dest",value_desc); + action->set_param("src",ValueNode::Handle(value_node)); + } + else + { + action=Action::create("value_node_replace"); + action->set_param("dest",value_desc.get_value_node()); + action->set_param("src",ValueNode::Handle(value_node)); + } + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + DEBUGPOINT(); + add_action_front(action); + } + else + { + value_node=value_node.cast_dynamic(value_desc.get_value_node()); + } + + DEBUGPOINT(); + if(!value_node) + throw Error(_("Direct manipulation of this ValueNode type is not yet supported")); + + Action::Handle action(WaypointSetSmart::create()); + + //Waypoint waypoint(value,time); + + Waypoint waypoint(value_node->new_waypoint_at_time(time)); + waypoint.set_value(value); + + waypoint.set_before(synfigapp::Main::get_interpolation()); + waypoint.set_after(synfigapp::Main::get_interpolation()); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("value_node",ValueNode::Handle(value_node)); + action->set_param("waypoint",waypoint); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + DEBUGPOINT(); + add_action(action); + + return; + } + else + { + if(value_desc.is_value_node()) + { + if(ValueNode_Const::Handle::cast_dynamic(value_desc.get_value_node())) + { + Action::Handle action(ValueNodeConstSet::create()); + + action->set_param("canvas",get_canvas()); + action->set_param("canvas_interface",get_canvas_interface()); + action->set_param("value_node",value_desc.get_value_node()); + action->set_param("new_value",value); + + if(!action->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action_front(action); + return; + } + else + if(ValueNode_Animated::Handle::cast_dynamic(value_desc.get_value_node())) + throw Error(_("You must be in Animate-Editing-Mode to directly manipulate this value")); + else + throw Error(_("Direct manipulation of this ValueNode type is not yet supported")); + } + else + if(value_desc.parent_is_layer_param() && !value_desc.is_value_node()) + { + Action::Handle layer_param_set(LayerParamSet::create()); + + 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()); + layer_param_set->set_param("param",value_desc.get_param_name()); + layer_param_set->set_param("new_value",value); + + if(!layer_param_set->is_ready()) + throw Error(Error::TYPE_NOTREADY); + + add_action_front(layer_param_set); + return; + } + + throw Error(_("Unsupported ValueDesc type")); + } +}