int Action::KeyframeSet::scale_activepoints(const synfigapp::ValueDesc& value_desc,const synfig::Time& old_begin,const synfig::Time& old_end,const synfig::Time& new_begin,const synfig::Time& new_end) { ValueNode_DynamicList::Handle value_node(ValueNode_DynamicList::Handle::cast_static(value_desc.get_parent_value_node())); ValueNode_DynamicList::ListEntry& list_entry(value_node->list[value_desc.get_index()]); std::vector<Activepoint*> selected; std::vector<Activepoint*>::iterator iter; if(list_entry.find(old_begin,old_end,selected)) { // check to make sure this operation is OK for(iter=selected.begin();iter!=selected.end();++iter) { try { Time new_time(old_2_new((*iter)->get_time())); if(new_time>=old_begin && new_time<old_end) continue; list_entry.find(new_time); // If we found a activepoint already at that time, then // we need to abort //throw Exception::BadTime(_("Activepoint Conflict")); } catch(Exception::NotFound&) { } } int ret(0); while(!selected.empty()) { if(selected.back()->get_time()!=old_2_new(selected.back()->get_time())) { Action::Handle action(Action::create("ActivepointSet")); action->set_param("canvas",get_canvas()); action->set_param("canvas_interface",get_canvas_interface()); action->set_param("value_desc",value_desc); Activepoint activepoint(*selected.back()); activepoint.set_time(old_2_new(selected.back()->get_time())); action->set_param("activepoint",activepoint); assert(action->is_ready()); if(!action->is_ready()) throw Error(Error::TYPE_NOTREADY); add_action_front(action); ret++; } selected.pop_back(); } return ret; } return 0; }
void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> &tlist, timepoints_ref &vals, synfig::Time time_offset, synfig::Real time_dilation) { //special cases for Animated, DynamicList, and Linkable //synfig::info("ValueBasenode... %p, %s", h.get_value_node().get(),typeid(*h.get_value_node()).name()); //animated case { synfig::ValueNode_Animated::Handle p = synfig::ValueNode_Animated::Handle::cast_dynamic(h.get_value_node()); if(p) { //loop through and determine which waypoint we will need to reference const synfig::WaypointList &w = p->waypoint_list(); synfig::WaypointList::const_iterator i = w.begin(), end = w.end(); std::set<Time>::const_iterator j = tlist.begin(), jend = tlist.end(); for(; i != end && j != jend;) { //synfig::info("tpair t(%.3f) = %.3f", (float)*j, (float)(i->get_time())); if((*j*time_dilation+time_offset).is_equal(i->get_time())) { vals.insert(p,*i,time_dilation); ++i,++j; }else if(*i < *j*time_dilation+time_offset) { ++i; }else ++j; } return; } } //parent dynamiclist case - just for active points for that object... if(h.parent_is_value_node()) { synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_parent_value_node()); if(p) { int index = h.get_index(); //check all the active points in each list... const synfig::ActivepointList &a = p->list[index].timing_info; //synfig::info("Our parent = dynamic list, searching in %d activepts",a.size()); std::set<Time>::const_iterator i = tlist.begin(), end = tlist.end(); synfig::ActivepointList::const_iterator j = a.begin(), jend = a.end(); for(; j != jend && i != end;) { double it = *i*time_dilation+time_offset; double jt = j->get_time(); double diff = (double)(it - jt); //synfig::info("\ttpair match(%.4lg) - %.4lg (diff = %lg",it,jt,diff); // if(abs(diff) < (double)Time::epsilon()) { //synfig::info("\tActivepoint to add being referenced (%x,%s,%.4lg)", // (int)j->get_uid(),j->state?"true":"false", (double)j->time); vals.insert(ValueDesc(p,index),*j,time_dilation); ++i,++j; }else if(it < jt) { ++i; //synfig::info("\tIncrementing time"); } else { ++j; //synfig::info("\tIncrementing actpt"); } } } } //dynamiclist case - we must still make sure that we read from the list entries the time values // because just the linked valuenodes will not do that { synfig::ValueNode_DynamicList::Handle p = synfig::ValueNode_DynamicList::Handle::cast_dynamic(h.get_value_node()); if(p) { //synfig::info("Process dynamic list valuenode"); int index = 0; std::vector<synfig::ValueNode_DynamicList::ListEntry>::const_iterator i = p->list.begin(), end = p->list.end(); for(; i != end; ++i, ++index) { const Node::time_set &tset = i->get_times(); if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset,time_dilation)) { recurse_valuedesc(ValueDesc(p,index),tlist,vals,time_offset,time_dilation); } } return; } } //the linkable case... { etl::handle<synfig::LinkableValueNode> p = etl::handle<synfig::LinkableValueNode>::cast_dynamic(h.get_value_node()); if(p) { //synfig::info("Process Linkable ValueBasenode"); int i = 0, size = p->link_count(); for(; i < size; ++i) { ValueNode::Handle v = p->get_link(i); const Node::time_set &tset = v->get_times(); if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset,time_dilation)) { recurse_valuedesc(ValueDesc(p,i),tlist,vals,time_offset,time_dilation); } } } } }