From c89a4ca0451081062a86ceef859ade1d33d1c8cf Mon Sep 17 00:00:00 2001 From: Rodolfo Ribeiro Gomes Date: Dec 13 2019 04:29:26 +0000 Subject: draw waypoints in Curves dock --- diff --git a/synfig-studio/src/gui/waypointrenderer.cpp b/synfig-studio/src/gui/waypointrenderer.cpp index 43b4750..ada9d42 100644 --- a/synfig-studio/src/gui/waypointrenderer.cpp +++ b/synfig-studio/src/gui/waypointrenderer.cpp @@ -35,11 +35,14 @@ #include +#include +#include #endif /* === U S I N G =========================================================== */ using namespace synfig; +using namespace synfigapp; /* === M A C R O S ========================================================= */ @@ -300,4 +303,91 @@ WaypointRenderer::render_time_point_to_window( } +static Time +get_time_offset_from_vdesc(const ValueDesc &v) +{ +#ifdef ADJUST_WAYPOINTS_FOR_TIME_OFFSET + if (v.get_value_type() != type_canvas || getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS")) + return Time::zero(); + + if (!v.get_value().get(Canvas::Handle())) + return Time::zero(); + + if (!v.parent_is_layer()) + return Time::zero(); + + synfig::Layer::Handle layer = v.get_layer(); + + if (!etl::handle::cast_dynamic(layer)) + return Time::zero(); + + return layer->get_param("time_offset").get(Time()); +#else // ADJUST_WAYPOINTS_FOR_TIME_OFFSET + return synfig::Time::zero(); +#endif +} + +static Time +get_time_dilation_from_vdesc(const ValueDesc &v) +{ +#ifdef ADJUST_WAYPOINTS_FOR_TIME_OFFSET + if (v.get_value_type() != type_canvas || getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS")) + return Time(1.0); + + if (!v.get_value().get(Canvas::Handle())) + return Time(1.0); + + if (!v.parent_is_layer()) + return Time(1.0); + + Layer::Handle layer = v.get_layer(); + + if (!etl::handle::cast_dynamic(layer)) + return Time(1.0); + + return layer->get_param("time_dilation").get(Time()); +#else // ADJUST_WAYPOINTS_FOR_TIME_OFFSET + return Time(1.0); +#endif +} + +static const Node::time_set* +get_times_from_vdesc(const ValueDesc &v) +{ + if (v.get_value_type() == type_canvas && !getenv("SYNFIG_SHOW_CANVAS_PARAM_WAYPOINTS")) + if(Canvas::Handle canvasparam = v.get_value().get(Canvas::Handle())) + return &canvasparam->get_times(); + + //we want a dynamic list entry to override the normal... + if (v.parent_is_value_node()) + if (ValueNode_DynamicList *parent_value_node = dynamic_cast(v.get_parent_value_node().get())) + return &parent_value_node->list[v.get_index()].get_times(); + + if (ValueNode *base_value = v.get_value_node().get()) //don't render stuff if it's just animated... + return &base_value->get_times(); + + return nullptr; +} + +void +WaypointRenderer::foreach_visible_waypoint(const synfigapp::ValueDesc &value_desc, + const studio::TimePlotData &time_plot_data, + std::function foreach_callback, + void* data) +{ + if (const Node::time_set * const tset = get_times_from_vdesc(value_desc)) { + const Time time_offset = get_time_offset_from_vdesc(value_desc); + const Time time_dilation = get_time_dilation_from_vdesc(value_desc); + const double time_k = time_dilation == Time::zero() ? 1.0 : 1.0/(double)time_dilation; + + for (const auto & waypoint : *tset) { + Time t = (waypoint.get_time() - time_offset)*time_k; + if (time_plot_data.is_time_visible_extra(t)) { + if (foreach_callback(waypoint, t, data)) + break; + } + } + } +} + } diff --git a/synfig-studio/src/gui/waypointrenderer.h b/synfig-studio/src/gui/waypointrenderer.h index 310d6e0..6c9140f 100644 --- a/synfig-studio/src/gui/waypointrenderer.h +++ b/synfig-studio/src/gui/waypointrenderer.h @@ -30,6 +30,10 @@ #include #include + +#include "synfigapp/value_desc.h" +#include "gui/timeplotdata.h" + /* === M A C R O S ========================================================= */ /* === T Y P E D E F S ===================================================== */ @@ -48,6 +52,20 @@ public: const synfig::TimePoint &tp, bool selected, bool hover); + + //! Callback called at every iteration of \ref foreach_visible_waypoint + //! \param tp A visible TimePoint + //! \param t The current time (including effects of layers: offset and zoom) + //! \param data Custom data passed to \ref foreach_visible_waypoint + /// \return Callback should return true to stop for-each loop + typedef bool ForeachCallback(const synfig::TimePoint &tp, const synfig::Time &t, void *data); + + static void foreach_visible_waypoint( + const synfigapp::ValueDesc &value_desc, + const studio::TimePlotData &time_plot_data, + std::function foreach_callback, + void* data = nullptr); + }; // END of class WaypointRenderer }; // END of namespace studio diff --git a/synfig-studio/src/gui/widgets/widget_curves.cpp b/synfig-studio/src/gui/widgets/widget_curves.cpp index d625119..917f002 100644 --- a/synfig-studio/src/gui/widgets/widget_curves.cpp +++ b/synfig-studio/src/gui/widgets/widget_curves.cpp @@ -48,6 +48,10 @@ #include "widget_curves.h" #include "gui/timeplotdata.h" +#include "gui/waypointrenderer.h" +#include +#include + #endif /* === U S I N G =========================================================== */ @@ -219,13 +223,15 @@ struct Widget_Curves::CurveStruct: sigc::trackable /* === M E T H O D S ======================================================= */ Widget_Curves::Widget_Curves(): - range_adjustment(Gtk::Adjustment::create(-1.0, -2.0, 2.0, 0.1, 0.1, 2)) + range_adjustment(Gtk::Adjustment::create(-1.0, -2.0, 2.0, 0.1, 0.1, 2)), + waypoint_edge_length(16) { set_size_request(64, 64); add_events(Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::SCROLL_MASK); time_plot_data = new TimePlotData(*this, range_adjustment); + time_plot_data->set_extra_time_margin(16/2); } Widget_Curves::~Widget_Curves() { @@ -439,6 +445,27 @@ Widget_Curves::on_draw(const Cairo::RefPtr &cr) cr->move_to(1, points[c][0].get_y() + 1); layout->show_in_cairo_context(cr); } + + // Draw waypoints + WaypointRenderer::foreach_visible_waypoint(curve_it->value_desc, *time_plot_data, + [&](const synfig::TimePoint &tp, const synfig::Time &t, void *_data) -> bool + { + int px = time_plot_data->get_pixel_t_coord(t); + Gdk::Rectangle area( + 0 - waypoint_edge_length/2 + 1 + px, + 0, //0 - waypoint_edge_length/2 + 1 + py, + waypoint_edge_length - 2, + waypoint_edge_length - 2); + bool selected = false; + bool hover = false; + for (int c = 0; c < channels; ++c) { + Real y = curve_it->get_value(c, t, time_plot_data->dt); + int py = time_plot_data->get_pixel_y_coord(y); + area.set_y(0 - waypoint_edge_length/2 + 1 + py); + WaypointRenderer::render_time_point_to_window(cr, area, tp, selected, hover); + } + return false; + }); } if (!curve_list.empty() && range_min < range_max) diff --git a/synfig-studio/src/gui/widgets/widget_curves.h b/synfig-studio/src/gui/widgets/widget_curves.h index c588256..7760f2b 100644 --- a/synfig-studio/src/gui/widgets/widget_curves.h +++ b/synfig-studio/src/gui/widgets/widget_curves.h @@ -61,6 +61,8 @@ private: TimePlotData * time_plot_data; + int waypoint_edge_length; + public: Widget_Curves(); ~Widget_Curves();