+++ /dev/null
-/* === S Y N F I G ========================================================= */
-/*! \file cellrenderer_timetrack.cpp
-** \brief Template Header
-**
-** $Id$
-**
-** \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
-** published by the Free Software Foundation; either version 2 of
-** the License, or (at your option) any later version.
-**
-** This package is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-** General Public License for more details.
-** \endlegal
-*/
-/* ========================================================================= */
-
-/* === H E A D E R S ======================================================= */
-
-#ifdef USING_PCH
-# include "pch.h"
-#else
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <gtkmm/label.h>
-#include "cellrenderer_timetrack.h"
-#include <gtk/gtk.h>
-#include <gtkmm/spinbutton.h>
-#include <gtkmm/combo.h>
-#include <ETL/stringf>
-#include "widget_value.h"
-#include "app.h"
-#include <gtkmm/menu.h>
-#include <gtkmm/optionmenu.h>
-#include "widget_time.h"
-#include "widget_timeslider.h"
-
-#include <synfigapp/canvasinterface.h>
-#include "instance.h"
-
-#include "general.h"
-
-#endif
-
-using namespace synfig;
-using namespace std;
-using namespace etl;
-using namespace studio;
-
-/* === M A C R O S ========================================================= */
-
-/* === G L O B A L S ======================================================= */
-
-static char stipple_xpm[] = { 2, 0 };
-
-//mode for modifier keys
-enum MODMODE
-{
- NONE = 0,
- SELECT_MASK = Gdk::CONTROL_MASK,
- COPY_MASK = Gdk::SHIFT_MASK,
- DELETE_MASK = Gdk::MOD1_MASK
-};
-
-/* === P R O C E D U R E S ================================================= */
-
-/* === M E T H O D S ======================================================= */
-
-CellRenderer_TimeTrack::CellRenderer_TimeTrack():
- Glib::ObjectBase (typeid(CellRenderer_TimeTrack)),
- Gtk::CellRenderer (),
- adjustment_ (10,10,20,0,0,0),
-
- property_valuedesc_ (*this,"value_desc",synfigapp::ValueDesc()),
- property_canvas_ (*this,"canvas",synfig::Canvas::Handle()),
- property_adjustment_(*this,"adjustment",&adjustment_),
- property_enable_timing_info_(*this,"enable-timing-info", false)
-{
- dragging=false;
- selection=false;
-}
-
-CellRenderer_TimeTrack::~CellRenderer_TimeTrack()
-{
- if (getenv("SYNFIG_DEBUG_DESTRUCTORS"))
- synfig::info("CellRenderer_TimeTrack::~CellRenderer_TimeTrack(): Deleted");
-}
-
-void
-CellRenderer_TimeTrack::set_adjustment(Gtk::Adjustment &x)
-{
- property_adjustment_=&x;
-// x.signal_value_changed().connect(sigc::mem_fun(*this,&Gtk::Widget::queue_draw));
-}
-
-synfig::Canvas::Handle
-CellRenderer_TimeTrack::get_canvas()const
-{
- return const_cast<CellRenderer_TimeTrack*>(this)->property_canvas().get_value();
-}
-
-Gtk::Adjustment *
-CellRenderer_TimeTrack::get_adjustment()
-{
- return (Gtk::Adjustment*)property_adjustment_;
-}
-
-const Gtk::Adjustment *
-CellRenderer_TimeTrack::get_adjustment()const
-{
- return (const Gtk::Adjustment*)property_adjustment_;
-}
-
-bool
-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(getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS") ||
- 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)
-{
- if(!getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS") &&
- v.get_value_type() == synfig::ValueBase::TYPE_CANVAS)
- {
- synfig::Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle());
-
- if(canvasparam)
- return &canvasparam->get_times();
- }
-
- ValueNode *base_value = v.get_value_node().get();
-
- ValueNode_DynamicList *parent_value_node =
- v.parent_is_value_node() ?
- dynamic_cast<ValueNode_DynamicList *>(v.get_parent_value_node().get()) :
- 0;
-
- //we want a dynamic list entry to override the normal...
- if(parent_value_node)
- {
- return &parent_value_node->list[v.get_index()].get_times();
- }else if(base_value) //don't render stuff if it's just animated...
- {
- return &base_value->get_times();
- }
- return 0;
-}
-
-bool get_closest_time(const synfig::Node::time_set &tset, const Time &t, const Time &range, Time &out)
-{
- 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)
- j = i; --j;
-
- double dist = Time::end();
- double closest = 0;
-
- if(i != end)
- {
- closest = i->get_time();
- dist = abs(i->get_time() - t);
- }
-
- if(j != end && (abs(j->get_time() - t) < dist) )
- {
- closest = j->get_time();
- dist = abs(j->get_time() - t);
- }
-
- if( dist <= range/2 )
- {
- out = closest;
- return true;
- }
-
- return false;
-}
-
-void
-CellRenderer_TimeTrack::render_vfunc(
- const Glib::RefPtr<Gdk::Drawable>& window,
- Gtk::Widget& widget,
- const Gdk::Rectangle& /*background_area*/,
- const Gdk::Rectangle& area_,
- const Gdk::Rectangle& /*expose_area*/,
- Gtk::CellRendererState /*flags*/)
-{
- if(!window)
- return;
-
- Glib::RefPtr<Gdk::GC> gc(Gdk::GC::create(window));
- Glib::RefPtr<Gdk::GC> inactive_gc(Gdk::GC::create(window));
- Gtk::Adjustment *adjustment=get_adjustment();
- // Gtk::StateType state = Gtk::STATE_ACTIVE;
- // Gtk::ShadowType shadow;
-
- Gdk::Color
- curr_time_color("#0000ff"),
- inactive_color("#000000"),
- keyframe_color("#a07f7f");
- Gdk::Color activepoint_color[2];
-
- activepoint_color[0]=Gdk::Color("#ff0000");
- activepoint_color[1]=Gdk::Color("#00ff00");
-
- inactive_gc->set_rgb_fg_color(inactive_color);
- inactive_gc->set_stipple(Gdk::Bitmap::create(stipple_xpm,2,2));
- inactive_gc->set_fill(Gdk::STIPPLED);
-
- synfig::Canvas::Handle canvas(property_canvas().get_value());
-
- synfigapp::ValueDesc value_desc = property_value_desc().get_value();
- synfig::ValueNode *base_value = value_desc.get_value_node().get();
- // synfig::ValueNode_Animated *value_node=dynamic_cast<synfig::ValueNode_Animated*>(base_value);
-
- synfig::ValueNode_DynamicList *parent_value_node(0);
- if(property_value_desc().get_value().parent_is_value_node())
- parent_value_node=dynamic_cast<synfig::ValueNode_DynamicList*>(property_value_desc().get_value().get_parent_value_node().get());
-
- // If the canvas is defined, then load up the keyframes
- if(canvas)
- {
- const synfig::KeyframeList& keyframe_list(canvas->keyframe_list());
- synfig::KeyframeList::const_iterator iter;
-
- for(iter=keyframe_list.begin();iter!=keyframe_list.end();++iter)
- {
- if(!iter->get_time().is_valid())
- continue;
-
- const int x((int)((float)area_.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(iter->get_time()-adjustment->get_lower())));
- if(iter->get_time()>=adjustment->get_lower() && iter->get_time()<adjustment->get_upper())
- {
- gc->set_rgb_fg_color(keyframe_color);
- window->draw_rectangle(gc, true, area_.get_x()+x, area_.get_y(), 1, area_.get_height()+1);
- }
- }
- }
-
- //render all the time points that exist
- {
- const synfig::Node::time_set *tset = get_times_from_vdesc(value_desc);
-
- 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(),
- upper = adjustment->get_upper();
-
- Glib::RefPtr<Gdk::GC> gc = Gdk::GC::create(widget.get_window());
-
- Gdk::Rectangle area(area_);
- gc->set_clip_rectangle(area);
- gc->set_line_attributes(1,Gdk::LINE_SOLID,Gdk::CAP_BUTT,Gdk::JOIN_MITER);
-
- bool valselected = sel_value.get_value_node() == base_value && !sel_times.empty();
-
- float cfps = get_canvas()->rend_desc().get_frame_rate();
-
- vector<Time> drawredafter;
-
- Time diff = actual_time - actual_dragtime;//selected_time-drag_time;
- for(; i != end; ++i)
- {
- //find the coordinate in the drawable space...
- Time t_orig = i->get_time();
- if(!t_orig.is_valid()) continue;
- Time t = t_orig - time_offset;
- if(t<adjustment->get_lower() || t>adjustment->get_upper()) continue;
-
- //if it found it... (might want to change comparison, and optimize
- // sel_times.find to not produce an overall nlogn solution)
-
- bool selected=false;
- //not dragging... just draw as per normal
- //if move dragging draw offset
- //if copy dragging draw both...
-
- 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));
- gc->set_rgb_fg_color(Gdk::Color("#00EEEE"));
- }else if(mode & DELETE_MASK) //it's just red...
- {
- gc->set_rgb_fg_color(Gdk::Color("#EE0000"));
- selected=true;
- }else //move - draw the red on top of the others...
- {
- drawredafter.push_back(t + diff.round(cfps));
- continue;
- }
- }else
- {
- gc->set_rgb_fg_color(Gdk::Color("#EE0000"));
- selected=true;
- }
- }else
- {
- gc->set_rgb_fg_color(Gdk::Color("#00EEEE"));
- }
-
- //synfig::info("Displaying time: %.3f s",(float)t);
- const int x = (int)((t-lower)*area.get_width()/(upper-lower));
-
- //should draw me a grey filled circle...
- Gdk::Rectangle area2(
- area.get_x() - area.get_height()/2 + x + 1,
- area.get_y() + 1,
- area.get_height()-2,
- area.get_height()-2
- );
- 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,
- area.get_height()/2, area.get_height()*3/4,
- 0, 64*360);
-
- gc->set_rgb_fg_color(Gdk::Color("#000000"));
- window->draw_arc(gc,false,
- area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
- area.get_height()/2, area.get_height()*3/4,
- 0, 64*360);
- */
- }
-
- {
- vector<Time>::iterator i = drawredafter.begin(), end = drawredafter.end();
- for(; i != end; ++i)
- {
- //find the coordinate in the drawable space...
- Time t = *i;
-
- if(!t.is_valid())
- continue;
-
- //synfig::info("Displaying time: %.3f s",(float)t);
- const int x = (int)((t-lower)*area.get_width()/(upper-lower));
-
- //should draw me a grey filled circle...
-
- Gdk::Rectangle area2(
- area.get_x() - area.get_height()/2 + x + 1,
- area.get_y() + 1,
- area.get_height()-2,
- area.get_height()-2
- );
- render_time_point_to_window(window,area2,*i,true);
-/* gc->set_rgb_fg_color(Gdk::Color("#EE0000"));
- window->draw_arc(gc,true,
- area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
- area.get_height()/2, area.get_height()*3/4,
- 0, 64*360);
-
- gc->set_rgb_fg_color(Gdk::Color("#000000"));
- window->draw_arc(gc,false,
- area.get_x() + x - area.get_height()/4, area.get_y() + area.get_height()/8,
- area.get_height()/2, area.get_height()*3/4,
- 0, 64*360);
-*/
- }
- }
- }
- }
-
- /* THIS IS NOW HANDLED ENTIRELY BY THE TIMEPOINT SYSTEM
- // This this is an animated value node, then render the waypoints
- if(value_node)
- {
- //now render the actual waypoints
- synfig::ValueNode_Animated::WaypointList::iterator iter;
- for(
- iter=value_node->waypoint_list().begin();
- iter!=value_node->waypoint_list().end();
- iter++
- )
- {
- if(!iter->get_time().is_valid())
- continue;
- int x;
- bool selected=false;
- if(is_selected(*iter))
- {
- Time t(iter->get_time());
-
-
- if(dragging)
- t=(t+selected_time-drag_time).round(get_canvas()->rend_desc().get_frame_rate());
-
- x=(int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(t-adjustment->get_lower()));
- shadow=Gtk::SHADOW_IN;
- selected=true;
- }
- else
- {
- x=(int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(iter->get_time()-adjustment->get_lower()));
- shadow=Gtk::SHADOW_OUT;
- selected=false;
- }
-
-
- widget.get_style()->paint_diamond(
- Glib::RefPtr<Gdk::Window>::cast_static(window),
- state,
- shadow,
- area,
- widget,
- "solid",
- area.get_x()+x-area.get_height()/4,
- area.get_y()+area.get_height()/4,
- area.get_height()/2,
- area.get_height()/2
- );
- }
- }
- */
- Gdk::Rectangle area(area_);
- // If the parent of this value node is a dynamic list, then
- // render the on and off times
- if(parent_value_node)
- {
- const int index(property_value_desc().get_value().get_index());
- const synfig::ValueNode_DynamicList::ListEntry& list_entry(parent_value_node->list[index]);
- const synfig::ValueNode_DynamicList::ListEntry::ActivepointList& activepoint_list(list_entry.timing_info);
- synfig::ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator iter,next;
-
- bool is_off(false);
- if(!activepoint_list.empty())
- is_off=!activepoint_list.front().state;
-
- int xstart(0);
-
- int x=0,prevx=0;
- for(next=activepoint_list.begin(),iter=next++;iter!=activepoint_list.end();iter=next++)
- {
- x=((int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(iter->time-adjustment->get_lower())));
- if(x<0)x=0;
- if(x>area.get_width())x=area.get_width();
-
- bool status_at_time=0;
- if(next!=activepoint_list.end())
- {
- status_at_time=!list_entry.status_at_time((iter->time+next->time)/2.0);
- }
- else
- status_at_time=!list_entry.status_at_time(Time::end());
-
- if(!is_off && status_at_time)
- {
- xstart=x;
- is_off=true;
- }
- else
- if(is_off && !status_at_time)
- {
- window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), x-xstart, area.get_height());
- is_off=false;
- }
-
- /*
- if(!is_off && iter!=activepoint_list.end() && next->state==false && iter->state==false)
- {
- xstart=x;
- is_off=true;
- }
- else if(is_off && next!=activepoint_list.end() && iter->state==false && next->state==true)
- {
- window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), x-xstart, area.get_height());
- is_off=false;
- }
- else if(is_off && iter!=activepoint_list.end() && iter->state==true)
- {
- window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), prevx-xstart, area.get_height());
- is_off=false;
- }
- */
-
-
-
- if(iter->time>=adjustment->get_lower() && iter->time<adjustment->get_upper())
- {
- int w(1);
- if(selected==*iter)
- w=3;
- gc->set_rgb_fg_color(activepoint_color[iter->state]);
- window->draw_rectangle(gc, true, area.get_x()+x-w/2, area.get_y(), w, area.get_height());
- }
- prevx=x;
- }
- if(is_off)
- {
- window->draw_rectangle(inactive_gc, true, area.get_x()+xstart, area.get_y(), area.get_width()-xstart, area.get_height());
- }
- }
-
- // Render a line that defines the current tick in time
- {
- gc->set_rgb_fg_color(curr_time_color);
-
- const int x((int)((float)area.get_width()/(adjustment->get_upper()-adjustment->get_lower())*(adjustment->get_value()-adjustment->get_lower())));
-
- if(adjustment->get_value()>=adjustment->get_lower() && adjustment->get_value()<adjustment->get_upper())
- window->draw_rectangle(gc, true, area.get_x()+x, area.get_y(), 1, area.get_height());
- }
-}
-
-synfig::ValueNode_Animated::WaypointList::iterator
-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());
-
- Time nearest(Time::end());
-
- synfig::ValueNode_Animated::WaypointList::iterator iter,ret;
-
- if(value_node)
- {
- for(
- iter=value_node->waypoint_list().begin();
- iter!=value_node->waypoint_list().end();
- iter++
- )
- {
- Time val=abs(iter->get_time()-selected_time);
- if(val<nearest)
- {
- nearest=val;
- ret=iter;
- }
- }
-
- if(nearest!=Time::end() && nearest<scope)
- {
- return ret;
- }
- }
- throw int();
-}
-
-bool
-CellRenderer_TimeTrack::activate_vfunc(
- GdkEvent* event,
- Gtk::Widget& /*widget*/,
- const Glib::ustring& treepath,
- const Gdk::Rectangle& /*background_area*/,
- const Gdk::Rectangle& cell_area,
- Gtk::CellRendererState /*flags*/)
-{
- path=treepath;
- synfig::ValueNode_Animated::WaypointList::iterator iter;
- Time nearest=1000000000;
- Gtk::Adjustment *adjustment=get_adjustment();
-
- // synfig::ValueNode_Animated *value_node=dynamic_cast<synfig::ValueNode_Animated*>(property_value_desc().get_value().get_value_node().get());
-
- synfig::Canvas::Handle canvas(get_canvas());
-
- synfig::ValueNode_DynamicList *parent_value_node(0);
- if(property_value_desc().get_value().parent_is_value_node())
- parent_value_node=dynamic_cast<synfig::ValueNode_DynamicList*>(property_value_desc().get_value().get_parent_value_node().get());
-
- Time deltatime = 0;
- Time curr_time;
- switch(event->type)
- {
- case GDK_MOTION_NOTIFY:
- curr_time=((float)event->motion.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
-
- mode = NONE;
- {
- Gdk::ModifierType mod;
- Gdk::Event(event).get_state(mod);
- mode = mod;
- }
- break;
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- default:
- curr_time=((float)event->button.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
- {
- Gdk::ModifierType mod;
- Gdk::Event(event).get_state(mod);
- mode = mod;
- }
- break;
- }
- actual_time = curr_time;
- if(canvas)
- curr_time=curr_time.round(canvas->rend_desc().get_frame_rate());
- selected_time=curr_time;
-
- Time pixel_width((adjustment->get_upper()-adjustment->get_lower())/cell_area.get_width());
-
- switch(event->type)
- {
- case GDK_BUTTON_PRESS:
- //selected_time=((float)event->button.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
-
- //Deal with time point selection, but only if they aren't involved in the insanity...
- if(/*!value_node && */event->button.button == 1)
- {
- Time stime;
-
- /*! UI specification:
-
- 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
- nothing (in both normal and add mode). Add mode clicking on an unselected
- point adds it to the set. Normal clicking on an unselected point will
- select only that one time point. Subtractive clicking on any point
- will remove it from the the set if it is included.
- */
-
- 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+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
- //we want to jump to the value desc if we're not currently on it
- // but only if we want to add the point
- if(clickfound && !(sel_value == valdesc))
- {
- sel_value = valdesc;
- sel_times.clear();
- }
-
- //now that we've made sure we're selecting the correct value, deal with the already selected points
- set<Time>::iterator foundi = clickfound ? sel_times.find(stime) : sel_times.end();
- bool found = foundi != sel_times.end();
-
- //remove all other points from our list... (only select the one we need)
- if(!selectmode && !found)
- {
- sel_times.clear();
- }
-
- if(found && selectmode) //remove a single already selected point
- {
- sel_times.erase(foundi);
- }else if(clickfound) //otherwise look at adding it
- {
- //for replace the list was cleared earlier, and for add it wasn't so it works
- sel_times.insert(stime);
- }
- }
-
- selection=false;
- try
- {
- iter=find_waypoint(selected_time,pixel_width*cell_area.get_height()/2);
- selected_waypoint=iter;
- selected=*iter;
-
- selection=true;
- }
- catch(int)
- {
- selection=false;
- selected=synfig::UniqueID::nil();
- }
-
- if((!sel_times.empty() || selection) && event->button.button==1)
- {
- dragging=true;
- drag_time=selected_time;
- actual_dragtime=actual_time;
- }
- //selected_time=iter->time;
-
- /*
- // Activepoint Selection
- if(parent_value_node)
- {
- const int index(property_value_desc().get_value().get_index());
- const synfig::ValueNode_DynamicList::ListEntry::ActivepointList& activepoint_list(parent_value_node->list[index].timing_info);
- synfig::ValueNode_DynamicList::ListEntry::ActivepointList::const_iterator iter;
-
- for(iter=activepoint_list.begin();iter!=activepoint_list.end();++iter)
- {
- Time val=abs(iter->time-selected_time);
- if(val<nearest)
- {
- nearest=val;
- selected=*iter;
- selection=true;
- }
- }
- // 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+time_offset,pixel_width*cell_area.get_height(),stime);
-
- etl::handle<synfig::Node> node;
- if(!getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS") &&
- valdesc.get_value(stime).get_type()==ValueBase::TYPE_CANVAS)
- {
- node=Canvas::Handle(valdesc.get_value(stime).get(Canvas::Handle()));
- }
- else //if(valdesc.is_value_node())
- {
- node=valdesc.get_value_node();
- }
-
- if(clickfound && node)
- signal_waypoint_clicked_cellrenderer()(node, stime, time_offset, 2);
- }
-
- break;
- case GDK_MOTION_NOTIFY:
- //if(selection && dragging)
- // selected_time=((float)event->motion.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
- return true;
-
- break;
- case GDK_BUTTON_RELEASE:
- {
- //selected_time=((float)event->button.x-(float)cell_area.get_x())/(float)cell_area.get_width()*(adjustment->get_upper()-adjustment->get_lower())+adjustment->get_lower();
- dragging=false;
-
- /*if(event->button.button==3 && selection)
- {
- signal_waypoint_clicked_cellrenderer()(path,*selected_waypoint,event->button.button-1);
- return true;
- }
- */
-
- //Time point stuff...
- if(event->button.button == 1)
- {
- bool delmode = (mode & DELETE_MASK) && !(mode & COPY_MASK);
- deltatime = actual_time - actual_dragtime;
- if(sel_times.size() != 0 && (delmode || !deltatime.is_equal(Time(0))))
- {
- synfigapp::Action::ParamList param_list;
- param_list.add("canvas",canvas_interface()->get_canvas());
- param_list.add("canvas_interface",canvas_interface());
-
- if(!getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS") &&
- sel_value.get_value_type() == synfig::ValueBase::TYPE_CANVAS)
- {
- param_list.add("addcanvas",sel_value.get_value().get(Canvas::Handle()));
- }else
- {
- param_list.add("addvaluedesc",sel_value);
- }
-
- set<Time> newset;
- std::set<synfig::Time>::iterator i = sel_times.begin(), end = sel_times.end();
- for(; i != end; ++i)
- {
- param_list.add("addtime",*i);
-
- newset.insert((*i + deltatime).round(get_canvas()->rend_desc().get_frame_rate()));
- }
-
- if(!delmode)
- param_list.add("deltatime",deltatime);
- // param_list.add("time",canvas_interface()->get_time());
-
- if(mode & COPY_MASK) //copy
- {
- etl::handle<studio::Instance>::cast_static(canvas_interface()->get_instance())
- ->process_action("TimepointsCopy", param_list);
- }else if(delmode) //DELETE
- {
- etl::handle<studio::Instance>::cast_static(canvas_interface()->get_instance())
- ->process_action("TimepointsDelete", param_list);
- }else //MOVE
- {
- etl::handle<studio::Instance>::cast_static(canvas_interface()->get_instance())
- ->process_action("TimepointsMove", param_list);
- }
-
- //now replace all the selected with the new selected
- sel_times = newset;
- }
- }
-
-
-
- /*if(value_node && selection)
- {
- if(selected_time==drag_time && event->button.button!=3)
- signal_waypoint_clicked_cellrenderer()(path,*selected_waypoint,event->button.button-1);
- else
- if(event->button.button==1)
- {
- synfig::Waypoint waypoint(*selected_waypoint);
- Time newtime((waypoint.get_time()+(selected_time-drag_time)).round(canvas->rend_desc().get_frame_rate()));
- if(waypoint.get_time()!=newtime)
- {
- waypoint.set_time(newtime);
- signal_waypoint_changed_(waypoint,value_node);
- }
- }
- }*/
-
- //if(selection)
- // selected_time=iter->time;
- //selected_time=iter->get_time();
- return true;
- }
- default:
- //std::cerr<<"unknown event type "<<event->type<<std::endl;
- return false;
- break;
- }
-
-
-
- return false;
-}
-
-
-
-// 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()
-{
- return Glib::PropertyProxy<synfigapp::ValueDesc>(this,"value_desc");
-}
-
-Glib::PropertyProxy<synfig::Canvas::Handle>
-CellRenderer_TimeTrack::property_canvas()
-{
- return Glib::PropertyProxy<synfig::Canvas::Handle>(this,"canvas");
-}
-
-Glib::PropertyProxy<Gtk::Adjustment* >
-CellRenderer_TimeTrack::property_adjustment()
-{
- return Glib::PropertyProxy<Gtk::Adjustment* >(this,"adjustment");
-}
-
-void
-CellRenderer_TimeTrack::set_canvas_interface(etl::loose_handle<synfigapp::CanvasInterface> h)
-{
- canvas_interface_ = h;
-}