#include <ardour/curve.h>
#include <ardour/dB.h>
-#include "canvas-simplerect.h"
+#include "simplerect.h"
#include "automation_line.h"
#include "rgb_macros.h"
#include "ardour_ui.h"
#include "i18n.h"
using namespace std;
+using namespace sigc;
using namespace ARDOUR;
+using namespace PBD;
using namespace Editing;
+using namespace Gnome; // for Canvas
-ControlPoint::ControlPoint (AutomationLine& al, gint (*event_handler)(GtkCanvasItem*, GdkEvent*, gpointer))
+ControlPoint::ControlPoint (AutomationLine& al)
: line (al)
{
model = al.the_list().end();
_size = 4.0;
selected = false;
- item = gtk_canvas_item_new (line.canvas_group(),
- gtk_canvas_simplerect_get_type(),
- "draw", (gboolean) TRUE,
- "fill", (gboolean) FALSE,
- "fill_color_rgba", color_map[cControlPointFill],
- "outline_color_rgba", color_map[cControlPointOutline],
- "outline_pixels", (gint) 1,
- NULL);
-
- gtk_object_set_data (GTK_OBJECT(item), "control_point", this);
- gtk_signal_connect (GTK_OBJECT(item), "event", (GtkSignalFunc) event_handler, this);
+ item = new Canvas::SimpleRect (line.canvas_group());
+ item->property_draw() = true;
+ item->property_fill() = false;
+ item->property_fill_color_rgba() = color_map[cControlPointFill];
+ item->property_outline_color_rgba() = color_map[cControlPointOutline];
+ item->property_outline_pixels() = 1;
+ item->set_data ("control_point", this);
+ item->signal_event().connect (mem_fun (this, &ControlPoint::event_handler));
hide ();
set_visible (false);
_size = other._size;
selected = false;
- item = gtk_canvas_item_new (line.canvas_group(),
- gtk_canvas_simplerect_get_type(),
- "fill", (gboolean) FALSE,
- "outline_color_rgba", color_map[cEnteredControlPointOutline],
- "outline_pixels", (gint) 1,
- NULL);
+ item = new Canvas::SimpleRect (line.canvas_group());
+ item->property_fill() = false;
+ item->property_outline_color_rgba() = color_map[cEnteredControlPointOutline];
+ item->property_outline_pixels() = 1;
/* NOTE: no event handling in copied ControlPoints */
ControlPoint::~ControlPoint ()
{
- gtk_object_destroy (GTK_OBJECT(item));
+ delete item;
+}
+
+bool
+ControlPoint::event_handler (GdkEvent* event)
+{
+ return PublicEditor::instance().canvas_control_point_event (event, item, this);
}
void
ControlPoint::hide ()
{
- gtk_canvas_item_hide (item);
+ item->hide();
}
void
ControlPoint::show()
{
- gtk_canvas_item_show (item);
+ item->show();
}
void
ControlPoint::set_visible (bool yn)
{
- gtk_canvas_item_set (item, "draw", (gboolean) yn, NULL);
+ item->property_draw() = (gboolean) yn;
}
void
{
if (entered) {
if (selected) {
- gtk_canvas_item_set (item, "outline_color_rgba", color_map[cEnteredControlPointSelected], NULL);
+ item->property_outline_color_rgba() = color_map[cEnteredControlPointSelected];
set_visible(true);
} else {
- gtk_canvas_item_set (item, "outline_color_rgba", color_map[cEnteredControlPoint], NULL);
+ item->property_outline_color_rgba() = color_map[cEnteredControlPoint];
if (hide_too) {
set_visible(false);
}
} else {
if (selected) {
- gtk_canvas_item_set (item, "outline_color_rgba", color_map[cControlPointSelected], NULL);
+ item->property_outline_color_rgba() = color_map[cControlPointSelected];
set_visible(true);
} else {
- gtk_canvas_item_set (item, "outline_color_rgba", color_map[cControlPoint], NULL);
+ item->property_outline_color_rgba() = color_map[cControlPoint];
if (hide_too) {
set_visible(false);
}
#if 0
if (_size > 6.0) {
- gtk_canvas_item_set (item,
- "fill", (gboolean) TRUE,
- NULL);
+ item->property_fill() = (gboolean) TRUE;
} else {
- gtk_canvas_item_set (item,
- "fill", (gboolean) FALSE,
- NULL);
+ item->property_fill() = (gboolean) FALSE;
}
#endif
break;
}
- gtk_canvas_item_set (item,
- "x1", x1,
- "x2", x2,
- "y1", y - half_size,
- "y2", y + half_size,
- NULL);
+ item->property_x1() = x1;
+ item->property_x2() = x2;
+ item->property_y1() = y - half_size;
+ item->property_y2() = y + half_size;
_x = x;
_y = y;
/*****/
-AutomationLine::AutomationLine (string name, TimeAxisView& tv, GtkCanvasItem* parent, AutomationList& al,
- gint (*point_handler)(GtkCanvasItem*, GdkEvent*, gpointer),
- gint (*line_handler)(GtkCanvasItem*, GdkEvent*, gpointer))
+AutomationLine::AutomationLine (const string & name, TimeAxisView& tv, ArdourCanvas::Group& parent, AutomationList& al)
: trackview (tv),
_name (name),
- alist (al)
+ alist (al),
+ _parent_group (parent)
{
- point_coords = 0;
points_visible = false;
update_pending = false;
_vc_uses_gain_mapping = false;
no_draw = false;
_visible = true;
- point_callback = point_handler;
- _parent_group = parent;
terminal_points_can_slide = true;
_height = 0;
- group = gtk_canvas_item_new (GTK_CANVAS_GROUP(parent),
- gtk_canvas_group_get_type(),
- "x", 0.0,
- "y", 0.0,
- NULL);
+ group = new ArdourCanvas::Group (parent);
+ group->property_x() = 0.0;
+ group->property_y() = 0.0;
- line = gtk_canvas_item_new (GTK_CANVAS_GROUP(group),
- gtk_canvas_line_get_type(),
- "width_pixels", (guint) 1,
- NULL);
+ line = new ArdourCanvas::Line (*group);
+ line->property_width_pixels() = (guint)1;
+ line->set_data ("line", this);
- // cerr << _name << " line @ " << line << endl;
+ line->signal_event().connect (mem_fun (*this, &AutomationLine::event_handler));
- gtk_object_set_data (GTK_OBJECT(line), "line", this);
- gtk_signal_connect (GTK_OBJECT(line), "event", (GtkSignalFunc) line_handler, this);
-
- alist.StateChanged.connect (slot (*this, &AutomationLine::list_changed));
+ alist.StateChanged.connect (mem_fun(*this, &AutomationLine::list_changed));
}
AutomationLine::~AutomationLine ()
{
- if (point_coords) {
- gtk_canvas_points_unref (point_coords);
- }
-
vector_delete (&control_points);
+ delete group;
+}
- gtk_object_destroy (GTK_OBJECT(group));
+bool
+AutomationLine::event_handler (GdkEvent* event)
+{
+ return PublicEditor::instance().canvas_line_event (event, line, this);
}
void
{
if (!update_pending) {
update_pending = true;
- Gtkmm2ext::UI::instance()->call_slot (slot (*this, &AutomationLine::reset));
+ Gtkmm2ext::UI::instance()->call_slot (mem_fun(*this, &AutomationLine::reset));
}
}
void
AutomationLine::show ()
{
- gtk_canvas_item_show (line);
+ line->show();
if (points_visible) {
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
void
AutomationLine::hide ()
{
- gtk_canvas_item_hide (line);
+ line->hide();
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->hide();
}
AutomationLine::set_line_color (uint32_t color)
{
_line_color = color;
- gtk_canvas_item_set (line, "fill_color_rgba", color, NULL);
+ line->property_fill_color_rgba() = color;
}
void
void
AutomationLine::reset_line_coords (ControlPoint& cp)
{
- if (point_coords) {
- point_coords->coords[cp.view_index*2] = cp.get_x();
- point_coords->coords[(cp.view_index*2) + 1] = cp.get_y();
- }
+ line_points[cp.view_index].set_x (cp.get_x());
+ line_points[cp.view_index].set_y (cp.get_y());
}
void
AutomationLine::update_line ()
{
- gtk_canvas_item_set (line, "points", point_coords, NULL);
+ line->property_points() = line_points;
}
void
}
void
-AutomationLine::determine_visible_control_points (GtkCanvasPoints* points)
+AutomationLine::determine_visible_control_points (ALPoints& points)
{
- uint32_t xi, yi, view_index, pi;
- int n;
+ uint32_t view_index, pi, n;
AutomationList::iterator model;
- uint32_t npoints = points->num_points;
+ uint32_t npoints;
double last_control_point_x = 0.0;
double last_control_point_y = 0.0;
uint32_t this_rx = 0;
uint32_t this_ry = 0;
uint32_t prev_ry = 0;
double* slope;
+
+ /* hide all existing points, and the line */
for (vector<ControlPoint*>::iterator i = control_points.begin(); i != control_points.end(); ++i) {
(*i)->hide();
}
- gtk_canvas_item_hide (line);
- if (points == 0 || points->num_points == 0) {
+ line->hide ();
+
+ if (points.empty()) {
return;
}
+ npoints = points.size();
+
/* compute derivative/slope for the entire line */
slope = new double[npoints];
- for (n = 0, xi = 2, yi = 3, view_index = 0; n < points->num_points - 1; xi += 2, yi +=2, ++n, ++view_index) {
- double xdelta;
- double ydelta;
- xdelta = points->coords[xi] - points->coords[xi-2];
- ydelta = points->coords[yi] - points->coords[yi-2];
- slope[view_index] = ydelta/xdelta;
+ for (n = 0; n < npoints - 1; ++n) {
+ double xdelta = points[n+1].x - points[n].x;
+ double ydelta = points[n+1].y - points[n].y;
+ slope[n] = ydelta/xdelta;
}
/* read all points and decide which ones to show as control points */
- for (model = alist.begin(), pi = 0, xi = 0, yi = 1, view_index = 0; pi < npoints; ++model, xi += 2, yi +=2, ++pi) {
+ view_index = 0;
+
+ for (model = alist.begin(), pi = 0; pi < npoints; ++model, ++pi) {
+
+ double tx = points[pi].x;
+ double ty = points[pi].y;
/* now ensure that the control_points vector reflects the current curve
state, but don't plot control points too close together. also, don't
points.
*/
- this_rx = (uint32_t) rint (points->coords[xi]);
- this_ry = (unsigned long) rint (points->coords[yi]);
+ this_rx = (uint32_t) rint (tx);
+ this_ry = (unsigned long) rint (ty);
if (view_index && pi != npoints && (this_rx == prev_rx) && (this_ry == prev_ry)) {
if (view_index >= control_points.size()) {
/* make sure we have enough control points */
- ControlPoint* ncp = new ControlPoint (*this, point_callback);
+ ControlPoint* ncp = new ControlPoint (*this);
if (_height > (guint32) TimeAxisView::Larger) {
ncp->set_size (8.0);
if (!terminal_points_can_slide) {
if (pi == 0) {
control_points[view_index]->can_slide = false;
- if (points->coords[xi] == 0) {
+ if (tx == 0) {
shape = ControlPoint::Start;
} else {
shape = ControlPoint::Full;
shape = ControlPoint::Full;
}
- control_points[view_index]->reset (points->coords[xi], points->coords[yi], model, view_index, shape);
+ last_control_point_x = tx;
+ last_control_point_y = ty;
- last_control_point_x = points->coords[xi];
- last_control_point_y = points->coords[yi];
+ control_points[view_index]->reset (tx, ty, model, view_index, shape);
prev_rx = this_rx;
prev_ry = this_ry;
delete [] slope;
- /* Now make sure the "point_coords" array is large enough
- to represent all the visible points.
- */
-
if (view_index > 1) {
npoints = view_index;
- if (point_coords) {
- if (point_coords->num_points < (int) npoints) {
- gtk_canvas_points_unref (point_coords);
- point_coords = get_canvas_points ("autoline", npoints);
- } else {
- point_coords->num_points = npoints;
- }
- } else {
- point_coords = get_canvas_points ("autoline", npoints);
- }
-
/* reset the line coordinates */
- uint32_t pci;
-
- for (pci = 0, view_index = 0; view_index < npoints; ++view_index) {
- point_coords->coords[pci++] = control_points[view_index]->get_x();
- point_coords->coords[pci++] = control_points[view_index]->get_y();
+ while (line_points.size() < npoints) {
+ line_points.push_back (Art::Point (0,0));
}
- // cerr << "set al2 points, nc = " << point_coords->num_points << endl;
- gtk_canvas_item_set (line, "points", point_coords, NULL);
+ for (view_index = 0; view_index < npoints; ++view_index) {
+ line_points[view_index].set_x (control_points[view_index]->get_x());
+ line_points[view_index].set_y (control_points[view_index]->get_y());
+ }
+
+ line->property_points() = line_points;
if (_visible) {
- gtk_canvas_item_show (line);
+ line->show ();
}
}
}
bool
-AutomationLine::invalid_point (GtkCanvasPoints* p, uint32_t index)
+AutomationLine::invalid_point (ALPoints& p, uint32_t index)
{
- return p->coords[index*2] == max_frames && p->coords[(index*2)+1] == DBL_MAX;
+ return p[index].x == max_frames && p[index].y == DBL_MAX;
}
void
-AutomationLine::invalidate_point (GtkCanvasPoints* p, uint32_t index)
+AutomationLine::invalidate_point (ALPoints& p, uint32_t index)
{
- p->coords[index*2] = max_frames;
- p->coords[(index*2)+1] = DBL_MAX;
+ p[index].x = max_frames;
+ p[index].y = DBL_MAX;
}
void
void
AutomationLine::reset_callback (const AutomationList& events)
{
- GtkCanvasPoints *tmp_points;
+ ALPoints tmp_points;
uint32_t npoints = events.size();
if (npoints == 0) {
delete *i;
}
control_points.clear ();
- gtk_canvas_item_hide (line);
+ line->hide();
return;
}
- tmp_points = get_canvas_points ("autoline reset", max (npoints, (uint32_t) 2));
-
- uint32_t xi, yi;
AutomationList::const_iterator ai;
- for (ai = events.const_begin(), xi = 0, yi = 1; ai != events.const_end(); xi += 2, yi +=2, ++ai) {
+ for (ai = events.const_begin(); ai != events.const_end(); ++ai) {
- tmp_points->coords[xi] = trackview.editor.frame_to_unit ((*ai)->when);
double translated_y;
-
+
translated_y = (*ai)->value;
model_to_view_y (translated_y);
- tmp_points->coords[yi] = _height - (translated_y * _height);
- }
-
- tmp_points->num_points = npoints;
+ tmp_points.push_back (ALPoint (trackview.editor.frame_to_unit ((*ai)->when),
+ _height - (translated_y * _height)));
+ }
+
determine_visible_control_points (tmp_points);
- gtk_canvas_points_unref (tmp_points);
}
void