13
0

refactor the "selectables" API to allow use within separate (e.g. cue) editors

This commit is contained in:
Paul Davis 2024-10-07 13:20:11 -06:00
parent 83ea6e18b5
commit 4b8c51574d
26 changed files with 104 additions and 36 deletions

View File

@ -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<Selectable*>& results)
AutomationLine::_get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list<Selectable*>& 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

View File

@ -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<Selectable*>&);
void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable*>&, bool within);
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
virtual void remove_point (ControlPoint&);

View File

@ -271,7 +271,7 @@ AutomationStreamView::clear ()
* confusing.
*/
void
AutomationStreamView::get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list<Selectable*>& results, bool /*within*/)
AutomationStreamView::_get_selectables (timepos_t const & start, timepos_t const & end, double botfrac, double topfrac, list<Selectable*>& results, bool /*within*/)
{
for (list<RegionView*>::iterator i = region_views.begin(); i != region_views.end(); ++i) {
AutomationRegionView* arv = dynamic_cast<AutomationRegionView*> (*i);

View File

@ -62,7 +62,7 @@ public:
void clear ();
void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable*> &, bool within = false);
void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable*> &, bool within);
void set_selected_points (PointSelection &);
std::list<std::shared_ptr<AutomationLine> > get_lines () const;

View File

@ -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<Selectable*>& results, bool /*within*/)
AutomationTimeAxisView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list<Selectable*>& results, bool /*within*/)
{
if (!_line && !_view) {
return;

View File

@ -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<Selectable *>&, bool within = false);
void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list<Selectable *>&, bool within);
void get_inverted_selectables (Selection&, std::list<Selectable*>& results);
void show_timestretch (Temporal::timepos_t const &/*start*/, Temporal::timepos_t const & /*end*/, int /*layers*/, int /*layer*/) {}

View File

@ -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<SelectableOwner*> const &, ARDOUR::SelectionOperation, bool)
{
}

View File

@ -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<SelectableOwner*> 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;

View File

@ -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<SelectableOwner*> 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<SelectableOwner*> const &, ARDOUR::SelectionOperation, bool) = 0;
virtual void get_per_region_note_selection (std::list<std::pair<PBD::ID, std::set<std::shared_ptr<Evoral::Note<Temporal::Beats> > > > >&) 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;

View File

@ -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<SelectableOwner*> selectable_owners();
void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&);
void set_selection (std::list<Selectable*>, 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<SelectableOwner*> const &, ARDOUR::SelectionOperation, bool);
EditorRouteGroups* _route_groups;
EditorRoutes* _routes;

View File

@ -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 ();
}

View File

@ -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 */

View File

@ -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);
}
}

View File

@ -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<SelectableOwner*> const & owners, SelectionOperation op, bool preserve_if_selected)
{
list<Selectable*> found;
for (TrackViewList::const_iterator iter = tracklist.begin(); iter != tracklist.end(); ++iter) {
for (auto & owner : owners) {
if ((*iter)->hidden()) {
TimeAxisView* tav = dynamic_cast<TimeAxisView*> (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<SelectableOwner*>
Editor::selectable_owners()
{
std::list<SelectableOwner*> sl;
for (auto & tv : track_views) {
sl.push_back (tv);
}
return sl;
}

View File

@ -541,7 +541,17 @@ MidiCueEditor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event
break;
case AutomationTrackItem:
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<ArdourCanvas::Rectangle*>(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<SelectableOwner*>
MidiCueEditor::selectable_owners()
{
if (view) {
return view->selectable_owners();
}
return std::list<SelectableOwner*> ();
}

View File

@ -98,6 +98,8 @@ class MidiCueEditor : public CueEditor
void midi_action (void (MidiView::*method)());
std::list<SelectableOwner*> selectable_owners();
Gdk::Cursor* which_track_cursor () const;
Gdk::Cursor* which_mode_cursor () const;
Gdk::Cursor* which_trim_cursor (bool left_side) const;

View File

@ -293,3 +293,13 @@ MidiCueView::show_automation (Evoral::Parameter const & param)
break;
}
}
std::list<SelectableOwner*>
MidiCueView::selectable_owners()
{
std::list<SelectableOwner*> sl;
if (automation_line) {
sl.push_back (automation_line);
}
return sl;
}

View File

@ -56,6 +56,8 @@ class MidiCueView : public MidiView
ArdourCanvas::Item* drag_group() const;
std::list<SelectableOwner*> selectable_owners();
protected:
bool scroll (GdkEventScroll* ev);

View File

@ -63,7 +63,6 @@ public:
MidiStreamView (MidiTimeAxisView&);
~MidiStreamView ();
void get_inverted_selectables (Selection&, std::list<Selectable* >& results);
void get_regions_with_selected_data (RegionSelection&);
void set_layer_display (LayerDisplay);

View File

@ -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<Selectable*>& results, bool within)
RouteTimeAxisView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list<Selectable*>& results, bool within)
{
if ((_view && ((top < 0.0 && bot < 0.0))) || touched (top, bot)) {
_view->get_selectables (start, end, top, bot, results, within);

View File

@ -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<Selectable *>&, bool within = false);
void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double top, double bot, std::list<Selectable *>&, bool within);
void get_inverted_selectables (Selection&, std::list<Selectable*>&);
void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&);

View File

@ -18,9 +18,14 @@
*/
#pragma once
#include <list>
#include <sigc++/signal.h>
#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<Selectable*>& 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<Selectable*>&, bool within) = 0;
virtual void get_inverted_selectables (Selection&, std::list<Selectable *>& results) = 0;
};

View File

@ -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<Selectable*>& results, bool within)
StreamView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bottom, list<Selectable*>& results, bool within)
{
layer_t min_layer = 0;
layer_t max_layer = 0;

View File

@ -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<void,RegionView*> slot);
void set_selected_regionviews (RegionSelection&);
void get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable* >&, bool within = false);
void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable* >&, bool within);
void get_inverted_selectables (Selection&, std::list<Selectable* >& results);
void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&);

View File

@ -1117,7 +1117,7 @@ TimeAxisView::remove_child (std::shared_ptr<TimeAxisView> 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<Selectable*>& results, bool within)
TimeAxisView::_get_selectables (timepos_t const & start, timepos_t const & end, double top, double bot, list<Selectable*>& results, bool within)
{
for (Children::iterator i = children.begin(); i != children.end(); ++i) {
if (!(*i)->hidden()) {

View File

@ -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<Selectable*>&, bool within = false);
virtual void get_inverted_selectables (Selection&, std::list<Selectable *>& results);
void _get_selectables (Temporal::timepos_t const &, Temporal::timepos_t const &, double, double, std::list<Selectable*>&, bool within);
void get_inverted_selectables (Selection&, std::list<Selectable *>& results);
virtual void get_regionviews_at_or_after (Temporal::timepos_t const &, RegionSelection&) {}
void add_ghost (RegionView*);