diff --git a/gtk2_ardour/automation_line.cc b/gtk2_ardour/automation_line.cc index 0aaa56d335..f00f0f2f8b 100644 --- a/gtk2_ardour/automation_line.cc +++ b/gtk2_ardour/automation_line.cc @@ -950,7 +950,7 @@ AutomationLine::remove_point (ControlPoint& cp) * @param result Filled in with selectable things; in this case, ControlPoints. */ void -AutomationLine::get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list& results) +AutomationLine::_get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list& results, bool /*within*/) { /* convert fractions to display coordinates with 0 at the top of the track */ double const bot_track = (1 - topfrac) * _height; // this should StreamView::child_height () for RegionGain diff --git a/gtk2_ardour/automation_line.h b/gtk2_ardour/automation_line.h index 2754af95f8..62781abc70 100644 --- a/gtk2_ardour/automation_line.h +++ b/gtk2_ardour/automation_line.h @@ -45,6 +45,8 @@ #include "canvas/container.h" #include "canvas/poly_line.h" +#include "selectable.h" + namespace ArdourCanvas { class Rectangle; } @@ -54,12 +56,11 @@ class ControlPoint; class PointSelection; class TimeAxisView; class AutomationTimeAxisView; -class Selectable; class Selection; class EditingContext; /** A GUI representation of an ARDOUR::AutomationList */ -class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible +class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible, public SelectableOwner { public: enum VisibleAspects { @@ -87,7 +88,7 @@ public: void set_fill (bool f) { _fill = f; } // owner needs to call set_height void set_selected_points (PointSelection const &); - void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&); + void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&, bool within); void get_inverted_selectables (Selection&, std::list& results); virtual void remove_point (ControlPoint&); diff --git a/gtk2_ardour/automation_streamview.cc b/gtk2_ardour/automation_streamview.cc index 2ef475b8a8..f1e403c4cd 100644 --- a/gtk2_ardour/automation_streamview.cc +++ b/gtk2_ardour/automation_streamview.cc @@ -271,7 +271,7 @@ AutomationStreamView::clear () * confusing. */ void -AutomationStreamView::get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list& results, bool /*within*/) +AutomationStreamView::_get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list& results, bool /*within*/) { for (list::iterator i = region_views.begin(); i != region_views.end(); ++i) { AutomationRegionView* arv = dynamic_cast (*i); diff --git a/gtk2_ardour/automation_streamview.h b/gtk2_ardour/automation_streamview.h index 97aba63793..7dff07076a 100644 --- a/gtk2_ardour/automation_streamview.h +++ b/gtk2_ardour/automation_streamview.h @@ -62,7 +62,7 @@ public: void clear (); - void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list &, bool within = false); + void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list &, bool within); void set_selected_points (PointSelection &); std::list > get_lines () const; diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index a33356c38a..c48bc7511a 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -917,7 +917,7 @@ AutomationTimeAxisView::paste_one (timepos_t const & pos, unsigned paste_count, } void -AutomationTimeAxisView::get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list& results, bool /*within*/) +AutomationTimeAxisView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list& results, bool /*within*/) { if (!_line && !_view) { return; diff --git a/gtk2_ardour/automation_time_axis.h b/gtk2_ardour/automation_time_axis.h index 06efc599a5..241d65eefc 100644 --- a/gtk2_ardour/automation_time_axis.h +++ b/gtk2_ardour/automation_time_axis.h @@ -100,7 +100,7 @@ public: AutomationStreamView* automation_view() const { return _view; } void set_selected_points (PointSelection&); - void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list&, bool within = false); + void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list&, bool within); void get_inverted_selectables (Selection&, std::list& results); void show_timestretch (Temporal::timepos_t const &/*start*/, Temporal::timepos_t const & /*end*/, int /*layers*/, int /*layer*/) {} diff --git a/gtk2_ardour/cue_editor.cc b/gtk2_ardour/cue_editor.cc index fb53b6abb6..218d5e0ffc 100644 --- a/gtk2_ardour/cue_editor.cc +++ b/gtk2_ardour/cue_editor.cc @@ -28,7 +28,7 @@ CueEditor::filter_to_unique_midi_region_views (RegionSelection const & ms) const } void -CueEditor::select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, TrackViewList const &, ARDOUR::SelectionOperation, bool) +CueEditor::select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list const &, ARDOUR::SelectionOperation, bool) { } diff --git a/gtk2_ardour/cue_editor.h b/gtk2_ardour/cue_editor.h index 1c794fc652..a19ee57f34 100644 --- a/gtk2_ardour/cue_editor.h +++ b/gtk2_ardour/cue_editor.h @@ -29,7 +29,7 @@ class CueEditor : public EditingContext, public PBD::HistoryOwner, public sigc:: CueEditor (std::string const & name); ~CueEditor (); - void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, TrackViewList const &, ARDOUR::SelectionOperation, bool); + void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list const &, ARDOUR::SelectionOperation, bool); void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const; StripableTimeAxisView* get_stripable_time_axis_by_id (const PBD::ID& id) const; diff --git a/gtk2_ardour/editing_context.h b/gtk2_ardour/editing_context.h index 6fd1121074..6487ca6367 100644 --- a/gtk2_ardour/editing_context.h +++ b/gtk2_ardour/editing_context.h @@ -70,6 +70,7 @@ class VerboseCursor; class TrackViewList; class Selection; class SelectionMemento; +class SelectableOwner; class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider { @@ -110,9 +111,11 @@ class EditingContext : public ARDOUR::SessionHandlePtr, public AxisViewProvider bool drag_active () const; bool preview_video_drag_active () const; + virtual std::list selectable_owners() = 0; + virtual ArdourCanvas::Duple upper_left() const { return ArdourCanvas::Duple (0, 0); } - virtual void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, TrackViewList const &, ARDOUR::SelectionOperation, bool) = 0; + virtual void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list const &, ARDOUR::SelectionOperation, bool) = 0; virtual void get_per_region_note_selection (std::list > > > >&) const = 0; virtual void get_regionviews_by_id (PBD::ID const id, RegionSelection & regions) const = 0; virtual StripableTimeAxisView* get_stripable_time_axis_by_id (const PBD::ID& id) const = 0; diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 37a92500eb..599e9fb3d0 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -218,6 +218,8 @@ public: bool get_selection_extents (Temporal::timepos_t &start, Temporal::timepos_t &end) const; // the time extents of the current selection, whether Range, Region(s), Control Points, or Notes Selection& get_cut_buffer() const { return *cut_buffer; } + std::list selectable_owners(); + void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&); void set_selection (std::list, ARDOUR::SelectionOperation); @@ -1874,7 +1876,7 @@ private: /* object rubberband select process */ - void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, TrackViewList const &, ARDOUR::SelectionOperation, bool); + void select_all_within (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list const &, ARDOUR::SelectionOperation, bool); EditorRouteGroups* _route_groups; EditorRoutes* _routes; diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index b7e8148e45..5d78541e62 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6119,7 +6119,7 @@ RangeMarkerBarDrag::finished (GdkEvent* event, bool movement_occurred) switch (editing_context.current_mouse_mode()) { case MouseObject: /* find the two markers on either side and then make the selection from it */ - editing_context.select_all_within (start, end, 0.0f, FLT_MAX, _editor.track_views, SelectionSet, false); + editing_context.select_all_within (start, end, 0.0f, FLT_MAX, _editor.selectable_owners(), SelectionSet, false); break; case MouseRange: @@ -6790,9 +6790,8 @@ MidiVerticalSelectDrag::deselect_things () /* XXX */ } -EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (Editor& e, ArdourCanvas::Item* i) +EditorRubberbandSelectDrag::EditorRubberbandSelectDrag (EditingContext& e, ArdourCanvas::Item* i) : RubberbandSelectDrag (e, i) - , editor (e) { } @@ -6807,7 +6806,7 @@ EditorRubberbandSelectDrag::select_things (int button_state, timepos_t const& x1 SelectionOperation op = ArdourKeyboard::selection_type (button_state); editing_context.begin_reversible_selection_op (X_("rubberband selection")); - editing_context.select_all_within (x1, x2.decrement (), y1, y2, editor.track_views, op, false); + editing_context.select_all_within (x1, x2.decrement (), y1, y2, editing_context.selectable_owners(), op, false); editing_context.commit_reversible_selection_op (); } diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 34a6060493..641dc26dc4 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -1319,12 +1319,11 @@ public: class EditorRubberbandSelectDrag : public RubberbandSelectDrag { public: - EditorRubberbandSelectDrag (Editor&, ArdourCanvas::Item *); + EditorRubberbandSelectDrag (EditingContext&, ArdourCanvas::Item *); void select_things (int, Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, bool); void deselect_things (); private: - Editor& editor; }; /** A RubberbandSelectDrag for selecting MIDI notes */ diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index c83fe3d6a9..268e06194c 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -1367,7 +1367,7 @@ Editor::marker_menu_select_all_selectables_using_range () bool is_start; if (((l = find_location_from_marker (marker, is_start)) != 0) && (l->end() > l->start())) { - select_all_within (l->start(), l->end(), 0, DBL_MAX, track_views, SelectionSet, false); + select_all_within (l->start(), l->end(), 0, DBL_MAX, selectable_owners(), SelectionSet, false); } } diff --git a/gtk2_ardour/editor_selection.cc b/gtk2_ardour/editor_selection.cc index c6ee337fe8..fcf0845023 100644 --- a/gtk2_ardour/editor_selection.cc +++ b/gtk2_ardour/editor_selection.cc @@ -1889,17 +1889,19 @@ Editor::invert_selection () * within the region are already selected. */ void -Editor::select_all_within (timepos_t const & start, timepos_t const & end, double top, double bot, const TrackViewList& tracklist, SelectionOperation op, bool preserve_if_selected) +Editor::select_all_within (timepos_t const & start, timepos_t const & end, double top, double bot, std::list const & owners, SelectionOperation op, bool preserve_if_selected) { list found; - for (TrackViewList::const_iterator iter = tracklist.begin(); iter != tracklist.end(); ++iter) { + for (auto & owner : owners) { - if ((*iter)->hidden()) { + TimeAxisView* tav = dynamic_cast (owner); + + if (tav && tav->hidden()) { continue; } - (*iter)->get_selectables (start, end, top, bot, found); + owner->get_selectables (start, end, top, bot, found); } if (found.empty()) { @@ -2481,3 +2483,14 @@ Editor::region_selection() { return get_regions_from_selection_and_entered (); } + +std::list +Editor::selectable_owners() +{ + std::list sl; + for (auto & tv : track_views) { + sl.push_back (tv); + } + + return sl; +} diff --git a/gtk2_ardour/midi_cue_editor.cc b/gtk2_ardour/midi_cue_editor.cc index 393fe7038e..af4e3f34aa 100644 --- a/gtk2_ardour/midi_cue_editor.cc +++ b/gtk2_ardour/midi_cue_editor.cc @@ -541,7 +541,17 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event break; case AutomationTrackItem: - _drags->set (new AutomationDrawDrag (*this, nullptr, *static_cast(item), false, Temporal::BeatTime), event); + switch (mouse_mode) { + case Editing::MouseContent: + /* rubberband drag to select automation points */ + // _drags->set (new EditorRubberbandSelectDrag (*this, item), event); + break; + case Editing::MouseDraw: + _drags->set (new AutomationDrawDrag (*this, nullptr, *static_cast(item), false, Temporal::BeatTime), event); + break; + default: + break; + } return true; break; @@ -1628,3 +1638,13 @@ MidiCueEditor::leave_handler (ArdourCanvas::Item* item, GdkEvent* ev, ItemType i return true; } + +std::list +MidiCueEditor::selectable_owners() +{ + if (view) { + return view->selectable_owners(); + } + + return std::list (); +} diff --git a/gtk2_ardour/midi_cue_editor.h b/gtk2_ardour/midi_cue_editor.h index 52a76062b4..b09b9d3c88 100644 --- a/gtk2_ardour/midi_cue_editor.h +++ b/gtk2_ardour/midi_cue_editor.h @@ -98,6 +98,8 @@ class MidiCueEditor : public CueEditor void midi_action (void (MidiView::*method)()); + std::list selectable_owners(); + Gdk::Cursor* which_track_cursor () const; Gdk::Cursor* which_mode_cursor () const; Gdk::Cursor* which_trim_cursor (bool left_side) const; diff --git a/gtk2_ardour/midi_cue_view.cc b/gtk2_ardour/midi_cue_view.cc index 8af28c08e1..b77d3438a2 100644 --- a/gtk2_ardour/midi_cue_view.cc +++ b/gtk2_ardour/midi_cue_view.cc @@ -293,3 +293,13 @@ MidiCueView::show_automation (Evoral::Parameter const & param) break; } } + +std::list +MidiCueView::selectable_owners() +{ + std::list sl; + if (automation_line) { + sl.push_back (automation_line); + } + return sl; +} diff --git a/gtk2_ardour/midi_cue_view.h b/gtk2_ardour/midi_cue_view.h index ff15e5ce0a..aab70ccdad 100644 --- a/gtk2_ardour/midi_cue_view.h +++ b/gtk2_ardour/midi_cue_view.h @@ -56,6 +56,8 @@ class MidiCueView : public MidiView ArdourCanvas::Item* drag_group() const; + std::list selectable_owners(); + protected: bool scroll (GdkEventScroll* ev); diff --git a/gtk2_ardour/midi_streamview.h b/gtk2_ardour/midi_streamview.h index 31550a66cb..d8c39b0206 100644 --- a/gtk2_ardour/midi_streamview.h +++ b/gtk2_ardour/midi_streamview.h @@ -63,7 +63,6 @@ public: MidiStreamView (MidiTimeAxisView&); ~MidiStreamView (); - void get_inverted_selectables (Selection&, std::list& results); void get_regions_with_selected_data (RegionSelection&); void set_layer_display (LayerDisplay); diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index b7e0c7631d..d10cb405ab 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -1203,7 +1203,7 @@ RouteTimeAxisView::set_selected_regionviews (RegionSelection& regions) * @param results List to add things to. */ void -RouteTimeAxisView::get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list& results, bool within) +RouteTimeAxisView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list& results, bool within) { if ((_view && ((top < 0.0 && bot < 0.0))) || touched (top, bot)) { _view->get_selectables (start, end, top, bot, results, within); diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h index 0cb64f7081..a443a88c43 100644 --- a/gtk2_ardour/route_time_axis.h +++ b/gtk2_ardour/route_time_axis.h @@ -98,7 +98,7 @@ public: void selection_click (GdkEventButton*); void set_selected_points (PointSelection&); void set_selected_regionviews (RegionSelection&); - void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list&, bool within = false); + void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list&, bool within); void get_inverted_selectables (Selection&, std::list&); void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&); diff --git a/gtk2_ardour/selectable.h b/gtk2_ardour/selectable.h index ee7eb55151..01d9b8ca35 100644 --- a/gtk2_ardour/selectable.h +++ b/gtk2_ardour/selectable.h @@ -18,9 +18,14 @@ */ #pragma once +#include #include +#include "temporal/timeline.h" + +class Selection; + class Selectable : public virtual sigc::trackable { public: @@ -44,3 +49,16 @@ protected: bool _selected; }; +class SelectableOwner +{ + public: + SelectableOwner() {} + virtual ~SelectableOwner() {} + + void get_selectables (Temporal::timepos_t const & start, Temporal::timepos_t const & end, double x, double y, std::list& sl, bool within = false) { + _get_selectables (start, end, x, y, sl, within); + } + + virtual void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&, bool within) = 0; + virtual void get_inverted_selectables (Selection&, std::list& results) = 0; +}; diff --git a/gtk2_ardour/streamview.cc b/gtk2_ardour/streamview.cc index aac13c57ba..13a1806a92 100644 --- a/gtk2_ardour/streamview.cc +++ b/gtk2_ardour/streamview.cc @@ -581,7 +581,7 @@ StreamView::set_selected_regionviews (RegionSelection& regions) * @param result Filled in with selectable things. */ void -StreamView::get_selectables (timepos_t const & start, timepos_t const & end, double top, double bottom, list& results, bool within) +StreamView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bottom, list& results, bool within) { layer_t min_layer = 0; layer_t max_layer = 0; diff --git a/gtk2_ardour/streamview.h b/gtk2_ardour/streamview.h index d6ee5a3bde..5e925e3adc 100644 --- a/gtk2_ardour/streamview.h +++ b/gtk2_ardour/streamview.h @@ -32,6 +32,7 @@ #include "ardour/location.h" #include "enums.h" +#include "selectable.h" #include "view_background.h" namespace Gdk { @@ -58,14 +59,13 @@ struct RecBoxInfo { ARDOUR::samplecnt_t length; }; -class Selectable; class RouteTimeAxisView; class RegionView; class RegionSelection; class CrossfadeView; class Selection; -class StreamView : public sigc::trackable, public PBD::ScopedConnectionList, public virtual ViewBackground +class StreamView : public sigc::trackable, public PBD::ScopedConnectionList, public virtual ViewBackground, public SelectableOwner { public: virtual ~StreamView (); @@ -105,7 +105,7 @@ public: void foreach_selected_regionview (sigc::slot slot); void set_selected_regionviews (RegionSelection&); - void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&, bool within = false); + void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&, bool within); void get_inverted_selectables (Selection&, std::list& results); void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&); diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index ef56e368d0..60bfd82b08 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -1117,7 +1117,7 @@ TimeAxisView::remove_child (std::shared_ptr child) * @param result Filled in with selectable things. */ void -TimeAxisView::get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list& results, bool within) +TimeAxisView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list& results, bool within) { for (Children::iterator i = children.begin(); i != children.end(); ++i) { if (!(*i)->hidden()) { diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index 0b0b1b3d97..b03570cffc 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -55,6 +55,7 @@ #include "axis_view.h" #include "enums.h" #include "editing.h" +#include "selectable.h" namespace ARDOUR { class Session; @@ -81,7 +82,6 @@ class TimeSelection; class PointSelection; class TimeAxisViewItem; class Selection; -class Selectable; class RegionView; class GhostRegion; class StreamView; @@ -94,7 +94,7 @@ class PasteContext; * This class provides the basic LHS controls and display methods. This should be * extended to create functional time-axis based views. */ -class TimeAxisView : public virtual AxisView +class TimeAxisView : public virtual AxisView, public SelectableOwner { private: enum NamePackingBits { @@ -207,8 +207,8 @@ public: void order_selection_trims (ArdourCanvas::Item *item, bool put_start_on_top); - virtual void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&, bool within = false); - virtual void get_inverted_selectables (Selection&, std::list& results); + void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list&, bool within); + void get_inverted_selectables (Selection&, std::list& results); virtual void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&) {} void add_ghost (RegionView*);