From cb2a501c44e16fed8c5c14f44f81d9ad0359fc71 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 19 Feb 2019 20:12:42 +0100 Subject: [PATCH 01/17] Cleanup: Fix inconsistent TransformDialog code style --- gtk2_ardour/transform_dialog.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/gtk2_ardour/transform_dialog.cc b/gtk2_ardour/transform_dialog.cc index 6eed4e10d7..82f869647d 100644 --- a/gtk2_ardour/transform_dialog.cc +++ b/gtk2_ardour/transform_dialog.cc @@ -229,15 +229,17 @@ TransformDialog::ValueChooser::source_changed() } double -TransformDialog::ValueChooser::get_value () const +TransformDialog::ValueChooser::get_value() const { - return value_spinner.get_value() + ((target_property == MidiModel::NoteDiffCommand::Channel) ? -1. : 0.); + const bool is_channel = target_property == MidiModel::NoteDiffCommand::Channel; + return value_spinner.get_value() + (is_channel ? -1.0 : 0.0); } double -TransformDialog::ValueChooser::get_max () const +TransformDialog::ValueChooser::get_max() const { - return max_spinner.get_value() + ((target_property == MidiModel::NoteDiffCommand::Channel) ? -1. : 0.); + const bool is_channel = target_property == MidiModel::NoteDiffCommand::Channel; + return max_spinner.get_value() + (is_channel ? -1.0 : 0.0); } void From 94271ee862ce9c1209923e141f491f87bb3b1147 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Tue, 19 Feb 2019 20:14:41 +0100 Subject: [PATCH 02/17] Cleanup: Remove unnecessary using namespace declarations --- gtk2_ardour/transform_dialog.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gtk2_ardour/transform_dialog.cc b/gtk2_ardour/transform_dialog.cc index 82f869647d..2cc6bf55f4 100644 --- a/gtk2_ardour/transform_dialog.cc +++ b/gtk2_ardour/transform_dialog.cc @@ -25,8 +25,6 @@ #include "pbd/i18n.h" -using namespace std; -using namespace Gtk; using namespace ARDOUR; TransformDialog::Model::Model() @@ -109,7 +107,7 @@ TransformDialog::TransformDialog() get_vbox()->pack_start(_operations_box, false, false); get_vbox()->pack_start(*add_hbox, false, false); - add_button(Stock::CANCEL, Gtk::RESPONSE_CANCEL); + add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); add_button(_("Transform"), Gtk::RESPONSE_OK); show_all(); From 0ee6b03144f7f40792aced150ddf6971659fb171 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 27 Mar 2019 23:23:33 +0100 Subject: [PATCH 03/17] Implement multi-region AutomationRange drag/drop --- gtk2_ardour/editor_drag.cc | 29 +++++++++++++++++------------ gtk2_ardour/editor_drag.h | 2 +- gtk2_ardour/editor_mouse.cc | 30 +++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 14 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index ebc5d97bb7..a2cc145ad0 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6223,7 +6223,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView } /** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */ -AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list const & r) +AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list const & v, list const & r) : Drag (editor, rv->get_canvas_group ()) , _ranges (r) , _y_origin (rv->get_time_axis_view().y_position()) @@ -6234,17 +6234,21 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list > lines; - AudioRegionView* audio_view; - AutomationRegionView* automation_view; - if ((audio_view = dynamic_cast(rv))) { - lines.push_back (audio_view->get_gain_line ()); - } else if ((automation_view = dynamic_cast(rv))) { - lines.push_back (automation_view->line ()); - _integral = true; - } else { - error << _("Automation range drag created for invalid region type") << endmsg; + bool found_primary = false; + for (list::const_iterator i = v.begin(); i != v.end(); ++i) { + if (*i == rv) { + found_primary = true; + } + if (AudioRegionView* audio_view = dynamic_cast(*i)) { + lines.push_back (audio_view->get_gain_line ()); + } else if (AutomationRegionView* automation_view = dynamic_cast(*i)) { + lines.push_back (automation_view->line ()); + _integral = true; + } else { + error << _("Automation range drag created for invalid region type") << endmsg; + } } - + assert (found_primary); setup (lines); } @@ -6254,6 +6258,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list > const & lines) { + printf ("AutomationRangeDrag::setup %d lines\n", lines.size()); /* find the lines that overlap the ranges being dragged */ list >::const_iterator i = lines.begin (); while (i != lines.end ()) { @@ -6344,7 +6349,7 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move) } if (first_move) { - _editor->begin_reversible_command (_("automation range move")); + _editor->begin_reversible_command (_("automation range move")); // XXX if (!_ranges.empty()) { diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 7ffb7ef57e..498488cb50 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1244,7 +1244,7 @@ class AutomationRangeDrag : public Drag { public: AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list const &); - AutomationRangeDrag (Editor *, RegionView *, std::list const &); + AutomationRangeDrag (Editor *, RegionView *, std::list const &, std::list const &); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 0e4d6bd322..38db9bcc3a 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -1119,7 +1119,35 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT { if (dynamic_cast(clicked_regionview) || dynamic_cast(clicked_regionview)) { - _drags->set (new AutomationRangeDrag (this, clicked_regionview, selection->time), + + /* collect all regions-views in the given range selection + * perhaps this should be a dedicated method: + * Editor::get_region_views_from_range_selection() ? + * except c-pointer list is not very reliable. + */ + list rvl; + TrackViewList ts = selection->tracks.filter_to_unique_playlists (); + for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) { + RouteTimeAxisView* tatv; + boost::shared_ptr playlist; + if ((tatv = dynamic_cast (*i)) == 0) { + continue; + } + if ((playlist = (*i)->playlist()) == 0) { + continue; + } + for (list::const_iterator j = selection->time.begin(); j != selection->time.end(); ++j) { + boost::shared_ptr rl = playlist->regions_touched (j->start, j->end); + for (RegionList::iterator ir = rl->begin(); ir != rl->end(); ++ir) { + RegionView* rv; + if ((rv = tatv->view()->find_view (*ir)) != 0) { + rvl.push_back (rv); + } + } + } + } + + _drags->set (new AutomationRangeDrag (this, clicked_regionview, rvl, selection->time), event, _cursors->up_down); } else { double const y = event->button.y; From 258b95834f447efa9997f0e5e9e559562c6a96f6 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 27 Mar 2019 23:24:58 +0100 Subject: [PATCH 04/17] Re-layout ctrl surface enable button: align left Since the Preferences window can be rather wide, and the table expands, a button on the left is preferred. --- gtk2_ardour/rc_option_editor.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc index 756252f348..6552b65077 100644 --- a/gtk2_ardour/rc_option_editor.cc +++ b/gtk2_ardour/rc_option_editor.cc @@ -1329,10 +1329,10 @@ class ControlSurfacesOptions : public OptionEditorMiniPage { _store = ListStore::create (_model); _view.set_model (_store); - _view.append_column (_("Control Surface Protocol"), _model.name); - _view.get_column(0)->set_resizable (true); - _view.get_column(0)->set_expand (true); _view.append_column_editable (_("Enable"), _model.enabled); + _view.append_column (_("Control Surface Protocol"), _model.name); + _view.get_column(1)->set_resizable (true); + _view.get_column(1)->set_expand (true); Gtk::HBox* edit_box = manage (new Gtk::HBox); edit_box->set_spacing(3); From 1fa2d15a9d976dd8f7a71baefa090b99ef34f56c Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 28 Mar 2019 01:51:50 +0100 Subject: [PATCH 05/17] Don't allow to cut/copy inserts via Drag/Drop It was already verboten via ctrl-x/c/v since copying inserts using the same I/O makes no sense, nor does moving them. --- gtk2_ardour/processor_box.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gtk2_ardour/processor_box.cc b/gtk2_ardour/processor_box.cc index a31bfc9f73..f120dab349 100644 --- a/gtk2_ardour/processor_box.cc +++ b/gtk2_ardour/processor_box.cc @@ -1985,6 +1985,9 @@ ProcessorBox::object_drop (DnDVBox* source, ProcessorEntry* posi if (boost::dynamic_pointer_cast ((*i)->processor())) { continue; } + if (boost::dynamic_pointer_cast ((*i)->processor())) { + continue; + } procs.push_back ((*i)->processor ()); } } From 0c368499f844d79ac6d268f459cd3b00a35e19ca Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 28 Mar 2019 03:01:53 +0100 Subject: [PATCH 06/17] Fix route-templates with external sends --- libs/ardour/io.cc | 15 +++++++++++++++ libs/ardour/session.cc | 8 ++++++++ 2 files changed, 23 insertions(+) diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index 5d6d343f2e..693dc07f23 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -576,6 +576,21 @@ IO::set_state (const XMLNode& node, int version) if (create_ports (node, version)) { return -1; } + if (_sendish && _direction == Output) { + /* ignore from XML for sends, but use the names + * ::ensure_ports_locked() creates port using ::build_legal_port_name() + * This is needed to properly restore connections when creating + * external sends from templates because the IO name changes. + */ + PortSet::iterator i = _ports.begin(); + XMLNodeConstIterator x = node.children().begin(); + for (; i != _ports.end(), x != node.children().end(); ++i, ++x) { + if ((*x)->name() == "Port") { + (*x)->remove_property (X_("name")); + (*x)->set_property (X_("name"), i->name()); + } + } + } // after create_ports, updates names if (node.get_property ("pretty-name", name)) { diff --git a/libs/ardour/session.cc b/libs/ardour/session.cc index d6753c50d9..5170456938 100644 --- a/libs/ardour/session.cc +++ b/libs/ardour/session.cc @@ -3439,6 +3439,14 @@ Session::new_route_from_template (uint32_t how_many, PresentationInfo::order_t i (*i)->remove_property (X_("name")); (*i)->set_property ("bitslot", bitslot); (*i)->set_property ("name", name); + XMLNodeList io_kids = (*i)->children (); + for (XMLNodeList::iterator j = io_kids.begin(); j != io_kids.end(); ++j) { + if ((*j)->name() != X_("IO")) { + continue; + } + (*j)->remove_property (X_("name")); + (*j)->set_property ("name", name); + } } else if (type && type->value() == X_("intreturn")) { (*i)->remove_property (X_("bitslot")); From 6f1fd3e4fdda2fbe44a9e5687c338f0baf295d84 Mon Sep 17 00:00:00 2001 From: John Emmas Date: Thu, 28 Mar 2019 11:39:30 +0000 Subject: [PATCH 07/17] Add a missing namespace qualifier (is needed now, following commit #94271ee862) --- gtk2_ardour/transform_dialog.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gtk2_ardour/transform_dialog.cc b/gtk2_ardour/transform_dialog.cc index 2cc6bf55f4..c1866ecc6f 100644 --- a/gtk2_ardour/transform_dialog.cc +++ b/gtk2_ardour/transform_dialog.cc @@ -97,7 +97,7 @@ TransformDialog::TransformDialog() Gtk::HBox* add_hbox = Gtk::manage(new Gtk::HBox); _add_button.add( - *manage(new Gtk::Image(Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON))); + *Gtk::manage(new Gtk::Image(Gtk::Stock::ADD, Gtk::ICON_SIZE_BUTTON))); add_hbox->pack_start(_add_button, false, false); _add_button.signal_clicked().connect( sigc::mem_fun(*this, &TransformDialog::add_clicked)); @@ -311,7 +311,7 @@ TransformDialog::OperationChooser::OperationChooser(const Model& model) pack_start(remove_button, false, false); remove_button.add( - *manage(new Gtk::Image(Gtk::Stock::REMOVE, Gtk::ICON_SIZE_BUTTON))); + *Gtk::manage(new Gtk::Image(Gtk::Stock::REMOVE, Gtk::ICON_SIZE_BUTTON))); remove_button.signal_clicked().connect( sigc::mem_fun(*this, &TransformDialog::OperationChooser::remove_clicked)); From 0eee891de91683dfec576e3ca6f7e26c2f04e587 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 29 Mar 2019 14:33:31 +0100 Subject: [PATCH 08/17] NO-OP: remove unused variable --- gtk2_ardour/editor_mouse.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 38db9bcc3a..00f292c5b0 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -2263,7 +2263,6 @@ Editor::region_view_item_click (AudioRegionView& rv, GdkEventButton* event) */ if (Keyboard::modifier_state_contains (event->state, Keyboard::PrimaryModifier)) { - TimeAxisView* tv = &rv.get_time_axis_view(); samplepos_t where = get_preferred_edit_position(); From 1a90cd90de25f441fc166d48c6216b300ccf6b98 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 29 Mar 2019 14:52:25 +0100 Subject: [PATCH 09/17] Fix action-name --- gtk2_ardour/editor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index c441139cc0..2b50dc9a6c 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2327,7 +2327,7 @@ Editor::set_edit_point_preference (EditPoint ep, bool force) action = "edit-at-playhead"; break; case EditAtSelectedMarker: - action = "edit-at-marker"; + action = "edit-at-selected-marker"; break; case EditAtMouse: action = "edit-at-mouse"; From 932892f794ef9eebd24caab10d472086b63a9cea Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 29 Mar 2019 14:53:07 +0100 Subject: [PATCH 10/17] Fix Mixbus special case --- gtk2_ardour/editor.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 2b50dc9a6c..9b3fbe3d5e 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -2302,12 +2302,15 @@ Editor::set_snap_mode (SnapMode mode) void Editor::set_edit_point_preference (EditPoint ep, bool force) { + if (Profile->get_mixbus()) { + if (ep == EditAtSelectedMarker) { + ep = EditAtPlayhead; + } + } + bool changed = (_edit_point != ep); _edit_point = ep; - if (Profile->get_mixbus()) - if (ep == EditAtSelectedMarker) - ep = EditAtPlayhead; string str = edit_point_strings[(int)ep]; if (str != edit_point_selector.get_text ()) { From d8571e2572e750f5cbe4f439ba3d6f9655713bc9 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Fri, 29 Mar 2019 15:57:07 +0100 Subject: [PATCH 11/17] cont'd AutomationRangeDrag updates -- safety commit This is work in progress towards fixing stacked region's region-gain and multiple discontinuous regions spanning multiple tracks. AutomationRangeDrag::setup() still does not collect all AutomationLine points for certain overlap scenarios. There's more to come... --- gtk2_ardour/editor_drag.cc | 11 ++---- gtk2_ardour/editor_drag.h | 2 +- gtk2_ardour/editor_mouse.cc | 68 ++++++++++++++++++++++++------------- 3 files changed, 49 insertions(+), 32 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index a2cc145ad0..1c89f7ad20 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6223,10 +6223,10 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView } /** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */ -AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list const & v, list const & r) - : Drag (editor, rv->get_canvas_group ()) +AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list const & v, list const & r, double y_origin) + : Drag (editor, v.front()->get_canvas_group ()) , _ranges (r) - , _y_origin (rv->get_time_axis_view().y_position()) + , _y_origin (y_origin) , _nothing_to_drag (false) , _integral (false) { @@ -6234,11 +6234,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list > lines; - bool found_primary = false; for (list::const_iterator i = v.begin(); i != v.end(); ++i) { - if (*i == rv) { - found_primary = true; - } if (AudioRegionView* audio_view = dynamic_cast(*i)) { lines.push_back (audio_view->get_gain_line ()); } else if (AutomationRegionView* automation_view = dynamic_cast(*i)) { @@ -6248,7 +6244,6 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, RegionView* rv, list const &); - AutomationRangeDrag (Editor *, RegionView *, std::list const &, std::list const &); + AutomationRangeDrag (Editor *, std::list const &, std::list const &, double y_origin); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 00f292c5b0..15f74b2491 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -37,6 +37,7 @@ #include "canvas/canvas.h" +#include "ardour/audioplaylist.h" #include "ardour/audioregion.h" #include "ardour/operations.h" #include "ardour/playlist.h" @@ -1116,15 +1117,43 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case SelectionItem: - { - if (dynamic_cast(clicked_regionview) || - dynamic_cast(clicked_regionview)) { + { + if (selection->time.empty ()) { + /* nothing to do */ + return true; + } + pair tvp = trackview_by_y_position (event->button.y, false); + if (!tvp.first) { + /* clicked outside of a track */ + return true; + } + /* handle automation lanes first */ + AutomationTimeAxisView* atv = dynamic_cast (tvp.first); + if (atv) { + /* smart "join" mode: drag automation */ + _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down); + return true; + } + if (dynamic_cast(clicked_regionview)) { + /* MIDI CC or similar -- TODO handle multiple? */ + list rvl; + rvl.push_back (clicked_regionview); + _drags->set (new AutomationRangeDrag (this, rvl, selection->time, clicked_regionview->get_time_axis_view().y_position()), event, _cursors->up_down); + return true; + } - /* collect all regions-views in the given range selection - * perhaps this should be a dedicated method: - * Editor::get_region_views_from_range_selection() ? - * except c-pointer list is not very reliable. - */ + /* no shift+drag: only apply to clicked_regionview (if any) */ + if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) { + if (dynamic_cast(clicked_regionview) == 0) { + return true; + } + list rvl; + rvl.push_back (clicked_regionview); + _drags->set (new AutomationRangeDrag (this, rvl, selection->time, clicked_regionview->get_time_axis_view().y_position()), event, _cursors->up_down); + return true; + } + + /* collect all audio regions-views in the given range selection */ list rvl; TrackViewList ts = selection->tracks.filter_to_unique_playlists (); for (TrackViewList::iterator i = ts.begin(); i != ts.end(); ++i) { @@ -1136,6 +1165,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT if ((playlist = (*i)->playlist()) == 0) { continue; } + if (boost::dynamic_pointer_cast (playlist) == 0) { + continue; + } for (list::const_iterator j = selection->time.begin(); j != selection->time.end(); ++j) { boost::shared_ptr rl = playlist->regions_touched (j->start, j->end); for (RegionList::iterator ir = rl->begin(); ir != rl->end(); ++ir) { @@ -1146,23 +1178,13 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } } } - - _drags->set (new AutomationRangeDrag (this, clicked_regionview, rvl, selection->time), - event, _cursors->up_down); - } else { - double const y = event->button.y; - pair tvp = trackview_by_y_position (y, false); - if (tvp.first) { - AutomationTimeAxisView* atv = dynamic_cast (tvp.first); - if (atv) { - /* smart "join" mode: drag automation */ - _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down); - } + /* region-gain drag */ + if (!rvl.empty ()) { + _drags->set (new AutomationRangeDrag (this, rvl, selection->time, tvp.first->y_position()), event, _cursors->up_down); } + return true; + break; } - return true; - break; - } case AutomationLineItem: _drags->set (new LineDrag (this, item), event); From f40456a649a882fed2b7a678d88d42c55c13e65e Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 30 Mar 2019 00:14:26 +0100 Subject: [PATCH 12/17] cont'd AutomationRangeDrag update Properly adding guard-points for all lanes, not just the first found for each range. --- gtk2_ardour/editor_drag.cc | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 1c89f7ad20..9a036fd3d3 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6253,7 +6253,6 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list cons void AutomationRangeDrag::setup (list > const & lines) { - printf ("AutomationRangeDrag::setup %d lines\n", lines.size()); /* find the lines that overlap the ranges being dragged */ list >::const_iterator i = lines.begin (); while (i != lines.end ()) { @@ -6344,26 +6343,25 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move) } if (first_move) { - _editor->begin_reversible_command (_("automation range move")); // XXX + _editor->begin_reversible_command (_("automation range move")); if (!_ranges.empty()) { + /* add guard points */ for (list::const_iterator i = _ranges.begin(); i != _ranges.end(); ++i) { samplecnt_t const half = (i->start + i->end) / 2; - /* find the line that this audio range starts in */ - list::iterator j = _lines.begin(); - while (j != _lines.end() && (j->range.first > i->start || j->range.second < i->start)) { - ++j; - } + for (list::iterator j = _lines.begin(); j != _lines.end(); ++j) { + if (j->range.first > i->start || j->range.second < i->start) { + continue; + } - if (j != _lines.end()) { boost::shared_ptr the_list = j->line->the_list (); - /* j is the line that this audio range starts in; fade into it; - 64 samples length plucked out of thin air. - */ + /* j is the line that this audio range starts in; fade into it; + * 64 samples length plucked out of thin air. + */ samplepos_t a = i->start + 64; if (a > half) { @@ -6384,18 +6382,17 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move) } /* same thing for the end */ + for (list::iterator j = _lines.begin(); j != _lines.end(); ++j) { - j = _lines.begin(); - while (j != _lines.end() && (j->range.first > i->end || j->range.second < i->end)) { - ++j; - } + if (j->range.first > i->end || j->range.second < i->end) { + continue; + } - if (j != _lines.end()) { boost::shared_ptr the_list = j->line->the_list (); /* j is the line that this audio range starts in; fade out of it; - 64 samples length plucked out of thin air. - */ + * 64 samples length plucked out of thin air. + */ samplepos_t b = i->end - 64; if (b < half) { @@ -6419,9 +6416,8 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move) _nothing_to_drag = true; /* Find all the points that should be dragged and put them in the relevant - points lists in the Line structs. - */ - + * points lists in the Line structs. + */ for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { uint32_t const N = i->line->npoints (); From 546d5d09b56082e1c4f3a287f5db6a611107a3dc Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 30 Mar 2019 01:15:17 +0100 Subject: [PATCH 13/17] Remove unused variable --- gtk2_ardour/editor_drag.cc | 1 - gtk2_ardour/editor_drag.h | 1 - 2 files changed, 2 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 9a036fd3d3..1b06d32d2e 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6315,7 +6315,6 @@ AutomationRangeDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) /* Get line states before we start changing things */ for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { i->state = &i->line->get_state (); - i->original_fraction = y_fraction (i->line, current_pointer_y()); } if (_ranges.empty()) { diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 184d1111a5..1147d82b96 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1268,7 +1268,6 @@ private: std::list points; ///< points to drag on the line std::pair range; ///< the range of all points on the line, in session samples XMLNode* state; ///< the XML state node before the drag - double original_fraction; ///< initial y-fraction before the drag }; std::list _lines; From 56047a094cdc1f41b369c6796690cded85e2a2c6 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sat, 30 Mar 2019 01:19:47 +0100 Subject: [PATCH 14/17] AutomationRangeDrag tweaks for stacked layer view Use y-pos and height of given TAV *layer* where the drag was initiated. --- gtk2_ardour/editor_drag.cc | 12 +++++++----- gtk2_ardour/editor_drag.h | 5 +++-- gtk2_ardour/editor_mouse.cc | 26 +++++++++++++++++++++----- 3 files changed, 31 insertions(+), 12 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 1b06d32d2e..079e9c81ac 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6216,6 +6216,7 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView : Drag (editor, atv->base_item ()) , _ranges (r) , _y_origin (atv->y_position()) + , _y_height (atv->effective_height()) // or atv->lines()->front()->height() ?! , _nothing_to_drag (false) { DEBUG_TRACE (DEBUG::Drags, "New AutomationRangeDrag\n"); @@ -6223,10 +6224,11 @@ AutomationRangeDrag::AutomationRangeDrag (Editor* editor, AutomationTimeAxisView } /** Make an AutomationRangeDrag for region gain lines or MIDI controller regions */ -AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list const & v, list const & r, double y_origin) +AutomationRangeDrag::AutomationRangeDrag (Editor* editor, list const & v, list const & r, double y_origin, double y_height) : Drag (editor, v.front()->get_canvas_group ()) , _ranges (r) , _y_origin (y_origin) + , _y_height (y_height) , _nothing_to_drag (false) , _integral (false) { @@ -6295,9 +6297,9 @@ AutomationRangeDrag::setup (list > const & lin } double -AutomationRangeDrag::y_fraction (boost::shared_ptr line, double global_y) const +AutomationRangeDrag::y_fraction (double global_y) const { - return 1.0 - ((global_y - _y_origin) / line->height()); + return 1.0 - ((global_y - _y_origin) / _y_height); } double @@ -6442,12 +6444,12 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move) } for (list::iterator i = _lines.begin(); i != _lines.end(); ++i) { - i->line->start_drag_multiple (i->points, y_fraction (i->line, current_pointer_y()), i->state); + i->line->start_drag_multiple (i->points, y_fraction (current_pointer_y()), i->state); } } for (list::iterator l = _lines.begin(); l != _lines.end(); ++l) { - float const f = y_fraction (l->line, current_pointer_y()); + float const f = y_fraction (current_pointer_y()); /* we are ignoring x position for this drag, so we can just pass in anything */ pair result; uint32_t ignored; diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 1147d82b96..c24ff32dc0 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1244,7 +1244,7 @@ class AutomationRangeDrag : public Drag { public: AutomationRangeDrag (Editor *, AutomationTimeAxisView *, std::list const &); - AutomationRangeDrag (Editor *, std::list const &, std::list const &, double y_origin); + AutomationRangeDrag (Editor *, std::list const &, std::list const &, double y_origin, double y_height); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); void motion (GdkEvent *, bool); @@ -1257,7 +1257,7 @@ public: private: void setup (std::list > const &); - double y_fraction (boost::shared_ptr, double global_y_position) const; + double y_fraction (double global_y_position) const; double value (boost::shared_ptr list, double x) const; std::list _ranges; @@ -1272,6 +1272,7 @@ private: std::list _lines; double _y_origin; + double _y_height; bool _nothing_to_drag; bool _integral; }; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 15f74b2491..8f875b88e3 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -1138,18 +1138,25 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT /* MIDI CC or similar -- TODO handle multiple? */ list rvl; rvl.push_back (clicked_regionview); - _drags->set (new AutomationRangeDrag (this, rvl, selection->time, clicked_regionview->get_time_axis_view().y_position()), event, _cursors->up_down); + _drags->set (new AutomationRangeDrag (this, rvl, selection->time, + clicked_regionview->get_time_axis_view().y_position(), + clicked_regionview->get_time_axis_view().current_height()), + event, _cursors->up_down); return true; } - /* no shift+drag: only apply to clicked_regionview (if any) */ - if (!Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) { + /* shift+drag: only apply to clicked_regionview (if any) */ + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) { if (dynamic_cast(clicked_regionview) == 0) { return true; } list rvl; rvl.push_back (clicked_regionview); - _drags->set (new AutomationRangeDrag (this, rvl, selection->time, clicked_regionview->get_time_axis_view().y_position()), event, _cursors->up_down); + // TODO: handle layer_display() == Stacked + _drags->set (new AutomationRangeDrag (this, rvl, selection->time, + clicked_regionview->get_time_axis_view().y_position(), + clicked_regionview->get_time_axis_view().current_height()), + event, _cursors->up_down); return true; } @@ -1180,7 +1187,16 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } /* region-gain drag */ if (!rvl.empty ()) { - _drags->set (new AutomationRangeDrag (this, rvl, selection->time, tvp.first->y_position()), event, _cursors->up_down); + double y_pos = tvp.first->y_position(); + double height = tvp.first->current_height(); + StreamView* cv = tvp.first->view (); + if (cv->layer_display() == Stacked && cv->layers() > 1) { + height /= cv->layers(); + double yy = event->button.y - _trackview_group->canvas_origin().y; + y_pos += floor ((yy - y_pos) / height) * height; + } + _drags->set (new AutomationRangeDrag (this, rvl, selection->time, y_pos, height), + event, _cursors->up_down); } return true; break; From 827b4ef8a1e74607a787b90e5e46f36e507f59b3 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 31 Mar 2019 16:08:35 +0200 Subject: [PATCH 15/17] NO-OP: Whitespace --- libs/ardour/plugin_manager.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index 06a7e0ee77..181516bf0a 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -1536,7 +1536,7 @@ PluginManager::save_tags () XMLNode* root = new XMLNode (X_("PluginTags")); for (PluginTagList::iterator i = ptags.begin(); i != ptags.end(); ++i) { - if ( (*i).tagtype == FromFactoryFile || (*i).tagtype == FromUserFile ) { + if ((*i).tagtype == FromFactoryFile || (*i).tagtype == FromUserFile) { /* user file should contain only plugins that are (a) newly user-tagged or (b) previously unknown */ continue; } @@ -1545,7 +1545,7 @@ PluginManager::save_tags () node->set_property (X_("id"), (*i).unique_id); node->set_property (X_("tags"), (*i).tags); node->set_property (X_("name"), (*i).name); - if ( (*i).tagtype >= FromUserFile ) { + if ((*i).tagtype >= FromUserFile) { node->set_property (X_("user-set"), "1"); } root->add_child_nocopy (*node); @@ -1593,25 +1593,25 @@ PluginManager::load_tags () user_set = false; } strip_whitespace_edges (tags); - set_tags (type, id, tags, name, user_set ? FromUserFile : FromFactoryFile ); + set_tags (type, id, tags, name, user_set ? FromUserFile : FromFactoryFile); } } } void -PluginManager::set_tags (PluginType t, string id, string tag, std::string name, TagType ttype ) +PluginManager::set_tags (PluginType t, string id, string tag, std::string name, TagType ttype) { string sanitized = sanitize_tag (tag); - PluginTag ps (to_generic_vst (t), id, sanitized, name, ttype ); + PluginTag ps (to_generic_vst (t), id, sanitized, name, ttype); PluginTagList::const_iterator i = find (ptags.begin(), ptags.end(), ps); if (i == ptags.end()) { ptags.insert (ps); - } else if ( (uint32_t) ttype >= (uint32_t) (*i).tagtype ) { // only overwrite if we are more important than the existing. Gui > UserFile > FactoryFile > Plugin + } else if ((uint32_t) ttype >= (uint32_t) (*i).tagtype) { // only overwrite if we are more important than the existing. Gui > UserFile > FactoryFile > Plugin ptags.erase (ps); ptags.insert (ps); } - if ( ttype == FromGui ) { + if (ttype == FromGui) { PluginTagChanged (t, id, sanitized); /* EMIT SIGNAL */ } } From da15b599de110fa43b97b92bbb772410f4462f0f Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 31 Mar 2019 22:25:29 +0200 Subject: [PATCH 16/17] Remove a hack of using flags to emit a signal-change from the GUI The GUI should not be calling `manager.PluginListChanged();` It's up to the plugin-manager to emit relevant signals. This fixes an issue when adding/removing plugin-favorites using the mixer's sidebar or via remote-control/surfaces or script. --- gtk2_ardour/plugin_selector.cc | 12 +----------- gtk2_ardour/plugin_selector.h | 1 - 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/gtk2_ardour/plugin_selector.cc b/gtk2_ardour/plugin_selector.cc index 7b599bc25d..338d3aa9ee 100644 --- a/gtk2_ardour/plugin_selector.cc +++ b/gtk2_ardour/plugin_selector.cc @@ -69,10 +69,9 @@ PluginSelector::PluginSelector (PluginManager& mgr) _plugin_menu = 0; in_row_change = false; - //anytime the list changes ( Status, Tags, or scanned plugins ) we need to rebuild redirect-box plugin selector menu manager.PluginListChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context()); + manager.PluginStatusChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::build_plugin_menu, this), gui_context()); - //these are used to update the info of specific entries, while they are being edited manager.PluginStatusChanged.connect (plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::plugin_status_changed, this, _1, _2, _3), gui_context()); manager.PluginTagChanged.connect(plugin_list_changed_connection, invalidator (*this), boost::bind (&PluginSelector::tags_changed, this, _1, _2, _3), gui_context()); @@ -788,10 +787,6 @@ PluginSelector::run () manager.save_statuses(); } - if ( _need_tag_save || _need_status_save || _need_menu_rebuild ) { - manager.PluginListChanged(); //emit signal - } - return (int) r; } @@ -810,7 +805,6 @@ PluginSelector::tag_reset_button_clicked () manager.reset_tags (pi); display_selection_changed (); _need_tag_save = true; - _need_menu_rebuild = true; } } @@ -833,7 +827,6 @@ PluginSelector::tag_entry_changed () manager.set_tags (pi->type, pi->unique_id, tag_entry->get_text(), pi->name, PluginManager::FromGui); _need_tag_save = true; - _need_menu_rebuild = true; } } @@ -888,7 +881,6 @@ PluginSelector::on_show () _need_tag_save = false; _need_status_save = false; - _need_menu_rebuild = false; } struct PluginMenuCompareByCreator { @@ -1172,7 +1164,6 @@ PluginSelector::favorite_changed (const std::string& path) manager.set_status (pi->type, pi->unique_id, status); _need_status_save = true; - _need_menu_rebuild = true; } in_row_change = false; } @@ -1205,7 +1196,6 @@ PluginSelector::hidden_changed (const std::string& path) manager.set_status (pi->type, pi->unique_id, status); _need_status_save = true; - _need_menu_rebuild = true; } in_row_change = false; } diff --git a/gtk2_ardour/plugin_selector.h b/gtk2_ardour/plugin_selector.h index fda03c10f3..ba09b08f7f 100644 --- a/gtk2_ardour/plugin_selector.h +++ b/gtk2_ardour/plugin_selector.h @@ -186,7 +186,6 @@ private: bool _need_tag_save; bool _need_status_save; - bool _need_menu_rebuild; bool _inhibit_refill; }; From 20201ef056b1713107b3c6a79fc61fe259f9f3e8 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Sun, 31 Mar 2019 22:25:40 +0200 Subject: [PATCH 17/17] Clarify documentation --- libs/ardour/ardour/plugin_manager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/ardour/ardour/plugin_manager.h b/libs/ardour/ardour/plugin_manager.h index 7b90b045c3..264018345d 100644 --- a/libs/ardour/ardour/plugin_manager.h +++ b/libs/ardour/ardour/plugin_manager.h @@ -106,7 +106,7 @@ public: }; std::vector get_all_tags (enum TagFilter) const; - /** plugins were added to or removed from one of the PluginInfoLists, OR the user has made changes to the status/tags */ + /** plugins were added to or removed from one of the PluginInfoLists */ PBD::Signal0 PluginListChanged; /** A single plugin's Hidden/Favorite status changed */