move most of AutomationLine into AutomatonLineBase, a class not strongly tied to the editor
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -45,6 +45,8 @@
|
||||
#include "canvas/container.h"
|
||||
#include "canvas/poly_line.h"
|
||||
|
||||
#include "automation_line_base.h"
|
||||
|
||||
class AutomationLine;
|
||||
class ControlPoint;
|
||||
class PointSelection;
|
||||
@@ -55,16 +57,13 @@ class Selection;
|
||||
class PublicEditor;
|
||||
|
||||
|
||||
/** A GUI representation of an ARDOUR::AutomationList */
|
||||
class AutomationLine : public sigc::trackable, public PBD::StatefulDestructible
|
||||
/** A GUI representation of an ARDOUR::AutomationList within the main editor
|
||||
* (i.e. in a TimeAxisView
|
||||
*/
|
||||
|
||||
class AutomationLine : public AutomationLineBase
|
||||
{
|
||||
public:
|
||||
enum VisibleAspects {
|
||||
Line = 0x1,
|
||||
ControlPoints = 0x2,
|
||||
SelectedControlPoints = 0x4
|
||||
};
|
||||
|
||||
AutomationLine (const std::string& name,
|
||||
TimeAxisView& tv,
|
||||
ArdourCanvas::Item& parent,
|
||||
@@ -74,182 +73,10 @@ public:
|
||||
|
||||
virtual ~AutomationLine ();
|
||||
|
||||
virtual Temporal::timepos_t get_origin () const;
|
||||
|
||||
void queue_reset ();
|
||||
void reset ();
|
||||
void clear ();
|
||||
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_inverted_selectables (Selection&, std::list<Selectable*>& results);
|
||||
|
||||
virtual void remove_point (ControlPoint&);
|
||||
bool control_points_adjacent (double xval, uint32_t& before, uint32_t& after);
|
||||
|
||||
/* dragging API */
|
||||
virtual void start_drag_single (ControlPoint*, double, float);
|
||||
virtual void start_drag_line (uint32_t, uint32_t, float);
|
||||
virtual void start_drag_multiple (std::list<ControlPoint*>, float, XMLNode *);
|
||||
virtual std::pair<float, float> drag_motion (Temporal::timecnt_t const &, float, bool, bool with_push, uint32_t& final_index);
|
||||
virtual void end_drag (bool with_push, uint32_t final_index);
|
||||
virtual void end_draw_merge () {}
|
||||
|
||||
ControlPoint* nth (uint32_t);
|
||||
ControlPoint const * nth (uint32_t) const;
|
||||
uint32_t npoints() const { return control_points.size(); }
|
||||
|
||||
std::string name() const { return _name; }
|
||||
bool visible() const { return _visible != VisibleAspects(0); }
|
||||
guint32 height() const { return _height; }
|
||||
|
||||
void set_line_color (std::string color, std::string mod = "");
|
||||
uint32_t get_line_color() const;
|
||||
|
||||
void set_visibility (VisibleAspects);
|
||||
void add_visibility (VisibleAspects);
|
||||
void remove_visibility (VisibleAspects);
|
||||
|
||||
void hide ();
|
||||
void set_height (guint32);
|
||||
|
||||
bool get_uses_gain_mapping () const;
|
||||
void tempo_map_changed ();
|
||||
|
||||
TimeAxisView& trackview;
|
||||
|
||||
ArdourCanvas::Container& canvas_group() const { return *group; }
|
||||
ArdourCanvas::Item& parent_group() const { return _parent_group; }
|
||||
ArdourCanvas::Item& grab_item() const { return *line; }
|
||||
|
||||
virtual std::string get_verbose_cursor_string (double) const;
|
||||
std::string get_verbose_cursor_relative_string (double, double) const;
|
||||
std::string fraction_to_string (double) const;
|
||||
std::string delta_to_string (double) const;
|
||||
double string_to_fraction (std::string const &) const;
|
||||
|
||||
void view_to_model_coord_y (double &) const;
|
||||
|
||||
double model_to_view_coord_y (double) const;
|
||||
Temporal::timecnt_t model_to_view_coord_x (Temporal::timepos_t const &) const;
|
||||
|
||||
double compute_delta (double from, double to) const;
|
||||
void apply_delta (double& val, double delta) const;
|
||||
|
||||
void set_list(std::shared_ptr<ARDOUR::AutomationList> list);
|
||||
std::shared_ptr<ARDOUR::AutomationList> the_list() const { return alist; }
|
||||
|
||||
void track_entered();
|
||||
void track_exited();
|
||||
|
||||
bool is_last_point (ControlPoint &);
|
||||
bool is_first_point (ControlPoint &);
|
||||
|
||||
XMLNode& get_state () const;
|
||||
int set_state (const XMLNode&, int version);
|
||||
void set_colors();
|
||||
|
||||
void modify_points_y (std::vector<ControlPoint*> const&, double);
|
||||
|
||||
virtual MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
||||
|
||||
std::pair<Temporal::timepos_t, Temporal::timepos_t> get_point_x_range () const;
|
||||
|
||||
void set_maximum_time (Temporal::timepos_t const &);
|
||||
Temporal::timepos_t maximum_time () const {
|
||||
return _maximum_time;
|
||||
}
|
||||
|
||||
void set_offset (Temporal::timepos_t const &);
|
||||
Temporal::timepos_t offset () { return _offset; }
|
||||
void set_width (Temporal::timecnt_t const &);
|
||||
|
||||
Temporal::timepos_t session_position (Temporal::timepos_t const &) const;
|
||||
void dump (std::ostream&) const;
|
||||
|
||||
double dt_to_dx (Temporal::timepos_t const &, Temporal::timecnt_t const &);
|
||||
|
||||
protected:
|
||||
|
||||
std::string _name;
|
||||
guint32 _height;
|
||||
std::string _line_color;
|
||||
std::string _line_color_mod;
|
||||
uint32_t _view_index_offset;
|
||||
std::shared_ptr<ARDOUR::AutomationList> alist;
|
||||
|
||||
VisibleAspects _visible;
|
||||
|
||||
bool terminal_points_can_slide;
|
||||
bool update_pending;
|
||||
bool have_reset_timeout;
|
||||
bool no_draw;
|
||||
bool _is_boolean;
|
||||
/** true if we did a push at any point during the current drag */
|
||||
bool did_push;
|
||||
|
||||
ArdourCanvas::Item& _parent_group;
|
||||
ArdourCanvas::Container* group;
|
||||
ArdourCanvas::PolyLine* line; /* line */
|
||||
ArdourCanvas::Points line_points; /* coordinates for canvas line */
|
||||
std::vector<ControlPoint*> control_points; /* visible control points */
|
||||
|
||||
class ContiguousControlPoints : public std::list<ControlPoint*> {
|
||||
public:
|
||||
ContiguousControlPoints (AutomationLine& al);
|
||||
Temporal::timecnt_t clamp_dt (Temporal::timecnt_t const & dx, Temporal::timepos_t const & region_limit);
|
||||
void move (Temporal::timecnt_t const &, double dvalue);
|
||||
void compute_x_bounds (PublicEditor& e);
|
||||
private:
|
||||
AutomationLine& line;
|
||||
Temporal::timepos_t before_x;
|
||||
Temporal::timepos_t after_x;
|
||||
};
|
||||
|
||||
friend class ContiguousControlPoints;
|
||||
|
||||
typedef std::shared_ptr<ContiguousControlPoints> CCP;
|
||||
std::vector<CCP> contiguous_points;
|
||||
|
||||
bool sync_model_with_view_point (ControlPoint&);
|
||||
bool sync_model_with_view_points (std::list<ControlPoint*>);
|
||||
void start_drag_common (double, float);
|
||||
|
||||
void reset_callback (const Evoral::ControlList&);
|
||||
void list_changed ();
|
||||
|
||||
protected:
|
||||
virtual bool event_handler (GdkEvent*);
|
||||
|
||||
private:
|
||||
std::list<ControlPoint*> _drag_points; ///< points we are dragging
|
||||
std::list<ControlPoint*> _push_points; ///< additional points we are dragging if "push" is enabled
|
||||
bool _drag_had_movement; ///< true if the drag has seen movement, otherwise false
|
||||
double _last_drag_fraction; ///< last y position of the drag, as a fraction
|
||||
/** offset from the start of the automation list to the start of the line, so that
|
||||
* a +ve offset means that the 0 on the line is at _offset in the list
|
||||
*/
|
||||
Temporal::timepos_t _offset;
|
||||
|
||||
bool is_stepped() const;
|
||||
void update_visibility ();
|
||||
void reset_line_coords (ControlPoint&);
|
||||
void add_visible_control_point (uint32_t, uint32_t, double, double, ARDOUR::AutomationList::iterator, uint32_t);
|
||||
double control_point_box_size ();
|
||||
void connect_to_list ();
|
||||
void interpolation_changed (ARDOUR::AutomationList::InterpolationStyle);
|
||||
|
||||
PBD::ScopedConnectionList _list_connections;
|
||||
|
||||
/** maximum time that a point on this line can be at, relative to the position of its region or start of its track */
|
||||
Temporal::timepos_t _maximum_time;
|
||||
|
||||
bool _fill;
|
||||
|
||||
const ARDOUR::ParameterDescriptor _desc;
|
||||
|
||||
friend class AudioRegionGainLine;
|
||||
friend class RegionFxLine;
|
||||
};
|
||||
|
||||
#endif /* __ardour_automation_line_h__ */
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
*/
|
||||
|
||||
#include "control_point.h"
|
||||
#include "automation_line.h"
|
||||
#include "automation_line_base.h"
|
||||
#include "public_editor.h"
|
||||
#include "ui_config.h"
|
||||
|
||||
@@ -33,7 +33,7 @@ using namespace PBD;
|
||||
|
||||
PBD::Signal1<void, ControlPoint *> ControlPoint::CatchDeletion;
|
||||
|
||||
ControlPoint::ControlPoint (AutomationLine& al)
|
||||
ControlPoint::ControlPoint (AutomationLineBase& al)
|
||||
: _line (al)
|
||||
{
|
||||
_model = al.the_list()->end();
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "selectable.h"
|
||||
|
||||
class AutomationLine;
|
||||
class AutomationLineBase;
|
||||
class ControlPoint;
|
||||
class PointSelection;
|
||||
class TimeAxisView;
|
||||
@@ -46,7 +46,7 @@ namespace ArdourCanvas {
|
||||
class ControlPoint : public Selectable
|
||||
{
|
||||
public:
|
||||
ControlPoint (AutomationLine& al);
|
||||
ControlPoint (AutomationLineBase& al);
|
||||
ControlPoint (const ControlPoint&, bool dummy_arg_to_force_special_copy_constructor);
|
||||
virtual ~ControlPoint ();
|
||||
|
||||
@@ -84,13 +84,13 @@ public:
|
||||
void unset_item () { _item = 0 ; }
|
||||
|
||||
ARDOUR::AutomationList::iterator model() const { return _model; }
|
||||
AutomationLine& line() const { return _line; }
|
||||
AutomationLineBase& line() const { return _line; }
|
||||
|
||||
static PBD::Signal1<void, ControlPoint *> CatchDeletion;
|
||||
|
||||
private:
|
||||
ArdourCanvas::Rectangle* _item;
|
||||
AutomationLine& _line;
|
||||
ArdourCanvas::Rectangle * _item;
|
||||
AutomationLineBase& _line;
|
||||
ARDOUR::AutomationList::iterator _model;
|
||||
uint32_t _view_index;
|
||||
bool _can_slide;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "gtkmm2ext/gtk_ui.h"
|
||||
|
||||
#include "automation_line.h"
|
||||
#include "automation_line_base.h"
|
||||
#include "control_point.h"
|
||||
#include "control_point_dialog.h"
|
||||
|
||||
|
||||
@@ -331,6 +331,8 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou
|
||||
bool
|
||||
Editor::canvas_automation_track_event (GdkEvent *event, ArdourCanvas::Item* item, AutomationTimeAxisView *atv)
|
||||
{
|
||||
std::cerr << "AT event\n";
|
||||
|
||||
if (atv->parameter().type() == MidiVelocityAutomation) {
|
||||
/* no event handling for velocity tracks until we can make the
|
||||
automation control affect note velocity.
|
||||
@@ -636,7 +638,7 @@ Editor::canvas_control_point_event (GdkEvent *event, ArdourCanvas::Item* item, C
|
||||
case GDK_2BUTTON_PRESS:
|
||||
case GDK_3BUTTON_PRESS:
|
||||
clicked_control_point = cp;
|
||||
clicked_axisview = &cp->line().trackview;
|
||||
clicked_axisview = &dynamic_cast<AutomationLine*> (&cp->line())->trackview;
|
||||
clicked_routeview = dynamic_cast<RouteTimeAxisView*>(clicked_axisview);
|
||||
clicked_regionview = 0;
|
||||
break;
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
|
||||
#include "canvas/canvas.h"
|
||||
#include "canvas/lollipop.h"
|
||||
#include "canvas/rectangle.h"
|
||||
#include "canvas/scroll_group.h"
|
||||
|
||||
#include "ardour_ui.h"
|
||||
|
||||
@@ -2198,7 +2198,7 @@ Editor::can_remove_control_point (ArdourCanvas::Item* item)
|
||||
abort(); /*NOTREACHED*/
|
||||
}
|
||||
|
||||
AutomationLine& line = control_point->line ();
|
||||
AutomationLineBase& line (control_point->line());
|
||||
if (dynamic_cast<RegionFxLine*> (&line)) {
|
||||
/* we shouldn't remove the first or last gain point in region gain lines */
|
||||
if (line.is_last_point(*control_point) || line.is_first_point(*control_point)) {
|
||||
|
||||
@@ -89,6 +89,7 @@
|
||||
#include "audio_region_view.h"
|
||||
#include "audio_streamview.h"
|
||||
#include "audio_time_axis.h"
|
||||
#include "automation_line_base.h"
|
||||
#include "automation_time_axis.h"
|
||||
#include "control_point.h"
|
||||
#include "debug.h"
|
||||
@@ -4815,11 +4816,11 @@ Editor::cut_copy (CutCopyOp op)
|
||||
|
||||
|
||||
struct AutomationRecord {
|
||||
AutomationRecord () : state (0) , line(NULL) {}
|
||||
AutomationRecord (XMLNode* s, const AutomationLine* l) : state (s) , line (l) {}
|
||||
AutomationRecord () : state (0) , line (nullptr) {}
|
||||
AutomationRecord (XMLNode* s, const AutomationLineBase* l) : state (s) , line (l) {}
|
||||
|
||||
XMLNode* state; ///< state before any operation
|
||||
const AutomationLine* line; ///< line this came from
|
||||
const AutomationLineBase* line; ///< line this came from
|
||||
std::shared_ptr<Evoral::ControlList> copy; ///< copied events for the cut buffer
|
||||
};
|
||||
|
||||
@@ -4842,7 +4843,9 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
|
||||
timepos_t earliest (earliest_time);
|
||||
|
||||
/* XXX: not ideal, as there may be more than one track involved in the point selection */
|
||||
_last_cut_copy_source_track = &selection->points.front()->line().trackview;
|
||||
AutomationLine* line = dynamic_cast<AutomationLine*> (&selection->points.front()->line());
|
||||
assert (line);
|
||||
_last_cut_copy_source_track = &line->trackview;
|
||||
|
||||
/* Keep a record of the AutomationLists that we end up using in this operation */
|
||||
typedef std::map<std::shared_ptr<AutomationList>, AutomationRecord> Lists;
|
||||
@@ -4852,8 +4855,8 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
|
||||
selection->points.sort(PointsSelectionPositionSorter ());
|
||||
|
||||
/* Go through all selected points, making an AutomationRecord for each distinct AutomationList */
|
||||
for (PointSelection::iterator sel_point = selection->points.begin(); sel_point != selection->points.end(); ++sel_point) {
|
||||
const AutomationLine& line = (*sel_point)->line();
|
||||
for (auto & selected_point : selection->points) {
|
||||
const AutomationLineBase& line (selected_point->line());
|
||||
const std::shared_ptr<AutomationList> al = line.the_list();
|
||||
if (lists.find (al) == lists.end ()) {
|
||||
/* We haven't seen this list yet, so make a record for it. This includes
|
||||
@@ -4873,9 +4876,9 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
|
||||
|
||||
/* Add all selected points to the relevant copy ControlLists */
|
||||
|
||||
for (PointSelection::iterator sel_point = selection->points.begin(); sel_point != selection->points.end(); ++sel_point) {
|
||||
std::shared_ptr<AutomationList> al = (*sel_point)->line().the_list();
|
||||
AutomationList::const_iterator ctrl_evt = (*sel_point)->model ();
|
||||
for (auto & selected_point : selection->points) {
|
||||
std::shared_ptr<AutomationList> al = selected_point->line().the_list();
|
||||
AutomationList::const_iterator ctrl_evt = selected_point->model ();
|
||||
|
||||
lists[al].copy->fast_simple_add ((*ctrl_evt)->when, (*ctrl_evt)->value);
|
||||
earliest = std::min (earliest, (*ctrl_evt)->when);
|
||||
@@ -4905,21 +4908,21 @@ Editor::cut_copy_points (Editing::CutCopyOp op, timepos_t const & earliest_time)
|
||||
}
|
||||
|
||||
/* Remove each selected point from its AutomationList */
|
||||
for (PointSelection::iterator sel_point = selection->points.begin(); sel_point != selection->points.end(); ++sel_point) {
|
||||
AutomationLine& line = (*sel_point)->line ();
|
||||
for (auto & selected_point : selection->points) {
|
||||
AutomationLineBase& line (selected_point->line ());
|
||||
std::shared_ptr<AutomationList> al = line.the_list();
|
||||
|
||||
bool erase = true;
|
||||
|
||||
if (dynamic_cast<RegionFxLine*> (&line)) {
|
||||
/* removing of first and last gain point in region gain lines is prohibited*/
|
||||
if (line.is_last_point (*(*sel_point)) || line.is_first_point (*(*sel_point))) {
|
||||
if (line.is_last_point (*selected_point) || line.is_first_point (*selected_point)) {
|
||||
erase = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(erase) {
|
||||
al->erase ((*sel_point)->model ());
|
||||
al->erase (selected_point->model ());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "control_protocol/control_protocol.h"
|
||||
|
||||
#include "audio_region_view.h"
|
||||
#include "automation_line_base.h"
|
||||
#include "debug.h"
|
||||
#include "gui_thread.h"
|
||||
#include "midi_cut_buffer.h"
|
||||
@@ -1163,25 +1164,27 @@ Selection::get_state () const
|
||||
}
|
||||
}
|
||||
|
||||
for (PointSelection::const_iterator i = points.begin(); i != points.end(); ++i) {
|
||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (&(*i)->line().trackview);
|
||||
for (auto & cp : points) {
|
||||
AutomationLine* al = dynamic_cast<AutomationLine*> (&cp->line());
|
||||
assert (al);
|
||||
AutomationTimeAxisView* atv = dynamic_cast<AutomationTimeAxisView*> (&al->trackview);
|
||||
if (atv) {
|
||||
|
||||
XMLNode* r = node->add_child (X_("ControlPoint"));
|
||||
r->set_property (X_("type"), "track");
|
||||
r->set_property (X_("route-id"), atv->parent_stripable()->id ());
|
||||
r->set_property (X_("automation-list-id"), (*i)->line().the_list()->id ());
|
||||
r->set_property (X_("parameter"), EventTypeMap::instance().to_symbol ((*i)->line().the_list()->parameter ()));
|
||||
r->set_property (X_("view-index"), (*i)->view_index());
|
||||
continue;
|
||||
}
|
||||
r->set_property (X_("automation-list-id"), al->the_list()->id ());
|
||||
r->set_property (X_("parameter"), EventTypeMap::instance().to_symbol (al->the_list()->parameter ()));
|
||||
r->set_property (X_("view-index"), cp->view_index());
|
||||
} else {
|
||||
|
||||
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> (&(*i)->line());
|
||||
if (fxl) {
|
||||
XMLNode* r = node->add_child (X_("ControlPoint"));
|
||||
r->set_property (X_("type"), "region");
|
||||
r->set_property (X_("region-id"), fxl->region_view ().region ()->id ());
|
||||
r->set_property (X_("view-index"), (*i)->view_index());
|
||||
RegionFxLine* fxl = dynamic_cast<RegionFxLine*> (al);
|
||||
if (fxl) {
|
||||
XMLNode* r = node->add_child (X_("ControlPoint"));
|
||||
r->set_property (X_("type"), "region");
|
||||
r->set_property (X_("region-id"), fxl->region_view ().region ()->id ());
|
||||
r->set_property (X_("view-index"), cp->view_index());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ gtk2_ardour_sources = [
|
||||
'audio_time_axis.cc',
|
||||
'automation_controller.cc',
|
||||
'automation_line.cc',
|
||||
'automation_line_base.cc',
|
||||
'automation_region_view.cc',
|
||||
'automation_streamview.cc',
|
||||
'automation_time_axis.cc',
|
||||
|
||||
Reference in New Issue
Block a user