bool operator() (ControlPoint const * a, ControlPoint const * b) const {
if (floateq (a->get_x(), b->get_x(), 1)) {
return a->view_index() < b->view_index();
bool operator() (ControlPoint const * a, ControlPoint const * b) const {
if (floateq (a->get_x(), b->get_x(), 1)) {
return a->view_index() < b->view_index();
return a->get_x() < b->get_x();
}
};
AutomationLine::ContiguousControlPoints::ContiguousControlPoints (AutomationLine& al)
return a->get_x() < b->get_x();
}
};
AutomationLine::ContiguousControlPoints::ContiguousControlPoints (AutomationLine& al)
tx = max (tx, before_x); // can't move later than following point
tx = min (tx, after_x); // can't move earlier than preceeding point
tx = max (tx, before_x); // can't move later than following point
tx = min (tx, after_x); // can't move earlier than preceeding point
{
for (std::list<ControlPoint*>::iterator i = begin(); i != end(); ++i) {
(*i)->move_to ((*i)->get_x() + dx, (*i)->get_y() - line.height() * dy, ControlPoint::Full);
{
for (std::list<ControlPoint*>::iterator i = begin(); i != end(); ++i) {
(*i)->move_to ((*i)->get_x() + dx, (*i)->get_y() - line.height() * dy, ControlPoint::Full);
/* partition the points we are dragging into (potentially several)
* set(s) of contiguous points. this will not happen with a normal
* drag, but if the user does a discontiguous selection, it can.
*/
/* partition the points we are dragging into (potentially several)
* set(s) of contiguous points. this will not happen with a normal
* drag, but if the user does a discontiguous selection, it can.
*/
for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
if (i == _drag_points.begin() || (*i)->view_index() != expected_view_index) {
contig.reset (new ContiguousControlPoints (*this));
for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
if (i == _drag_points.begin() || (*i)->view_index() != expected_view_index) {
contig.reset (new ContiguousControlPoints (*this));
/* OK, now on to the stuff related to *this* motion event. First, for
* each contiguous range, figure out the maximum x-axis motion we are
* allowed (because of neighbouring points that are not moving.
/* OK, now on to the stuff related to *this* motion event. First, for
* each contiguous range, figure out the maximum x-axis motion we are
* allowed (because of neighbouring points that are not moving.
for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
double const y = ((_height - (*i)->get_y()) / _height) + dy;
if (y < 0) {
for (list<ControlPoint*>::iterator i = _drag_points.begin(); i != _drag_points.end(); ++i) {
double const y = ((_height - (*i)->get_y()) / _height) + dy;
if (y < 0) {
trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
trackview.editor().begin_reversible_command (_("remove control point"));
XMLNode &before = alist->get_state();
trackview.editor().session()->add_command(
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
trackview.editor().session()->add_command(
new MementoCommand<AutomationList> (memento_command_binder (), &before, &alist->get_state()));
/* model_when is relative to the start of the source, so we just need to add on the origin_b here
(as it is the session frame position of the start of the source)
*/
/* model_when is relative to the start of the source, so we just need to add on the origin_b here
(as it is the session frame position of the start of the source)
*/
framepos_t const session_frames_when = _time_converter->to (model_when) + _time_converter->origin_b ();
if (session_frames_when >= start && session_frames_when <= end && (*i)->get_y() >= bot_track && (*i)->get_y() <= top_track) {
framepos_t const session_frames_when = _time_converter->to (model_when) + _time_converter->origin_b ();
if (session_frames_when >= start && session_frames_when <= end && (*i)->get_y() >= bot_track && (*i)->get_y() <= top_track) {
/* convert from canonical view height (0..1.0) to actual
* height coordinates (using X11's top-left rooted system)
*/
/* convert from canonical view height (0..1.0) to actual
* height coordinates (using X11's top-left rooted system)
*/
if ( alist->parameter().type() == GainAutomation
|| alist->parameter().type() == EnvelopeAutomation
|| (_desc.logarithmic && _desc.lower == 0. && _desc.upper > _desc.lower)) {
if ( alist->parameter().type() == GainAutomation
|| alist->parameter().type() == EnvelopeAutomation
|| (_desc.logarithmic && _desc.lower == 0. && _desc.upper > _desc.lower)) {
} else if (alist->parameter().type() == TrimAutomation
|| (_desc.logarithmic && _desc.lower * _desc.upper > 0 && _desc.upper > _desc.lower)) {
const double lower_db = accurate_coefficient_to_dB (_desc.lower);
} else if (alist->parameter().type() == TrimAutomation
|| (_desc.logarithmic && _desc.lower * _desc.upper > 0 && _desc.upper > _desc.lower)) {
const double lower_db = accurate_coefficient_to_dB (_desc.lower);
-AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, double tx, double ty,
+AutomationLine::add_visible_control_point (uint32_t view_index, uint32_t pi, double tx, double ty,
AutomationList::iterator model, uint32_t npoints)
{
ControlPoint::ShapeType shape;
AutomationList::iterator model, uint32_t npoints)
{
ControlPoint::ShapeType shape;