**
** \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
#include <synfig/timepointcollect.h>
+#include "general.h"
+
#endif
using namespace synfig;
property_adjustment_(*this,"adjustment",&adjustment_),
property_enable_timing_info_(*this,"enable-timing-info", false)
{
- dragging=false;
+ dragging=false;
selection=false;
}
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)
{
synfig::Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle());
if(canvasparam)
- {
return &canvasparam->get_times();
- }
}
ValueNode *base_value = v.get_value_node().get();
{
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)
CellRenderer_TimeTrack::render_vfunc(
const Glib::RefPtr<Gdk::Drawable>& 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;
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(),
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)
//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...
{
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
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,
}
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<synfig::ValueNode_Animated*>(property_value_desc().get_value().get_value_node().get());
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;
/*! 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
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
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)
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<synfig::Node> node;
if(valdesc.get_value(stime).get_type()==ValueBase::TYPE_CANVAS)
if(clickfound && node)
{
- show_timepoint_menu(node, stime, actual_time<stime?SIDE_LEFT:SIDE_RIGHT);
+ show_timepoint_menu(node, stime, time_offset, actual_time+time_offset<stime?SIDE_LEFT:SIDE_RIGHT);
}
}
+// The following three functions don't get documented correctly by
+// doxygen 1.5.[23] because of a bug with any function whose name
+// begins with 'property'. Fixed in doxygen 1.5.4 apparently. See
+// http://bugzilla.gnome.org/show_bug.cgi?id=471185 .
Glib::PropertyProxy<synfigapp::ValueDesc>
CellRenderer_TimeTrack::property_value_desc()
{
}
void
-CellRenderer_TimeTrack::show_timepoint_menu(const etl::handle<synfig::Node>& node, const synfig::Time& time, Side side)
+CellRenderer_TimeTrack::show_timepoint_menu(const etl::handle<synfig::Node>& node, const synfig::Time& time, const synfig::Time& time_offset, Side side)
{
std::set<synfig::Waypoint, std::less<UniqueID> > 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"),
*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;