From: dooglus <dooglus@1f10aa63-cdf2-0310-b900-c93c546f37ac> Date: Tue, 23 Oct 2007 19:55:53 +0000 (+0000) Subject: Improvements to interaction with waypoints in time-shifted canvases. X-Git-Url: https://git.pterodactylus.net/?a=commitdiff_plain;h=606a53ecae1c2993a50f9af49f65864d7bcab656;p=synfig.git Improvements to interaction with waypoints in time-shifted canvases. git-svn-id: http://svn.voria.com/code@947 1f10aa63-cdf2-0310-b900-c93c546f37ac --- diff --git a/synfig-core/trunk/src/synfig/node.h b/synfig-core/trunk/src/synfig/node.h index aeb5da1..ccdaaad 100644 --- a/synfig-core/trunk/src/synfig/node.h +++ b/synfig-core/trunk/src/synfig/node.h @@ -40,7 +40,7 @@ // When a PasteCanvas layer has a non-zero 'time offset' parameter, should // the waypoints shown for the canvas be adjusted? This currently only // partially works - see the TODO at the end of layer_pastecanvas.cpp -// #define ADJUST_WAYPOINTS_FOR_TIME_OFFSET +#define ADJUST_WAYPOINTS_FOR_TIME_OFFSET /* === T Y P E D E F S ===================================================== */ diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp b/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp index 7d2d6c0..af5b57c 100644 --- a/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp +++ b/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp @@ -124,6 +124,30 @@ CellRenderer_TimeTrack::is_selected(const Waypoint& waypoint)const return selected==waypoint; } +const synfig::Time get_time_offset_from_vdesc(const synfigapp::ValueDesc &v) +{ +#ifdef ADJUST_WAYPOINTS_FOR_TIME_OFFSET + if(v.get_value_type() != synfig::ValueBase::TYPE_CANVAS) + return synfig::Time::zero(); + + synfig::Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle()); + if(!canvasparam) + return synfig::Time::zero(); + + if (!v.parent_is_layer_param()) + return synfig::Time::zero(); + + synfig::Layer::Handle layer = v.get_layer(); + + if (layer->get_name()!="PasteCanvas") + return synfig::Time::zero(); + + return layer->get_param("time_offset").get(Time()); +#else // ADJUST_WAYPOINTS_FOR_TIME_OFFSET + return synfig::Time::zero(); +#endif +} + //kind of a hack... pointer is ugly const synfig::Node::time_set *get_times_from_vdesc(const synfigapp::ValueDesc &v) { @@ -132,33 +156,7 @@ const synfig::Node::time_set *get_times_from_vdesc(const synfigapp::ValueDesc &v synfig::Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle()); if(canvasparam) - { -#ifdef ADJUST_WAYPOINTS_FOR_TIME_OFFSET // see node.h - synfig::Time::value_type time_offset = 0; - if (v.parent_is_layer_param()) - { - synfig::Layer::Handle layer = v.get_layer(); - if (layer->get_name()=="PasteCanvas") - time_offset = layer->get_param("time_offset").get(Time()); - } - - const Node::time_set *times = &canvasparam->get_times(); - - if (time_offset) - { - //! \todo this is a memory leak - blame the 'kind of hack' above - Node::time_set *tmp = new Node::time_set; - Node::time_set::iterator i = times->begin(), end = times->end(); - for (; i != end; ++i) - tmp->insert(*i - time_offset); - return tmp; - } - - return times; -#else // ADJUST_WAYPOINTS_FOR_TIME_OFFSET return &canvasparam->get_times(); -#endif - } } ValueNode *base_value = v.get_value_node().get(); @@ -287,6 +285,7 @@ CellRenderer_TimeTrack::render_vfunc( if(tset) { + const synfig::Time time_offset = get_time_offset_from_vdesc(value_desc); synfig::Node::time_set::const_iterator i = tset->begin(), end = tset->end(); float lower = adjustment->get_lower(), @@ -308,10 +307,9 @@ CellRenderer_TimeTrack::render_vfunc( for(; i != end; ++i) { //find the coordinate in the drawable space... - Time t = i->get_time(); - - if(!t.is_valid()) - continue; + Time t_orig = i->get_time(); + if(!t_orig.is_valid()) continue; + Time t = t_orig - time_offset; //if it found it... (might want to change comparison, and optimize // sel_times.find to not produce an overall nlogn solution) @@ -321,13 +319,13 @@ CellRenderer_TimeTrack::render_vfunc( //if move dragging draw offset //if copy dragging draw both... - if(valselected && sel_times.find(t) != sel_times.end()) + if(valselected && sel_times.find(t_orig) != sel_times.end()) { if(dragging) //skip if we're dragging because we'll render it later { if(mode & COPY_MASK) // draw both blue and red moved { - drawredafter.push_back((t + diff).round(cfps)); + drawredafter.push_back(t + diff.round(cfps)); gc->set_rgb_fg_color(Gdk::Color("#00EEEE")); }else if(mode & DELETE_MASK) //it's just red... { @@ -335,7 +333,7 @@ CellRenderer_TimeTrack::render_vfunc( selected=true; }else //move - draw the red on top of the others... { - drawredafter.push_back((t + diff).round(cfps)); + drawredafter.push_back(t + diff.round(cfps)); continue; } }else @@ -358,7 +356,7 @@ CellRenderer_TimeTrack::render_vfunc( area.get_height()-2, area.get_height()-2 ); - render_time_point_to_window(window,area2,*i,selected); + render_time_point_to_window(window,area2,*i - time_offset,selected); /*window->draw_arc(gc,true, area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8, @@ -665,8 +663,9 @@ CellRenderer_TimeTrack::activate_vfunc( synfigapp::ValueDesc valdesc = property_value_desc().get_value(); const Node::time_set *tset = get_times_from_vdesc(valdesc); + const synfig::Time time_offset = get_time_offset_from_vdesc(valdesc); - bool clickfound = tset && get_closest_time(*tset,actual_time,pixel_width*cell_area.get_height(),stime); + bool clickfound = tset && get_closest_time(*tset,actual_time+time_offset,pixel_width*cell_area.get_height(),stime); bool selectmode = mode & SELECT_MASK; //NOTE LATER ON WE SHOULD MAKE IT SO MULTIPLE VALUENODES CAN BE SELECTED AT ONCE @@ -748,7 +747,7 @@ CellRenderer_TimeTrack::activate_vfunc( synfigapp::ValueDesc valdesc = property_value_desc().get_value(); const Node::time_set *tset = get_times_from_vdesc(valdesc); - bool clickfound = tset && get_closest_time(*tset,actual_time,pixel_width*cell_area.get_height(),stime); + bool clickfound = tset && get_closest_time(*tset,actual_time+get_time_offset_from_vdesc(valdesc),pixel_width*cell_area.get_height(),stime); etl::handle<synfig::Node> node; if(valdesc.get_value(stime).get_type()==ValueBase::TYPE_CANVAS) diff --git a/synfig-studio/trunk/src/synfigapp/timegather.cpp b/synfig-studio/trunk/src/synfigapp/timegather.cpp index e7a05dc..7e2f34a 100644 --- a/synfig-studio/trunk/src/synfigapp/timegather.cpp +++ b/synfig-studio/trunk/src/synfigapp/timegather.cpp @@ -96,7 +96,7 @@ void synfigapp::timepoints_ref::insert(synfigapp::ValueDesc v, synfig::Activepoi //recursion functions void synfigapp::recurse_canvas(synfig::Canvas::Handle h, const std::set<Time> &tlist, - timepoints_ref &vals) + timepoints_ref &vals, synfig::Time time_offset) { //synfig::info("Canvas...\n Recurse through layers"); @@ -107,15 +107,15 @@ void synfigapp::recurse_canvas(synfig::Canvas::Handle h, const std::set<Time> &t for(; i != end; ++i) { const Node::time_set &tset = (*i)->get_times(); - if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end())) + if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset)) { - recurse_layer(*i,tlist,vals); + recurse_layer(*i,tlist,vals,time_offset); } } } void synfigapp::recurse_layer(synfig::Layer::Handle h, const std::set<Time> &tlist, - timepoints_ref &vals) + timepoints_ref &vals, synfig::Time time_offset) { // iterate through the layers //check for special case of paste canvas @@ -128,20 +128,10 @@ void synfigapp::recurse_layer(synfig::Layer::Handle h, const std::set<Time> &tli //synfig::info("We are a paste canvas so go into that"); //recurse into the canvas const synfig::Node::time_set &tset = p->get_sub_canvas()->get_times(); + synfig::Time subcanvas_time_offset(time_offset + p->get_time_offset()); - if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end())) - { - //we have to offset the times so it won't wreck havoc if the canvas is imported more than once... - // and so we get correct results when offsets are present - std::set<Time> tlistoff; - std::set<Time>::iterator i = tlist.begin(), end = tlist.end(); - for(; i != end; ++i) - { - tlistoff.insert(*i - p->get_time_offset()); - } - - recurse_canvas(p->get_sub_canvas(),tlist,vals); - } + if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),subcanvas_time_offset)) + recurse_canvas(p->get_sub_canvas(),tlist,vals,subcanvas_time_offset); } //check all the valuenodes regardless... @@ -152,9 +142,9 @@ void synfigapp::recurse_layer(synfig::Layer::Handle h, const std::set<Time> &tli { const synfig::Node::time_set &tset = i->second->get_times(); - if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end())) + if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset)) { - recurse_valuedesc(ValueDesc(h,i->first),tlist,vals); + recurse_valuedesc(ValueDesc(h,i->first),tlist,vals,time_offset); } } } @@ -174,7 +164,7 @@ static bool sorted(IT i,IT end, const CMP &cmp = CMP()) } void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> &tlist, - timepoints_ref &vals) + timepoints_ref &vals, synfig::Time time_offset) { //special cases for Animated, DynamicList, and Linkable @@ -199,11 +189,11 @@ void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> & { //synfig::info("tpair t(%.3f) = %.3f", (float)*j, (float)(i->get_time())); - if(j->is_equal(i->get_time())) + if((*j+time_offset).is_equal(i->get_time())) { vals.insert(p,*i); ++i,++j; - }else if(*i < *j) + }else if(*i < *j+time_offset) { ++i; }else ++j; @@ -234,7 +224,7 @@ void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> & for(; j != jend && i != end;) { - double it = *i; + double it = *i+time_offset; double jt = j->get_time(); double diff = (double)(it - jt); @@ -279,9 +269,9 @@ void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> & { const Node::time_set &tset = i->get_times(); - if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end())) + if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset)) { - recurse_valuedesc(ValueDesc(p,index),tlist,vals); + recurse_valuedesc(ValueDesc(p,index),tlist,vals,time_offset); } } return; @@ -302,9 +292,9 @@ void synfigapp::recurse_valuedesc(synfigapp::ValueDesc h, const std::set<Time> & 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())) + if(check_intersect(tset.begin(),tset.end(),tlist.begin(),tlist.end(),time_offset)) { - recurse_valuedesc(ValueDesc(p,i),tlist,vals); + recurse_valuedesc(ValueDesc(p,i),tlist,vals,time_offset); } } } diff --git a/synfig-studio/trunk/src/synfigapp/timegather.h b/synfig-studio/trunk/src/synfigapp/timegather.h index 5db4afd..5792496 100644 --- a/synfig-studio/trunk/src/synfigapp/timegather.h +++ b/synfig-studio/trunk/src/synfigapp/timegather.h @@ -92,40 +92,36 @@ struct timepoints_ref //assumes they're sorted... (incremental advance) //checks the intersection of the two sets... might be something better in the stl template < typename I1, typename I2 > -bool check_intersect(I1 b1, I1 end1, I2 b2, I2 end2) +bool check_intersect(I1 b1, I1 end1, I2 b2, I2 end2, synfig::Time time_offset = 0) { if(b1 == end1 || b2 == end2) return false; for(; b1 != end1 && b2 != end2;) { - if(*b1 < *b2) ++b1; - else if(*b2 < *b1) ++b2; + if(*b1 < *b2 + time_offset) ++b1; + else if(*b2 + time_offset < *b1) ++b2; else { - assert(*b1 == *b2); + assert(*b1 == *b2 + time_offset); return true; } } return false; } -//pointer kind of a hack, gets the accurate times from a value desc -// (deals with dynamic list member correctly... i.e. gathers activepoints) -const synfig::Node::time_set *get_times_from_vdesc(const synfigapp::ValueDesc &v); - -//get's the closest time inside the set +//gets the closest time inside the set bool get_closest_time(const synfig::Node::time_set &tset, const synfig::Time &t, const synfig::Time &range, synfig::Time &out); //recursion functions based on time restrictions (can be expanded later)... //builds a list of relevant waypoints and activepoints inside the timepoints_ref structure void recurse_valuedesc(synfigapp::ValueDesc valdesc, const std::set<synfig::Time> &tlist, - timepoints_ref &vals); + timepoints_ref &vals, synfig::Time time = 0); void recurse_layer(synfig::Layer::Handle layer, const std::set<synfig::Time> &tlist, - timepoints_ref &vals); + timepoints_ref &vals, synfig::Time time = 0); void recurse_canvas(synfig::Canvas::Handle canvas, const std::set<synfig::Time> &tlist, - timepoints_ref &vals); + timepoints_ref &vals, synfig::Time time = 0);