GUI changes to *try* to adapt to a world without explicit beats<->samples converter objects (i.e. use AutomationLine::get_origin() instead
This commit is contained in:
parent
0877500437
commit
0162d3f9d6
|
@ -79,8 +79,7 @@ using namespace PBD;
|
||||||
using namespace Editing;
|
using namespace Editing;
|
||||||
using namespace Temporal;
|
using namespace Temporal;
|
||||||
|
|
||||||
#define TIME_TO_SAMPLES(x) (_distance_measure (x, Temporal::AudioTime))
|
#define SAMPLES_TO_TIME(x) (get_origin().distance (x))
|
||||||
#define SAMPLES_TO_TIME(x) (_distance_measure (x, alist->time_domain()))
|
|
||||||
|
|
||||||
/** @param converter A TimeConverter whose origin_b is the start time of the AutomationList in session samples.
|
/** @param converter A TimeConverter whose origin_b is the start time of the AutomationList in session samples.
|
||||||
* This will not be deleted by AutomationLine.
|
* This will not be deleted by AutomationLine.
|
||||||
|
@ -89,8 +88,7 @@ AutomationLine::AutomationLine (const string& name,
|
||||||
TimeAxisView& tv,
|
TimeAxisView& tv,
|
||||||
ArdourCanvas::Item& parent,
|
ArdourCanvas::Item& parent,
|
||||||
boost::shared_ptr<AutomationList> al,
|
boost::shared_ptr<AutomationList> al,
|
||||||
const ParameterDescriptor& desc,
|
const ParameterDescriptor& desc)
|
||||||
Temporal::DistanceMeasure const & m)
|
|
||||||
: trackview (tv)
|
: trackview (tv)
|
||||||
, _name (name)
|
, _name (name)
|
||||||
, alist (al)
|
, alist (al)
|
||||||
|
@ -99,7 +97,6 @@ AutomationLine::AutomationLine (const string& name,
|
||||||
, _maximum_time (timepos_t::max (al->time_domain()))
|
, _maximum_time (timepos_t::max (al->time_domain()))
|
||||||
, _fill (false)
|
, _fill (false)
|
||||||
, _desc (desc)
|
, _desc (desc)
|
||||||
, _distance_measure (m)
|
|
||||||
{
|
{
|
||||||
_visible = Line;
|
_visible = Line;
|
||||||
|
|
||||||
|
@ -139,6 +136,15 @@ AutomationLine::~AutomationLine ()
|
||||||
control_points.clear ();
|
control_points.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timepos_t
|
||||||
|
AutomationLine::get_origin() const
|
||||||
|
{
|
||||||
|
/* this is the default for all non-derived AutomationLine classes: the
|
||||||
|
origin is zero, in whatever time domain the list we represent uses.
|
||||||
|
*/
|
||||||
|
return timepos_t (the_list()->time_domain());
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
AutomationLine::event_handler (GdkEvent* event)
|
AutomationLine::event_handler (GdkEvent* event)
|
||||||
{
|
{
|
||||||
|
@ -762,6 +768,14 @@ AutomationLine::end_drag (bool with_push, uint32_t final_index)
|
||||||
contiguous_points.clear ();
|
contiguous_points.clear ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* get model coordinates synced with (possibly changed) view coordinates.
|
||||||
|
*
|
||||||
|
* For example, we call this in ::end_drag(), when we have probably moved a
|
||||||
|
* point in the view, and now want to "push" that change back into the
|
||||||
|
* corresponding model point.
|
||||||
|
*/
|
||||||
bool
|
bool
|
||||||
AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
||||||
{
|
{
|
||||||
|
@ -773,22 +787,49 @@ AutomationLine::sync_model_with_view_point (ControlPoint& cp)
|
||||||
double view_x = cp.get_x();
|
double view_x = cp.get_x();
|
||||||
double view_y = 1.0 - cp.get_y() / (double)_height;
|
double view_y = 1.0 - cp.get_y() / (double)_height;
|
||||||
|
|
||||||
/* if xval has not changed, set it directly from the model to avoid rounding errors */
|
timepos_t model_time = (*cp.model())->when;
|
||||||
|
|
||||||
timepos_t model_x = (*cp.model())->when;
|
/* convert to absolute time by taking the origin of the line into
|
||||||
|
* account.
|
||||||
|
*/
|
||||||
|
|
||||||
if (view_x != trackview.editor().time_to_pixel_unrounded (model_x.earlier (_offset))) {
|
const timepos_t absolute_time = model_time + get_origin();
|
||||||
/* convert from view coordinates, via pixels->samples->timepos_t
|
|
||||||
|
/* convert the absolute time of the model event into unrounded pixels,
|
||||||
|
* taking _offset into account.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const double model_x = trackview.editor().time_to_pixel_unrounded (absolute_time.earlier (_offset));
|
||||||
|
|
||||||
|
if (view_x != model_x) {
|
||||||
|
|
||||||
|
/* convert the current position in the view (units: pixels)
|
||||||
|
* into samples, then use that to create a timecnt_t that
|
||||||
|
* measures the distance from the origin for this line.
|
||||||
*/
|
*/
|
||||||
const timecnt_t p = timecnt_t (trackview.editor().pixel_to_sample (view_x), timepos_t()); /* samples */
|
|
||||||
model_x = SAMPLES_TO_TIME (p + _offset); /* correct time domain for list */
|
const timecnt_t view_samples (trackview.editor().pixel_to_sample (view_x)); /* implicit zero origin */
|
||||||
|
|
||||||
|
/* adjust to measure distance from origin (this preserves time domain) */
|
||||||
|
const timecnt_t distance_from_origin = get_origin().distance (timepos_t (view_samples));
|
||||||
|
|
||||||
|
/* now convert to relevant time domain, and use _offset.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (model_time.time_domain() == Temporal::AudioTime) {
|
||||||
|
model_time = timepos_t (distance_from_origin.samples()) + _offset;
|
||||||
|
} else {
|
||||||
|
model_time = timepos_t (distance_from_origin.beats()) + _offset;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
model_time = model_time.earlier (_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_pending = true;
|
update_pending = true;
|
||||||
|
|
||||||
view_to_model_coord_y (view_y);
|
view_to_model_coord_y (view_y);
|
||||||
|
|
||||||
alist->modify (cp.model(), model_x, view_y);
|
alist->modify (cp.model(), model_time, view_y);
|
||||||
|
|
||||||
/* convert back from model to view y for clamping position (for integer/boolean/etc) */
|
/* convert back from model to view y for clamping position (for integer/boolean/etc) */
|
||||||
model_to_view_coord_y (view_y);
|
model_to_view_coord_y (view_y);
|
||||||
|
@ -1346,13 +1387,13 @@ AutomationLine::get_point_x_range () const
|
||||||
samplepos_t
|
samplepos_t
|
||||||
AutomationLine::session_sample_position (AutomationList::const_iterator p) const
|
AutomationLine::session_sample_position (AutomationList::const_iterator p) const
|
||||||
{
|
{
|
||||||
return (*p)->when.samples() + _offset.samples() + _distance_measure.origin().samples();
|
return (*p)->when.samples() + _offset.samples() + get_origin().samples();
|
||||||
}
|
}
|
||||||
|
|
||||||
timepos_t
|
timepos_t
|
||||||
AutomationLine::session_position (AutomationList::const_iterator p) const
|
AutomationLine::session_position (AutomationList::const_iterator p) const
|
||||||
{
|
{
|
||||||
return (*p)->when + _offset + _distance_measure.origin();
|
return (*p)->when + _offset + get_origin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1365,9 +1406,3 @@ AutomationLine::set_offset (timecnt_t const & off)
|
||||||
_offset = off;
|
_offset = off;
|
||||||
reset ();
|
reset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
AutomationLine::set_distance_measure_origin (timepos_t const & pos)
|
|
||||||
{
|
|
||||||
_distance_measure.set_origin (pos);
|
|
||||||
}
|
|
||||||
|
|
|
@ -37,8 +37,6 @@
|
||||||
#include "pbd/statefuldestructible.h"
|
#include "pbd/statefuldestructible.h"
|
||||||
#include "pbd/memento_command.h"
|
#include "pbd/memento_command.h"
|
||||||
|
|
||||||
#include "temporal/time_converter.h"
|
|
||||||
|
|
||||||
#include "ardour/automation_list.h"
|
#include "ardour/automation_list.h"
|
||||||
#include "ardour/parameter_descriptor.h"
|
#include "ardour/parameter_descriptor.h"
|
||||||
#include "ardour/types.h"
|
#include "ardour/types.h"
|
||||||
|
@ -71,11 +69,13 @@ public:
|
||||||
TimeAxisView& tv,
|
TimeAxisView& tv,
|
||||||
ArdourCanvas::Item& parent,
|
ArdourCanvas::Item& parent,
|
||||||
boost::shared_ptr<ARDOUR::AutomationList> al,
|
boost::shared_ptr<ARDOUR::AutomationList> al,
|
||||||
const ARDOUR::ParameterDescriptor& desc,
|
const ARDOUR::ParameterDescriptor& desc);
|
||||||
Temporal::DistanceMeasure const &);
|
|
||||||
|
|
||||||
virtual ~AutomationLine ();
|
virtual ~AutomationLine ();
|
||||||
|
|
||||||
|
virtual Temporal::timepos_t get_origin () const;
|
||||||
|
|
||||||
void queue_reset ();
|
void queue_reset ();
|
||||||
void reset ();
|
void reset ();
|
||||||
void clear ();
|
void clear ();
|
||||||
|
@ -164,9 +164,6 @@ public:
|
||||||
samplepos_t session_sample_position (ARDOUR::AutomationList::const_iterator) const;
|
samplepos_t session_sample_position (ARDOUR::AutomationList::const_iterator) const;
|
||||||
Temporal::timepos_t session_position (ARDOUR::AutomationList::const_iterator) const;
|
Temporal::timepos_t session_position (ARDOUR::AutomationList::const_iterator) const;
|
||||||
|
|
||||||
Temporal::DistanceMeasure const & distance_measure () const { return _distance_measure; }
|
|
||||||
void set_distance_measure_origin (Temporal::timepos_t const &);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::string _name;
|
std::string _name;
|
||||||
|
@ -245,7 +242,6 @@ private:
|
||||||
bool _fill;
|
bool _fill;
|
||||||
|
|
||||||
const ARDOUR::ParameterDescriptor _desc;
|
const ARDOUR::ParameterDescriptor _desc;
|
||||||
Temporal::DistanceMeasure _distance_measure;
|
|
||||||
|
|
||||||
friend class AudioRegionGainLine;
|
friend class AudioRegionGainLine;
|
||||||
};
|
};
|
||||||
|
|
|
@ -305,8 +305,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
||||||
*this,
|
*this,
|
||||||
*_canvas_display,
|
*_canvas_display,
|
||||||
_control->alist(),
|
_control->alist(),
|
||||||
_control->desc(),
|
_control->desc()
|
||||||
Temporal::DistanceMeasure (timepos_t()) /* default distance measure, origin at absolute zero */
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -868,8 +867,7 @@ AutomationTimeAxisView::paste_one (timepos_t const & pos, unsigned paste_count,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert position to model's unit and position */
|
/* convert position to model's unit and position */
|
||||||
Temporal::DistanceMeasure const & dm (_line->distance_measure());
|
Temporal::timepos_t model_pos (_line->get_origin().distance (tpos));
|
||||||
Temporal::timepos_t model_pos = dm (_line->distance_measure().origin().distance (tpos), line()->the_list()->time_domain());
|
|
||||||
|
|
||||||
XMLNode &before = alist->get_state();
|
XMLNode &before = alist->get_state();
|
||||||
alist->paste (**p, model_pos);
|
alist->paste (**p, model_pos);
|
||||||
|
@ -1143,9 +1141,8 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
||||||
XMLNode &before = alist->get_state();
|
XMLNode &before = alist->get_state();
|
||||||
|
|
||||||
/* convert time selection to automation list model coordinates */
|
/* convert time selection to automation list model coordinates */
|
||||||
/* convert time selection to automation list model coordinates */
|
timepos_t start = selection.time.front().start().earlier (line.get_origin());
|
||||||
timepos_t start = selection.time.front().start().earlier (line.distance_measure().origin());
|
timepos_t end = selection.time.front().end().earlier (line.get_origin());
|
||||||
timepos_t end = selection.time.front().end().earlier (line.distance_measure().origin());
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Delete:
|
case Delete:
|
||||||
|
|
|
@ -6537,7 +6537,7 @@ AutomationRangeDrag::setup (list<boost::shared_ptr<AutomationLine> > const & lin
|
||||||
//TODO: if we implement automation regions, this check can probably be removed
|
//TODO: if we implement automation regions, this check can probably be removed
|
||||||
AudioRegionGainLine *argl = dynamic_cast<AudioRegionGainLine*> ((*i).get());
|
AudioRegionGainLine *argl = dynamic_cast<AudioRegionGainLine*> ((*i).get());
|
||||||
if (!argl) {
|
if (!argl) {
|
||||||
//in automation lanes, the EFFECTIVE range should be considered 0->max_samplepos (even if there is no line)
|
//in automation lanes, the EFFECTIVE range should be considered 0->max_position (even if there is no line)
|
||||||
r.first = Temporal::timepos_t ((*i)->the_list()->time_domain());
|
r.first = Temporal::timepos_t ((*i)->the_list()->time_domain());
|
||||||
r.second = Temporal::timepos_t::max ((*i)->the_list()->time_domain());
|
r.second = Temporal::timepos_t::max ((*i)->the_list()->time_domain());
|
||||||
}
|
}
|
||||||
|
@ -6702,6 +6702,23 @@ AutomationRangeDrag::motion (GdkEvent*, bool first_move)
|
||||||
/* here's a control point on this line */
|
/* here's a control point on this line */
|
||||||
ControlPoint* p = i->line->nth (j);
|
ControlPoint* p = i->line->nth (j);
|
||||||
#warning NUTEMPO figure out what this code is/was doing and replace it
|
#warning NUTEMPO figure out what this code is/was doing and replace it
|
||||||
|
/*
|
||||||
|
convert is <double,samplepos_t> ... double meant beats
|
||||||
|
so origin_b is the origin in samplepos_t (since a=double b=samplepos_t)
|
||||||
|
|
||||||
|
so ->to() returns samples
|
||||||
|
|
||||||
|
so to (p->model->when) is the beat time (as dobule)
|
||||||
|
we convert to samples
|
||||||
|
then add the originin samples
|
||||||
|
|
||||||
|
BUT ... mostly used IdentityConverter, except MIDI
|
||||||
|
|
||||||
|
where the time_converter() is a source-relative converter
|
||||||
|
source-relative uses the the source_position() as the origin
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
//double const w = i->line->time_converter().to ((*p->model())->when) + i->line->time_converter().origin_b ();
|
//double const w = i->line->time_converter().to ((*p->model())->when) + i->line->time_converter().origin_b ();
|
||||||
double const w = 0;;
|
double const w = 0;;
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ MidiAutomationLine::MidiAutomationLine (
|
||||||
boost::shared_ptr<ARDOUR::AutomationList> list,
|
boost::shared_ptr<ARDOUR::AutomationList> list,
|
||||||
boost::shared_ptr<ARDOUR::MidiRegion> region,
|
boost::shared_ptr<ARDOUR::MidiRegion> region,
|
||||||
Evoral::Parameter parameter)
|
Evoral::Parameter parameter)
|
||||||
: AutomationLine (name, tav, parent, list, parameter, Temporal::DistanceMeasure (Temporal::timepos_t()))
|
: AutomationLine (name, tav, parent, list, parameter)
|
||||||
, _region (region)
|
, _region (region)
|
||||||
, _parameter (parameter)
|
, _parameter (parameter)
|
||||||
{
|
{
|
||||||
|
@ -51,6 +51,17 @@ MidiAutomationLine::memento_command_binder ()
|
||||||
return new ARDOUR::MidiAutomationListBinder (_region->midi_source(), _parameter);
|
return new ARDOUR::MidiAutomationListBinder (_region->midi_source(), _parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Temporal::timepos_t
|
||||||
|
MidiAutomationLine::get_origin() const
|
||||||
|
{
|
||||||
|
/* Events in the automation list are relative to the start of the
|
||||||
|
source, not the start of the region, so we need to use the
|
||||||
|
position-of-the-start-of-the-source, rather than just the
|
||||||
|
position-of-the-region.
|
||||||
|
*/
|
||||||
|
return _region->source_position();
|
||||||
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
MidiAutomationLine::get_verbose_cursor_string (double fraction) const
|
MidiAutomationLine::get_verbose_cursor_string (double fraction) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@ public:
|
||||||
MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
||||||
|
|
||||||
virtual std::string get_verbose_cursor_string (double) const;
|
virtual std::string get_verbose_cursor_string (double) const;
|
||||||
|
Temporal::timepos_t get_origin() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::shared_ptr<ARDOUR::MidiRegion> _region;
|
boost::shared_ptr<ARDOUR::MidiRegion> _region;
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "evoral/midi_util.h"
|
#include "evoral/midi_util.h"
|
||||||
#include "evoral/Note.h"
|
#include "evoral/Note.h"
|
||||||
|
|
||||||
#include "ardour/beats_samples_converter.h"
|
|
||||||
#include "ardour/midi_model.h"
|
#include "ardour/midi_model.h"
|
||||||
#include "ardour/midi_region.h"
|
#include "ardour/midi_region.h"
|
||||||
#include "ardour/midi_source.h"
|
#include "ardour/midi_source.h"
|
||||||
|
|
|
@ -44,7 +44,7 @@ using namespace ARDOUR;
|
||||||
using namespace PBD;
|
using namespace PBD;
|
||||||
|
|
||||||
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, ArdourCanvas::Container& parent, boost::shared_ptr<AutomationList> l)
|
AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView& r, ArdourCanvas::Container& parent, boost::shared_ptr<AutomationList> l)
|
||||||
: AutomationLine (name, r.get_time_axis_view(), parent, l, l->parameter(), Temporal::DistanceMeasure (r.region()->position()))
|
: AutomationLine (name, r.get_time_axis_view(), parent, l, l->parameter())
|
||||||
, rv (r)
|
, rv (r)
|
||||||
{
|
{
|
||||||
// If this isn't true something is horribly wrong, and we'll get catastrophic gain values
|
// If this isn't true something is horribly wrong, and we'll get catastrophic gain values
|
||||||
|
@ -57,6 +57,13 @@ AudioRegionGainLine::AudioRegionGainLine (const string & name, AudioRegionView&
|
||||||
terminal_points_can_slide = false;
|
terminal_points_can_slide = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
timepos_t
|
||||||
|
AudioRegionGainLine::get_origin() const
|
||||||
|
{
|
||||||
|
return rv.region()->position();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fraction)
|
AudioRegionGainLine::start_drag_single (ControlPoint* cp, double x, float fraction)
|
||||||
{
|
{
|
||||||
|
@ -110,10 +117,6 @@ AudioRegionGainLine::region_changed (const PropertyChange& what_changed)
|
||||||
interesting_stuff.add (ARDOUR::Properties::start);
|
interesting_stuff.add (ARDOUR::Properties::start);
|
||||||
interesting_stuff.add (ARDOUR::Properties::position);
|
interesting_stuff.add (ARDOUR::Properties::position);
|
||||||
|
|
||||||
if (what_changed.contains (ARDOUR::Properties::position)) {
|
|
||||||
set_distance_measure_origin (rv.region()->position());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (what_changed.contains (interesting_stuff)) {
|
if (what_changed.contains (interesting_stuff)) {
|
||||||
reset ();
|
reset ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ class AudioRegionGainLine : public AutomationLine
|
||||||
public:
|
public:
|
||||||
AudioRegionGainLine (const std::string & name, AudioRegionView&, ArdourCanvas::Container& parent, boost::shared_ptr<ARDOUR::AutomationList>);
|
AudioRegionGainLine (const std::string & name, AudioRegionView&, ArdourCanvas::Container& parent, boost::shared_ptr<ARDOUR::AutomationList>);
|
||||||
|
|
||||||
|
Temporal::timepos_t get_origin() const;
|
||||||
|
|
||||||
void start_drag_single (ControlPoint*, double, float);
|
void start_drag_single (ControlPoint*, double, float);
|
||||||
void end_drag (bool with_push, uint32_t final_index);
|
void end_drag (bool with_push, uint32_t final_index);
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
|
|
||||||
#include <sigc++/signal.h>
|
#include <sigc++/signal.h>
|
||||||
#include "ardour/region.h"
|
#include "ardour/region.h"
|
||||||
#include "ardour/beats_samples_converter.h"
|
|
||||||
|
|
||||||
#include "canvas/fwd.h"
|
#include "canvas/fwd.h"
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#ifndef __ardour_tempo_lines_h__
|
#ifndef __ardour_tempo_lines_h__
|
||||||
#define __ardour_tempo_lines_h__
|
#define __ardour_tempo_lines_h__
|
||||||
|
|
||||||
#include "ardour/beats_samples_converter.h"
|
|
||||||
#include "ardour/tempo.h"
|
#include "ardour/tempo.h"
|
||||||
|
|
||||||
#include "canvas/line_set.h"
|
#include "canvas/line_set.h"
|
||||||
|
|
Loading…
Reference in New Issue