X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fduckmatic.cpp;h=ae01119a447add1e701be98f857db2d9fc3f30a2;hb=207785229d58cdebc3012076596fdc255dcf9879;hp=a2cc733c993a83938b7fa1517d0843ddbddc68d6;hpb=d2f84aebee06cd05129fc4dadb706e856efde9bb;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/duckmatic.cpp b/synfig-studio/trunk/src/gtkmm/duckmatic.cpp index a2cc733..ae01119 100644 --- a/synfig-studio/trunk/src/gtkmm/duckmatic.cpp +++ b/synfig-studio/trunk/src/gtkmm/duckmatic.cpp @@ -6,6 +6,7 @@ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007, 2008 Chris Moore ** ** This package is free software; you can redistribute it and/or ** modify it under the terms of the GNU General Public License as @@ -55,6 +56,8 @@ #include "onemoment.h" +#include "general.h" + #endif /* === U S I N G =========================================================== */ @@ -86,7 +89,7 @@ Duckmatic::Duckmatic(): grid_snap(false), guide_snap(false), grid_size(1.0/4.0,1.0/4.0), - show_persistant_strokes(true) + show_persistent_strokes(true) { axis_lock=false; drag_offset_=Point(0,0); @@ -96,7 +99,24 @@ Duckmatic::Duckmatic(): Duckmatic::~Duckmatic() { clear_ducks(); - //synfig::info("Duckmatic::~Duckmatic(): Deleted. Duck Count=%d",Duck::duck_count); + + if (Duck::duck_count) + synfig::error("%d ducks not yet deleted!", Duck::duck_count); + + if (getenv("SYNFIG_DEBUG_DESTRUCTORS")) + synfig::info("Duckmatic::~Duckmatic(): Deleted"); +} + +void +Duckmatic::set_flip_x(bool flip_x) +{ + flip_x_ = flip_x; +} + +void +Duckmatic::set_flip_y(bool flip_y) +{ + flip_y_ = flip_y; } void @@ -109,8 +129,8 @@ Duckmatic::clear_ducks() bezier_list_.clear(); stroke_list_.clear(); - if(show_persistant_strokes) - stroke_list_=persistant_stroke_list_; + if(show_persistent_strokes) + stroke_list_=persistent_stroke_list_; } //! Returns \a true if the given duck is currently selected @@ -150,8 +170,6 @@ Duckmatic::set_guide_snap(bool x) } } - - Duckmatic::GuideList::iterator Duckmatic::find_guide_x(synfig::Point pos, float radius) { @@ -241,26 +259,21 @@ Duckmatic::is_duck_group_selectable(const etl::handle& x)const { const Type type(get_type_mask()); - if(( x->get_type() && (!(type & x->get_type())) ) ) - { + if (((x->get_type() && (!(type & x->get_type()))) || + !x->get_editable())) return false; - } + if(x->get_value_desc().parent_is_layer_param() && type & Duck::TYPE_POSITION) { Layer::Handle layer(x->get_value_desc().get_layer()); String layer_name(layer->get_name()); - if( - layer_name=="outline" || - layer_name=="region" || - layer_name=="polygon" || - layer_name=="curve_gradient" - ) + + if (layer_name == "outline" || layer_name == "region" || layer_name == "plant" || + layer_name == "polygon" || layer_name == "curve_gradient") return false; - if( - (layer_name=="PasteCanvas"|| - layer_name=="paste_canvas") - && !layer->get_param("children_lock").get(bool()) - ) + + if((layer_name=="PasteCanvas"|| layer_name=="paste_canvas") && + !layer->get_param("children_lock").get(bool())) return false; } return true; @@ -276,6 +289,25 @@ Duckmatic::select_all_ducks() } void +Duckmatic::toggle_select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br) +{ + Vector vmin, vmax; + vmin[0]=std::min(tl[0],br[0]); + vmin[1]=std::min(tl[1],br[1]); + vmax[0]=std::max(tl[0],br[0]); + vmax[1]=std::max(tl[1],br[1]); + + DuckMap::const_iterator iter; + for(iter=duck_map.begin();iter!=duck_map.end();++iter) + { + Point p(iter->second->get_trans_point()); + if(p[0]<=vmax[0] && p[0]>=vmin[0] && p[1]<=vmax[1] && p[1]>=vmin[1] && + is_duck_group_selectable(iter->second)) + toggle_select_duck(iter->second); + } +} + +void Duckmatic::select_ducks_in_box(const synfig::Vector& tl,const synfig::Vector& br) { Vector vmin, vmax; @@ -365,7 +397,6 @@ Duckmatic::toggle_select_duck(const etl::handle &duck) select_duck(duck); } - void Duckmatic::translate_selected_ducks(const synfig::Vector& vector) { @@ -392,7 +423,7 @@ Duckmatic::end_duck_drag() } Point -Duckmatic::snap_point_to_grid(const Point& x, float radius)const +Duckmatic::snap_point_to_grid(const synfig::Point& x, float radius)const { Point ret(x); @@ -411,8 +442,7 @@ Duckmatic::snap_point_to_grid(const Point& x, float radius)const { Point snap( floor(ret[0]/get_grid_size()[0]+0.5)*get_grid_size()[0], - floor(ret[1]/get_grid_size()[1]+0.5)*get_grid_size()[1] - ); + floor(ret[1]/get_grid_size()[1]+0.5)*get_grid_size()[1]); if(abs(snap[0]-ret[0])<=radius && (!has_guide_x || abs(snap[0]-ret[0])<=abs(*guide_x-ret[0]))) ret[0]=snap[0],has_guide_x=false; @@ -488,26 +518,21 @@ DuckDrag_Translate::duck_drag(Duckmatic* duckmatic, const synfig::Vector& vector for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++) { - if((*iter)->get_type()!=Duck::TYPE_VERTEX&&(*iter)->get_type()!=Duck::TYPE_POSITION)continue; + if((*iter)->get_type()!=Duck::TYPE_VERTEX && + (*iter)->get_type()!=Duck::TYPE_POSITION) + continue; (*iter)->set_trans_point(positions[i]+vect); } for(i=0,iter=selected_ducks.begin();iter!=selected_ducks.end();++iter,i++) { - if((*iter)->get_type()==Duck::TYPE_VERTEX||(*iter)->get_type()==Duck::TYPE_POSITION)continue; + if((*iter)->get_type()==Duck::TYPE_VERTEX || + (*iter)->get_type()==Duck::TYPE_POSITION) + continue; (*iter)->set_trans_point(positions[i]+vect); } last_translate_=vect; } - - - - - - - - - void Duckmatic::signal_edited_selected_ducks() { @@ -523,10 +548,46 @@ Duckmatic::signal_edited_selected_ducks() // Go ahead and call everyone's signals for(iter=ducks.begin();iter!=ducks.end();++iter) { - if(!(*iter)->signal_edited()((*iter)->get_point())) + if ((*iter)->get_type() == Duck::TYPE_ANGLE) { - selected_ducks=old_set; - throw String("Bad edit"); + if(!(*iter)->signal_edited_angle()((*iter)->get_rotations())) + { + selected_ducks=old_set; + throw String("Bad edit"); + } + } + else if (App::restrict_radius_ducks && + (*iter)->is_radius()) + { + Point point((*iter)->get_point()); + bool changed = false; + + if (point[0] * (flip_x_ ? -1 : 1) < 0) + { + point[0] = 0; + changed = true; + } + if (point[1] * (flip_y_ ? -1 : 1) < 0) + { + point[1] = 0; + changed = true; + } + + if (changed) (*iter)->set_point(point); + + if(!(*iter)->signal_edited()(point)) + { + selected_ducks=old_set; + throw String("Bad edit"); + } + } + else + { + if(!(*iter)->signal_edited()((*iter)->get_point())) + { + selected_ducks=old_set; + throw String("Bad edit"); + } } } selected_ducks=old_set; @@ -544,10 +605,6 @@ Duckmatic::signal_user_click_selected_ducks(int button) } } - - - - void Duckmatic::add_duck(const etl::handle &duck) { @@ -598,26 +655,26 @@ Duckmatic::add_stroke(etl::smart_ptr > stroke_point_lis } void -Duckmatic::add_persistant_stroke(etl::smart_ptr > stroke_point_list, const synfig::Color& color) +Duckmatic::add_persistent_stroke(etl::smart_ptr > stroke_point_list, const synfig::Color& color) { add_stroke(stroke_point_list,color); - persistant_stroke_list_.push_back(stroke_list_.back()); + persistent_stroke_list_.push_back(stroke_list_.back()); } void -Duckmatic::clear_persistant_strokes() +Duckmatic::clear_persistent_strokes() { - persistant_stroke_list_.clear(); + persistent_stroke_list_.clear(); } void -Duckmatic::set_show_persistant_strokes(bool x) +Duckmatic::set_show_persistent_strokes(bool x) { - if(x!=show_persistant_strokes) + if(x!=show_persistent_strokes) { - show_persistant_strokes=x; + show_persistent_strokes=x; if(x) - stroke_list_=persistant_stroke_list_; + stroke_list_=persistent_stroke_list_; else stroke_list_.clear(); } @@ -694,7 +751,6 @@ Duckmatic::last_bezier()const return bezier_list_.back(); } - etl::handle Duckmatic::find_duck(synfig::Point point, synfig::Real radius, Duck::Type type) { @@ -712,12 +768,14 @@ Duckmatic::find_duck(synfig::Point point, synfig::Real radius, Duck::Type type) { const Duck::Handle& duck(iter->second); - if(!duck->get_editable()) + if(duck->get_ignore()) continue; Real dist((duck->get_trans_point()-point).mag_squared()); if(duck->get_type()&Duck::TYPE_VERTEX) dist*=1.0001; + else if(duck->get_type()&Duck::TYPE_RADIUS) + dist*=0.9999; if(dist<=closest && !( duck->get_type() && (!(type & duck->get_type())) ) ) { @@ -797,11 +855,10 @@ Duckmatic::find_bezier(synfig::Point pos, synfig::Real scale, synfig::Real radiu return 0; } - - bool Duckmatic::save_sketch(const synfig::String& filename)const { + ChangeLocale change_locale(LC_NUMERIC, "C"); std::ofstream file(filename.c_str()); if(!file)return false; @@ -810,7 +867,7 @@ Duckmatic::save_sketch(const synfig::String& filename)const std::list >::const_iterator iter; - for(iter=persistant_stroke_list_.begin();iter!=persistant_stroke_list_.end();++iter) + for(iter=persistent_stroke_list_.begin();iter!=persistent_stroke_list_.end();++iter) { file<<"C " <<(*iter)->color.get_r()<<' ' @@ -835,6 +892,7 @@ Duckmatic::save_sketch(const synfig::String& filename)const bool Duckmatic::load_sketch(const synfig::String& filename) { + ChangeLocale change_locale(LC_NUMERIC, "C"); std::ifstream file(filename.c_str()); if(!file) @@ -849,7 +907,6 @@ Duckmatic::load_sketch(const synfig::String& filename) return false; } - etl::smart_ptr > stroke_data; while(file) @@ -871,7 +928,7 @@ Duckmatic::load_sketch(const synfig::String& filename) synfig::warning("Bad color line \"%s\"",line.c_str()); r=0;g=0;b=0; } - add_persistant_stroke(stroke_data, synfig::Color(r,g,b)); + add_persistent_stroke(stroke_data, synfig::Color(r,g,b)); } break; case 'V': @@ -879,7 +936,7 @@ Duckmatic::load_sketch(const synfig::String& filename) if(!stroke_data) { stroke_data.spawn(); - add_persistant_stroke(stroke_data, synfig::Color(0,0,0)); + add_persistent_stroke(stroke_data, synfig::Color(0,0,0)); } float x,y; if(!strscanf(line,"V %f %f",&x, &y)) @@ -897,13 +954,6 @@ Duckmatic::load_sketch(const synfig::String& filename) return true; } - - - - - - - Duckmatic::Push::Push(Duckmatic *duckmatic_): duckmatic_(duckmatic_) { @@ -932,14 +982,6 @@ Duckmatic::Push::restore() needs_restore=false; } - - - - - - - - inline String guid_string(const synfigapp::ValueDesc& x) { if(x.parent_is_layer_param()) @@ -992,7 +1034,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_radius(true); duck->set_type(Duck::TYPE_RADIUS); - duck->set_point(Point(value_desc.get_value(get_time()).get(Real()),0)); + // put the duck on the right hand side of the center, whether the display is flipped or not + duck->set_point(Point(value_desc.get_value(get_time()).get(Real()) * (flip_x_ ? -1 : 1), 0)); duck->set_name(guid_string(value_desc)); if(value_desc.is_value_node()) { @@ -1019,16 +1062,13 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_scalar(param_desc->get_scalar()); } - duck->signal_edited().clear(); + duck->signal_edited().clear(); // value_desc.get_value_type() == ValueBase::TYPE_REAL: duck->signal_edited().connect( sigc::bind( sigc::mem_fun( *canvas_view, - &studio::CanvasView::on_duck_changed - ), - value_desc - ) - ); + &studio::CanvasView::on_duck_changed), + value_desc)); duck->set_value_desc(value_desc); duck->signal_user_click(2).connect( @@ -1036,13 +1076,9 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple)); @@ -1095,16 +1131,14 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_scalar(param_desc->get_scalar()); } - duck->signal_edited().clear(); - duck->signal_edited().connect( + duck->signal_edited().clear(); // value_desc.get_value_type() == ValueBase::TYPE_ANGLE: + duck->signal_edited_angle().clear(); + duck->signal_edited_angle().connect( sigc::bind( sigc::mem_fun( *canvas_view, - &studio::CanvasView::on_duck_changed - ), - value_desc - ) - ); + &studio::CanvasView::on_duck_angle_changed), + value_desc)); duck->set_value_desc(value_desc); duck->signal_user_click(2).connect( @@ -1112,13 +1146,9 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple)); add_duck(duck); @@ -1193,17 +1223,13 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_type(Duck::TYPE_POSITION); - - duck->signal_edited().clear(); + duck->signal_edited().clear(); // value_desc.get_value_type() == ValueBase::TYPE_VECTOR: duck->signal_edited().connect( sigc::bind( sigc::mem_fun( *canvas_view, - &studio::CanvasView::on_duck_changed - ), - value_desc - ) - ); + &studio::CanvasView::on_duck_changed), + value_desc)); duck->set_value_desc(value_desc); duck->signal_user_click(2).connect( @@ -1211,13 +1237,9 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_guid(calc_duck_guid(value_desc,transform_stack)^GUID::hasher(multiple)); add_duck(duck); @@ -1230,8 +1252,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handlec1->set_scalar(TANGENT_BEZIER_SCALE); bezier->c1->set_tangent(true); - if(!add_to_ducks(synfigapp::ValueDesc(value_node,2),canvas_view,transform_stack)) return false; bezier->p2=last_duck(); @@ -1262,11 +1282,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle vertex_duck(last_duck()); @@ -1374,9 +1389,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle first_duck; etl::handle duck, tduck; - for(i=0;ilink_count();i++) + for (i = 0; i < value_node->link_count(); i++) { float amount(value_node->list[i].amount_at_time(get_time())); - if(amount<0.9999f) + + // skip vertices that aren't fully on + if (amount < 0.9999f) continue; - if(first==-1)first=i; + + // remember the index of the first vertex we didn't skip + if (first == -1) + first = i; BLinePoint bline_point((*value_node->get_link(i))(get_time())); - ValueNode_Composite::Handle vertex_value_node( - ValueNode_Composite::Handle::cast_dynamic( - value_node->get_link(i) - ) - ); + // try casting the vertex to Composite - this tells us whether it is composite or not + ValueNode_Composite::Handle composite_vertex_value_node( + ValueNode_Composite::Handle::cast_dynamic(value_node->get_link(i))); - // Add the vertex duck - if(vertex_value_node) + // add the vertex duck - it's a composite + if(composite_vertex_value_node) { - if(add_to_ducks(synfigapp::ValueDesc(vertex_value_node,0),canvas_view,transform_stack)) + if (add_to_ducks(synfigapp::ValueDesc(composite_vertex_value_node,0),canvas_view,transform_stack)) { duck=last_duck(); if(i==first) @@ -1418,13 +1435,9 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_value_desc(synfigapp::ValueDesc(value_node,i)); if(param_desc) @@ -1436,7 +1449,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_origin(last_duck()); /* ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time())); - if(value.same_as(synfig::Point())) + if(value.same_type_as(synfig::Point())) duck->set_origin(value.get(synfig::Point())); */ } @@ -1445,6 +1458,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_origin(last_duck()); /* ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time())); - if(value.same_as(synfig::Point())) + if(value.same_type_as(synfig::Point())) duck->set_origin(value.get(synfig::Point())); */ } @@ -1475,32 +1489,45 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleget_hint().empty()) + // Add the width duck if it is a parameter with a hint (ie. "width") or if it isn't a parameter + if ((param_desc && !param_desc->get_hint().empty()) || + !param_desc) { etl::handle width; - if(add_to_ducks(synfigapp::ValueDesc(vertex_value_node,1),canvas_view,transform_stack,REAL_COOKIE)) + if (add_to_ducks(synfigapp::ValueDesc(composite_vertex_value_node,1),canvas_view,transform_stack,REAL_COOKIE)) { width=last_duck(); width->set_origin(duck); width->set_type(Duck::TYPE_WIDTH); width->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".w"); + + // if the bline is a layer's parameter, scale the width duck by the layer's "width" parameter + if (param_desc) { ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_hint()).get_value(get_time())); - if(value.same_as(synfig::Real())) + if(value.same_type_as(synfig::Real())) width->set_scalar(value.get(synfig::Real())*0.5f); + // if it doesn't have a "width" parameter, scale by 0.5f instead + else + width->set_scalar(0.5f); } + // otherwise just present the raw unscaled width + else + width->set_scalar(0.5f); } else synfig::error("Unable to add width duck!"); } + // each bezier uses t2 of one point and t1 of the next + // the first time through this loop we won't have the t2 duck from the previous vertex + // and so we don't make a bezier. instead we skip on to t2 for this point if(bezier) { // Add the tangent1 duck - if(vertex_value_node) + if(composite_vertex_value_node) { - if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,4),canvas_view,transform_stack)) + if(!add_to_ducks(synfigapp::ValueDesc(composite_vertex_value_node,4),canvas_view,transform_stack)) return false; tduck=last_duck(); } @@ -1527,11 +1554,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handlesignal_user_click(2).clear(); duck->signal_user_click(2).connect( @@ -1539,50 +1563,39 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_value_desc(synfigapp::ValueDesc(value_node,i)); add_bezier(bezier); bezier=0; } + // don't start a new bezier for the last point in the line if we're not looped if(i+1>=value_node->link_count() && !value_node->get_loop()) continue; bezier=new Bezier(); // Add the tangent2 duck - if(vertex_value_node) + if(composite_vertex_value_node) { int i=bline_point.get_split_tangent_flag()?5:4; - if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,i),canvas_view,transform_stack,0,2)) + if(!add_to_ducks(synfigapp::ValueDesc(composite_vertex_value_node,i),canvas_view,transform_stack,0,2)) return false; tduck=last_duck(); } else { if(bline_point.get_split_tangent_flag()) - { tduck=new Duck(bline_point.get_tangent2()); - tduck->set_transform_stack(transform_stack); - //tduck->set_name(strprintf("%x-tangent2",value_node->get_link(i).get())); - tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".t2"); - tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t2")); - } else - { tduck=new Duck(bline_point.get_tangent1()); - tduck->set_transform_stack(transform_stack); - //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(i).get())); - tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".t1"); - tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1")); - } + + tduck->set_transform_stack(transform_stack); + tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,i))+".t2"); + tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t2")); tduck->set_editable(false); tduck=add_similar_duck(tduck); // add_duck(duck); @@ -1593,7 +1606,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_origin(last_duck()); /* ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time())); - if(value.same_as(synfig::Point())) + if(value.same_type_as(synfig::Point())) duck->set_origin(value.get(synfig::Point())); */ // if(!param_desc->get_origin().empty()) @@ -1605,14 +1618,10 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_value_desc(synfigapp::ValueDesc(value_node,0)); + &studio::CanvasView::popup_param_menu), + 1.0f), + synfigapp::ValueDesc(value_node,0))); + duck->set_value_desc(synfigapp::ValueDesc(value_node,i)); } @@ -1622,109 +1631,72 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handlep1=duck; bezier->c1=tduck; - } + // Loop if necessary if(bezier && value_node->get_loop()) { BLinePoint bline_point((*value_node->get_link(first))(get_time())); - ValueNode_Composite::Handle vertex_value_node( + ValueNode_Composite::Handle composite_vertex_value_node( ValueNode_Composite::Handle::cast_dynamic( - value_node->get_link(first) - ) - ); + value_node->get_link(first))); // Add the vertex duck duck=first_duck; - /* - if(vertex_value_node) + + // Add the tangent1 duck + if(composite_vertex_value_node) { - if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,0),canvas_view,transform_stack)) + if(!add_to_ducks(synfigapp::ValueDesc(composite_vertex_value_node,4),canvas_view,transform_stack)) return false; - duck=last_duck(); - if(param_desc) - { - if(!param_desc->get_origin().empty()) - duck->set_origin(value_desc.get_layer()->get_param(param_desc->get_origin()).get(synfig::Point())); - } - duck->set_type(Duck::TYPE_VERTEX); + tduck=last_duck(); } else { - duck=new Duck(bline_point.get_vertex()); - duck->set_transform_stack(transform_stack); - if(param_desc) - { - if(!param_desc->get_origin().empty()) - duck->set_origin(value_desc.get_layer()->get_param(param_desc->get_origin()).get(synfig::Point())); - } - duck->set_editable(false); - duck->set_name(strprintf("%x-vertex",value_node->get_link(first).get())); - duck->set_type(Duck::TYPE_VERTEX); - duck=add_similar_duck(duck); + tduck=new Duck(bline_point.get_tangent1()); + tduck->set_transform_stack(transform_stack); + tduck->set_editable(false); + tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,first))+".t1"); + //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(first).get())); + tduck=add_similar_duck(tduck); + tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,first),transform_stack)^GUID::hasher(".t1")); + //add_duck(duck); } - */ - // Add the tangent1 duck - if(vertex_value_node) - { - if(!add_to_ducks(synfigapp::ValueDesc(vertex_value_node,4),canvas_view,transform_stack)) - return false; - tduck=last_duck(); - } - else - { - tduck=new Duck(bline_point.get_tangent1()); - tduck->set_transform_stack(transform_stack); - tduck->set_editable(false); - tduck->set_name(guid_string(synfigapp::ValueDesc(value_node,first))+".t1"); - //tduck->set_name(strprintf("%x-tangent1",value_node->get_link(first).get())); - tduck=add_similar_duck(tduck); - tduck->set_guid(calc_duck_guid(synfigapp::ValueDesc(value_node,i),transform_stack)^GUID::hasher(".t1")); - //add_duck(duck); - } + tduck->set_origin(duck); + tduck->set_scalar(-TANGENT_BEZIER_SCALE); + tduck->set_tangent(true); - tduck->set_origin(duck); - tduck->set_scalar(-TANGENT_BEZIER_SCALE); - tduck->set_tangent(true); + bezier->p2=duck; + bezier->c2=tduck; - bezier->p2=duck; - bezier->c2=tduck; - bezier->signal_user_click(2).connect( + bezier->signal_user_click(2).connect( + sigc::bind( + sigc::mem_fun( + *canvas_view, + &studio::CanvasView::popup_param_menu_bezier), + synfigapp::ValueDesc(value_node,first))); + + duck->signal_user_click(2).clear(); + duck->signal_user_click(2).connect( + sigc::bind( sigc::bind( sigc::mem_fun( *canvas_view, - &studio::CanvasView::popup_param_menu_bezier - ), - synfigapp::ValueDesc(value_node,first) - ) - ); - duck->signal_user_click(2).clear(); - duck->signal_user_click(2).connect( - sigc::bind( - sigc::bind( - sigc::mem_fun( - *canvas_view, - &studio::CanvasView::popup_param_menu - ), - 1.0f - ), - synfigapp::ValueDesc(value_node,first) - ) - ); - duck->set_value_desc(synfigapp::ValueDesc(value_node,first)); - - add_bezier(bezier); - bezier=0; + &studio::CanvasView::popup_param_menu), + 1.0f), + synfigapp::ValueDesc(value_node,first))); + duck->set_value_desc(synfigapp::ValueDesc(value_node,first)); + add_bezier(bezier); + bezier=0; } return true; } else // Check for DynamicList if(value_desc.is_value_node() && - ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node()) - ) + ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node())) { ValueNode_DynamicList::Handle value_node; value_node=ValueNode_DynamicList::Handle::cast_dynamic(value_desc.get_value_node()); @@ -1748,7 +1720,7 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handleset_origin(last_duck()); /* ValueBase value(synfigapp::ValueDesc(value_desc.get_layer(),param_desc->get_origin()).get_value(get_time())); - if(value.same_as(synfig::Point())) + if(value.same_type_as(synfig::Point())) duck->set_origin(value.get(synfig::Point())); */ // if(!param_desc->get_origin().empty()) @@ -1770,11 +1742,8 @@ Duckmatic::add_to_ducks(const synfigapp::ValueDesc& value_desc,etl::handle