Fix MIDI edit opertaiont (trim, draw) across tempo-changes

In the presence of tempo-changes distinguishing between offsets and
absolute positions is signficant. It is only valid to convert absolute
times using the tempo-map

Furthermore since GUI zoom-factor is time-invariant (samples per pixel),
all GUI operations must explictly use samples (or timecnt). It is not
valid (and problematic) to use use a location dependent timepos.
This commit is contained in:
Robin Gareus 2022-10-23 19:12:31 +02:00
parent 0504db2a67
commit 63c78ebced
6 changed files with 22 additions and 22 deletions

View file

@ -192,7 +192,7 @@ AutomationRegionView::add_automation_event (GdkEvent *, timepos_t const & w, dou
/* snap time */
when = snap_region_time_to_region_time (when.earlier (_region->start()), false) + _region->start ();
when = snap_region_time_to_region_time (_region->start().distance (when), false) + _region->start ();
/* map using line */

View file

@ -6692,11 +6692,11 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor)
* coordinates relative to the region in order to draw it correctly.
*/
const timepos_t rrp1 (_region_view->region()->region_relative_position (_note[0]));
const timepos_t rrp2 (_region_view->region()->region_relative_position (_note[1]));
const timecnt_t rrp1 (_region_view->region()->region_relative_position (_note[0]));
const timecnt_t rrp2 (_region_view->region()->region_relative_position (_note[1]));
double const x0 = _editor->time_to_pixel (rrp1);
double const x1 = _editor->time_to_pixel (rrp2);
double const x0 = _editor->sample_to_pixel (rrp1.samples ());
double const x1 = _editor->sample_to_pixel (rrp2.samples ());
double const y = _region_view->note_to_y (_region_view->y_to_note (y_to_region (event->button.y)));
_drag_rect->set (ArdourCanvas::Rect (x0, y, x1, y + floor (_region_view->midi_stream_view()->note_height ())));
@ -6717,11 +6717,11 @@ NoteCreateDrag::motion (GdkEvent* event, bool)
_note[1] = timepos_t (max (Temporal::Beats(), aligned_beats));
const timepos_t rrp1 (_region_view->region()->region_relative_position (_note[0]));
const timepos_t rrp2 (_region_view->region()->region_relative_position (_note[1]));
const timecnt_t rrp1 (_region_view->region()->region_relative_position (_note[0]));
const timecnt_t rrp2 (_region_view->region()->region_relative_position (_note[1]));
double const x0 = _editor->time_to_pixel (rrp1);
double const x1 = _editor->time_to_pixel (rrp2);
double const x0 = _editor->sample_to_pixel (rrp1.samples());
double const x1 = _editor->sample_to_pixel (rrp2.samples());
_drag_rect->set_x0 (std::min(x0, x1));
_drag_rect->set_x1 (std::max(x0, x1));
}

View file

@ -2527,8 +2527,8 @@ MidiRegionView::update_drag_selection(timepos_t const & start, timepos_t const &
// Convert to local coordinates
const double y = midi_view()->y_position();
const double x0 = editor.time_to_pixel (max (timepos_t(), _region->region_relative_position (start)));
const double x1 = editor.time_to_pixel (max (timepos_t(), _region->region_relative_position (end)));
const double x0 = editor.sample_to_pixel (max<samplepos_t>(0, _region->region_relative_position (start).samples()));
const double x1 = editor.sample_to_pixel (max<samplepos_t>(0, _region->region_relative_position (end).samples()));
const double y0 = max(0.0, gy0 - y);
const double y1 = max(0.0, gy1 - y);
@ -2941,11 +2941,11 @@ MidiRegionView::note_dropped(NoteBase *, timecnt_t const & d_qn, int8_t dnote, b
* Used for inverting the snap logic with key modifiers and snap delta calculation.
* @return Snapped time relative to the region position.
*/
timepos_t
timecnt_t
MidiRegionView::snap_pixel_to_time (double x, bool ensure_snap)
{
PublicEditor& editor (trackview.editor());
return snap_region_time_to_region_time (timepos_t (editor.pixel_to_sample (x)), ensure_snap);
return snap_region_time_to_region_time (timecnt_t (editor.pixel_to_sample (x)), ensure_snap);
}
/** @param x Pixel relative to the region position.
@ -2955,7 +2955,7 @@ MidiRegionView::snap_pixel_to_time (double x, bool ensure_snap)
double
MidiRegionView::snap_to_pixel(double x, bool ensure_snap)
{
return (double) trackview.editor().time_to_pixel(snap_pixel_to_time(x, ensure_snap));
return (double) trackview.editor().sample_to_pixel (snap_pixel_to_time(x, ensure_snap).samples());
}
double
@ -3188,11 +3188,11 @@ MidiRegionView::finish_resizing (NoteBase* primary, bool at_front, double delta_
}
/* Convert the new x position to a position within the source */
timepos_t current_time;
timecnt_t current_time;
if (with_snap) {
current_time = snap_pixel_to_time (current_x, ensure_snap);
} else {
current_time = timepos_t (trackview.editor().pixel_to_sample (current_x));
current_time = timecnt_t (trackview.editor().pixel_to_sample (current_x));
}
/* and then to beats */
@ -4124,7 +4124,7 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state)
_ghost_note->show();
/* calculate time in of a single grid units worth of beats, at the start of source */
const Temporal::Beats length = get_draw_length_beats (_region->source_position() + timepos_t (snapped_beats));
const Temporal::Beats length = get_draw_length_beats (_region->source_position() + timecnt_t (snapped_beats));
_ghost_note->note()->set_time (snapped_beats);
_ghost_note->note()->set_length (length);

View file

@ -279,9 +279,9 @@ public:
* @param x a pixel coordinate relative to region start
* @param ensure_snap ignore SnapOff and magnetic snap.
* Required for inverting snap logic with modifier keys and snap delta calculation.
* @return the snapped timepos_t coordinate relative to region start
* @return the snapped timecnt_t coordinate relative to region start
*/
Temporal::timepos_t snap_pixel_to_time (double x, bool ensure_snap = false);
Temporal::timecnt_t snap_pixel_to_time (double x, bool ensure_snap = false);
void goto_previous_note (bool add_to_selection);
void goto_next_note (bool add_to_selection);

View file

@ -1160,8 +1160,8 @@ RegionView::move_contents (timecnt_t const & distance)
* Used when inverting snap mode logic with key modifiers, or snap distance calculation.
* @return Snapped time offset from this region's position.
*/
timepos_t
RegionView::snap_region_time_to_region_time (timepos_t const & x, bool ensure_snap) const
timecnt_t
RegionView::snap_region_time_to_region_time (timecnt_t const & x, bool ensure_snap) const
{
PublicEditor& editor = trackview.editor();
/* x is region relative, convert it to global absolute time */

View file

@ -148,7 +148,7 @@ public:
}
};
Temporal::timepos_t snap_region_time_to_region_time (Temporal::timepos_t const &, bool ensure_snap = false) const;
Temporal::timecnt_t snap_region_time_to_region_time (Temporal::timecnt_t const &, bool ensure_snap = false) const;
void update_visibility ();