X-Git-Url: https://git.pterodactylus.net/?a=blobdiff_plain;ds=sidebyside;f=synfig-studio%2Ftrunk%2Fsrc%2Fgtkmm%2Fcellrenderer_timetrack.cpp;h=c1e6c87dafcc4736895fa30a0f2d7770647974df;hb=c2813b4d63804cac9b4067146a9e6eca717cb3e4;hp=754d260b5ed45012ad5b5815a5187d1a8dfa391b;hpb=c34eaa5441242b3e9a7b7645e9ee4983d14eae85;p=synfig.git diff --git a/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp b/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp index 754d260..c1e6c87 100644 --- a/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp +++ b/synfig-studio/trunk/src/gtkmm/cellrenderer_timetrack.cpp @@ -2,10 +2,11 @@ /*! \file cellrenderer_timetrack.cpp ** \brief Template Header ** -** $Id: cellrenderer_timetrack.cpp,v 1.4 2005/01/13 20:23:01 darco Exp $ +** $Id$ ** ** \legal ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley +** Copyright (c) 2007 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 @@ -47,6 +48,8 @@ #include +#include "general.h" + #endif using namespace synfig; @@ -83,7 +86,7 @@ CellRenderer_TimeTrack::CellRenderer_TimeTrack(): property_adjustment_(*this,"adjustment",&adjustment_), property_enable_timing_info_(*this,"enable-timing-info", false) { - dragging=false; + dragging=false; selection=false; } @@ -123,6 +126,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) { @@ -131,9 +158,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) - { return &canvasparam->get_times(); - } } ValueNode *base_value = v.get_value_node().get(); @@ -158,6 +183,14 @@ bool get_closest_time(const synfig::Node::time_set &tset, const Time &t, const T { Node::time_set::const_iterator i,j,end = tset.end(); + // stop the crash mentioned in bug #1689282 + // doesn't solve the underlying problem though, I don't think + if (tset.size() == 0) + { + synfig::error(__FILE__":%d: tset.size() == 0",__LINE__); + return false; + } + //TODO add in RangeGet so it's not so damn hard to click on points i = tset.upper_bound(t); //where t is the lower bound, t < [first,i) @@ -191,10 +224,10 @@ void CellRenderer_TimeTrack::render_vfunc( const Glib::RefPtr& window, Gtk::Widget& widget, - const Gdk::Rectangle& background_area, + const Gdk::Rectangle& /*background_area*/, const Gdk::Rectangle& area_, - const Gdk::Rectangle& expose_area, - Gtk::CellRendererState flags) + const Gdk::Rectangle& /*expose_area*/, + Gtk::CellRendererState /*flags*/) { if(!window) return; @@ -254,6 +287,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(), @@ -275,10 +309,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) @@ -288,13 +321,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... { @@ -302,7 +335,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 @@ -325,7 +358,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, @@ -521,7 +554,7 @@ CellRenderer_TimeTrack::render_vfunc( } synfig::ValueNode_Animated::WaypointList::iterator -CellRenderer_TimeTrack::find_waypoint(const synfig::Time& t,const synfig::Time& scope) +CellRenderer_TimeTrack::find_waypoint(const synfig::Time& /*t*/,const synfig::Time& scope) { synfig::ValueNode_Animated *value_node=dynamic_cast(property_value_desc().get_value().get_value_node().get()); @@ -556,11 +589,11 @@ CellRenderer_TimeTrack::find_waypoint(const synfig::Time& t,const synfig::Time& bool CellRenderer_TimeTrack::activate_vfunc( GdkEvent* event, - Gtk::Widget& widget, + Gtk::Widget& /*widget*/, const Glib::ustring& treepath, - const Gdk::Rectangle& background_area, + const Gdk::Rectangle& /*background_area*/, const Gdk::Rectangle& cell_area, - Gtk::CellRendererState flags) + Gtk::CellRendererState /*flags*/) { path=treepath; synfig::ValueNode_Animated::WaypointList::iterator iter; @@ -619,8 +652,8 @@ CellRenderer_TimeTrack::activate_vfunc( /*! UI specification: - When nothing is selected, clicking on a point in either normal mode order - addative mode will select the time point closest to the click. + When nothing is selected, clicking on a point in either normal mode or + additive mode will select the time point closest to the click. Subtractive click will do nothing When things are already selected, clicking on a selected point does @@ -632,8 +665,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 @@ -706,7 +740,7 @@ CellRenderer_TimeTrack::activate_vfunc( selection=true; } } - // Perhaps I sould signal if we selected this activepoint? + // Perhaps I should signal if we selected this activepoint? }*/ if(event->button.button==3) @@ -714,8 +748,9 @@ CellRenderer_TimeTrack::activate_vfunc( Time stime; synfigapp::ValueDesc valdesc = property_value_desc().get_value(); const Node::time_set *tset = get_times_from_vdesc(valdesc); + 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); etl::handle node; if(valdesc.get_value(stime).get_type()==ValueBase::TYPE_CANVAS) @@ -729,7 +764,7 @@ CellRenderer_TimeTrack::activate_vfunc( if(clickfound && node) { - show_timepoint_menu(node, stime, actual_time CellRenderer_TimeTrack::property_value_desc() { @@ -898,20 +937,31 @@ set_waypoint_model(std::set > waypoints, W } void -CellRenderer_TimeTrack::show_timepoint_menu(const etl::handle& node, const synfig::Time& time, Side side) +CellRenderer_TimeTrack::show_timepoint_menu(const etl::handle& node, const synfig::Time& time, const synfig::Time& time_offset, Side side) { std::set > waypoint_set; int n; n=synfig::waypoint_collect(waypoint_set,time,node); Gtk::Menu* menu(manage(new Gtk::Menu())); + menu->signal_hide().connect(sigc::bind(sigc::ptr_fun(&delete_widget), menu)); // Create the interpolation method menu if(!waypoint_set.empty()) { Gtk::Menu* interp_menu(manage(new Gtk::Menu())); + // no need to connect to signal_hide for this one - it will be deleted when its parent is deleted Waypoint::Model model; + // note: each of the following 4 'if' blocks provokes these warnings: + // /usr/include/sigc++-2.0/sigc++/adaptors/bound_argument.h:57: warning: + // 'model.synfig::Waypoint::Model::temporal_tension' is used uninitialized in this function + // 'model.synfig::Waypoint::Model::bias' is used uninitialized in this function + // 'model.synfig::Waypoint::Model::continuity' is used uninitialized in this function + // 'model.synfig::Waypoint::Model::tension' is used uninitialized in this function + // 'model.synfig::Waypoint::Model::priority' is used uninitialized in this function + // I don't know if that matters or not. + if(side==SIDE_LEFT)model.set_before(INTERPOLATION_TCB); else model.set_after(INTERPOLATION_TCB); interp_menu->items().push_back(Gtk::Menu_Helpers::MenuElem(_("TCB"), @@ -971,13 +1021,15 @@ CellRenderer_TimeTrack::show_timepoint_menu(const etl::handle& nod *canvas_interface(), &synfigapp::CanvasInterface::set_time ), - time + time - time_offset ) )); if(!waypoint_set.empty()) { - if(waypoint_set.size()==1) + // attempting to locate the valuenode for the clicked waypoint doesn't work if this is a Canvas parameter, + // so act as if there were multiple waypoints in that case as a workaround + if(waypoint_set.size()==1 && !Canvas::Handle::cast_dynamic(node)) { delete menu; menu=0;