From 4270569528c8972ae00060b4d52668deaeb35ea7 Mon Sep 17 00:00:00 2001 From: nick_m Date: Fri, 23 Sep 2016 05:06:03 +1000 Subject: Fix bug where drawing long notes placed the new note on the previous snap line. - NoteCreateDrag already applies this shift, so it was always applied twice to the note start frame. --- gtk2_ardour/editor_drag.cc | 15 +++++++-------- gtk2_ardour/midi_region_view.cc | 14 +++++++------- gtk2_ardour/midi_region_view.h | 5 +++-- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index c35d1fedef..f7b75a5855 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -6190,8 +6190,8 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) const framepos_t pf = _drags->current_pointer_frame (); const int32_t divisions = _editor->get_grid_music_divisions (event->button.state); - const double qaf = map.quarter_note_at_frame (pf); - double eqaf; + double eqaf = map.exact_qn_at_frame (pf, divisions); + if (divisions != 0) { bool success = false; Evoral::Beats grid_beats = _editor->get_grid_type_as_beats (success, pf); @@ -6199,17 +6199,16 @@ NoteCreateDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) grid_beats = Evoral::Beats(1); } - eqaf = map.exact_qn_at_frame (pf, divisions); + const double qaf = map.quarter_note_at_frame (pf); /* Hack so that we always snap to the note that we are over, instead of snapping to the next one if we're more than halfway through the one we're over. */ - const double rem = fmod (qaf, grid_beats.to_double()); - if (rem >= grid_beats.to_double() / 2.0) { + + const double rem = eqaf - qaf; + if (rem >= 0.0 && eqaf - grid_beats.to_double() > _region_view->region()->pulse() * 4.0) { eqaf -= grid_beats.to_double(); } - } else { - eqaf = qaf; } _note[0] = map.frame_at_quarter_note (eqaf) - _region_view->region()->position(); @@ -6257,7 +6256,7 @@ NoteCreateDrag::finished (GdkEvent* ev, bool had_movement) const double qn_length = map.quarter_note_at_frame (start_sess_rel + length) - map.quarter_note_at_frame (start_sess_rel); Evoral::Beats qn_length_beats = max (one_tick, Evoral::Beats (qn_length)); - _region_view->create_note_at (start, _drag_rect->y0(), qn_length_beats, ev->button.state); + _region_view->create_note_at (start, _drag_rect->y0(), qn_length_beats, ev->button.state, false); } double diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc index 49aac7bbc0..a2aa46f3ff 100644 --- a/gtk2_ardour/midi_region_view.cc +++ b/gtk2_ardour/midi_region_view.cc @@ -551,7 +551,7 @@ MidiRegionView::button_release (GdkEventButton* ev) group->canvas_to_item (event_x, event_y); Evoral::Beats beats = get_grid_beats(editor.pixel_to_sample(event_x) + _region->position()); - create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state); + create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state, true); } else { clear_editor_note_selection (); } @@ -561,7 +561,7 @@ MidiRegionView::button_release (GdkEventButton* ev) case MouseDraw: { Evoral::Beats beats = get_grid_beats(editor.pixel_to_sample(event_x) + _region->position()); - create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state); + create_note_at (editor.pixel_to_sample (event_x), event_y, beats, ev->state, true); break; } default: @@ -916,7 +916,7 @@ MidiRegionView::show_list_editor () * \param snap_t true to snap t to the grid, otherwise false. */ void -MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state) +MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state, bool shift_snap) { if (length < 2 * DBL_EPSILON) { return; @@ -932,7 +932,7 @@ MidiRegionView::create_note_at (framepos_t t, double y, Evoral::Beats length, ui // Start of note in frames relative to region start const int32_t divisions = trackview.editor().get_grid_music_divisions (state); - Evoral::Beats beat_time = snap_frame_to_grid_underneath (t, divisions); + Evoral::Beats beat_time = snap_frame_to_grid_underneath (t, divisions, shift_snap); const double note = view->y_to_note(y); const uint8_t chan = mtv->get_channel_for_add(); @@ -3743,7 +3743,7 @@ MidiRegionView::update_ghost_note (double x, double y, uint32_t state) framepos_t const unsnapped_frame = editor.pixel_to_sample (x); const int32_t divisions = editor.get_grid_music_divisions (state); - const double snapped_region_qn = snap_frame_to_grid_underneath (unsnapped_frame, divisions).to_double(); + const double snapped_region_qn = snap_frame_to_grid_underneath (unsnapped_frame, divisions, true).to_double(); Evoral::Beats snapped_beats = Evoral::Beats (snapped_region_qn); /* calculate time in beats relative to start of source */ @@ -4116,12 +4116,12 @@ MidiRegionView::get_velocity_for_add (MidiModel::TimeType time) const * @return beat duration of p snapped to the grid subdivision underneath it. */ Evoral::Beats -MidiRegionView::snap_frame_to_grid_underneath (framepos_t p, int32_t divisions) const +MidiRegionView::snap_frame_to_grid_underneath (framepos_t p, int32_t divisions, bool shift_snap) const { TempoMap& map (trackview.session()->tempo_map()); double eqaf = map.exact_qn_at_frame (p + _region->position(), divisions); - if (divisions != 0) { + if (divisions != 0 && shift_snap) { const double qaf = map.quarter_note_at_frame (p + _region->position()); /* Hack so that we always snap to the note that we are over, instead of snapping to the next one if we're more than halfway through the one we're over. diff --git a/gtk2_ardour/midi_region_view.h b/gtk2_ardour/midi_region_view.h index c79227d5a9..db769b44fc 100644 --- a/gtk2_ardour/midi_region_view.h +++ b/gtk2_ardour/midi_region_view.h @@ -325,8 +325,9 @@ public: * \param y vertical position in pixels * \param length duration of the note in beats * \param state the keyboard modifier mask for the canvas event (click). + * \param shift_snap true alters snap behavior to round down always (false if the gui has already done that). */ - void create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state); + void create_note_at (framepos_t t, double y, Evoral::Beats length, uint32_t state, bool shift_snap); /** An external request to clear the note selection, remove MRV from editor * selection. @@ -508,7 +509,7 @@ private: bool _mouse_changed_selection; - Evoral::Beats snap_frame_to_grid_underneath (framepos_t p, int32_t divisions) const; + Evoral::Beats snap_frame_to_grid_underneath (framepos_t p, int32_t divisions, bool shift_snap) const; PBD::ScopedConnection _mouse_mode_connection; -- cgit v1.2.3