diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 573303825b..e17c8046c4 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -281,6 +281,7 @@ Editor::Editor () , _region_selection_change_updates_region_list (true) , _following_mixer_selection (false) + , _control_point_toggled_on_press (false) { constructed = false; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 1953bb27ea..e51fe88d45 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -2092,6 +2092,9 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD void toggle_sound_midi_notes (); + /** Flag for a bit of a hack wrt control point selection; see set_selected_control_point_from_click */ + bool _control_point_toggled_on_press; + friend class Drag; friend class RegionDrag; friend class RegionMoveDrag; diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index 6e12a03856..eb67fb3631 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -318,19 +318,39 @@ Editor::set_selected_control_point_from_click (bool press, Selection::Operation return false; } - if (!press) { - return true; - } - switch (op) { case Selection::Set: - selection->set (clicked_control_point); + if (press) { + selection->set (clicked_control_point); + } break; case Selection::Add: - selection->add (clicked_control_point); + if (press) { + selection->add (clicked_control_point); + } break; case Selection::Toggle: - selection->toggle (clicked_control_point); + /* This is a bit of a hack; if we Primary-Click-Drag a control + point (for push drag) we want the point we clicked on to be + selected, otherwise we end up confusingly dragging an + unselected point. So here we ensure that the point is selected + after the press, and if we subsequently get a release (meaning no + drag occurred) we set things up so that the toggle has happened. + */ + if (press && !selection->selected (clicked_control_point)) { + /* This is the button press, and the control point is not selected; make it so, + in case this press leads to a drag. Also note that having done this, we don't + need to toggle again on release. + */ + selection->toggle (clicked_control_point); + _control_point_toggled_on_press = true; + } else if (!press && !_control_point_toggled_on_press) { + /* This is the release, and the point wasn't toggled on the press, so do it now */ + selection->toggle (clicked_control_point); + } else { + /* Reset our flag */ + _control_point_toggled_on_press = false; + } break; case Selection::Extend: /* XXX */ diff --git a/gtk2_ardour/selection.cc b/gtk2_ardour/selection.cc index 724618e540..009b40d26d 100644 --- a/gtk2_ardour/selection.cc +++ b/gtk2_ardour/selection.cc @@ -861,6 +861,12 @@ Selection::selected (RegionView* rv) return find (regions.begin(), regions.end(), rv) != regions.end(); } +bool +Selection::selected (ControlPoint* cp) +{ + return find (points.begin(), points.end(), cp) != points.end(); +} + bool Selection::empty (bool internal_selection) { diff --git a/gtk2_ardour/selection.h b/gtk2_ardour/selection.h index df7212593f..e30ca612ea 100644 --- a/gtk2_ardour/selection.h +++ b/gtk2_ardour/selection.h @@ -114,6 +114,7 @@ class Selection : public sigc::trackable, public PBD::ScopedConnectionList bool selected (TimeAxisView*); bool selected (RegionView*); bool selected (Marker*); + bool selected (ControlPoint*); void set (std::list const &); void add (std::list const &);