/* Copyright (C) 2002-2007 Paul Davis This program 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 program 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "control_point.h" #include "diamond.h" #include "automation_line.h" #include "ardour_ui.h" #include "public_editor.h" #include "i18n.h" using namespace std; using namespace ARDOUR; using namespace PBD; using namespace Gnome; // for Canvas PBD::Signal1 ControlPoint::CatchDeletion; ControlPoint::ControlPoint (AutomationLine& al) : _line (al) { _model = al.the_list()->end(); _view_index = 0; _can_slide = true; _x = 0; _y = 0; _shape = Full; _size = 4.0; _item = new Canvas::SimpleRect (_line.canvas_group()); _item->property_draw() = true; _item->property_fill() = false; _item->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_ControlPointFill.get(); _item->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_ControlPointOutline.get(); _item->property_outline_pixels() = 1; _item->set_data ("control_point", this); _item->signal_event().connect (sigc::mem_fun (this, &ControlPoint::event_handler)); hide (); set_visible (false); } ControlPoint::ControlPoint (const ControlPoint& other, bool /*dummy_arg_to_force_special_copy_constructor*/) : _line (other._line) { if (&other == this) { return; } _model = other._model; _view_index = other._view_index; _can_slide = other._can_slide; _x = other._x; _y = other._y; _shape = other._shape; _size = other._size; _item = new Canvas::SimpleRect (_line.canvas_group()); _item->property_fill() = false; _item->property_outline_color_rgba() = ARDOUR_UI::config()->canvasvar_ControlPointOutline.get(); _item->property_outline_pixels() = 1; /* NOTE: no event handling in copied ControlPoints */ hide (); set_visible (false); } ControlPoint::~ControlPoint () { CatchDeletion (this); /* EMIT SIGNAL */ delete _item; } bool ControlPoint::event_handler (GdkEvent* event) { return PublicEditor::instance().canvas_control_point_event (event, _item, this); } void ControlPoint::hide () { _item->hide(); } void ControlPoint::show() { _item->show(); } void ControlPoint::set_visible (bool yn) { _item->property_draw() = (gboolean) yn; } bool ControlPoint::visible () const { return _item->property_draw (); } void ControlPoint::reset (double x, double y, AutomationList::iterator mi, uint32_t vi, ShapeType shape) { /* If this is too big, libart will confuse itself and segfault after it casts the bounding box of this automation line to ints. Sigh. */ if (x > INT32_MAX) { x = INT32_MAX; } _model = mi; _view_index = vi; move_to (x, y, shape); } void ControlPoint::set_color () { uint32_t color = 0; if (_selected) { color = ARDOUR_UI::config()->canvasvar_ControlPointSelected.get(); } else { color = ARDOUR_UI::config()->canvasvar_ControlPointOutline.get(); } _item->property_outline_color_rgba() = color; _item->property_fill_color_rgba() = ARDOUR_UI::config()->canvasvar_ControlPointFill.get(); } void ControlPoint::set_size (double sz) { _size = sz; move_to (_x, _y, _shape); } void ControlPoint::move_to (double x, double y, ShapeType shape) { double x1 = 0; double x2 = 0; double half_size = rint(_size/2.0); switch (shape) { case Full: x1 = x - half_size; x2 = x + half_size; break; case Start: x1 = x; x2 = x + half_size; break; case End: x1 = x - half_size; x2 = x; break; } _item->property_x1() = x1; _item->property_x2() = x2; _item->property_y1() = y - half_size; _item->property_y2() = y + half_size; _x = x; _y = y; _shape = shape; } void ControlPoint::i2w (double& x, double& y) const { _item->i2w (x, y); }