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 Temporal;
|
||||
|
||||
#define TIME_TO_SAMPLES(x) (_distance_measure (x, Temporal::AudioTime))
|
||||
#define SAMPLES_TO_TIME(x) (_distance_measure (x, alist->time_domain()))
|
||||
#define SAMPLES_TO_TIME(x) (get_origin().distance (x))
|
||||
|
||||
/** @param converter A TimeConverter whose origin_b is the start time of the AutomationList in session samples.
|
||||
* This will not be deleted by AutomationLine.
|
||||
@ -89,8 +88,7 @@ AutomationLine::AutomationLine (const string& name,
|
||||
TimeAxisView& tv,
|
||||
ArdourCanvas::Item& parent,
|
||||
boost::shared_ptr<AutomationList> al,
|
||||
const ParameterDescriptor& desc,
|
||||
Temporal::DistanceMeasure const & m)
|
||||
const ParameterDescriptor& desc)
|
||||
: trackview (tv)
|
||||
, _name (name)
|
||||
, alist (al)
|
||||
@ -99,7 +97,6 @@ AutomationLine::AutomationLine (const string& name,
|
||||
, _maximum_time (timepos_t::max (al->time_domain()))
|
||||
, _fill (false)
|
||||
, _desc (desc)
|
||||
, _distance_measure (m)
|
||||
{
|
||||
_visible = Line;
|
||||
|
||||
@ -139,6 +136,15 @@ AutomationLine::~AutomationLine ()
|
||||
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
|
||||
AutomationLine::event_handler (GdkEvent* event)
|
||||
{
|
||||
@ -762,6 +768,14 @@ AutomationLine::end_drag (bool with_push, uint32_t final_index)
|
||||
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
|
||||
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_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))) {
|
||||
/* convert from view coordinates, via pixels->samples->timepos_t
|
||||
const timepos_t absolute_time = model_time + get_origin();
|
||||
|
||||
/* 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;
|
||||
|
||||
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) */
|
||||
model_to_view_coord_y (view_y);
|
||||
@ -1346,13 +1387,13 @@ AutomationLine::get_point_x_range () const
|
||||
samplepos_t
|
||||
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
|
||||
AutomationLine::session_position (AutomationList::const_iterator p) const
|
||||
{
|
||||
return (*p)->when + _offset + _distance_measure.origin();
|
||||
return (*p)->when + _offset + get_origin();
|
||||
}
|
||||
|
||||
void
|
||||
@ -1365,9 +1406,3 @@ AutomationLine::set_offset (timecnt_t const & off)
|
||||
_offset = off;
|
||||
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/memento_command.h"
|
||||
|
||||
#include "temporal/time_converter.h"
|
||||
|
||||
#include "ardour/automation_list.h"
|
||||
#include "ardour/parameter_descriptor.h"
|
||||
#include "ardour/types.h"
|
||||
@ -71,11 +69,13 @@ public:
|
||||
TimeAxisView& tv,
|
||||
ArdourCanvas::Item& parent,
|
||||
boost::shared_ptr<ARDOUR::AutomationList> al,
|
||||
const ARDOUR::ParameterDescriptor& desc,
|
||||
Temporal::DistanceMeasure const &);
|
||||
const ARDOUR::ParameterDescriptor& desc);
|
||||
|
||||
|
||||
virtual ~AutomationLine ();
|
||||
|
||||
virtual Temporal::timepos_t get_origin () const;
|
||||
|
||||
void queue_reset ();
|
||||
void reset ();
|
||||
void clear ();
|
||||
@ -164,9 +164,6 @@ public:
|
||||
samplepos_t session_sample_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:
|
||||
|
||||
std::string _name;
|
||||
@ -245,7 +242,6 @@ private:
|
||||
bool _fill;
|
||||
|
||||
const ARDOUR::ParameterDescriptor _desc;
|
||||
Temporal::DistanceMeasure _distance_measure;
|
||||
|
||||
friend class AudioRegionGainLine;
|
||||
};
|
||||
|
@ -305,8 +305,7 @@ AutomationTimeAxisView::AutomationTimeAxisView (
|
||||
*this,
|
||||
*_canvas_display,
|
||||
_control->alist(),
|
||||
_control->desc(),
|
||||
Temporal::DistanceMeasure (timepos_t()) /* default distance measure, origin at absolute zero */
|
||||
_control->desc()
|
||||
)
|
||||
);
|
||||
|
||||
@ -868,8 +867,7 @@ AutomationTimeAxisView::paste_one (timepos_t const & pos, unsigned paste_count,
|
||||
}
|
||||
|
||||
/* convert position to model's unit and position */
|
||||
Temporal::DistanceMeasure const & dm (_line->distance_measure());
|
||||
Temporal::timepos_t model_pos = dm (_line->distance_measure().origin().distance (tpos), line()->the_list()->time_domain());
|
||||
Temporal::timepos_t model_pos (_line->get_origin().distance (tpos));
|
||||
|
||||
XMLNode &before = alist->get_state();
|
||||
alist->paste (**p, model_pos);
|
||||
@ -1143,9 +1141,8 @@ AutomationTimeAxisView::cut_copy_clear_one (AutomationLine& line, Selection& sel
|
||||
XMLNode &before = alist->get_state();
|
||||
|
||||
/* 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.distance_measure().origin());
|
||||
timepos_t end = selection.time.front().end().earlier (line.distance_measure().origin());
|
||||
timepos_t start = selection.time.front().start().earlier (line.get_origin());
|
||||
timepos_t end = selection.time.front().end().earlier (line.get_origin());
|
||||
|
||||
switch (op) {
|
||||
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
|
||||
AudioRegionGainLine *argl = dynamic_cast<AudioRegionGainLine*> ((*i).get());
|
||||
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.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 */
|
||||
ControlPoint* p = i->line->nth (j);
|
||||
#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 = 0;;
|
||||
|
||||
|
@ -38,7 +38,7 @@ MidiAutomationLine::MidiAutomationLine (
|
||||
boost::shared_ptr<ARDOUR::AutomationList> list,
|
||||
boost::shared_ptr<ARDOUR::MidiRegion> region,
|
||||
Evoral::Parameter parameter)
|
||||
: AutomationLine (name, tav, parent, list, parameter, Temporal::DistanceMeasure (Temporal::timepos_t()))
|
||||
: AutomationLine (name, tav, parent, list, parameter)
|
||||
, _region (region)
|
||||
, _parameter (parameter)
|
||||
{
|
||||
@ -51,6 +51,17 @@ MidiAutomationLine::memento_command_binder ()
|
||||
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
|
||||
MidiAutomationLine::get_verbose_cursor_string (double fraction) const
|
||||
{
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
MementoCommandBinder<ARDOUR::AutomationList>* memento_command_binder ();
|
||||
|
||||
virtual std::string get_verbose_cursor_string (double) const;
|
||||
Temporal::timepos_t get_origin() const;
|
||||
|
||||
private:
|
||||
boost::shared_ptr<ARDOUR::MidiRegion> _region;
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include "evoral/midi_util.h"
|
||||
#include "evoral/Note.h"
|
||||
|
||||
#include "ardour/beats_samples_converter.h"
|
||||
#include "ardour/midi_model.h"
|
||||
#include "ardour/midi_region.h"
|
||||
#include "ardour/midi_source.h"
|
||||
|
@ -44,7 +44,7 @@ using namespace ARDOUR;
|
||||
using namespace PBD;
|
||||
|
||||
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)
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
|
||||
timepos_t
|
||||
AudioRegionGainLine::get_origin() const
|
||||
{
|
||||
return rv.region()->position();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
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::position);
|
||||
|
||||
if (what_changed.contains (ARDOUR::Properties::position)) {
|
||||
set_distance_measure_origin (rv.region()->position());
|
||||
}
|
||||
|
||||
if (what_changed.contains (interesting_stuff)) {
|
||||
reset ();
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ class AudioRegionGainLine : public AutomationLine
|
||||
public:
|
||||
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 end_drag (bool with_push, uint32_t final_index);
|
||||
|
||||
|
@ -32,7 +32,6 @@
|
||||
|
||||
#include <sigc++/signal.h>
|
||||
#include "ardour/region.h"
|
||||
#include "ardour/beats_samples_converter.h"
|
||||
|
||||
#include "canvas/fwd.h"
|
||||
|
||||
|
@ -21,7 +21,6 @@
|
||||
#ifndef __ardour_tempo_lines_h__
|
||||
#define __ardour_tempo_lines_h__
|
||||
|
||||
#include "ardour/beats_samples_converter.h"
|
||||
#include "ardour/tempo.h"
|
||||
|
||||
#include "canvas/line_set.h"
|
||||
|
Loading…
Reference in New Issue
Block a user