From e7e506afaa868e76c2dfa74dd33614a9a029bb85 Mon Sep 17 00:00:00 2001 From: Nikita Kitaev Date: Wed, 16 Jun 2010 21:28:29 -0700 Subject: [PATCH] Refactor duck reverse manipulation into duckmatic --- synfig-studio/src/gui/canvasview.cpp | 147 ---------------------------- synfig-studio/src/gui/canvasview.h | 3 - synfig-studio/src/gui/duckmatic.cpp | 179 ++++++++++++++++++++++++++++++++--- synfig-studio/src/gui/duckmatic.h | 14 ++- synfig-studio/src/gui/workarea.cpp | 1 + 5 files changed, 176 insertions(+), 168 deletions(-) diff --git a/synfig-studio/src/gui/canvasview.cpp b/synfig-studio/src/gui/canvasview.cpp index 717e11f..74f36ee 100644 --- a/synfig-studio/src/gui/canvasview.cpp +++ b/synfig-studio/src/gui/canvasview.cpp @@ -2869,153 +2869,6 @@ CanvasView::duck_change_param(const synfig::Point &value,synfig::Layer::Handle l return canvas_interface()->change_value(synfigapp::ValueDesc(layer,param_name),value); } -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")); - Real radius = 0.0; - 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())) - { - 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); - } - default: - break; - } - } - - if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) - { - int link_index(scale_value_node->get_link_index_from_name("link")); - if(scale_value_node->is_invertible(get_time())) - return canvas_interface()->change_value( - synfigapp::ValueDesc(scale_value_node,link_index), - scale_value_node->get_inverse(get_time(), value) - ); - else - 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: - 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); - } -} - -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); - } - - if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) - { - int link_index(scale_value_node->get_link_index_from_name("link")); - if(scale_value_node->is_invertible(get_time())) - return canvas_interface()->change_value( - synfigapp::ValueDesc(scale_value_node,link_index), - scale_value_node->get_inverse(get_time(), rotation) - ); - else - 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); -} - void CanvasView::selected_layer_color_set(synfig::Color color) { diff --git a/synfig-studio/src/gui/canvasview.h b/synfig-studio/src/gui/canvasview.h index 9b08626..6600d0a 100644 --- a/synfig-studio/src/gui/canvasview.h +++ b/synfig-studio/src/gui/canvasview.h @@ -707,9 +707,6 @@ private: void on_audio_file_notify(); void on_audio_offset_notify(); - bool on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc); - bool on_duck_angle_changed(const synfig::Angle &rotation,const synfigapp::ValueDesc& value_desc); - void on_layer_toggle(synfig::Layer::Handle); void on_edited_value(synfigapp::ValueDesc,synfig::ValueBase); diff --git a/synfig-studio/src/gui/duckmatic.cpp b/synfig-studio/src/gui/duckmatic.cpp index 51ed17f..fe2d6a3 100644 --- a/synfig-studio/src/gui/duckmatic.cpp +++ b/synfig-studio/src/gui/duckmatic.cpp @@ -38,11 +38,13 @@ #include "duckmatic.h" #include +#include #include #include #include #include #include +#include #include #include #include @@ -88,7 +90,8 @@ using namespace studio; /* === E N T R Y P O I N T ================================================= */ -Duckmatic::Duckmatic(): +Duckmatic::Duckmatic(etl::loose_handle canvas_interface): + canvas_interface(canvas_interface), type_mask(Duck::TYPE_ALL-Duck::TYPE_WIDTH), grid_snap(false), guide_snap(false), @@ -635,6 +638,20 @@ DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector last_translate_=vect; } + +void +Duckmatic::signal_user_click_selected_ducks(int button) +{ + const DuckList ducks(get_selected_ducks()); + DuckList::const_iterator iter; + + for(iter=ducks.begin();iter!=ducks.end();++iter) + { + (*iter)->signal_user_click(button)(); + } +} + + void Duckmatic::signal_edited_selected_ducks() { @@ -695,16 +712,152 @@ Duckmatic::signal_edited_selected_ducks() selected_ducks=old_set; } -void -Duckmatic::signal_user_click_selected_ducks(int button) + +bool +Duckmatic::on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc) { - const DuckList ducks(get_selected_ducks()); - DuckList::const_iterator iter; + 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); + } - for(iter=ducks.begin();iter!=ducks.end();++iter) + if (ValueNode_BLineCalcVertex::Handle bline_vertex = ValueNode_BLineCalcVertex::Handle::cast_dynamic(value_desc.get_value_node())) { - (*iter)->signal_user_click(button)(); + ValueNode_BLine::Handle bline = ValueNode_BLine::Handle::cast_dynamic(bline_vertex->get_link("bline")); + Real radius = 0.0; + 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())) + { + 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); + } + default: + break; + } + } + + if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) + { + int link_index(scale_value_node->get_link_index_from_name("link")); + if(scale_value_node->is_invertible(get_time())) + return canvas_interface->change_value( + synfigapp::ValueDesc(scale_value_node,link_index), + scale_value_node->get_inverse(get_time(), value) + ); + else + 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: + 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); + } +} + +bool +Duckmatic::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); + } + + if (ValueNode_Scale::Handle scale_value_node = ValueNode_Scale::Handle::cast_dynamic(value_desc.get_value_node())) + { + int link_index(scale_value_node->get_link_index_from_name("link")); + if(scale_value_node->is_invertible(get_time())) + return canvas_interface->change_value( + synfigapp::ValueDesc(scale_value_node,link_index), + scale_value_node->get_inverse(get_time(), rotation) + ); + else + 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); } void @@ -1170,8 +1323,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handlesignal_edited().connect( sigc::bind( sigc::mem_fun( - *canvas_view, - &studio::CanvasView::on_duck_changed), + *this, + &studio::Duckmatic::on_duck_changed), value_desc)); duck->set_value_desc(value_desc); @@ -1242,8 +1395,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handlesignal_edited_angle().connect( sigc::bind( sigc::mem_fun( - *canvas_view, - &studio::CanvasView::on_duck_angle_changed), + *this, + &studio::Duckmatic::on_duck_angle_changed), value_desc)); duck->set_value_desc(value_desc); @@ -1335,8 +1488,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handlesignal_edited().connect( sigc::bind( sigc::mem_fun( - *canvas_view, - &studio::CanvasView::on_duck_changed), + *this, + &studio::Duckmatic::on_duck_changed), value_desc)); duck->set_value_desc(value_desc); diff --git a/synfig-studio/src/gui/duckmatic.h b/synfig-studio/src/gui/duckmatic.h index 68e4671..c97bbb6 100644 --- a/synfig-studio/src/gui/duckmatic.h +++ b/synfig-studio/src/gui/duckmatic.h @@ -82,7 +82,7 @@ public: /* === C L A S S E S & S T R U C T S ======================================= */ -namespace synfigapp { class ValueDesc; } +namespace synfigapp { class ValueDesc; class CanvasInterface; } namespace synfig { class ParamDesc; } namespace studio @@ -158,6 +158,8 @@ typedef std::map > DuckDataMap; private: + etl::loose_handle canvas_interface; + Type type_mask; DuckMap duck_map; @@ -235,7 +237,7 @@ private: public: - Duckmatic(); + Duckmatic(etl::loose_handle canvas_interface); virtual ~Duckmatic(); sigc::signal& signal_duck_selection_changed() { return signal_duck_selection_changed_; } @@ -337,13 +339,15 @@ public: //! Ends the duck drag bool end_duck_drag(); + //! Signals to each selected duck that it has been clicked + void signal_user_click_selected_ducks(int button); + //! Calls all of the ducks' edited signals /*! Updates corresponding valuenodes after a drag */ void signal_edited_selected_ducks(); - //! Signals to each selected duck that it has been clicked - void signal_user_click_selected_ducks(int button); - + bool on_duck_changed(const synfig::Point &value,const synfigapp::ValueDesc& value_desc); + bool on_duck_angle_changed(const synfig::Angle &rotation,const synfigapp::ValueDesc& value_desc); etl::handle find_similar_duck(etl::handle duck); etl::handle add_similar_duck(etl::handle duck); diff --git a/synfig-studio/src/gui/workarea.cpp b/synfig-studio/src/gui/workarea.cpp index 7529452..f84f9ea 100644 --- a/synfig-studio/src/gui/workarea.cpp +++ b/synfig-studio/src/gui/workarea.cpp @@ -646,6 +646,7 @@ public: WorkArea::WorkArea(etl::loose_handle canvas_interface): Gtk::Table(3, 3, false), /* 3 columns by 3 rows*/ + Duckmatic(canvas_interface), canvas_interface(canvas_interface), canvas(canvas_interface->get_canvas()), scrollx_adjustment(0,-4,4,0.01,0.1), -- 2.7.4